Advertisement
Guest User

Untitled

a guest
Mar 31st, 2019
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.42 KB | None | 0 0
  1. /**********
  2.  GENERIC MATRIX IMPLEMENTATION
  3.  CHRIS DE CLAVERIE <c.de-claverie@pm.me>
  4.  VERSION 1.0
  5. **********/
  6.  
  7. #ifndef MATRIX_HEADER_INCLUDED
  8. #define MATRIX_HEADER_INCLUDED
  9.  
  10. #include <vector>
  11. #include <cassert>
  12. #include <utility>
  13. #include <random>
  14. #include <functional>
  15.  
  16.  
  17. template<class T>
  18. class Matrix {
  19. protected:
  20.     std::vector<std::vector<T>> data;
  21.  
  22. public:
  23.     // CONSTRUCTORS & DESTRUCTORS
  24.     Matrix() : data{ {T{}} } {}; // Implemented
  25.     Matrix(std::vector<std::vector<T>> _data) : data{ _data } {}; // Implemented
  26.     Matrix(unsigned int const lines, unsigned int const cols) { // Implemented
  27.         for (unsigned int i = 0; i < lines; i++) { this->data.push_back(std::vector<T>(cols, T())); }
  28.     };
  29.     template<class T2> Matrix(Matrix<T2> const& other) : data{ other.data } {}; // Implemented
  30.  
  31.     // UTILITIES
  32.     unsigned int cols(); // Implemented
  33.     unsigned int lines(); // Implemented
  34.  
  35.     // OPERATORS
  36.     std::vector<T> operator[](unsigned int line); // Implemented
  37.     template<class T2> auto operator+(Matrix<T2> const& other); // Implemented
  38.     template<class T2> auto operator-(Matrix<T2> const& other);
  39.     Matrix<T> operator-();
  40.     template<class T2> bool operator==(Matrix<T2> const& other);
  41.     template<class T2> Matrix<T> const& operator=(Matrix<T2> const& other);
  42.  
  43.     // MATHEMATICS
  44.     T det(); // Implemented
  45.     template<class T2> auto dot(Matrix<T2> const& other);  // Implemented
  46.     Matrix<T> transp(); // Implemented
  47.     std::vector<T> diag(); // Implemented
  48.     Matrix<T> inv(); // Implemented
  49.     Matrix<T> tri_lo(bool include_diag = false) const; // Implemented
  50.     Matrix<T> tri_up(bool include_diag = false); // Implemented
  51.     T highest_eigenval();
  52.     T lowest_eigenval();
  53.     std::vector<T> eigenvals();
  54.     Matrix<T> abs(); // Implemented
  55.     T norm(); // Implemented
  56.     Matrix<T> comatrix(); // Implemented
  57.  
  58.     // GENERATORS
  59.     static Matrix<T> gen_random(unsigned int size, T min, T max); // Implemented
  60.     static Matrix<T> gen_random(unsigned int lines, unsigned int cols, T min, T max);
  61.     static Matrix<T> gen_diag(unsigned int size, T value = T()); // Implemented
  62.     static Matrix<T> gen_diag(unsigned int lines, unsigned int cols, T value = T()); // Implemented
  63.     static Matrix<T> gen_diag(std::vector<T> values); // Implemented
  64.     static Matrix<T> gen_full(unsigned int size, T value = T()); // Implemented
  65.     static Matrix<T> gen_full(unsigned int lines, unsigned int cols, T value = T()); // Implemented
  66.  
  67.     // COMPARATORS
  68.     static bool allclose(std::vector<Matrix<T>> matrices, long double abs_precision, long double rel_precision);
  69. };
  70.  
  71. template<class T>
  72. unsigned int Matrix<T>::cols() { return this->data.size(); };
  73.  
  74. template<class T>
  75. unsigned int Matrix<T>::lines() { return this->data[0].size(); };
  76.  
  77. template<class T>
  78. std::vector<T> Matrix<T>::operator[](unsigned int line) { return this->data[line]; };
  79.  
  80. template<class T>
  81. template<class T2>
  82. auto Matrix<T>::dot(Matrix<T2> const& other) { // Here, auto is decltype(std::declval<T>() * std::declval<T2>())
  83.     assert(this->cols() == other.lines());
  84.     assert(this->lines() == other.cols());
  85.  
  86.     decltype (std::declval<T>()*std::declval<T2>()) T3;
  87.     Matrix<T3> result = Matrix<T3>::gen_full(this->lines(), other.cols());
  88.  
  89.     for(unsigned int i = 0; i < result.lines(); i++) {
  90.         for(unsigned int j = 0; j < result.cols(); i++) {
  91.  
  92.             unsigned int total = 0;
  93.             for(unsigned int pos = 0; pos < this->cols(); pos++) {
  94.                 total += ((*this)[i][pos] * other[pos][j]);
  95.             }
  96.             result.data[i][j] = total;
  97.         }
  98.     }
  99.  
  100.     return result;
  101. };
  102.  
  103. template<class T>
  104. Matrix<T> Matrix<T>::transp() {
  105.     Matrix<T> result = Matrix<T>::gen_uninitialized(this->cols(), this->lines());
  106.     for(unsigned int i = 0; i < this->lines(); i++) {
  107.         for(unsigned int j = 0; j < this->cols(); j++) {
  108.             result[i][j] = this[j][i];
  109.         }
  110.     }
  111.  
  112.     return result;
  113. };
  114.  
  115. template<class T>
  116. Matrix<T> Matrix<T>::gen_random(unsigned int lines, unsigned int cols, T min, T max) {
  117.     std::default_random_engine generator;
  118.     std::uniform_real_distribution<T> distribution(min, max);
  119.     auto generate = std::bind(distribution, generator);
  120.  
  121.     Matrix<T> result;
  122.     for (unsigned int i = 0; i < lines; i++) {
  123.         std::vector<T> line;
  124.         for (unsigned int j = 0; j < cols; j++) {
  125.             line.push_back(generate());
  126.         }
  127.         result.data.push_back(line);
  128.     }
  129.  
  130.     return result;
  131. }
  132.  
  133. template<class T>
  134. Matrix<T> Matrix<T>::gen_random(unsigned int size, T min, T max) { return Matrix<T>::gen_random(size, size, min, max); };
  135.  
  136. template<class T>
  137. Matrix<T> Matrix<T>::gen_diag(unsigned int lines, unsigned int cols, T value) {
  138.     Matrix<T> result;
  139.    
  140.     for(unsigned int i = 0; i < lines; i++) {
  141.         for(unsigned int j = 0; j < cols; j++) {
  142.             long l;
  143.             if (i == j) {
  144.                 result[i][j] = value;
  145.             } else {
  146.                 result[i][j] = T();
  147.             }
  148.         }
  149.     }
  150.  
  151.     return result;
  152. };
  153.  
  154. template<class T>
  155. Matrix<T> Matrix<T>::gen_diag(unsigned int size, T value) {
  156.     return Matrix<T>::gen_diag(size, size, value);
  157. }
  158.  
  159. template<class T>
  160. Matrix<T> Matrix<T>::gen_diag(std::vector<T> values) {
  161.     Matrix<T> result;
  162.     unsigned int pos = 0;
  163.  
  164.     for(unsigned int i = 0; i < values.size(); i++) {
  165.         for(unsigned int j = 0; j < values.size(); j++) {
  166.             long l;
  167.             if (i == j) {
  168.                 result[i][j] = values[pos];
  169.                 i++;
  170.             } else {
  171.                 result[i][j] = T(0);
  172.             }
  173.         }
  174.     }
  175.  
  176.     return result;
  177. }
  178.  
  179. template<class T>
  180. Matrix<T> Matrix<T>::gen_full(unsigned int lines, unsigned int cols, T value){
  181.     for(unsigned int i = 0; i < lines; i++) {
  182.         std::vector<T> line;
  183.         for(unsigned int j = 0; j < cols; j++) {
  184.             line.push_back(value);
  185.         }
  186.         this->data.push_back(line);
  187.     }
  188. };
  189.  
  190. template<class T>
  191. Matrix<T> Matrix<T>::gen_full(unsigned int size, T value) {
  192.     return Matrix<T>::gen_full(size, size, value);
  193. }
  194.  
  195. template<class T>
  196. T Matrix<T>::det() {
  197.     T det = T();
  198.     if (this->data[0].size() == 1) {
  199.         det = this->data[0][0];
  200.     }
  201.     else {
  202.         for (int p = 0; p < this->cols(); p++) {
  203.  
  204.             std::vector<std::vector<T>> sub_data(this->data.size() - 1);
  205.             for (int i = 0; i < this->lines(); i++) {
  206.                 std::vector<T> line;
  207.                 for (int j = 0; j < this->cols(); j++) {
  208.                     if (i != j) {
  209.                         line.push_back(this->data[i][j]);
  210.                     }
  211.                 }
  212.                 sub_data.push_back(line);
  213.             }
  214.  
  215.             Matrix<T> sub(sub_data);
  216.             det += std::pow((-1), (p + 1)) * data[0][p] * det(sub);
  217.         }
  218.     }
  219.     return det;
  220. }
  221.  
  222. template<class T>
  223. std::vector<T> Matrix<T>::diag() {
  224.     std::vector<T> diag();
  225.     for (int i = 0; i < std::min(this->lines(), this->cols()); i++) {
  226.         diag.push_back(this->data[i][i]);
  227.     }
  228. }
  229.  
  230. template<class T>
  231. Matrix<T> Matrix<T>::comatrix() {
  232.     Matrix<T> res(this->lines(), this->cols());
  233.     for (unsigned int i = 0; i < this->lines(); i++) {
  234.         for (unsigned int j = 0; j < this->cols(); j++) {
  235.  
  236.             std::vector<std::vector<T>> tempdata;
  237.             for (unsigned int k = 0; k < this->lines(); k++) {
  238.                 std::vector<T> line();
  239.                 for (unsigned int l = 0; l < this->cols(); l++) {
  240.                     if (k != l) {
  241.                         line.push_back(this->data[k][l]);
  242.                     }
  243.                 }
  244.                 tempdata.push_back(line);
  245.             }
  246.  
  247.             Matrix<T> temp(tempdata);
  248.             res.data[i][j] = det(temp);
  249.         }
  250.     }
  251. }
  252.  
  253. template<class T>
  254. Matrix<T> Matrix<T>::inv() {
  255.     return this->comatrix().transp();
  256. }
  257.  
  258. template<class T>
  259. Matrix<T> Matrix<T>::tri_lo(bool include_diag) const {
  260.     Matrix<T> res(this->lines(), this->cols());
  261.     for (int i = 0; i < this->lines(); i++) {
  262.         for (int j = 0; j < this->cols(); j++) {
  263.             if (i <= j) {
  264.                 if (i == j && !include_diag) {
  265.                     continue;
  266.                 }
  267.                 res.data[i][j] = this->data[i][j];
  268.             }
  269.             else {
  270.                 res.data[i][j] = T();
  271.             }
  272.         }
  273.     }
  274.  
  275.     return res;
  276. }
  277.  
  278. template<class T>
  279. Matrix<T> Matrix<T>::tri_up(bool include_diag) {
  280.     Matrix<T> res(this->lines(), this->cols());
  281.     for (int i = 0; i < this->lines(); i++) {
  282.         for (int j = 0; j < this->cols(); j++) {
  283.             if (i >= j) {
  284.                 if (i == j && !include_diag) {
  285.                     continue;
  286.                 }
  287.                 res.data[i][j] = this->data[i][j];
  288.             }
  289.             else {
  290.                 res.data[i][j] = T();
  291.             }
  292.         }
  293.     }
  294.  
  295.     return res;
  296. }
  297.  
  298. template<class T>
  299. Matrix<T> Matrix<T>::abs() {
  300.     Matrix<T> res(*this);
  301.  
  302.     for (int i = 0; i < res.lines(); i++) {
  303.         for (int j = 0; j < res.cols(); j++) {
  304.             res[i][j] = std::abs(res[i][j]);
  305.         }
  306.     }
  307.  
  308.     return res;
  309. }
  310.  
  311. template<class T>
  312. T Matrix<T>::norm() {
  313.     auto eigs = this->eigenvals();
  314.     return std::max(eigs) / std::min(eigs);
  315. }
  316.  
  317. template<class T>
  318. T Matrix<T>::highest_eigenval() {
  319.  
  320. }
  321.  
  322. template<class T>
  323. T Matrix<T>::lowest_eigenval() {
  324.  
  325. }
  326.  
  327. template<class T>
  328. template<class T2>
  329. auto Matrix<T>::operator+(Matrix<T2> const& other) {
  330.     Matrix<T> res(this->lines(), this->cols());
  331.  
  332.     for (unsigned int i = 0; i < this->lines(); i++) {
  333.         for (unsigned int j = 0; j < this->cols(); j++) {
  334.             res.data[i][j] = this->data[i][j] + other.data[i][j];
  335.         }
  336.     }
  337.     return res;
  338. }
  339.  
  340. template<class T>
  341. template<class T2>
  342. auto Matrix<T>::operator-(Matrix<T2> const& other) {
  343.     assert(this->lines() == other.lines());
  344.     assert(this->cols() == other.cols());
  345.  
  346.     decltype(std::declval<T>() - std::declval<T2>()) T3;
  347.  
  348.     Matrix<T3> res(this->lines(), this->cols());
  349.  
  350.     for (unsigned int const i = 0; i < this->lines(); i++) {
  351.         for (unsigned int const j = 0; j < this->cols(); i++) {
  352.             res[i][j] -= other[i][j];
  353.         }
  354.     }
  355.  
  356.     return res;
  357. };
  358.  
  359. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement