Advertisement
AlezM

Sonya MPI

Mar 16th, 2019
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.98 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4.  
  5. double RandomDouble(double min = -1, double max = 1)
  6. {
  7.     double f = (double)std::rand() / RAND_MAX;
  8.     return min + f * (max - min);
  9. }
  10.  
  11. std::vector<double> RandomDoubleVector(size_t size, double min = -1, double max = 1)
  12. {
  13.     auto vector = std::vector<double>(size);
  14.     for (int i = 0; i < size; ++i) {
  15.         vector[i] = RandomDouble(min, max);
  16.     }
  17.  
  18.     return vector;
  19. }
  20.  
  21. class Matrix {
  22. public:
  23.     Matrix(size_t size) : _size(size), _data(size * size) {}
  24.     Matrix(size_t size, std::vector<double> data) : _size(size), _data(size * size) {
  25.         _data = data;
  26.     }
  27.     double& operator()(size_t i, size_t j) {
  28.         return _data[i * _size + j];
  29.     }
  30.     double operator()(size_t i, size_t j) const {
  31.         return _data[i * _size + j];
  32.     }
  33.     static Matrix I(size_t size) {
  34.         auto matrix = Matrix(size);
  35.         for (size_t i = 0; i < size; ++i)
  36.             matrix(i, i) = 1;
  37.  
  38.         return matrix;
  39.     }
  40.     static Matrix Zero(size_t size) {
  41.         auto matrix = Matrix(size);
  42.         return matrix;
  43.     }
  44.  
  45.     static Matrix RandomMatrix(size_t size, double min = -1, double max = 1) {
  46.         auto matrix = Matrix(size);
  47.         for (size_t i = 0; i < size; ++i)
  48.             for (size_t j = 0; j < size; ++j)
  49.                 matrix(i, j) = RandomDouble(min, max);
  50.  
  51.         return matrix;
  52.     }
  53.  
  54.     Matrix operator+(const Matrix& b) {
  55.         auto sum = Matrix(_size, _data);
  56.         for (size_t i = 0; i < _size; ++i)
  57.             for (size_t j = 0; j < _size; ++j)
  58.                 sum(i, j) += b(i, j);
  59.  
  60.         return sum;
  61.     }
  62.  
  63.     Matrix operator+(const double & d) {
  64.         auto sum = Matrix(_size, _data);
  65.         for (size_t i = 0; i < _size; ++i)
  66.             sum(i, i) += d;
  67.  
  68.         return sum;
  69.     }
  70.  
  71.     Matrix operator+=(const Matrix& b) {
  72.         for (size_t i = 0; i < _size; ++i)
  73.             for (size_t j = 0; j < _size; ++j)
  74.                 operator()(i, j) += b(i, j);
  75.  
  76.         return *this;
  77.     }
  78.  
  79.     Matrix operator*(const Matrix& b) {
  80.         auto product = Matrix(_size);
  81.  
  82.         for (size_t i = 0; i < _size; ++i)
  83.             for (size_t j = 0; j < _size; ++j)
  84.                 for (size_t k = 0; k < _size; ++k) {
  85.                     product(i, j) += operator()(i, k) * b(k, j);
  86.                 }
  87.  
  88.         return product;
  89.     }
  90.  
  91.     Matrix operator*(const double& d) {
  92.         auto scalarMult = Matrix(_size, _data);
  93.         for (size_t i = 0; i < _size; ++i)
  94.             for (size_t j = 0; j < _size; ++j)
  95.                 scalarMult(i, j) *= d;
  96.  
  97.         return scalarMult;
  98.     }
  99.  
  100.     Matrix Pow(size_t n) {
  101.         auto result = Matrix(_size);
  102.  
  103.         for (size_t i = 0; i < _size; i++)
  104.         {
  105.             result(i, i) = 1;
  106.         }
  107.  
  108.         for (size_t i = 0; i < n; i++) {
  109.             result = result * *this;
  110.         }
  111.  
  112.         return result;
  113.     }
  114.  
  115.     void Show() {
  116.         for (size_t i = 0; i < _size; ++i) {
  117.             for (size_t j = 0; j < _size; ++j)
  118.                 std::cout << operator()(i, j) << " ";
  119.             std::cout << std::endl;
  120.         }
  121.         std::cout << std::endl;
  122.     }
  123.  
  124.     size_t GetSize() {
  125.         return _size;
  126.     }
  127. private:
  128.     size_t _size;
  129.     std::vector<double> _data;
  130. };
  131.  
  132. Matrix Horner(std::vector<double> polinomialCoefs, Matrix& A) {
  133.     size_t matrixSize = A.GetSize();
  134.  
  135.     auto result = Matrix::I(matrixSize) * polinomialCoefs[polinomialCoefs.size() - 1];
  136.     for (int n = polinomialCoefs.size() - 2; n >= 0; n--) {
  137.         result = result * A + Matrix::I(matrixSize) * polinomialCoefs[n];
  138.     }
  139.  
  140.     return result;
  141. }
  142.  
  143. Matrix SimpleParallelHorner(std::vector<double> polinomialCoefs, Matrix &A, int threadsCount) {
  144.     size_t matrixSize = A.GetSize();
  145.  
  146.     auto result = Matrix::Zero(A.GetSize());
  147.  
  148.     for (int k = 0; k < threadsCount; k++)
  149.     {
  150.         auto part = Matrix::Zero(matrixSize);
  151.         for (int i = k, j = 0; i < polinomialCoefs.size(); i += threadsCount, j += threadsCount) {
  152.             part += A.Pow(j) * polinomialCoefs[i];
  153.         }
  154.  
  155.         part = A.Pow(k) * part;
  156.  
  157.         result += part;
  158.     }
  159.  
  160.     return result;
  161. }
  162.  
  163. Matrix TrueParallelHorner(std::vector<double> polinomialCoefs, Matrix &A, int threadsCount) {
  164.     size_t matrixSize = A.GetSize();
  165.  
  166.     auto result = Matrix::Zero(A.GetSize());
  167.  
  168.     for (int k = 0; k < threadsCount; k++)
  169.     {
  170.         std::vector<size_t> indexes(0);
  171.         for (int i = k; i < polinomialCoefs.size(); i += threadsCount) {
  172.             indexes.push_back(i);
  173.         }
  174.         std::reverse(std::begin(indexes), std::end(indexes));
  175.  
  176.         auto part = Matrix::I(matrixSize) * polinomialCoefs[indexes[0]];
  177.         for (int n = 1; n < indexes.size(); n++) {
  178.             part = part * A.Pow(threadsCount) + Matrix::I(matrixSize) * polinomialCoefs[indexes[n]];
  179.         }
  180.  
  181.         part = A.Pow(k) * part;
  182.  
  183.         result += part;
  184.     }
  185.  
  186.     return result;
  187. }
  188.  
  189. int main() {
  190.     size_t matrixSize = 3;
  191.     auto A = Matrix::RandomMatrix(matrixSize);
  192.     std::vector<double> polinomialCoefs = RandomDoubleVector(20, -5, 5);
  193.  
  194.     std::cout << "A:" << std::endl;
  195.     A.Show();
  196.  
  197.     std::cout << "Polinomial coefs:" << std::endl;
  198.     for (int i = 0; i < polinomialCoefs.size(); i++) {
  199.         std::cout << polinomialCoefs[i] << " ";
  200.     }
  201.     std::cout << std::endl << std::endl;
  202.  
  203.  
  204.     std::cout << "Forward method:" << std::endl;
  205.     auto P1 = Matrix(matrixSize);
  206.     for (size_t n = 0; n < polinomialCoefs.size(); n++) {
  207.         P1 += A.Pow(n) * polinomialCoefs[n];
  208.     }
  209.     P1.Show();
  210.  
  211.     std::cout << "Horner method:" << std::endl;
  212.     auto P2 = Horner(polinomialCoefs, A);
  213.     P2.Show();
  214.  
  215.     std::cout << "Parallel Horner method:" << std::endl;
  216.     auto P3 = SimpleParallelHorner(polinomialCoefs, A, 3);
  217.     P3.Show();
  218.  
  219.     std::cout << "Improved parallel Horner method:" << std::endl;
  220.     auto P4 = TrueParallelHorner(polinomialCoefs, A, 4);
  221.     P4.Show();
  222.  
  223.     return 0;
  224. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement