TShiva

MNK

Mar 4th, 2018
204
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.07 KB | None | 0 0
  1. #include <windows.h>
  2. #include <math.h>
  3. #include <random>
  4. #include <fstream>
  5. #include <sstream>
  6. #include <string>
  7. #include <vector>
  8. #include <cmath>
  9. #include <ctime>
  10.  
  11. /////////////////////////////////////////////////////////////////////////////////////////////////////
  12. ////////////////////////////////////////Не интерактивное меню////////////////////////////////////////
  13. /////////////////////////////////////////////////////////////////////////////////////////////////////
  14.  
  15. #define isFunction 3 // выбор функции, 1 = cos(2*pi*x), 2 = pow(x,3)*5.0+pow(x,2)+5.0, 3 = sin(2*pi*x)*x
  16.  
  17. const double Pi = 3.14;//число пи
  18.  
  19. const int points = 6;//кол-во точек выборки
  20. double mistake = 0.10; // модуль максимального значения ошибки
  21.  
  22. int typeOfError = 1;//тип ошибки: равномерная =1  или нормальная =2.
  23.  
  24. double coef_x, coef_y; // коэффициенты
  25.  
  26. int power_of_polynom = 5;//полином n-й степени
  27. const double lambda = 0.0003;
  28.  
  29. std::mt19937 gen(time(0));
  30. std::uniform_real_distribution<> uid(0, 1);
  31.  
  32. double currentError = 0.;
  33. /////////////////////////////////////////////////////////////////////////////////////////////////////
  34. /////////////////////////////////////////////////////////////////////////////////////////////////////
  35. /////////////////////////////////////////////////////////////////////////////////////////////////////
  36. inline double cosinus(double x) {
  37.     return cos(2 * Pi*x / coef_x);
  38. }
  39. inline double cube(double x) {//не подогнал
  40.     double cock = pow(x / coef_x, 3)*5.0 + pow(x / coef_x, 2) + 5.0 / coef_x;
  41.     return cock;
  42. }
  43. inline double sinus(double x) {
  44.     double cock = sin(2.0 * Pi*x / coef_x)*x / coef_x;
  45.     return cock;
  46. }
  47.  
  48. double WhatTheFunction(int f, double coef_y, int i)
  49. {
  50.     if (f == 1)
  51.         return coef_y * cosinus(i);
  52.     if (f == 2)
  53.         return coef_y * cube(i);
  54.     if (f == 3)
  55.         return coef_y * sinus(i);
  56. }
  57.  
  58.  
  59. //теперь функция, которая рисует полином этот
  60. inline double polynom(double vec_sol[], int sizeOfMatrix, double coef_x, double x) {
  61.     double polynom = 0;
  62.     for (int i = 0; i < sizeOfMatrix; i++) {
  63.         polynom += vec_sol[i] * pow(x, i) ;
  64.     }
  65.     return polynom;
  66. }
  67.  
  68. double* Gauss(double** matrix, int n) {
  69.     //Метод Гаусса
  70.     //Прямой ход, приведение к верхнетреугольному виду
  71.     int i, j, k;
  72.     double tmp;
  73.     double* vec_sol = new double[n];
  74.  
  75.     for (i = 0; i<n; i++)
  76.     {
  77.         tmp = matrix[i][i];//Элемент на главной диагонали
  78.         for (j = n + 1; j >= i; j--)//приведение элемента главной диагонали к 1, деление элементов строки
  79.             matrix[i][j] /= tmp;
  80.         for (j = i + 1; j<n; j++)
  81.         {
  82.             tmp = matrix[j][i];//зануление столбцов под главной диагональю
  83.             for (k = n; k >= i; k--)
  84.                 matrix[j][k] -= tmp * matrix[i][k];
  85.         }
  86.     }
  87.     //имеем верхнетреугольную матрицу с правым столбиком
  88.     /*обратный ход*/
  89.     vec_sol[n - 1] = matrix[n - 1][n];
  90.     for (i = n - 2; i >= 0; i--)
  91.     {
  92.         vec_sol[i] = matrix[i][n];
  93.         for (j = i + 1; j<n; j++)
  94.             vec_sol[i] -= matrix[i][j] * vec_sol[j];
  95.     }
  96.     return vec_sol;
  97. }
  98.  
  99. double NormalErr(double mistake) {
  100.     double ksi = 0, randomNumber;
  101.     for (int i = 0; i< 12; i++) {
  102.         randomNumber = uid(gen);
  103.         ksi += randomNumber;//сумма 12 случайно распределённых числел
  104.     }
  105.     double etha = ksi - 6;//Etha принадлежит отрезку от 0 до 1
  106.     randomNumber = uid(gen);
  107.     double randomValue = mistake * (2 * randomNumber - 1);
  108.     return etha * randomValue;
  109. }
  110.  
  111. void logging(int sizeOfMatrix, std::ofstream& loggi, double** matrix) {
  112.     for (int i = 0; i < sizeOfMatrix; i++) {
  113.         for (int j = 0; j < sizeOfMatrix + 1; j++) {
  114.             loggi << matrix[i][j] << " ";
  115.         }
  116.         loggi << std::endl;
  117.     }
  118.     loggi << std::endl;
  119. }
  120.  
  121. LRESULT CALLBACK WndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam)
  122. {
  123.     static int cxClient, cyClient;
  124.     HDC hdc;
  125.     PAINTSTRUCT ps;
  126.     HPEN hPen, hPenOld;
  127.     HBRUSH hBrush, hBrushOld;
  128.  
  129.     switch (iMsg)
  130.     {
  131.  
  132.     case WM_CREATE:
  133.         break;
  134.  
  135.     case WM_SIZE:
  136.         cxClient = LOWORD(lParam);//ширина
  137.         cyClient = HIWORD(lParam);//высота
  138.         break;
  139.  
  140.     case WM_PAINT:
  141.     {
  142.         std::ofstream loggi;// для сохранения матриц в файл
  143.         loggi.open("loggi.txt");
  144.  
  145.         double *xx = new double[points];
  146.         double *yy = new double[points];
  147.         double *tt = new double[points];
  148.  
  149.         hdc = BeginPaint(hwnd, &ps);//начало рисования
  150.  
  151.         SetMapMode(hdc, MM_ISOTROPIC);// режим рисования с единообразными осями
  152.         SetWindowExtEx(hdc, cxClient, cyClient, 0);//установили размеры
  153.         SetViewportExtEx(hdc, cxClient / 2, -cyClient / 2, 0);
  154.         SetViewportOrgEx(hdc, cxClient / 2, cyClient / 2, 0);
  155.  
  156.         MoveToEx(hdc, -cxClient, 0, nullptr);//переместили курсор
  157.         LineTo(hdc, cxClient, 0);//нарисовали одну ось
  158.         MoveToEx(hdc, 0, -cyClient, nullptr);
  159.         LineTo(hdc, 0, cyClient);//нарисовали другую
  160.  
  161.  
  162.         hPen = CreatePen(PS_SOLID, 0, RGB(255, 0, 0));
  163.         SelectObject(hdc, hPen);
  164.  
  165.         coef_x = cxClient;
  166.         coef_y = cyClient;// / 2;
  167.  
  168.         MoveToEx(hdc, -cxClient, static_cast<int>(WhatTheFunction(isFunction, coef_y, -coef_x)), nullptr);//устанавливаем начальную позицию
  169.  
  170.         for (int i = -cxClient; i < cxClient; i++)//рисуем график функции
  171.         {
  172.             double y = static_cast<int>(WhatTheFunction(isFunction, coef_y, i));
  173.             LineTo(hdc, i, (int)y);
  174.         }
  175.  
  176.         for (int i = 0; i < points; i++)
  177.         {
  178.             // вычисление равномерного распределённого вектора X
  179.             //генерируем точки для метода
  180.             xx[i] = uid(gen)*coef_x * 2 - coef_x;// генерация элемента выборки, из отрезка [0,1] -> [-cxClient,cxClient]
  181.             yy[i] = WhatTheFunction(isFunction, coef_y, xx[i]);
  182.            
  183.             //double mis = 0;// ошибка измерений
  184.  
  185.             //находим t[i] в зависимости от вида распределения ошибки
  186.             if (typeOfError == 1)//имеет равномерное распределение
  187.             {
  188.                 currentError = uid(gen) * 2 * mistake*coef_y - mistake*coef_y;
  189.                 //домножение на коэффициент (coef_y) оправдано
  190.                 tt[i] = yy[i] + currentError;
  191.             }
  192.             if (typeOfError == 2)//имеет нормальное распределение
  193.             {
  194.                 currentError = NormalErr(mistake*coef_y);
  195.                 tt[i] = yy[i] + currentError;
  196.             }
  197.  
  198.             hPen = CreatePen(PS_SOLID, 0, RGB(0, 0, 255));
  199.             hPenOld = (HPEN)SelectObject(hdc, hPen);
  200.             hBrush = CreateSolidBrush(RGB(0, 0, 255));
  201.             hBrushOld = (HBRUSH)SelectObject(hdc, hBrush);
  202.             Ellipse(hdc, xx[i] - 5, tt[i] - 5, xx[i] + 5, tt[i] + 5);
  203.  
  204.             //  xx[i] /= coef_x;
  205.             //  yy[i] /= coef_y;
  206.  
  207.             SelectObject(hdc, hBrushOld);
  208.             DeleteObject(hBrush);
  209.  
  210.             SelectObject(hdc, hPenOld);
  211.             DeleteObject(hPen);
  212.         }
  213.        
  214.  
  215.         const int sizeOfMatrix = power_of_polynom + 1;
  216.         double** matrix = new double*[sizeOfMatrix];
  217.         for (int i = 0; i < sizeOfMatrix; i++) {
  218.             matrix[i] = new double[sizeOfMatrix + 1];
  219.         }
  220.  
  221.         //слау такого-то размера подготавливаем к работе
  222.         for (int i = 0; i < sizeOfMatrix; i++) {
  223.             for (int j = 0; j < sizeOfMatrix + 1; j++)
  224.                 matrix[i][j] = 0;
  225.         }
  226.         //вычисление всей матрицы, кроме последнего столбца
  227.         for (int i = 0; i < sizeOfMatrix; i++)
  228.         {
  229.             for (int j = 0; j < sizeOfMatrix; j++)
  230.             {
  231.                 for (int k = 0; k < points; k++)
  232.                     matrix[i][j] += pow(xx[k], i + j);
  233.             }
  234.         }
  235.        
  236.         //вычисление последнего столбца (правых частей)
  237.         for (int i = 0; i < sizeOfMatrix; i++) {
  238.             for (int k = 0; k < points; k++)
  239.                 matrix[i][sizeOfMatrix] += tt[k] * pow(xx[k], i);
  240.         }
  241.         //логирование
  242.         logging(sizeOfMatrix, loggi, matrix);
  243.         double* vec_sol = Gauss(matrix, sizeOfMatrix);
  244.         logging(sizeOfMatrix, loggi, matrix);
  245.        
  246.         //регуляризация
  247.         for (int i = 0; i < sizeOfMatrix; i++) {
  248.         matrix[i][i] += lambda;
  249.         }
  250.  
  251.         double* vec_sol_reg = new double[sizeOfMatrix];
  252.         vec_sol_reg = Gauss(matrix, sizeOfMatrix);
  253.    
  254.         //Выводим решения
  255.         for (int i = 0; i < sizeOfMatrix; i++) {
  256.         loggi << vec_sol[i] << " ";
  257.         }
  258.         loggi << std::endl;
  259.         for (int i = 0; i < sizeOfMatrix; i++) {
  260.         loggi << vec_sol_reg[i] << " ";
  261.         }
  262.         loggi.close();
  263.        
  264.  
  265.         hPen = CreatePen(PS_SOLID, 0, RGB(0, 255, 0));
  266.         hPenOld = (HPEN)SelectObject(hdc, hPen);
  267.         hBrush = CreateSolidBrush(RGB(0, 255, 0));
  268.         hBrushOld = (HBRUSH)SelectObject(hdc, hBrush);
  269.  
  270.         MoveToEx(hdc, -cxClient, (int)polynom(vec_sol, sizeOfMatrix, coef_x, -cxClient), nullptr);//устанавливаем начальную позицию
  271.         for (int i = -cxClient; i < cxClient; i++)//рисуем график функции
  272.         {
  273.         double y = polynom(vec_sol, sizeOfMatrix, coef_x, i);
  274.         LineTo(hdc, i, y);
  275.         }
  276.  
  277.    
  278.  
  279.         hPen = CreatePen(PS_SOLID, 0, RGB(0, 0, 0));
  280.         hPenOld = (HPEN)SelectObject(hdc, hPen);
  281.         hBrush = CreateSolidBrush(RGB(0, 0, 0));
  282.         hBrushOld = (HBRUSH)SelectObject(hdc, hBrush);
  283.         MoveToEx(hdc, -cxClient, (int)polynom(vec_sol_reg, sizeOfMatrix, coef_x, -cxClient), nullptr);//устанавливаем начальную позицию
  284.         for (int i = -cxClient; i < cxClient; i++)//рисуем график функции
  285.         {
  286.         double y = polynom(vec_sol_reg, sizeOfMatrix, coef_x, i);
  287.         LineTo(hdc, i, y);
  288.         }
  289.  
  290.  
  291.  
  292.         /*for (int i = 0; i < sizeOfMatrix; i++) {
  293.         delete[] matrix[i];
  294.         }
  295.         delete[] matrix; */
  296.  
  297.         ///////////////////////////////////////////////////////////////////////////
  298.  
  299.         return 0;
  300.     }
  301.     case WM_DESTROY:
  302.         PostQuitMessage(0);
  303.         return 0;
  304.     }
  305.     return DefWindowProc(hwnd, iMsg, wParam, lParam);
  306. }
  307.  
  308. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  309.     PSTR szCmdLine, int iCmdShow)
  310. {
  311.     static TCHAR szAppName[] = TEXT("SineWave");
  312.     HWND hwnd;
  313.     MSG msg;
  314.  
  315.     WNDCLASSEX wndclass;
  316.     wndclass.cbSize = sizeof(wndclass);
  317.     wndclass.style = CS_HREDRAW | CS_VREDRAW;
  318.     wndclass.lpfnWndProc = WndProc;
  319.     wndclass.cbClsExtra = 0;
  320.     wndclass.cbWndExtra = 0;
  321.     wndclass.hInstance = hInstance;
  322.     wndclass.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
  323.     wndclass.hCursor = LoadCursor(nullptr, IDC_ARROW);
  324.     wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  325.     wndclass.lpszMenuName = TEXT("MYMENU");
  326.     wndclass.lpszClassName = (szAppName);
  327.     wndclass.hIconSm = LoadIcon(nullptr, IDI_APPLICATION);
  328.     RegisterClassEx(&wndclass);
  329.     hwnd = CreateWindow(szAppName, TEXT("Метод наименьших квадратов"),
  330.         WS_OVERLAPPEDWINDOW,
  331.         CW_USEDEFAULT, CW_USEDEFAULT,
  332.         1000, 750,
  333.         nullptr, nullptr, hInstance, nullptr);
  334.     ShowWindow(hwnd, iCmdShow);
  335.     UpdateWindow(hwnd);
  336.     while (GetMessage(&msg, nullptr, 0, 0))
  337.     {
  338.         TranslateMessage(&msg);
  339.         DispatchMessage(&msg);
  340.     }
  341.     return msg.wParam;
  342. }
Add Comment
Please, Sign In to add comment