Advertisement
edward4324

matrix template class

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