Advertisement
AlezM

Untitled

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