Advertisement
Guest User

Untitled

a guest
Apr 6th, 2020
326
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 20.64 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdlib>
  3.  
  4. //================ class Rational ===============//
  5.  
  6. class Rational {
  7. private:
  8.     int64_t p = 1;
  9.     int64_t q = 1;
  10.  
  11.     void reduce();
  12.  
  13. public:
  14.     Rational() = default;
  15.     Rational(int);
  16.     Rational(int64_t num, int64_t dom = 1);
  17.     Rational& operator=(const Rational& other) = default;
  18.     ~Rational() = default;
  19.  
  20.     int64_t getNumerator() const;
  21.     int64_t getDenominator() const;
  22.  
  23.     void SetNumerator(int64_t value);
  24.     void SetDenominator(int64_t value);
  25.  
  26.     Rational operator-() const;
  27.     Rational operator+() const ;
  28.  
  29.     Rational& operator++();
  30.     Rational& operator--();
  31.  
  32.     Rational operator++(int);
  33.     Rational operator--(int);
  34.  
  35.     Rational& operator+=(const Rational& rhs);
  36.     Rational& operator-=(const Rational& rhs);
  37.     Rational& operator*=(const Rational& rhs);
  38.     Rational& operator/=(const Rational& rhs);
  39. };
  40.  
  41.  
  42.  
  43. class MatrixWrongSizeError: std::exception {
  44. };
  45.  
  46. class MatrixIndexError: std::exception {
  47. };
  48.  
  49. class MatrixIsDegenerateError: std::exception {
  50. };
  51.  
  52. class RationalDivisionByZero: std::exception {
  53. };
  54.  
  55.  
  56. template <typename T>
  57. T getZero() {
  58.     return T(0);
  59. }
  60.  
  61.  
  62. //================ Rational ===============//
  63.  
  64. int64_t GCD(int64_t x, int64_t y) {
  65.     x = (x >= 0) ? x : -x;
  66.     y = (y >= 0) ? y : -y;
  67.     if (x == 0 || y == 1) {
  68.         return y;
  69.     }
  70.     if (y == 0 || x == 1) {
  71.         return x;
  72.     }
  73.     int64_t tmp;
  74.     while (y) {
  75.         tmp = x % y;
  76.         x = y;
  77.         y = tmp;
  78.     }
  79.     return x;
  80. }
  81.  
  82. void Rational::reduce() {
  83.     int64_t gcd = GCD(p, q);
  84.     p /= gcd;
  85.     q /= gcd;
  86.  
  87.     if (q < 0) {
  88.         q *= -1;
  89.         p *= -1;
  90.     }
  91. }
  92.  
  93. Rational::Rational(int64_t num, int64_t den){
  94.     p = num;
  95.     q = den;
  96.  
  97.     if (q < 0) {
  98.         p *= -1;
  99.         q *= -1;
  100.     }
  101.  
  102.     reduce();
  103. }
  104.  
  105. Rational::Rational(int num):Rational(static_cast<int64_t>(num)) {
  106. }
  107.  
  108. int64_t Rational::getNumerator() const {
  109.     return p;
  110. }
  111.  
  112. int64_t Rational::getDenominator() const {
  113.     return q;
  114. }
  115.  
  116. void Rational::SetNumerator(int64_t value) {
  117.     p = value;
  118.     reduce();
  119. }
  120. void Rational::SetDenominator(int64_t value) {
  121.     if (value == 0) {
  122.         throw RationalDivisionByZero();
  123.     }
  124.     q = value;
  125.     reduce();
  126. }
  127.  
  128. Rational Rational::operator+() const {
  129.     return *this;
  130. }
  131.  
  132. Rational Rational::operator-() const {
  133.     Rational res;
  134.     res.p = -getNumerator();
  135.     res.q = getDenominator();
  136.     return res;
  137. }
  138.  
  139. Rational& Rational::operator+=(const Rational& rhs) {
  140.     p = p * rhs.q + q * rhs.p;
  141.     q *= rhs.q;
  142.     reduce();
  143.     return *this;
  144. }
  145.  
  146. Rational& Rational::operator-=(const Rational& rhs) {
  147.     *this += (-rhs);
  148.     return *this;
  149. }
  150.  
  151. Rational& Rational::operator*=(const Rational& rhs) {
  152.     p *= rhs.p;
  153.     q *= rhs.q;
  154.     reduce();
  155.     return *this;
  156. }
  157.  
  158. bool operator==(const Rational& lhs, const Rational& rhs) {
  159.     return (lhs.getNumerator() == rhs.getNumerator() &&
  160.             lhs.getDenominator() == rhs.getDenominator());
  161. }
  162.  
  163. Rational& Rational::operator/=(const Rational& rhs) {
  164.     if (rhs == 0) {
  165.         throw RationalDivisionByZero();
  166.     }
  167.     p *= rhs.q;
  168.     q *= rhs.p;
  169.     reduce();
  170.     return *this;
  171. }
  172.  
  173. Rational operator+(const Rational& lhs, const Rational& rhs) {
  174.     Rational result = lhs;
  175.     result += rhs;
  176.     return result;
  177. }
  178.  
  179. Rational operator-(const Rational& lhs, const Rational& rhs) {
  180.     Rational result = lhs;
  181.     result -= rhs;
  182.     return result;
  183. }
  184.  
  185. Rational operator*(const Rational& lhs, const Rational& rhs) {
  186.     Rational result = lhs;
  187.     result *= rhs;
  188.     return result;
  189. }
  190.  
  191. Rational operator/(const Rational& lhs, const Rational& rhs) {
  192.     Rational result = lhs;
  193.     result /= rhs;
  194.     return result;
  195. }
  196.  
  197. //pre increment
  198. Rational& Rational::operator++() {
  199.     *this += 1;
  200.     return *this;
  201. }
  202.  
  203. //pre decrement
  204. Rational& Rational::operator--() {
  205.     *this -= 1;
  206.     return *this;
  207. }
  208.  
  209. //post increment
  210. Rational Rational::operator++(int) {
  211.     Rational old_value = *this;
  212.     *this += 1;
  213.     return old_value;
  214. }
  215.  
  216. //post decrement
  217. Rational Rational::operator--(int) {
  218.     Rational old_value = *this;
  219.     *this -= 1;
  220.     return old_value;
  221. }
  222.  
  223. bool operator<(const Rational& lhs, const Rational& rhs) {
  224.     return (lhs.getNumerator() * rhs.getDenominator() <
  225.             lhs.getDenominator() * rhs.getNumerator());
  226. }
  227.  
  228. bool operator>(const Rational& lhs, const Rational& rhs) {
  229.     return (rhs < lhs);
  230. }
  231.  
  232. bool operator!=(const Rational& lhs, const Rational& rhs) {
  233.     return !(lhs == rhs);
  234. }
  235.  
  236. bool operator<=(const Rational& lhs, const Rational& rhs) {
  237.     return !(lhs > rhs);
  238. }
  239.  
  240. bool operator>=(const Rational& lhs, const Rational& rhs) {
  241.     return !(lhs < rhs);
  242. }
  243.  
  244. std::ostream& operator<<(std::ostream& os, const Rational& rational) {
  245.     os << rational.getNumerator();
  246.     if (rational.getDenominator() != 1) {
  247.         os << '/' << rational.getDenominator();
  248.     }
  249.     return os;
  250. }
  251.  
  252. std::istream& operator>>(std::istream& is, Rational& rational) {
  253.     const int kMaxFractionSize = 6;
  254.     char str[kMaxFractionSize];
  255.     is >> str;
  256.  
  257.     char* end;
  258.     rational.SetNumerator(strtoll(str, &end, 10));
  259.     if (*end != 0) {
  260.         ++end;
  261.         rational.SetDenominator(strtoll(end, &end, 10));
  262.     } else {
  263.         rational.SetDenominator(1);
  264.     }
  265.  
  266.     return is;
  267. }
  268.  
  269. //=============== Matrix class ===============//
  270.  
  271. template <class T>
  272. class Matrix {
  273. protected:
  274.     T** array_;
  275.     int rowsCnt_;
  276.     int colsCnt_;
  277.  
  278.     void ArrayReallocation(int new_rows, int new_cols);
  279.  
  280. public:
  281.     Matrix();
  282.     Matrix(int rows_cnt, int cols_cnt);
  283.     Matrix(const Matrix& other);
  284.  
  285.     virtual Matrix& operator=(const Matrix& other);
  286.     virtual ~Matrix();
  287.  
  288.     int getRowsNumber() const;
  289.     int getColumnsNumber() const;
  290.  
  291.     Matrix& transpose();
  292.     Matrix getTransposed() const;
  293.  
  294.     virtual Matrix operator-() const;
  295.  
  296.     virtual Matrix& operator+=(const Matrix& other);
  297.     virtual Matrix& operator-=(const Matrix& other);
  298.     virtual Matrix& operator*=(const Matrix& other);
  299.  
  300.  
  301.     T& operator()(int i, int j);
  302.     const T& operator()(int i, int j) const;
  303.  
  304.     template <class U>
  305.     friend std::istream& operator>>(std::istream& is, Matrix<U>& other);
  306.    
  307.     friend Matrix<T> operator*(const Matrix<T>& mtr, T nmb) {
  308.         Matrix<T> res = mtr;
  309.         return res *= nmb;
  310.     }
  311.    
  312.     friend Matrix<T> operator*(T nmb, const Matrix<T>& mtr) {
  313.         return mtr * nmb;
  314.     }
  315. };
  316.  
  317. //================ Matrix ===============//
  318.  
  319. template <class T>
  320. void FillZeroes(Matrix<T>& mtr) {
  321.     T zero = getZero<T>();
  322.     for (int i = 0; i < mtr.getRowsNumber(); ++i) {
  323.         for (int j = 0; j < mtr.getColumnsNumber(); ++j) {
  324.             mtr(i, j) = zero;
  325.         }
  326.     }
  327. }
  328.  
  329. template <class T>
  330. Matrix<T>::Matrix()
  331.     : rowsCnt_(0)
  332.     , colsCnt_(0)
  333.     , array_(nullptr){
  334.     }
  335.  
  336. template <class T>
  337. Matrix<T>::Matrix(int rows_cnt, int cols_cnt)
  338.     : rowsCnt_(rows_cnt)
  339.     , colsCnt_(cols_cnt) {
  340.  
  341.     array_ = new T*[rows_cnt];
  342.     for (int i = 0; i < rows_cnt; ++i) {
  343.         array_[i] = new T[cols_cnt];
  344.     }
  345.  
  346.     FillZeroes(*this);
  347. }
  348.  
  349. template <class T>
  350. int Matrix<T>::getRowsNumber() const {
  351.     return rowsCnt_;
  352. }
  353.  
  354. template <class T>
  355. int Matrix<T>::getColumnsNumber() const {
  356.     return colsCnt_;
  357. }
  358.  
  359. template <class T>
  360. void Copy(const Matrix<T>& mtr_from, Matrix<T>& mtr_to) {
  361.     for (int i = 0; i < mtr_from.getRowsNumber(); ++i) {
  362.         for (int j = 0; j < mtr_from.getColumnsNumber(); ++j) {
  363.             mtr_to(i, j) = mtr_from(i, j);
  364.         }
  365.     }
  366. }
  367.  
  368. template <class T>
  369. Matrix<T>::Matrix(const Matrix& other): Matrix(other.getRowsNumber(), other.getColumnsNumber()) {
  370.     Copy(other, *this);
  371. }
  372.  
  373. template <class T>
  374. Matrix<T>& Matrix<T>::operator=(const Matrix<T>& other) {
  375.     if (&other == this) {
  376.         return *this;
  377.     }
  378.  
  379.     for (int i = 0; i < getRowsNumber(); ++i) {
  380.         delete array_[i];
  381.     }
  382.     delete[] array_;
  383.  
  384.     array_ = new T*[other.getRowsNumber()];
  385.     for (int i = 0; i < other.getRowsNumber(); ++i) {
  386.         array_[i] = new T[other.getColumnsNumber()];
  387.     }
  388.  
  389.     rowsCnt_ = other.getRowsNumber();
  390.     colsCnt_ = other.getColumnsNumber();
  391.  
  392.     Copy(other, *this);
  393.     return *this;
  394. }
  395.  
  396. template <class T>
  397. Matrix<T>::~Matrix() {
  398.     for (int i = 0; i < getRowsNumber(); ++i) {
  399.         delete array_[i];
  400.     }
  401.     delete[] array_;
  402. }
  403.  
  404. template <class T>
  405. bool InvalidIndex(int i, int j, const Matrix<T>& mtr) {
  406.     return (i < 0 || j < 0 || i >= mtr.getRowsNumber() || j >= mtr.getColumnsNumber());
  407. }
  408.  
  409. template <class T>
  410. T& Matrix<T>::operator()(int i, int j) {
  411.     if (InvalidIndex(i, j, *this)) {
  412.         throw MatrixIndexError();
  413.     }
  414.     return array_[i][j];
  415. }
  416.  
  417. template <class T>
  418. const T& Matrix<T>::operator()(int i, int j) const {
  419.     if (InvalidIndex(i, j, *this)) {
  420.         throw MatrixIndexError();
  421.     }
  422.     return array_[i][j];
  423. }
  424.  
  425. template <class T>
  426. void Swap(T& a, T& b) {
  427.     T tmp = a;
  428.     a = b;
  429.     b = tmp;
  430. }
  431.  
  432. template <class T>
  433. Matrix<T>& Matrix<T>::transpose() {
  434.     if (getRowsNumber() == getColumnsNumber()) {
  435.         for (int i = 0; i < getRowsNumber(); ++i) {
  436.             for (int j = 0; j < getColumnsNumber(); ++j) {
  437.                 if (j > i) {
  438.                     Swap(array_[i][j], array_[j][i]);
  439.                 }
  440.             }
  441.         }
  442.     } else {
  443.         Matrix<T> old_mtr = *this;
  444.         *this = Matrix(getColumnsNumber(), getRowsNumber());
  445.  
  446.         for (int i = 0; i < getRowsNumber(); ++i) {
  447.             for (int j = 0; j < getColumnsNumber(); ++j) {
  448.                 array_[i][j] = old_mtr(j, i);
  449.             }
  450.         }
  451.     }
  452.     return *this;
  453. }
  454.  
  455. template <class T>
  456. Matrix<T> Matrix<T>::getTransposed() const {
  457.     Matrix<T> res = *this;
  458.     res.transpose();
  459.     return res;
  460. }
  461.  
  462. template <class T>
  463. Matrix<T>& operator*=(Matrix<T>& mtr, T nmb) {
  464.     for (int i = 0; i < mtr.getRowsNumber(); ++i) {
  465.         for (int j = 0; j < mtr.getColumnsNumber(); ++j) {
  466.             mtr(i, j) *= nmb;
  467.         }
  468.     }
  469.  
  470.     return mtr;
  471. }
  472.  
  473. template <class T, class U>
  474. Matrix<T>& operator/=(Matrix<T>& mtr, U nmb) {
  475.     for (int i = 0; i < mtr.getRowsNumber(); ++i) {
  476.         for (int j = 0; j < mtr.getColumnsNumber(); ++j) {
  477.             mtr(i, j) /= nmb;
  478.         }
  479.     }
  480.  
  481.     return mtr;
  482. }
  483.  
  484. template <class T>
  485. bool InvalidSizeForAddition(const Matrix<T>& lhs, const Matrix<T>& rhs) {
  486.     return (lhs.getRowsNumber() != rhs.getRowsNumber()) ||
  487.            (lhs.getColumnsNumber() != rhs.getColumnsNumber());
  488. }
  489.  
  490. template <class T>
  491. Matrix<T> Matrix<T>::operator-() const {
  492.     Matrix<T> res = *this;
  493.     for (int i = 0; i < getRowsNumber(); ++i) {
  494.         for (int j = 0; j < getColumnsNumber(); ++j) {
  495.             res(i, j) *= -1;
  496.         }
  497.     }
  498.     return res;
  499. }
  500.  
  501. template <class T>
  502. Matrix<T>& Matrix<T>::operator+=(const Matrix<T>& other) {
  503.     if (InvalidSizeForAddition(*this, other)) {
  504.         throw MatrixWrongSizeError();
  505.     }
  506.  
  507.     for (int i = 0; i < getRowsNumber(); ++i) {
  508.         for (int j = 0; j < getColumnsNumber(); ++j) {
  509.             array_[i][j] += other(i, j);
  510.         }
  511.     }
  512.  
  513.     return *this;
  514. }
  515.  
  516. template <class T>
  517. Matrix<T>& Matrix<T>::operator-=(const Matrix<T>& other) {
  518.     *this += -other;
  519.     return *this;
  520. }
  521.  
  522. template <class T>
  523. bool InvalidSizeForMultiplication(const Matrix<T>& lhs, const Matrix<T>& rhs) {
  524.     return (lhs.getColumnsNumber() != rhs.getRowsNumber());
  525. }
  526.  
  527. template <class T>
  528. void Matrix<T>::ArrayReallocation(int new_rows, int new_cols) {
  529.     for (int i = 0; i < getRowsNumber(); ++i) {
  530.         delete array_[i];
  531.     }
  532.     delete[] array_;
  533.  
  534.     array_ = new T*[new_rows];
  535.     for (int i = 0; i < new_rows; ++i) {
  536.         array_[i] = new T[new_cols];
  537.     }
  538.  
  539.     rowsCnt_ = new_rows;
  540.     colsCnt_ = new_cols;
  541.  
  542.     FillZeroes(*this);
  543. }
  544.  
  545. template <class T>
  546. Matrix<T>& Matrix<T>::operator*=(const Matrix<T>& other){
  547.     if (InvalidSizeForMultiplication(*this, other)) {
  548.         throw MatrixWrongSizeError();
  549.     }
  550.    
  551.     bool isSameMatrix = false;
  552.     if (this == &other) {
  553.         isSameMatrix = true;
  554.     }
  555.  
  556.     Matrix copy = *this;
  557.  
  558.     ArrayReallocation(getRowsNumber(), other.getColumnsNumber());
  559.  
  560.     for (int i = 0; i < copy.getRowsNumber(); ++i) {
  561.         for (int j = 0; j < other.getColumnsNumber(); ++j) {
  562.             for (int k = 0; k < copy.getColumnsNumber(); ++k) {
  563.                 array_[i][j] += copy(i, k) * (isSameMatrix ? copy(k, j) : other(k, j));
  564.             }
  565.         }
  566.     }
  567.  
  568.     return *this;
  569. }
  570.  
  571. template <class T>
  572. Matrix<T> operator*(const Matrix<T>& lhs, const Matrix<T>& rhs) {
  573.     Matrix<T> res = lhs;
  574.     return res *= rhs;
  575. }
  576.  
  577. template <class T>
  578. Matrix<T> operator+(const Matrix<T>& lhs, const Matrix<T>& rhs) {
  579.     Matrix<T> res = lhs;
  580.     return res += rhs;
  581. }
  582.  
  583. template <class T>
  584. Matrix<T> operator-(const Matrix<T>& lhs, const Matrix<T>& rhs) {
  585.     Matrix<T> res = lhs;
  586.     return res -= rhs;
  587. }
  588.  
  589. template <class T>
  590. std::istream& operator>>(std::istream& is, Matrix<T>& mtr) {
  591.     for (int i = 0; i < mtr.getRowsNumber(); ++i) {
  592.         for (int j = 0; j < mtr.getColumnsNumber(); ++j) {
  593.             is >> mtr(i, j);
  594.         }
  595.     }
  596.  
  597.     return is;
  598. }
  599.  
  600. template <class T>
  601. std::ostream& operator<<(std::ostream& os, const Matrix<T>& mtr) {
  602.     for (int i = 0; i < mtr.getRowsNumber(); ++i) {
  603.         for (int j = 0; j < mtr.getColumnsNumber(); ++j) {
  604.             os << mtr(i, j) << ' ';
  605.         }
  606.         os << '\n';
  607.     }
  608.  
  609.     return os;
  610. }
  611.  
  612. //=============== SquareMatrix class ===============//
  613.  
  614. template <class T>
  615. class SquareMatrix : public Matrix<T> {
  616. private:
  617.     void MinorMatrix(const SquareMatrix<T>&, SquareMatrix<T>&, int, int) const ;
  618.     T Determinant(const SquareMatrix& matrix) const ;
  619.     void ArrayReallocation(int size);
  620.     void Free();
  621.  
  622. public:
  623.    
  624.     SquareMatrix();
  625.     explicit SquareMatrix(int size);
  626.     SquareMatrix(const SquareMatrix<T>& other);
  627.  
  628.     SquareMatrix<T> getInverse() const;
  629.     SquareMatrix<T>& invert();
  630.  
  631.     int getSize() const;
  632.     T getTrace() const;
  633.     T getDeterminant() const;
  634.     SquareMatrix<T> getTransposed() const;
  635.     SquareMatrix<T>& transpose();
  636.  
  637.     T Cofactor(const SquareMatrix &matrix, int row_to_delete, int col_to_delete) const;
  638.    
  639.     friend SquareMatrix<T> operator*(const SquareMatrix<T>& matrix, T number) {
  640.         SquareMatrix<T> res = matrix;
  641.         res *= number;
  642.         return res;
  643.     }
  644.  
  645.     friend SquareMatrix<T> operator*(T number, const SquareMatrix<T>& matrix) {
  646.         return matrix * number;
  647.     }
  648. };
  649.  
  650.  
  651. //================ SquareMatrix ===============//
  652.  
  653. template<typename T>
  654. SquareMatrix<T>::SquareMatrix(): Matrix<T>() {
  655. }
  656.  
  657. template<typename T>
  658. SquareMatrix<T>::SquareMatrix(int size) : Matrix<T>(size, size) {
  659. }
  660.  
  661. template<typename T>
  662. SquareMatrix<T>::SquareMatrix(const SquareMatrix<T>& other) : Matrix<T>(other) {
  663. }
  664.  
  665. template <class T>
  666. int SquareMatrix<T>::getSize() const {
  667.     return this->getRowsNumber();
  668. }
  669.  
  670. template <class T>
  671. void SquareMatrix<T>::MinorMatrix(const SquareMatrix<T>& matrix, SquareMatrix<T>& new_matrix, int row_to_delete, int col_to_delete) const {
  672.     int row_shift = 0;
  673.     int col_shift = 0;
  674.     for (int i = 0; i < new_matrix.getSize(); ++i) {
  675.         if (i == row_to_delete) {
  676.             row_shift = 1;
  677.         }
  678.  
  679.         col_shift = 0;
  680.         for (int j = 0; j < new_matrix.getSize(); ++j) {
  681.             if (j == col_to_delete) {
  682.                 col_shift = 1;
  683.             }
  684.             new_matrix(i, j) = matrix(i + row_shift, j + col_shift);
  685.         }
  686.     }
  687. }
  688.  
  689. template <class T>
  690. void SquareMatrix<T>::Free() {
  691.     for(int i = 0; i < getSize(); i++) {
  692.         delete[] this->array_[i];
  693.     }
  694.     delete[] this->array_;
  695. }
  696.  
  697. template <class T>
  698. T SquareMatrix<T>::Determinant(const SquareMatrix& matrix) const {
  699.     T det = getZero<T>();
  700.     int sign = 1;
  701.  
  702.     if (matrix.getSize() == 1) {
  703.         return matrix(0, 0);
  704.     }
  705.     if (matrix.getSize() == 2) {
  706.         return matrix(0, 0) * matrix(1, 1) - matrix(1, 0) * matrix(0, 1);
  707.     }
  708.  
  709.     SquareMatrix minor = SquareMatrix(matrix.getSize() - 1);
  710.    
  711.     T detMinor = Determinant(minor);
  712.  
  713.     for(int j = 0; j < matrix.getSize(); ++j) {
  714.         MinorMatrix(matrix, minor, 0, j);
  715.         det += sign * matrix(0, j) * detMinor;
  716.         sign *= -1;
  717.     }
  718.  
  719.     //minor.Free();
  720.  
  721.     return det;
  722. }
  723.  
  724. template <class T>
  725. T SquareMatrix<T>::getDeterminant() const {
  726.     return Determinant(*this);
  727. }
  728.  
  729. template <class T>
  730. T SquareMatrix<T>::Cofactor(const SquareMatrix<T>& matrix, int row_to_delete, int col_to_delete) const {
  731.     if (getSize() == 1) {
  732.         return T(1);
  733.     }
  734.  
  735.     SquareMatrix minor = SquareMatrix(matrix.getSize() - 1);
  736.     MinorMatrix(matrix, minor, row_to_delete, col_to_delete);
  737.  
  738.     if ((row_to_delete + col_to_delete) % 2 == 1) {
  739.         return -minor.getDeterminant();
  740.     }
  741.  
  742.     return minor.getDeterminant();
  743. }
  744.  
  745. template <class T>
  746. SquareMatrix<T> SquareMatrix<T>::getInverse() const {
  747.     T det = getDeterminant();
  748.  
  749.     if (det == 0) {
  750.         throw MatrixIsDegenerateError();
  751.     }
  752.  
  753.     SquareMatrix transposed_mtr = this->getTransposed();
  754.     SquareMatrix cofactor_mtr(getSize());
  755.  
  756.     for (int i = 0; i < getSize(); ++i) {
  757.         for (int j = 0; j < getSize(); ++j) {
  758.             cofactor_mtr(i, j) = Cofactor(transposed_mtr, i, j);
  759.         }
  760.     }
  761.  
  762.  
  763.     return (cofactor_mtr /= det);
  764. }
  765.  
  766. template <typename T>
  767. SquareMatrix<T>& SquareMatrix<T>::invert() {
  768.     *this = getInverse();
  769.     return *this;
  770. }
  771.  
  772.  
  773. template <class T>
  774. T SquareMatrix<T>::getTrace() const {
  775.     T trace = getZero<T>();
  776.     for (int i = 0; i < getSize(); ++i) {
  777.         trace += this->array_[i][i];
  778.     }
  779.  
  780.     return trace;
  781. }
  782.  
  783. template <typename T>
  784. SquareMatrix<T> SquareMatrix<T>::getTransposed() const {
  785.     SquareMatrix<T> res = *this;
  786.     res.Matrix<T>::transpose();
  787.     return res;
  788. }
  789.  
  790. template <typename T>
  791. SquareMatrix<T>& SquareMatrix<T>::transpose() {
  792.     *this = this->getTransposed();
  793.     return *this;
  794. }
  795.  
  796. template <class T, class U>
  797. SquareMatrix<T>& operator/=(SquareMatrix<T>& mtr, U nmb) {
  798.     for (int i = 0; i < mtr.getSize(); ++i) {
  799.         for (int j = 0; j < mtr.getSize(); ++j) {
  800.             mtr(i, j) /= nmb;
  801.         }
  802.     }
  803.  
  804.     return mtr;
  805. }
  806.  
  807. template <class T>
  808. void SquareMatrix<T>::ArrayReallocation(int size) {
  809.     for (int i = 0; i < getSize(); ++i) {
  810.         delete this->array_[i];
  811.     }
  812.     delete[] this->array_;
  813.  
  814.     this->array_ = new T*[size];
  815.     for (int i = 0; i < size; ++i) {
  816.         this->array_[i] = new T[size];
  817.     }
  818.  
  819.     this->rowsCnt_ = this->colsCnt_ = size;
  820.  
  821.     FillZeroes(*this);
  822. }
  823.  
  824. template <class T>
  825. SquareMatrix<T> operator*(const SquareMatrix<T>& lhs, const SquareMatrix<T>& rhs) {
  826.     SquareMatrix<T> res = lhs;
  827.     res *= rhs;
  828.     return res;
  829. }
  830.  
  831.  
  832. template <class T>
  833. SquareMatrix<T> operator/(const SquareMatrix<T>& matrix, const T& number) {
  834.     SquareMatrix<T> res = matrix;
  835.     res /= number;
  836.     return res;
  837. }
  838.  
  839. template <class T>
  840. SquareMatrix<T> operator/(const T& number, const SquareMatrix<T>& matrix) {
  841.     return matrix / number;
  842. }
  843.  
  844. template <class T>
  845. Matrix<T> operator*(const Matrix<T>& mtr, const SquareMatrix<T>& square_mtr) {
  846.     return mtr * dynamic_cast<const Matrix<T>&>(square_mtr);
  847. }
  848.  
  849. template <class T>
  850. SquareMatrix<T> operator+(const SquareMatrix<T>& lhs, const SquareMatrix<T>& rhs) {
  851.     SquareMatrix<T> res = lhs;
  852.     res += rhs;
  853.     return res;
  854. }
  855.  
  856. template <class T>
  857. SquareMatrix<T> operator-(const SquareMatrix<T>& lhs, const SquareMatrix<T>& rhs) {
  858.     SquareMatrix<T> res = lhs;
  859.     res -= rhs;
  860.     return res;
  861. }
  862.  
  863. //=================== main() ===============//
  864.  
  865. using namespace std;
  866.  
  867.  
  868. int main() {
  869.     int m, n, p;
  870.     Rational r;
  871.     cin >> m >> n >> p >> r;
  872.  
  873.     Matrix<Rational> A(m, n);
  874.     SquareMatrix<Rational> S(p);
  875.     cin >> A >> S;
  876.  
  877.     try {
  878.         cout << (A * S) * A.getTransposed() << endl;
  879.     } catch (const MatrixWrongSizeError&) {
  880.         cout << "A and S have not appropriate sizes for multiplication." << endl;
  881.     }
  882.  
  883.     cout << (r * (S = S) * S).getSize() << endl;
  884.  
  885.     SquareMatrix<Rational> P(S);
  886.  
  887.     cout << (P * (S + S - 3 * P)).getDeterminant() << endl;
  888.  
  889.     const SquareMatrix<Rational>& rS = S;
  890.  
  891.     cout << rS.getSize() << ' ' << rS.getDeterminant() << ' ' << rS.getTrace() << endl;
  892.     cout << (S = S) * (S + rS) << endl;
  893.     cout << (S *= S) << endl;
  894.  
  895.     try {
  896.         cout << rS.getInverse() << endl;
  897.         cout << P.invert().getTransposed().getDeterminant() << endl;
  898.         cout << P << endl;
  899.     } catch (const MatrixIsDegenerateError&) {
  900.         cout << "Cannot inverse matrix." << endl;
  901.     }
  902.  
  903.     return 0;
  904. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement