Advertisement
Guest User

Untitled

a guest
Mar 25th, 2017
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.88 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <stdexcept>
  4. #include <cmath>
  5. #include <fstream>
  6.  
  7. using namespace std;
  8.  
  9. class Matrix {
  10.     public:
  11.         Matrix() {};
  12.  
  13.         Matrix(int a_,int b_): a(a_),b(b_) {
  14.             m = vector<vector<double>>(a);
  15.             for(int i=0;i<a;i++)
  16.                 m[i].resize(b);
  17.         };
  18.  
  19.         double& at(int i,int j) {
  20.             return m[i][j];
  21.         }
  22.  
  23.         int get_a() const {
  24.             return this->a;
  25.         }
  26.  
  27.         int get_b() const {
  28.             return this->b;
  29.         }
  30.  
  31.  
  32.         Matrix* sum(Matrix* b) {
  33.             Matrix* c = new Matrix(std::min(this->a,b->a),std::min(this->b,b->b));
  34.             for(int i=0;i<c->a;i++)
  35.                 for (int j=0;j<c->b;j++) {
  36.                     double &val = c->at(i,j);
  37.                     val = this->at(i, j) + b->at(i, j);
  38.                 }
  39.             return c;
  40.         }
  41.  
  42.         Matrix* mul(Matrix* b) {
  43.             Matrix* c = new Matrix(this->a,b->b);
  44.             if (this->b != b->a)
  45.                 throw std::invalid_argument("Only matrix MxN,NxC can multiply");
  46.             for(int i=0;i<c->a;i++) {
  47.                 for (int j = 0; j < c->b; j++) {
  48.                     double &val = c->at(i,j);
  49.                     val = 0;
  50.                     for (int k = 0; k < this->b; k++)
  51.                         val += this->at(i,k) * b->at(k,j);
  52.                 }
  53.             }
  54.             return c;
  55.         }
  56.  
  57.         void scalar_mul(double m) {
  58.             for(int i=0;i<this->a;i++) {
  59.                 for (int j = 0; j < this->b; j++) {
  60.                     double& val = this->at(i,j);
  61.                     val *= m;
  62.                 }
  63.             }
  64.         }
  65.  
  66.         Matrix* transpose() {
  67.             Matrix* b = new Matrix(this->b,this->a);
  68.             for(int i=0;i<this->a;i++) {
  69.                 for (int j=0;j<this->b;j++) {
  70.                     double &val = b->at(j,i);
  71.                     val=this->at(i,j);
  72.                 }
  73.             }
  74.             return b;
  75.         }
  76.  
  77.         virtual void step_matrix() {
  78.             int count_swap=1;
  79.             for (int i = 0; i < this->a; ++ i) {
  80.                 int iMax = i;
  81.                 for (int j = i + 1; j < this->a; ++ j)
  82.                     if (fabs (this->at(j,i)) > fabs(this->at(iMax,i)))
  83.                         iMax = j;
  84.                 if (fabs(this->at(iMax,i)) < 1E-9)
  85.                     continue;
  86.                 std::swap(this->m[i], this->m[iMax]);
  87.                 count_swap = - count_swap * (i != iMax ? 1 : - 1);
  88.  
  89.                 for (int j = i + 1; j < this->a; ++ j) {
  90.                     double q = - this->at(j,i) / this->at(i,i);
  91.                     for (int k = this->b - 1; k >= i; -- k) {
  92.                         double& val = this->at(j,k);
  93.                         val += q * this->at(i, k);
  94.                     }
  95.                 }
  96.             }
  97.         }
  98.  
  99.         virtual double det() {
  100.             throw std::invalid_argument("No determinant for quad matrix. Only sqMatrix!");
  101.         }
  102.  
  103.         virtual void inverse_matrix() {
  104.             throw std::invalid_argument("No inverse for quad matrix. Only sqMatrix!");
  105.         }
  106.  
  107.         friend ostream &operator<< (ostream &os, const Matrix &mat) {
  108.             for(int i = 0; i < mat.a; i++) {
  109.                 for (int j = 0; j < mat.b; j++)
  110.                     os << mat.m[i][j] << " ";
  111.                 os << endl;
  112.             }
  113.             return os;
  114.         }
  115.  
  116.         virtual ~Matrix(){};
  117.  
  118.  
  119.     protected:
  120.         int a; // row
  121.         int b; // column
  122.         vector<vector<double>> m;
  123. };
  124.  
  125. class vMatrix: public Matrix {
  126. public:
  127.     vMatrix(int a_,bool flag): invert_x(flag) {
  128.         if (flag) {
  129.             a = a_;
  130.             b = 1;
  131.         }
  132.         else {
  133.             a = 1;
  134.             b = a_;
  135.         }
  136.         m = vector<vector<double>>(a);
  137.         for (int i = 0; i < a; i++)
  138.             m[i].resize(b);
  139.     };
  140.  
  141.     vMatrix* sum(vMatrix* b) {
  142.         if (this->a != b->a || this->b != b->b)
  143.             throw std::invalid_argument("Dimensions of two vMatrix must be equal!");
  144.         vMatrix* c = new vMatrix(std::max(this->a,this->b),this->invert_x);
  145.         for(int i=0;i<c->a;i++)
  146.             for (int j=0;j<c->b;j++) {
  147.                 double &val = c->at(i,j);
  148.                 val = this->at(i, j) + b->at(i,j);
  149.             }
  150.         return c;
  151.     }
  152.  
  153.     double mul(vMatrix* b) {
  154.         double val = 0;
  155.         if (this->b != b->a)
  156.             throw std::invalid_argument("Only matrix MxN,NxC can multiply");
  157.         for(int i=0;i<this->a;i++) {
  158.             for (int j = 0; j < b->b; j++) {
  159.                 for (int k = 0; k < this->b; k++)
  160.                     val += this->at(i,k) * b->at(k,j);
  161.             }
  162.         }
  163.         return val;
  164.     }
  165.  
  166.  
  167.     vMatrix* transpose() {
  168.         vMatrix* b = new vMatrix(std::max(this->a,this->b),!this->invert_x);
  169.         for(int i=0;i<this->a;i++) {
  170.             for (int j=0;j<this->b;j++) {
  171.                 double &val = b->at(j,i);
  172.                 val=this->at(i,j);
  173.             }
  174.         }
  175.         return b;
  176.     }
  177.  
  178.     virtual void step_matrix() {
  179.         throw std::invalid_argument("No step_matrix for vectors. Only sqMatrix!");
  180.     }
  181.  
  182.     virtual double det() {
  183.         throw std::invalid_argument("No determinant for vectors. Only sqMatrix!");
  184.     }
  185.  
  186.     virtual void inverse_matrix() {
  187.         throw std::invalid_argument("No inverse for vectors. Only sqMatrix!");
  188.     }
  189.  
  190.     friend ostream &operator<< (ostream &os, const vMatrix &mat) {
  191.         for(int i = 0; i < mat.a; i++) {
  192.             for (int j = 0; j < mat.b; j++)
  193.                 os << mat.m[i][j] << " ";
  194.             os << endl;
  195.         }
  196.         return os;
  197.     }
  198.  
  199. private:
  200.     bool invert_x; // true if vector[3,1] else vector[1,3]
  201.  
  202. };
  203.  
  204. class sqMatrix: public Matrix
  205. {
  206.     public:
  207.     sqMatrix(int a_): Matrix(a_,a_) {};
  208.  
  209.  
  210.     sqMatrix* sum(sqMatrix* b) {
  211.         sqMatrix* c = new sqMatrix(std::min(this->a,b->a));
  212.         for(int i=0;i<c->a;i++)
  213.             for (int j=0;j<c->b;j++) {
  214.                 double &val = c->at(i,j);
  215.                 val = this->at(i, j) + b->at(i, j);
  216.             }
  217.         return c;
  218.     }
  219.  
  220.     sqMatrix* mul(sqMatrix* b) {
  221.         if (this->a != b->a)
  222.             throw std::invalid_argument("Only matrix MxN,NxC can multiply");
  223.         sqMatrix* c = new sqMatrix(this->a);
  224.         for(int i=0;i<c->a;i++) {
  225.             for (int j = 0; j < c->b; j++) {
  226.                 double &val = c->at(i,j);
  227.                 val = 0;
  228.                 for (int k = 0; k < this->b; k++)
  229.                     val += this->at(i,k) * b->at(k,j);
  230.             }
  231.         }
  232.         return c;
  233.     }
  234.  
  235.  
  236.     sqMatrix* transpose() {
  237.         for(int i=0;i<this->a;i++) {
  238.             for (int j=i+1;j<this->b;j++) {
  239.                 if (i!=j) {
  240.                     double& var = this->at(i,j);
  241.                     double& val = this->at(j,i);
  242.                     std::swap(var,val);
  243.                 }
  244.             }
  245.         }
  246.         return this;
  247.     }
  248.  
  249.     double det() {
  250.         double det = 1.;
  251.         for (int i = 0; i < this->a; ++ i) {
  252.             int iMax = i;
  253.             for (int j = i + 1; j < this->a; ++ j)
  254.                 if (fabs (this->at(j,i)) > fabs(this->at(iMax,i)))
  255.                     iMax = j;
  256.             if (fabs(this->at(iMax,i)) < 1E-9) {
  257.                 det = 0.;
  258.                 return det;
  259.             }
  260.             std::swap(this->m[i], this->m[iMax]);
  261.             if (i != iMax)
  262.                 det *= (-1);
  263.             det *= this->at(i,i);
  264.             for (int j=i+1; j<this->a; ++j) {
  265.                 double& var = this->at(i,j);
  266.                 var /= this->at(i,i);
  267.             }
  268.             for (int j=0; j<this->a; ++j)
  269.                 if (j != i && fabs(this->at(j,i)) > 1E-9)
  270.                     for (int k=i+1; k<this->a; ++k) {
  271.                         double& val = this->at(j, k);
  272.                         val -= this->at(i, k) * this->at(j, i);
  273.                     }
  274.         }
  275.         return det;
  276.     }
  277.  
  278.     void inverse_matrix() {
  279.         vector<int> row(this->a);
  280.         vector<int> col(this->a);
  281.         vector<double> temp(this->a);
  282.         int hold, I_pivot, J_pivot;
  283.         double pivot;
  284.         double abs_pivot;
  285.  
  286.         for (int k = 0; k < this->a; k++) {
  287.             row[k] = k;
  288.             col[k] = k;
  289.         }
  290.  
  291.         for (int k = 0; k <  this->a; k++) {
  292.             pivot = this->at(row[k],col[k]);
  293.             I_pivot = k;
  294.             J_pivot = k;
  295.             for (int i = k; i < this->a; i++) {
  296.                 for (int j = k; j < this->a; j++) {
  297.                     abs_pivot = fabs(pivot);
  298.                     if (fabs(this->at(row[i],col[j])) > abs_pivot) {
  299.                         I_pivot = i;
  300.                         J_pivot = j;
  301.                         pivot = this->at(row[i],col[j]);
  302.                     }
  303.                 }
  304.             }
  305.             if (fabs(pivot) < 1.0E-9) {
  306.                 throw std::invalid_argument("Matrix is singular !");
  307.             }
  308.             std::swap(row[k],row[I_pivot]);
  309.             std::swap(col[k],col[J_pivot]);
  310.  
  311.             double &val = this->at(row[k],col[k]);
  312.             val = 1.0 / pivot;
  313.             for (int j = 0; j < this->a; j++) {
  314.                 if (j != k) {
  315.                     double &var = this->at(row[k],col[j]);
  316.                     var = this->at(row[k],col[j]) * this->at(row[k],col[k]);
  317.                 }
  318.             }
  319.             for (int i = 0; i < this->a; i++) {
  320.                 if (k != i) {
  321.                     for (int j = 0; j < this->a; j++) {
  322.                         if (k != j) {
  323.                             double &buf = this->at(row[i],col[j]);
  324.                             buf = this->at(row[i],col[j]) - this->at(row[i],col[k]) *
  325.                                                                     this->at(row[k],col[j]);
  326.                         }
  327.                     }
  328.                     double &b = this->at(row[i],col[k]);
  329.                     b = -this->at(row[i],col[k]) * this->at(row[k],col[k]);
  330.                 }
  331.             }
  332.         }
  333.         for (int j = 0; j < this->a; j++) {
  334.             for (int i = 0; i < this->a; i++) {
  335.                 temp[col[i]] = this->at(row[i],j);
  336.             }
  337.             for (int i = 0; i < this->a; i++) {
  338.                 double &y = this->at(i,j);
  339.                 y = temp[i];
  340.             }
  341.         }
  342.         for (int i = 0; i < this->a; i++) {
  343.             for (int j = 0; j < this->a; j++) {
  344.                 temp[row[j]] = this->at(i,col[j]);
  345.             }
  346.             for (int j = 0; j < this->a; j++) {
  347.                 double &y = this->at(i,j);
  348.                 y = temp[j];
  349.             }
  350.         }
  351.     }
  352.  
  353.     friend ostream &operator<< (ostream &os, const sqMatrix &mat) {
  354.         for(int i = 0; i < mat.a; i++) {
  355.             for (int j = 0; j < mat.b; j++)
  356.                 os << mat.m[i][j] << " ";
  357.             os << endl;
  358.         }
  359.         return os;
  360.     }
  361.  
  362.  
  363. };
  364.  
  365.  
  366. int main() {
  367.     ifstream in("C:\\Users\\User\\CLionProjects\\Test\\in.txt");
  368.     ofstream out("C:\\Users\\User\\CLionProjects\\Test\\out.txt",ofstream::out);
  369.     Первое задание
  370.     double k;
  371.     in >> k;
  372.     int n, m;
  373.     in >> n >> m;
  374.     Matrix *a;
  375.     if (n == m)
  376.         a = new sqMatrix(n);
  377.     else
  378.         a = new Matrix(n,m);
  379.     for (int i = 0; i < n; i++) {
  380.         for (int j = 0; j < m; j++) {
  381.             double &var = a->at(i, j);
  382.             in >> var;
  383.         }
  384.     }
  385.     int n1,m1;
  386.     in >> n1 >> m1;
  387.     Matrix* b;
  388.     if (n == m)
  389.         b = new sqMatrix(n);
  390.     else
  391.         b = new Matrix(n,m);
  392.     for (int i = 0; i < n; i++) {
  393.         for (int j = 0; j < m; j++) {
  394.             double &var = b->at(i, j);
  395.             in >> var;
  396.         }
  397.     }
  398.     int n2,m2;
  399.     in >> n2 >> m2;
  400.     Matrix *c;
  401.     if (n == m)
  402.         c = new sqMatrix(n);
  403.     else
  404.         c = new Matrix(n,m);
  405.     for (int i = 0; i < n; i++) {
  406.         for (int j = 0; j < m; j++) {
  407.             double &var = c->at(i, j);
  408.             in >> var;
  409.         }
  410.     }
  411.     try {
  412.         sqMatrix* bb = dynamic_cast<sqMatrix*>(b);
  413.         if (bb == NULL)
  414.             throw std::invalid_argument(" ");
  415.  
  416.         bb=bb->transpose();
  417.         c->inverse_matrix();
  418.  
  419.         sqMatrix* cc = dynamic_cast<sqMatrix*>(c);
  420.         if (cc == NULL)
  421.             throw std::invalid_argument(" ");
  422.  
  423.         sqMatrix* buffer = bb->mul(cc);
  424.         buffer->scalar_mul(k);
  425.  
  426.         sqMatrix* aa = dynamic_cast<sqMatrix*>(a);
  427.         if (aa == NULL)
  428.             throw std::invalid_argument(" ");
  429.  
  430.         sqMatrix* d = buffer->sum(aa);
  431.         double det = d->det();
  432.  
  433.         out << 1 << endl;
  434.         out << det << endl;
  435.         out << d->get_a() << " " << d->get_b() << endl;
  436.         out << *d << endl;
  437.  
  438.     }
  439.     catch (std::invalid_argument &err) {
  440.         out << "-1" << endl;
  441.     }
  442.     in.close();
  443.     out.close();
  444.     return 0;
  445. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement