Advertisement
DacCum

Метод наименьших квадратов

Nov 6th, 2021
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.22 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3. #include <iomanip>
  4. #define N 9 //количество експериментов
  5. #define xcp 0 //индекс таблицы в котором храняться средние значения х
  6. #define ycp 1 //индекс таблицы в котором храняться средние значения у
  7. #define tillday 2 //индекс таблицы в котором храняться значения ~y
  8. #define form 3 //индекс таблицы в котором храняться значения выражения
  9. #define a 0 //индекс коэффициента а
  10. #define b 1 //индекс коэффициента b
  11. #define x 0 //индекс коэффициента x
  12. #define y 1 //индекс коэффициента y
  13.  
  14. using namespace std;
  15.  
  16. //функция вычисления среднего арифметического елементов массива
  17. double average(double* arr) {
  18.     double res = 0;
  19.     for (int i = 0; i < N; i++)
  20.         res += arr[i];
  21.    
  22.     return res / N;
  23. }
  24.  
  25. //функция вычисления среднего геометрического елементов массива
  26. double geometric_mean(double* arr) {
  27.     double res = 1;
  28.     for (int i = 0; i < N; i++)
  29.         res *= arr[i];
  30.  
  31.     return pow(res, 1./N);
  32. }
  33.  
  34. //функция вычисления среднего гармонического елементов массива
  35. double harmonic_mean(double* arr) {
  36.     double res = 0;
  37.     for (int i = 0; i < N; i++)
  38.         res += 1/arr[i];
  39.  
  40.     return N / res;
  41. }
  42.  
  43. //функция вычисления ~y
  44. double calc_tilday(double* X, double* Y, double _xcp) {
  45.     int tmp_i = 0;
  46.     for (int i = 0; i < N; i++){
  47.         if (_xcp == X[i])
  48.             return Y[i];
  49.         else if (X[i] < _xcp)
  50.             tmp_i = i;
  51.     }
  52.  
  53.     return ((_xcp - X[tmp_i]) / (X[tmp_i + 1] - X[tmp_i])) * (Y[tmp_i + 1] - Y[tmp_i]) + Y[tmp_i];
  54. }
  55.  
  56. //функция выведения таблицы на экран
  57. void print_table(double** tabl, int i_func) {
  58.     cout << "Dependency selection table: " << endl;
  59.     cout << "| # |  xcp\t|  ycp\t|  ~y\t|  abs(ycp - ~y) / ~y\t" << endl;
  60.     for (int i = 0; i < N; i++) {
  61.         cout << "| " << i + 1 << ' ';
  62.         for (int j = 0; j < 4; j++)
  63.             cout << "| " << fixed << setprecision(3) << tabl[j][i] << '\t';
  64.         if (i == i_func)
  65.             cout << "+";
  66.         cout << endl;
  67.     }
  68. }
  69.  
  70. //функция выведения одномерного массива на экран
  71. void print_arr(double* arr, char name_arr) {
  72.     cout << name_arr << " = { " << arr[0];
  73.     for (int i = 1; i < N; i++)
  74.         cout << ", " << arr[i] ;
  75.     cout << " }" << endl;
  76. }
  77.  
  78. //функция создания таблицы и введения в неё данных
  79. double** build_table(double* X, double* Y) {
  80.     //создаём пустую таблицу
  81.     double** res_tabl = new double* [4];
  82.     for (int i = 0; i < 4; i++)
  83.         res_tabl[i] = new double[N] ();
  84.    
  85.     //создаём массив врменных значений
  86.     double *tmp_res = new double[3];
  87.     //вычисляем и записываем средние значения Х
  88.     tmp_res[0] = average(X);
  89.     tmp_res[1] = geometric_mean(X);
  90.     tmp_res[2] = harmonic_mean(X);
  91.     //вводим эти значения в таблицу
  92.     for (int i = 0; i < 3; i++)
  93.         for (int j = i; j < N; j += 3)
  94.             res_tabl[xcp][j] = tmp_res[i];
  95.  
  96.     //вычисляем и записываем средние значения для У
  97.     tmp_res[0] = average(Y);
  98.     tmp_res[1] = geometric_mean(Y);
  99.     tmp_res[2] = harmonic_mean(Y);
  100.     //вводим эти значения в таблицу
  101.     for (int i = 0; i < N; i += 3)
  102.         for (int j = i; j < N; j++)
  103.             res_tabl[ycp][j] = tmp_res[i/3];
  104.  
  105.     //вычисляем и вводим в таблицу значения ~У и выражения
  106.     for (int i = 0; i < N; i++) {
  107.         res_tabl[tillday][i] = calc_tilday(X, Y, res_tabl[xcp][i]);
  108.         res_tabl[form][i] = fabs((res_tabl[ycp][i] - res_tabl[tillday][i]) / res_tabl[tillday][i]);
  109.     }
  110.  
  111.     return res_tabl;
  112. }
  113.  
  114. //функция нахождения индекса минимального елемента
  115. int min(double *arr) {
  116.     int min = 0;
  117.     for (int i = 0; i < N; i++)
  118.         if (arr[min] > arr[i])
  119.             min = i;
  120.  
  121.     return min;
  122. }
  123.  
  124. //функция для преобразования елементов массивов Х и У
  125. //для их дальнейшего подставления в формулу нахождения а и b
  126. double** func(double* X, double* Y, int i_func) {
  127.     double** res = new double* [2];
  128.     for (int i = 0; i < 2; i++)
  129.         res[i] = new double[N];
  130.     if(i_func == 0)
  131.         for (int i = 0; i < N; i++) {
  132.             res[y][i] = Y[i];
  133.             res[x][i] = X[i];
  134.         }
  135.     else if (i_func == 1)
  136.         for (int i = 0; i < N; i++) {
  137.             res[y][i] = Y[i];
  138.             res[x][i] = 1. / X[i];
  139.         }
  140.     else if (i_func == 2)
  141.         for (int i = 0; i < N; i++) {
  142.             res[y][i] = Y[i];
  143.             res[x][i] = log(X[i]);
  144.         }
  145.     else if (i_func == 3)
  146.         for (int i = 0; i < N; i++) {
  147.             res[y][i] = log(Y[i]);
  148.             res[x][i] = X[i];
  149.         }
  150.     else if (i_func == 4)
  151.         for (int i = 0; i < N; i++) {
  152.             res[y][i] = log(Y[i]);
  153.             res[x][i] = log(X[i]);
  154.         }
  155.     else if (i_func == 5)
  156.         for (int i = 0; i < N; i++) {
  157.             res[y][i] = log(Y[i]);
  158.             res[x][i] = 1. / X[i];
  159.         }
  160.     else if (i_func == 6)
  161.         for (int i = 0; i < N; i++) {
  162.             res[y][i] = 1. / Y[i];
  163.             res[x][i] = X[i];
  164.         }
  165.     else if (i_func == 7)
  166.         for (int i = 0; i < N; i++) {
  167.             res[y][i] = 1. / Y[i];
  168.             res[x][i] = log(X[i]);
  169.         }
  170.     else if (i_func == 8)
  171.         for (int i = 0; i < N; i++) {
  172.             res[y][i] = 1. / Y[i];
  173.             res[x][i] = 1. / X[i];
  174.         }
  175.     else
  176.         cout << "ERROR: i_func = " << i_func;
  177.  
  178.     return res;
  179. }
  180.  
  181. //функция вычисления а и b
  182. double* calc_coef(double* X, double* Y, int i_func) {
  183.     //создаем массив коэффициентов
  184.     double* coef = new double[2];
  185.     //преобразовываем х и у под нужную формулу
  186.     double** newXY = func(X, Y, i_func);
  187.  
  188.     double sumxy = 0, //сумма х*у
  189.            sumx = 0, //сумма х
  190.            sumy = 0, //сумма у
  191.            sumx2 = 0; //сумма х^2
  192.     //вычисляем суммы
  193.     for (int i = 0; i < N; i++) {
  194.         sumxy += (newXY[x][i] * newXY[y][i]);
  195.         sumx += newXY[x][i];
  196.         sumy += newXY[y][i];
  197.         sumx2 += (newXY[x][i] * newXY[x][i]);
  198.     }
  199.  
  200.     //вичисляем коэффициенты за формулами(1)
  201.     coef[a] = (sumxy - (1. / N) * sumx * sumy) / (sumx2 - (1. / N) * sumx * sumx);
  202.     coef[b] = (1. / N) * sumy - (coef[a] / N) * sumx;
  203.    
  204.     //если нужно преобразовываем коэффициенти до нормального вида
  205.     if (i_func == 3) {
  206.         coef[a] = exp(coef[a]);
  207.         coef[b] = exp(coef[b]);
  208.     }
  209.     else if (i_func == 4)
  210.         coef[b] = exp(coef[b]);
  211.    
  212.     return coef;
  213. }
  214.  
  215. //функция вывода функции НМК с коэфициентами
  216. void print_func(double* coef, int i_func) {
  217.     cout << "Function MNK: " << endl;
  218.     if (i_func == 0)
  219.         cout << "y = " << coef[b] << " + " << coef[a] << " * x" << endl;
  220.     else if (i_func == 1)
  221.         cout << "y = " << coef[b] << " + " << coef[a] << " / x" << endl;
  222.     else if (i_func == 2)
  223.         cout << "y = " << coef[b] << " + " << coef[a] << " * ln(x)" << endl;
  224.     else if (i_func == 3)
  225.         cout << "y = " << coef[b] << " * " << coef[a] << "^x" << endl;
  226.     else if (i_func == 4)
  227.         cout << "y = " << coef[b] << " * x^" << coef[a] << endl;
  228.     else if (i_func == 5)
  229.         cout << "y = exp(" << coef[b] << " + " << coef[a] << " / x)" << endl;
  230.     else if (i_func == 6)
  231.         cout << "y = 1 / (" << coef[b] << " + " << coef[a] << " * x" << endl;
  232.     else if (i_func == 7)
  233.         cout << "y = 1 / (" << coef[b] << " + " << coef[a] << " * ln(x)" << endl;
  234.     else if (i_func == 8)
  235.         cout << "y = x(" << coef[b] << " + " << coef[a] << " * x)" << endl;
  236.     else
  237.         cout << "ERROR: i_func = " << i_func;
  238. }
  239.  
  240. int main() {
  241.     //инициализируем значения експерементов
  242.     double* X = new double[N] {23.1, 26.3, 29.8, 31.6, 34.7, 48.1, 55.3, 62.1, 72};
  243.     double* Y = new double[N] {0.99, 0.83, 0.65, 0.59, 0.48, 0.38, 0.27, 0.19, 0.1};
  244.    
  245.     double **table;
  246.     table = build_table(X, Y);
  247.     print_arr(X, 'X');
  248.     print_arr(Y, 'Y');
  249.     cout << endl;
  250.     int i_func = min(table[3]);
  251.     print_table(table, i_func);
  252.    
  253.     double* coef = calc_coef(X, Y, i_func);
  254.     cout << endl;
  255.     print_func(coef, i_func);
  256.  
  257.     return 0;
  258. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement