Advertisement
AlezM

Untitled

Mar 17th, 2019
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.16 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. #include "mpi.h"
  5.  
  6. double RandomDouble(double min = -1, double max = 1)
  7. {
  8.     double f = (double)std::rand() / RAND_MAX;
  9.     return min + f * (max - min);
  10. }
  11.  
  12. std::vector<double> RandomDoubleVector(size_t size, double min = -1, double max = 1)
  13. {
  14.     std::vector<double> vector = std::vector<double>(size);
  15.     for (int i = 0; i < size; ++i) {
  16.         vector[i] = RandomDouble(min, max);
  17.     }
  18.  
  19.     return vector;
  20. }
  21.  
  22. class Matrix {
  23. public:
  24.     Matrix(size_t size) : _size(size), _data(size * size) {}
  25.     Matrix(size_t size, std::vector<double> data) : _size(size), _data(size * size) {
  26.         _data = data;
  27.     }
  28.     double& operator()(size_t i, size_t j) {
  29.         return _data[i * _size + j];
  30.     }
  31.     double operator()(size_t i, size_t j) const {
  32.         return _data[i * _size + j];
  33.     }
  34.     static Matrix I(size_t size) {
  35.         Matrix matrix = Matrix(size);
  36.         for (size_t i = 0; i < size; ++i)
  37.             matrix(i, i) = 1;
  38.  
  39.         return matrix;
  40.     }
  41.     static Matrix Zero(size_t size) {
  42.         Matrix matrix = Matrix(size);
  43.         return matrix;
  44.     }
  45.  
  46.     static Matrix RandomMatrix(size_t size, double min = -1, double max = 1) {
  47.         Matrix matrix = Matrix(size);
  48.         for (size_t i = 0; i < size; ++i)
  49.             for (size_t j = 0; j < size; ++j)
  50.                 matrix(i, j) = RandomDouble(min, max);
  51.  
  52.         return matrix;
  53.     }
  54.  
  55.     Matrix operator+(const Matrix& b) {
  56.         Matrix sum = Matrix(_size, _data);
  57.         for (size_t i = 0; i < _size; ++i)
  58.             for (size_t j = 0; j < _size; ++j)
  59.                 sum(i, j) += b(i, j);
  60.  
  61.         return sum;
  62.     }
  63.  
  64.     Matrix operator+(const double & d) {
  65.         Matrix sum = Matrix(_size, _data);
  66.         for (size_t i = 0; i < _size; ++i)
  67.             sum(i, i) += d;
  68.  
  69.         return sum;
  70.     }
  71.  
  72.     Matrix operator+=(const Matrix& b) {
  73.         for (size_t i = 0; i < _size; ++i)
  74.             for (size_t j = 0; j < _size; ++j)
  75.                 operator()(i, j) += b(i, j);
  76.  
  77.         return *this;
  78.     }
  79.  
  80.     Matrix operator*(const Matrix& b) {
  81.         Matrix product = Matrix(_size);
  82.  
  83.         for (size_t i = 0; i < _size; ++i)
  84.             for (size_t j = 0; j < _size; ++j)
  85.                 for (size_t k = 0; k < _size; ++k) {
  86.                     product(i, j) += operator()(i, k) * b(k, j);
  87.                 }
  88.  
  89.         return product;
  90.     }
  91.  
  92.     Matrix operator*(const double& d) {
  93.         Matrix scalarMult = Matrix(_size, _data);
  94.         for (size_t i = 0; i < _size; ++i)
  95.             for (size_t j = 0; j < _size; ++j)
  96.                 scalarMult(i, j) *= d;
  97.  
  98.         return scalarMult;
  99.     }
  100.  
  101.     Matrix Pow(size_t n) {
  102.         Matrix result = Matrix(_size);
  103.  
  104.         for (size_t i = 0; i < _size; i++)
  105.         {
  106.             result(i, i) = 1;
  107.         }
  108.  
  109.         for (size_t i = 0; i < n; i++) {
  110.             result = result * *this;
  111.         }
  112.  
  113.         return result;
  114.     }
  115.  
  116.     void Show() {
  117.         for (size_t i = 0; i < _size; ++i) {
  118.             for (size_t j = 0; j < _size; ++j)
  119.                 std::cout << operator()(i, j) << " ";
  120.             std::cout << std::endl;
  121.         }
  122.         std::cout << std::endl;
  123.     }
  124.  
  125.     size_t GetSize() {
  126.         return _size;
  127.     }
  128. private:
  129.     size_t _size;
  130.     std::vector<double> _data;
  131. };
  132.  
  133. int main(int argc, char* argv[]) {
  134.     size_t matrixSize = 200;
  135.     Matrix A = Matrix::RandomMatrix(matrixSize);
  136.     std::vector<double> polinomialCoefs = RandomDoubleVector(20, -5, 5);
  137.  
  138.     int threadsCount;
  139.     int myRank;
  140.     MPI_Init(&argc, &argv);
  141.     MPI_Comm_size(MPI_COMM_WORLD, &threadsCount); // Find number of processes
  142.     MPI_Comm_rank(MPI_COMM_WORLD, &myRank);
  143.  
  144.     std::cout << "Improved parallel Horner method:" << std::endl;
  145.     std::cout << "Matrix size: " << matrixSize << "x" << matrixSize << std::endl;
  146.     std::cout << "Polynomial rang: " << polinomialCoefs.size() << std::endl;
  147.     std::cout << "Threads: " << threadsCount << std::endl;
  148.  
  149.     clock_t begin = clock();
  150.  
  151.     Matrix result = Matrix::Zero(A.GetSize());
  152.  
  153.     {
  154.         std::vector<size_t> indexes(0);
  155.         for (int i = myRank; i < polinomialCoefs.size(); i += threadsCount) {
  156.             indexes.push_back(i);
  157.         }
  158.         std::reverse(std::begin(indexes), std::end(indexes));
  159.  
  160.         Matrix APowered = A.Pow(threadsCount);
  161.         Matrix I = Matrix::I(matrixSize);
  162.         Matrix part = Matrix::I(matrixSize) * polinomialCoefs[indexes[0]];
  163.         for (int n = 1; n < indexes.size(); n++) {
  164.             part = part * APowered + I * polinomialCoefs[indexes[n]];
  165.         }
  166.  
  167.         part = A.Pow(myRank) * part;
  168.  
  169.         part.Show();
  170.     }
  171.  
  172.     clock_t end = clock();
  173.     std::cout << "Done in " << double(end - begin) / CLOCKS_PER_SEC << " sec." << std::endl;
  174.  
  175.     return 0;
  176. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement