Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <vector>
- #include <stdexcept>
- #include <cmath>
- #include <fstream>
- using namespace std;
- class Matrix {
- public:
- Matrix() {};
- Matrix(int a_,int b_): a(a_),b(b_) {
- m = vector<vector<double>>(a);
- for(int i=0;i<a;i++)
- m[i].resize(b);
- };
- double& at(int i,int j) {
- return m[i][j];
- }
- int get_a() const {
- return this->a;
- }
- int get_b() const {
- return this->b;
- }
- Matrix* sum(Matrix* b) {
- Matrix* c = new Matrix(std::min(this->a,b->a),std::min(this->b,b->b));
- for(int i=0;i<c->a;i++)
- for (int j=0;j<c->b;j++) {
- double &val = c->at(i,j);
- val = this->at(i, j) + b->at(i, j);
- }
- return c;
- }
- Matrix* mul(Matrix* b) {
- Matrix* c = new Matrix(this->a,b->b);
- if (this->b != b->a)
- throw std::invalid_argument("Only matrix MxN,NxC can multiply");
- for(int i=0;i<c->a;i++) {
- for (int j = 0; j < c->b; j++) {
- double &val = c->at(i,j);
- val = 0;
- for (int k = 0; k < this->b; k++)
- val += this->at(i,k) * b->at(k,j);
- }
- }
- return c;
- }
- void scalar_mul(double m) {
- for(int i=0;i<this->a;i++) {
- for (int j = 0; j < this->b; j++) {
- double& val = this->at(i,j);
- val *= m;
- }
- }
- }
- Matrix* transpose() {
- Matrix* b = new Matrix(this->b,this->a);
- for(int i=0;i<this->a;i++) {
- for (int j=0;j<this->b;j++) {
- double &val = b->at(j,i);
- val=this->at(i,j);
- }
- }
- return b;
- }
- virtual void step_matrix() {
- int count_swap=1;
- for (int i = 0; i < this->a; ++ i) {
- int iMax = i;
- for (int j = i + 1; j < this->a; ++ j)
- if (fabs (this->at(j,i)) > fabs(this->at(iMax,i)))
- iMax = j;
- if (fabs(this->at(iMax,i)) < 1E-9)
- continue;
- std::swap(this->m[i], this->m[iMax]);
- count_swap = - count_swap * (i != iMax ? 1 : - 1);
- for (int j = i + 1; j < this->a; ++ j) {
- double q = - this->at(j,i) / this->at(i,i);
- for (int k = this->b - 1; k >= i; -- k) {
- double& val = this->at(j,k);
- val += q * this->at(i, k);
- }
- }
- }
- }
- virtual double det() {
- throw std::invalid_argument("No determinant for quad matrix. Only sqMatrix!");
- }
- virtual void inverse_matrix() {
- throw std::invalid_argument("No inverse for quad matrix. Only sqMatrix!");
- }
- friend ostream &operator<< (ostream &os, const Matrix &mat) {
- for(int i = 0; i < mat.a; i++) {
- for (int j = 0; j < mat.b; j++)
- os << mat.m[i][j] << " ";
- os << endl;
- }
- return os;
- }
- virtual ~Matrix(){};
- protected:
- int a; // row
- int b; // column
- vector<vector<double>> m;
- };
- class vMatrix: public Matrix {
- public:
- vMatrix(int a_,bool flag): invert_x(flag) {
- if (flag) {
- a = a_;
- b = 1;
- }
- else {
- a = 1;
- b = a_;
- }
- m = vector<vector<double>>(a);
- for (int i = 0; i < a; i++)
- m[i].resize(b);
- };
- vMatrix* sum(vMatrix* b) {
- if (this->a != b->a || this->b != b->b)
- throw std::invalid_argument("Dimensions of two vMatrix must be equal!");
- vMatrix* c = new vMatrix(std::max(this->a,this->b),this->invert_x);
- for(int i=0;i<c->a;i++)
- for (int j=0;j<c->b;j++) {
- double &val = c->at(i,j);
- val = this->at(i, j) + b->at(i,j);
- }
- return c;
- }
- double mul(vMatrix* b) {
- double val = 0;
- if (this->b != b->a)
- throw std::invalid_argument("Only matrix MxN,NxC can multiply");
- for(int i=0;i<this->a;i++) {
- for (int j = 0; j < b->b; j++) {
- for (int k = 0; k < this->b; k++)
- val += this->at(i,k) * b->at(k,j);
- }
- }
- return val;
- }
- vMatrix* transpose() {
- vMatrix* b = new vMatrix(std::max(this->a,this->b),!this->invert_x);
- for(int i=0;i<this->a;i++) {
- for (int j=0;j<this->b;j++) {
- double &val = b->at(j,i);
- val=this->at(i,j);
- }
- }
- return b;
- }
- virtual void step_matrix() {
- throw std::invalid_argument("No step_matrix for vectors. Only sqMatrix!");
- }
- virtual double det() {
- throw std::invalid_argument("No determinant for vectors. Only sqMatrix!");
- }
- virtual void inverse_matrix() {
- throw std::invalid_argument("No inverse for vectors. Only sqMatrix!");
- }
- friend ostream &operator<< (ostream &os, const vMatrix &mat) {
- for(int i = 0; i < mat.a; i++) {
- for (int j = 0; j < mat.b; j++)
- os << mat.m[i][j] << " ";
- os << endl;
- }
- return os;
- }
- private:
- bool invert_x; // true if vector[3,1] else vector[1,3]
- };
- class sqMatrix: public Matrix
- {
- public:
- sqMatrix(int a_): Matrix(a_,a_) {};
- sqMatrix* sum(sqMatrix* b) {
- sqMatrix* c = new sqMatrix(std::min(this->a,b->a));
- for(int i=0;i<c->a;i++)
- for (int j=0;j<c->b;j++) {
- double &val = c->at(i,j);
- val = this->at(i, j) + b->at(i, j);
- }
- return c;
- }
- sqMatrix* mul(sqMatrix* b) {
- if (this->a != b->a)
- throw std::invalid_argument("Only matrix MxN,NxC can multiply");
- sqMatrix* c = new sqMatrix(this->a);
- for(int i=0;i<c->a;i++) {
- for (int j = 0; j < c->b; j++) {
- double &val = c->at(i,j);
- val = 0;
- for (int k = 0; k < this->b; k++)
- val += this->at(i,k) * b->at(k,j);
- }
- }
- return c;
- }
- sqMatrix* transpose() {
- for(int i=0;i<this->a;i++) {
- for (int j=i+1;j<this->b;j++) {
- if (i!=j) {
- double& var = this->at(i,j);
- double& val = this->at(j,i);
- std::swap(var,val);
- }
- }
- }
- return this;
- }
- double det() {
- double det = 1.;
- for (int i = 0; i < this->a; ++ i) {
- int iMax = i;
- for (int j = i + 1; j < this->a; ++ j)
- if (fabs (this->at(j,i)) > fabs(this->at(iMax,i)))
- iMax = j;
- if (fabs(this->at(iMax,i)) < 1E-9) {
- det = 0.;
- return det;
- }
- std::swap(this->m[i], this->m[iMax]);
- if (i != iMax)
- det *= (-1);
- det *= this->at(i,i);
- for (int j=i+1; j<this->a; ++j) {
- double& var = this->at(i,j);
- var /= this->at(i,i);
- }
- for (int j=0; j<this->a; ++j)
- if (j != i && fabs(this->at(j,i)) > 1E-9)
- for (int k=i+1; k<this->a; ++k) {
- double& val = this->at(j, k);
- val -= this->at(i, k) * this->at(j, i);
- }
- }
- return det;
- }
- void inverse_matrix() {
- vector<int> row(this->a);
- vector<int> col(this->a);
- vector<double> temp(this->a);
- int hold, I_pivot, J_pivot;
- double pivot;
- double abs_pivot;
- for (int k = 0; k < this->a; k++) {
- row[k] = k;
- col[k] = k;
- }
- for (int k = 0; k < this->a; k++) {
- pivot = this->at(row[k],col[k]);
- I_pivot = k;
- J_pivot = k;
- for (int i = k; i < this->a; i++) {
- for (int j = k; j < this->a; j++) {
- abs_pivot = fabs(pivot);
- if (fabs(this->at(row[i],col[j])) > abs_pivot) {
- I_pivot = i;
- J_pivot = j;
- pivot = this->at(row[i],col[j]);
- }
- }
- }
- if (fabs(pivot) < 1.0E-9) {
- throw std::invalid_argument("Matrix is singular !");
- }
- std::swap(row[k],row[I_pivot]);
- std::swap(col[k],col[J_pivot]);
- double &val = this->at(row[k],col[k]);
- val = 1.0 / pivot;
- for (int j = 0; j < this->a; j++) {
- if (j != k) {
- double &var = this->at(row[k],col[j]);
- var = this->at(row[k],col[j]) * this->at(row[k],col[k]);
- }
- }
- for (int i = 0; i < this->a; i++) {
- if (k != i) {
- for (int j = 0; j < this->a; j++) {
- if (k != j) {
- double &buf = this->at(row[i],col[j]);
- buf = this->at(row[i],col[j]) - this->at(row[i],col[k]) *
- this->at(row[k],col[j]);
- }
- }
- double &b = this->at(row[i],col[k]);
- b = -this->at(row[i],col[k]) * this->at(row[k],col[k]);
- }
- }
- }
- for (int j = 0; j < this->a; j++) {
- for (int i = 0; i < this->a; i++) {
- temp[col[i]] = this->at(row[i],j);
- }
- for (int i = 0; i < this->a; i++) {
- double &y = this->at(i,j);
- y = temp[i];
- }
- }
- for (int i = 0; i < this->a; i++) {
- for (int j = 0; j < this->a; j++) {
- temp[row[j]] = this->at(i,col[j]);
- }
- for (int j = 0; j < this->a; j++) {
- double &y = this->at(i,j);
- y = temp[j];
- }
- }
- }
- friend ostream &operator<< (ostream &os, const sqMatrix &mat) {
- for(int i = 0; i < mat.a; i++) {
- for (int j = 0; j < mat.b; j++)
- os << mat.m[i][j] << " ";
- os << endl;
- }
- return os;
- }
- };
- int main() {
- ifstream in("C:\\Users\\User\\CLionProjects\\Test\\in.txt");
- ofstream out("C:\\Users\\User\\CLionProjects\\Test\\out.txt",ofstream::out);
- Первое задание
- double k;
- in >> k;
- int n, m;
- in >> n >> m;
- Matrix *a;
- if (n == m)
- a = new sqMatrix(n);
- else
- a = new Matrix(n,m);
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < m; j++) {
- double &var = a->at(i, j);
- in >> var;
- }
- }
- int n1,m1;
- in >> n1 >> m1;
- Matrix* b;
- if (n == m)
- b = new sqMatrix(n);
- else
- b = new Matrix(n,m);
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < m; j++) {
- double &var = b->at(i, j);
- in >> var;
- }
- }
- int n2,m2;
- in >> n2 >> m2;
- Matrix *c;
- if (n == m)
- c = new sqMatrix(n);
- else
- c = new Matrix(n,m);
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < m; j++) {
- double &var = c->at(i, j);
- in >> var;
- }
- }
- try {
- sqMatrix* bb = dynamic_cast<sqMatrix*>(b);
- if (bb == NULL)
- throw std::invalid_argument(" ");
- bb=bb->transpose();
- c->inverse_matrix();
- sqMatrix* cc = dynamic_cast<sqMatrix*>(c);
- if (cc == NULL)
- throw std::invalid_argument(" ");
- sqMatrix* buffer = bb->mul(cc);
- buffer->scalar_mul(k);
- sqMatrix* aa = dynamic_cast<sqMatrix*>(a);
- if (aa == NULL)
- throw std::invalid_argument(" ");
- sqMatrix* d = buffer->sum(aa);
- double det = d->det();
- out << 1 << endl;
- out << det << endl;
- out << d->get_a() << " " << d->get_b() << endl;
- out << *d << endl;
- }
- catch (std::invalid_argument &err) {
- out << "-1" << endl;
- }
- in.close();
- out.close();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement