Advertisement
Guest User

Untitled

a guest
Nov 26th, 2015
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.26 KB | None | 0 0
  1. #define EPSILON 0.000001
  2.  
  3. #include <math.h>
  4. #include <iostream>
  5. #include <iomanip>
  6. #include <stdio.h>
  7. #include <fstream>
  8.  
  9. using namespace std;
  10.  
  11. class matrix {
  12. private:
  13.     int size;
  14.     double **content;
  15.  
  16. public:
  17.     //Конструкторы и деструктор
  18.     matrix(int n = 1, double con = 0) {
  19.         size = n;
  20.         content = new double*[n];
  21.         for (int i = 0; i < n; i++) content[i] = new double[n];
  22.         if (!con) for (int i = 0; i < n; i++) {
  23.             for (int j = 0; j < n; j++)
  24.                 content[i][j] = 0;
  25.         }
  26.         else {
  27.             for (int i = 0; i < n; i++) content[i][i] = con;
  28.         }
  29.     }
  30.  
  31.     matrix(const matrix& m) {
  32.         size = m.size;
  33.         content = new double*[size];
  34.         for (int i = 0; i < size; i++) content[i] = new double[size];
  35.         for (int i = 0; i < size; i++)
  36.             for (int j = 0; j < size; j++) content[i][j] = m.content[i][j];
  37.     }
  38.  
  39.     ~matrix() {
  40.         for (int i = 0; i < size; i++)
  41.             delete[] content[i];
  42.         delete[] content;
  43.     }
  44.  
  45.         //Общие методы
  46.         void setCell(int i, int j, double num);
  47.     void switchLines(int line1, int line2);
  48.         double detUpperTriangular(int count);
  49.         double norm();
  50.         void print();
  51.    
  52.         //Методы для обычного метода Гаусса и нахождения обратной матрицы
  53.         //Объединены для экономии времени работы программы
  54.         int makeUpperTriangular(matrix& I, double *f); //Меняем также и единичную матрицу
  55.         void finishInverseSolve(matrix &I, double *f); //из верхней треугольной
  56.         void printGaussDetInverse(double *f);
  57.    
  58.         //Методы для метода Гаусса с выбором главного элемента
  59.         int makeUpperTriangularChoose(double *f);
  60.         void printGaussChoose(double *f);
  61.         void solveChoose(double *f);
  62. };
  63.  
  64. //Реализация методов
  65. void matrix::setCell(int i, int j, double num) {
  66.     content[i][j] = num;
  67. }
  68.  
  69. void matrix::switchLines(int line1, int line2) {
  70.     double *temp = new double[size];
  71.     for (int i = 0; i < size; i++)  temp[i] = content[line1][i];
  72.     for (int i = 0; i < size; i++)  content[line1][i] = content[line2][i];
  73.     for (int i = 0; i < size; i++)  content[line2][i] = temp[i];
  74.     delete[] temp;
  75. }
  76.  
  77. double matrix::detUpperTriangular(int count) {
  78.     double res = 1;
  79.     for (int i = 0; i < size; i++) {
  80.         res *= content[i][i];
  81.     }
  82.     if(res == 0.0 || res == -0.0) return 0.0;
  83.     if(count % 2 == 0) return res;
  84.     return -res;
  85. }
  86.  
  87. int matrix::makeUpperTriangular(matrix& I, double *f) {
  88.     int count = 0;
  89.     double temp = 0;
  90.     for(int k = 0; k < size - 1; k++) {
  91.         if (content[k][k] == 0) {
  92.             int l = k;
  93.             while (content[l][k] == 0) {
  94.                 if (l == size - 1) break;
  95.                 l++;
  96.             }
  97.             if((content[l][k] == 0) && (l = size - 1)) continue;
  98.             this->switchLines(k, l);
  99.             I.switchLines(k, l);
  100.             count++;
  101.             temp = f[k];
  102.             f[k] = f[l];
  103.             f[l] = temp;
  104.         }
  105.        
  106.         for(int i = k + 1; i < size; i++) {
  107.             temp = content[i][k] / content[k][k];
  108.             for(int j = k; j < size; j++) {
  109.                 content[i][j] -= temp * content[k][j];
  110.                 I.content[i][j] -= temp * I.content[k][j];
  111.             }
  112.             f[i] -= temp * f[k];
  113.         }
  114.     }
  115.     return count;
  116. }
  117.  
  118. double matrix::norm() {
  119.     double res = 0;
  120.     for(int i = 0; i < size; i++)
  121.         for(int j = 0; j < size; j++) {
  122.             res += content[i][j] * content[i][j];
  123.         }
  124.     return sqrt(res);
  125. }
  126.  
  127. void matrix::finishInverseSolve(matrix& I, double *f) {
  128.     for(int k = size - 1; k >= 0; k--) {
  129.         f[k] /= content[k][k];
  130.         I.content[k][k] /= content[k][k];
  131.         /* Здесь должно быть
  132.          * content[k][k] = 1.0;
  133.          * но для экономии времени не будем этого делать
  134.          */
  135.         for(int i = k - 1; i >= 0; i--) {
  136.             I.content[i][k] -= content[i][k] * I.content[k][k];
  137.             f[i] -= f[k] * content[i][k];
  138.             /* Здесь должно быть
  139.              * content[i][k] = 0.0;
  140.              * но для экономии времени не будем этого делать
  141.              */
  142.         }
  143.     }
  144. }
  145.  
  146. void matrix::printGaussDetInverse(double *f) {
  147.     matrix I(size, 1);
  148.     double det;
  149.    
  150.     if((det = this->detUpperTriangular(this->makeUpperTriangular(I, f))) < EPSILON) {
  151.         cout << "Матрица не является обратимой" << endl;
  152.         cout << "Бесконечное множество решений" << endl;
  153.         return;
  154.     }
  155.     else {
  156.         cout << "Определитель матрицы: " << det << endl << endl;
  157.     }
  158.    
  159.     this->finishInverseSolve(I, f);
  160.     I.print();
  161.     cout << endl;
  162.    
  163.     for(int i = 0; i < size; i++) {
  164.         cout << 'X' << i + 1 << "= " << f[i] << endl;
  165.     }
  166.     cout << endl;
  167. }
  168.  
  169. int matrix::makeUpperTriangularChoose(double *f) {
  170.     int count = 0;
  171.     double temp = 0;
  172.     for(int k = 0; k < size - 1; k++) {
  173.         double max = content[k][k];
  174.         int l = k;
  175.        
  176.         for(int i = k + 1; i < size; i++) {
  177.             if(content[i][k] > max) {
  178.                 max = content[i][k];
  179.                 l = i;
  180.             }
  181.         }
  182.        
  183.         if(max == 0) continue;
  184.         if(l != k) {
  185.             this->switchLines(k, l);
  186.             count++;
  187.             temp = f[k];
  188.             f[k] = f[l];
  189.             f[l] = temp;    
  190.         }
  191.        
  192.         for(int i = k + 1; i < size; i++) {
  193.             temp = content[i][k] / content[k][k];
  194.             for(int j = k; j < size; j++) {
  195.                 content[i][j] -= temp * content[k][j];
  196.             }
  197.             f[i] -= temp * f[k];
  198.         }
  199.     }
  200.     return count;
  201. }
  202.  
  203. void matrix::solveChoose(double *f) {
  204.     for(int k = size - 1; k >= 0; k--) {
  205.         f[k] /= content[k][k];
  206.         /* Здесь должно быть
  207.          * content[k][k] = 1.0;
  208.          * но для экономии времени не будем этого делать
  209.          */
  210.         for(int i = k - 1; i >= 0; i--) {
  211.             f[i] -= f[k] * content[i][k];
  212.             /* Здесь должно быть
  213.              * content[i][k] = 0.0;
  214.              * но для экономии времени не будем этого делать
  215.              */
  216.         }
  217.     }
  218. }
  219.  
  220. void matrix::printGaussChoose(double *f) {
  221.     if((this->detUpperTriangular(this->makeUpperTriangularChoose(f))) < EPSILON) {
  222.         cout << "Бесконечное множество решений" << endl;
  223.         return;
  224.     }
  225.    
  226.     this->solveChoose(f);
  227.    
  228.     for(int i = 0; i < size; i++) {
  229.         cout << 'X' << i + 1 << "= " << f[i] << endl;
  230.     }
  231. }
  232.  
  233. void matrix::print() {
  234.     for(int i = 0; i < size; i++) {
  235.         for(int j = 0; j < size - 1; j++) {
  236.             cout << content[i][j] << ' ';
  237.         }
  238.         cout << content[i][size - 1] << endl;
  239.     }
  240. }
  241.  
  242. int main(int argc, char **argv) {
  243.     int n;
  244.     int m = 8;
  245.     sscanf(argv[1], "%d", &n);
  246.    
  247.     matrix A(n, n);
  248.     double *f = new double[n];
  249.     double *f1 = new double[n];
  250.    
  251.     cout << setprecision(2) << fixed;
  252.    
  253.     if(argc < 3) { //Ввод формул
  254.         for(int i = 0; i < n; i++) {
  255.             for(int j = 0; j < n; j++) {
  256.                 if(i != j) {
  257.                     A.setCell(i, j, ((double)(i + j + 2)/(m + n)));
  258.                 }
  259.                 else {
  260.                     A.setCell(i, j, (double)(n + (double)m * m + (double)(j + 1) / m + (double)(i + 1) / n));
  261.                 }
  262.             }
  263.             f[i] = 200 + 50 * (i + 1);
  264.             f1[i] = f[i];
  265.         }
  266.     }
  267.     else { //Ввод из файла
  268.         ifstream input;
  269.         input.open(argv[2]);
  270.         double temp;
  271.         for(int i = 0; i < n; i++) {
  272.             for(int j = 0; j < n; j++) {
  273.                 input >> temp;
  274.                 A.setCell(i, j, temp);
  275.             }
  276.             input >> temp;
  277.             f[i] = temp;
  278.             f1[i] = f[i];
  279.         }
  280.         input.close();
  281.     }
  282.    
  283.     matrix B(A);
  284.    
  285.     A.printGaussDetInverse(f);
  286.     B.printGaussChoose(f1);
  287.    
  288.     delete[] f1;
  289.     delete[] f;
  290.    
  291.     return 0;
  292. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement