Advertisement
edward4324

yebanie shablony

Nov 25th, 2021
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.58 KB | None | 0 0
  1. #ifndef MATRIX_H
  2. #define MATRIX_H
  3. #include <vector>
  4. //#include <debugapi.h>
  5. #include <ostream>
  6.  
  7. template <class T>
  8. class matrix
  9. {
  10.     std::vector<std::vector<T>> matrix_;
  11.  
  12.     //util functions
  13.     static T& prod_of_sum (const std::vector<T>& a, const std::vector<T>& b)
  14.     {
  15.         auto result = new T(0);
  16.  
  17.         for (size_t i = 0; i < a.size(); i++)
  18.             *result += a[i] * b[i];
  19.  
  20.         return *result;
  21.     }
  22.  
  23.     static std::vector<T>& get_column(matrix& obj, const size_t& column_number)
  24.     {
  25.         const auto column = new std::vector<T>;
  26.         column->resize(obj.n());
  27.  
  28.         for (size_t i = 0; i < obj.n(); i++)
  29.             (*column)[i] = obj[i][column_number];
  30.  
  31.         return *column;
  32.     }
  33.  
  34. public:
  35.     explicit matrix(const std::vector<std::vector<T>> matrix)
  36.     {
  37.         matrix_ = std::move(matrix);
  38.     }
  39.  
  40.     matrix(const T** matrix, const size_t n)
  41.     {
  42.  
  43.         matrix_.resize(n);
  44.         for (size_t i = 0; i < n; i++)
  45.             matrix_[i].resize(n);
  46.  
  47.         for (size_t i = 0; i < n; i++)
  48.         {
  49.             for (size_t j = 0; j < n; j++)
  50.                 matrix_[i][j] = matrix[i][j];
  51.         }
  52.  
  53.     }
  54.  
  55.     matrix(const T** matrix, const size_t n, const size_t m)
  56.     {
  57.  
  58.         matrix_.resize(n);
  59.         for (size_t i = 0; i < n; i++)
  60.             matrix_[i].resize(m);
  61.  
  62.         for (size_t i = 0; i < n; i++)
  63.         {
  64.             for (size_t j = 0; j < m; j++)
  65.                 matrix_[i][j] = matrix[i][j];
  66.         }
  67.  
  68.     }
  69.  
  70.     matrix(const size_t& n, const size_t& m)
  71.     {
  72.         matrix_.resize(n);
  73.  
  74.         for (size_t i = 0; i < n; i++)
  75.             matrix_[i].resize(m);
  76.  
  77.         for (auto& row : matrix_)
  78.             for (auto& element : row)
  79.                 element = 0;
  80.  
  81.     }
  82.  
  83.     matrix(const matrix& other)
  84.         : matrix_(other.matrix_)
  85.     {
  86.     }
  87.  
  88.     matrix(matrix&& other) noexcept
  89.         : matrix_(std::move(other.matrix_))
  90.     {
  91.     }
  92.  
  93.     ~matrix()
  94.     = default;
  95.  
  96.     matrix& operator=(const matrix& other)
  97.     {
  98.         if (this == &other)
  99.             return *this;
  100.         matrix_ = other.matrix_;
  101.         return *this;
  102.     }
  103.  
  104.     matrix& operator=(matrix&& other) noexcept
  105.     {
  106.         if (this == &other)
  107.             return *this;
  108.         matrix_ = std::move(other.matrix_);
  109.         return *this;
  110.     }
  111.  
  112.     void set_ones()
  113.     {
  114.         try
  115.         {
  116.  
  117.             if (n == m)
  118.                 throw std::exception("This is not a square matrix, try standart set method");
  119.  
  120.             for (size_t i = 0; i < n(); i++)
  121.                 matrix_[i][i] = 1;
  122.  
  123.         } catch (std::exception& e)
  124.         {
  125.             //OutputDebugStringA(e.what());
  126.         }
  127.     }
  128.  
  129.     void clear()
  130.     {
  131.         for (auto& row : matrix_)
  132.             for (auto& element : row)
  133.                 element = 0;
  134.     }
  135.  
  136.     void set(const std::vector<T>& array)
  137.     {
  138.         size_t i = 0;
  139.         size_t j = 0;
  140.  
  141.         for (auto& element : array)
  142.         {
  143.             matrix_[i][j] = element;
  144.             if (j < m())
  145.                 j++;
  146.             else
  147.             {
  148.                 i++;
  149.                 j = 0;
  150.             }
  151.         }
  152.     }
  153.  
  154.     size_t m(){
  155.         return
  156.             matrix_[0].size();
  157.     }
  158.  
  159.     size_t n()
  160.     {
  161.         return
  162.             matrix_.size();
  163.     }
  164.  
  165.     matrix& transpose()
  166.     {
  167.         auto transposed_matrix = new matrix<T>(m(), n());
  168.  
  169.         for (size_t i = 0; i < n(); i++)
  170.             for (size_t j = 0; j < m(); j++)
  171.                 (*transposed_matrix)[j][i] = (*this)[i][j];
  172.  
  173.         return *transposed_matrix;
  174.     }
  175.  
  176.     friend double det(matrix matr)
  177.     {
  178.         size_t n = matr.n();
  179.         const size_t m = matr.m();
  180.  
  181.         if (m == 1)
  182.         {
  183.             return matr[0][0];
  184.         }
  185.         if (m == 2)
  186.         {
  187.             return matr[0][0] * matr[1][1] - matr[0][1] * matr[1][0];
  188.         }
  189.  
  190.         double determinant = 0;
  191.         int degree = 1;
  192.  
  193.         std::vector<std::vector<T>> minor(n);
  194.         for (size_t i = 0; i < n - 1; i++)
  195.             minor.resize(m - 1);
  196.  
  197.         for (size_t j = 0; j < n - 1; j++)
  198.         {
  199.             minor = get_matrix_without_row_column(matr, 0, j);
  200.             determinant = determinant + matr[0][j] * static_cast<T>(degree) * det(matrix(minor));
  201.             degree = -degree;
  202.         }          
  203.  
  204.         return determinant;
  205.  
  206.     }
  207.  
  208.     matrix& inv()
  209.     {
  210.  
  211.         return
  212.             this->transpose() * (1 / det(*this));
  213.  
  214.     }
  215.  
  216.     friend bool operator==(matrix& lhs, matrix& rhs)
  217.     {
  218.         if (lhs.m() != rhs.m() || lhs.n() != rhs.n())
  219.             return false;
  220.  
  221.         for (size_t i = 0; i < rhs.n(); i++)
  222.             for (size_t j = 0; j < rhs.m(); j++)
  223.                 if (lhs[i][j] != rhs[i][j])
  224.                     return false;
  225.  
  226.         return true;
  227.     }
  228.  
  229.     friend bool operator!=(matrix& lhs, matrix& rhs)
  230.     {
  231.         return !(lhs == rhs);
  232.     }
  233.  
  234.     matrix& operator+(matrix& obj)
  235.     {
  236.         try
  237.         {
  238.  
  239.             if (this->m() != obj.m() || this->n() != obj.n())
  240.                 throw std::exception("Matrixes spaces are not equal");
  241.  
  242.             const size_t n = this->n();
  243.             const size_t m = this->m();
  244.  
  245.             for (size_t i = 0; i < n; i++)
  246.                 for (size_t j = 0; j < m; j++)
  247.                     this->matrix_[i][j] += obj.matrix_[i][j];
  248.  
  249.         } catch (std::exception& e)
  250.         {
  251.             //OutputDebugStringA(e.what());
  252.         }
  253.  
  254.         return *this;
  255.     }
  256.  
  257.     matrix& operator-(matrix& obj)
  258.     {
  259.         return obj * -1 + *this;
  260.     }
  261.  
  262.     matrix& operator*(const int& k)
  263.     {
  264.         for (auto& row : matrix_)
  265.             for (auto& element : row)
  266.                 element *= static_cast<T>(k);
  267.         return *this;
  268.     }
  269.  
  270.     matrix& operator*(const double& k)
  271.     {
  272.         for (auto& row : matrix_)
  273.             for (auto& element : row)
  274.                 element *= static_cast<T>(k);
  275.         return *this;
  276.     }
  277.  
  278.     matrix& operator/(const int& k)
  279.     {
  280.         for (auto& row : matrix_)
  281.             for (auto& element : row)
  282.                 element /= static_cast<T>(k);
  283.         return *this;
  284.     }
  285.  
  286.     matrix& operator/(const double& k)
  287.     {
  288.         for (auto& row : matrix_)
  289.             for (auto& element : row)
  290.                 element /= static_cast<T>(k);
  291.         return *this;
  292.     }
  293.  
  294.     matrix& operator*(matrix& obj)
  295.     {
  296.         const auto c = new matrix<T>(this->n(), obj.m());
  297.         try
  298.         {
  299.             if (this->m() != obj.n())
  300.                 throw std::exception("Number of columns of first matrix is not equal to number of rows of second matrix\nOutputing null matrix");
  301.  
  302.             for (size_t i = 0; i < n(); i++)
  303.                 for (size_t j = 0; j < obj.m(); j++)
  304.                     (*c)[i][j] = prod_of_sum(matrix_[i], get_column(obj, j));
  305.         } catch(std::exception& e)
  306.         {
  307.                 //OutputDebugStringA(e.what());
  308.         }
  309.  
  310.         return *c;
  311.     }
  312.  
  313.     std::vector<T>& operator[](const size_t& i)
  314.     {
  315.         return
  316.             matrix_[i];
  317.     }
  318.  
  319.     friend std::ostream& operator<<(std::ostream& os, matrix& obj)
  320.     {
  321.         const size_t n = obj.n();
  322.         const size_t m = obj.m();
  323.  
  324.         for (size_t i = 0; i < n; i++)
  325.         {
  326.             for (size_t j = 0; j < m; j++)
  327.             {
  328.                 os << obj[i][j] << "\t";
  329.             }
  330.             os << "\n";
  331.         }
  332.  
  333.         return os;
  334.  
  335.     }
  336.  
  337. private:
  338.     static std::vector<std::vector<T>> get_matrix_without_row_column(
  339.         matrix matr, const size_t row, const size_t column
  340.     )
  341.     {
  342.         size_t n = matr.n() - 1;
  343.         size_t m = matr.m() - 1;
  344.  
  345.         std::vector<std::vector<T>> new_matrix(n);
  346.         for (size_t i = 0; i < n; i++)
  347.             new_matrix[i].resize(m);
  348.  
  349.         size_t offset_row = 0;
  350.         size_t offset_column = 0;
  351.  
  352.         for (size_t i = 0; i < n; i++)
  353.         {
  354.             if(i == row)
  355.             {
  356.                 offset_row = 1;
  357.             }      
  358.  
  359.             for (size_t j = 0; j < m; j++)
  360.             {
  361.  
  362.                 if (j == column)
  363.                     offset_column = 1;
  364.  
  365.                 new_matrix[i][j] = matr[i + offset_row][j + offset_column];
  366.  
  367.             }
  368.         }
  369.  
  370.         return new_matrix;
  371.     }
  372. };
  373.  
  374. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement