Advertisement
Lesnic

Least square approximation Lera

Apr 18th, 2020
264
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.47 KB | None | 0 0
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <cstdio>
  4. #include <math.h>
  5.  
  6. #define GNUPLOT_NAME "C:\\gnuplot\\bin\\gnuplot.exe -persist"
  7.  
  8. using namespace std;
  9.  
  10. class Matrix
  11. {
  12. private:
  13.     int row, column;
  14.     double** matrix;
  15.  
  16. public:
  17.     Matrix(int row, int column) {
  18.         (*this).row = row;
  19.         (*this).column = column;
  20.         matrix = new double* [row];
  21.         for (int i = 0; i < row; i++)
  22.             matrix[i] = new double[column];
  23.     }
  24.  
  25.     friend Matrix operator*(const Matrix& a, const Matrix& b) {
  26.         Matrix* enmat = new Matrix(a.row, b.column);
  27.         for (int i = 0; i < enmat->row; i++) {
  28.             for (int j = 0; j < enmat->column; j++) {
  29.                 enmat->matrix[i][j] = 0;
  30.                 for (int k = 0; k < a.column; k++)
  31.                     enmat->matrix[i][j] += a.matrix[i][k] * b.matrix[k][j];
  32.             }
  33.         }
  34.         return *enmat;
  35.     }
  36.  
  37.     Matrix& operator=(const Matrix& right) {
  38.         Matrix enmat(right.row, right.column);
  39.         for (int i = 0; i < enmat.row; i++)
  40.             for (int j = 0; j < enmat.column; j++)
  41.                 enmat.matrix[i][j] = right.matrix[i][j];
  42.         (*this).matrix = enmat.matrix;
  43.         (*this).row = enmat.row;
  44.         (*this).column = enmat.column;
  45.         return *this;
  46.     }
  47.  
  48.     Matrix transp() {
  49.         Matrix transp(column, row);
  50.         for (int i = 0; i < row; i++)
  51.             for (int j = 0; j < column; j++) {
  52.                 transp.matrix[j][i] = matrix[i][j];
  53.             }
  54.         return transp;
  55.     }
  56.  
  57.     void permut(int row1, int row2, Matrix& a) {
  58.         double* tempo = *(matrix + row1);
  59.         *(matrix + row1) = *(matrix + row2);
  60.         *(matrix + row2) = tempo;
  61.  
  62.         tempo = *(a.matrix + row1);
  63.         *(a.matrix + row1) = *(a.matrix + row2);
  64.         *(a.matrix + row2) = tempo;
  65.     }
  66.  
  67.     void elimin(int topLine, int botLine, Matrix& a) {
  68.         double f = matrix[botLine][topLine] / matrix[topLine][topLine];
  69.         if (matrix[botLine][topLine] != 0) {
  70.             for (int j = 0; j < column; j++) {
  71.                 matrix[botLine][j] -= matrix[topLine][j] * f;
  72.                 a.matrix[botLine][j] -= a.matrix[topLine][j] * f;
  73.             }
  74.         }
  75.     }
  76.  
  77.     void norm(Matrix& a) {
  78.         for (int i = 0; i < row; i++) {
  79.             double ct = matrix[i][i];
  80.             for (int j = 0; j < column; j++) {
  81.                 matrix[i][j] /= ct;
  82.                 a.matrix[i][j] /= ct;
  83.             }
  84.         }
  85.     }
  86.  
  87.     Matrix inv() {
  88.         Matrix base(this->row, this->column), inverse(this->row, this->column);
  89.         for (int i = 0; i < row; i++) {
  90.             for (int j = 0; j < column; j++) {
  91.                 base.matrix[i][j] = matrix[i][j];
  92.                 inverse.matrix[i][j] = i == j;
  93.             }
  94.         }
  95.  
  96.         for (int line = 0; line < row; line++) {
  97.             int maxLine = line;
  98.             for (int i = line + 1; i < base.row; i++) {
  99.                 if (abs(base.matrix[i][line]) > abs(base.matrix[maxLine][line]))
  100.                     maxLine = i;
  101.             }
  102.  
  103.             if (maxLine != line)
  104.                 base.permut(line, maxLine, inverse);
  105.  
  106.             for (int i = line + 1; i < base.row; i++)
  107.                 base.elimin(line, i, inverse);
  108.         }
  109.  
  110.         for (int line = row - 1; line > 0; line--)
  111.             for (int i = line - 1; i >= 0; i--)
  112.                 base.elimin(line, i, inverse);
  113.         base.norm(inverse);
  114.         return inverse;
  115.     }
  116.     friend double* findCoef(double points[15][2]);
  117.     friend ostream& operator<<(ostream& cout, Matrix matrix) {
  118.         for (int i = 0; i < matrix.row; i++) {
  119.             for (int j = 0; j < matrix.column; j++) {
  120.                 cout << matrix.matrix[i][j];
  121.                 if (j != matrix.column - 1)
  122.                     cout << " ";
  123.             }
  124.             cout << endl;
  125.         }
  126.         return cout;
  127.     }
  128. };
  129.  
  130. double* findCoef(double points[15][2]) {
  131.     Matrix a(15, 3), b(15, 1);
  132.  
  133.     for (int i = 0; i < 15; i++) {
  134.         b.matrix[i][0] = points[i][1];
  135.         a.matrix[i][0] = 1;
  136.         a.matrix[i][1] = points[i][0];
  137.         a.matrix[i][2] = points[i][0] * points[i][0];
  138.     }
  139.     Matrix at = a.transp();
  140.     Matrix at_A = at * a;
  141.     Matrix at_A_inverse = at_A.inv();
  142.     Matrix at_b = at * b;
  143.     Matrix res = at_A_inverse * at_b;
  144.     double* coef = new double[3];
  145.     for (int i = 0; i < 3; i++)
  146.         coef[2 - i] = res.matrix[i][0];
  147.     return coef;
  148. }
  149.  
  150. int main() {
  151.     FILE* pipe = _popen(GNUPLOT_NAME, "w");
  152.  
  153.     if (pipe != NULL) {
  154.         fprintf(pipe, "set xrange [0:13]\nset yrange[0:17]\nset multiplot\n");
  155.  
  156.         double points[15][2] = { {1, 3}, {2, 9}, {3, 5},
  157.         {3, 12}, {4, 8}, {4, 14},
  158.         {5, 10}, {6, 15}, {7, 10},
  159.         {8, 8}, {8, 14}, {9, 5},
  160.         {9, 12}, {10, 9}, {11, 3} };
  161.  
  162.         double* coef = findCoef(points);
  163.  
  164.         fprintf(pipe, "set nokey\nplot '-' using 1:2 title ' ' with lines linecolor 3\n");
  165.  
  166.         for (int i = 0; i < 1300; i++) {
  167.             double x = i / 100.0;
  168.             double y = coef[0] * pow(x, 2) + coef[1] * x + coef[2];
  169.             fprintf(pipe, "%f\t%f\n", x, y);
  170.         }
  171.         fprintf(pipe, "e\n");
  172.  
  173.         fprintf(pipe, "set nokey\nplot '-' using 1:2 title ' ' with points pointtype 7\n");
  174.         for (int i = 0; i < 15; i++) {
  175.             fprintf(pipe, "%f\t%f\n", points[i][0], points[i][1]);
  176.         }
  177.         fprintf(pipe, "e\n");
  178.  
  179.         fflush(pipe);
  180.  
  181.         _pclose(pipe);
  182.     }
  183. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement