vadimk772336

Untitled

Oct 17th, 2019
205
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.37 KB | None | 0 0
  1. #include <iostream>
  2. #include <math.h>
  3. #include <vector>
  4. #include <Windows.h>
  5. #include <stdlib.h>
  6. #include <fstream>
  7. #include <string.h>
  8.  
  9. using namespace std;
  10.  
  11. const double PI = 3.1415926535897932384626433832795;
  12.  
  13. typedef double(*functiontype)(double x);
  14.  
  15. typedef struct Node
  16. {
  17.     double x, y;
  18. } Node;
  19.  
  20. typedef struct Interval
  21. {
  22.     double InitialNode, EndNode;
  23. } Interval;
  24.  
  25. int Factorial(int n)
  26. { // Факториал
  27.     int x = 1;
  28.     for (int i = 1; i <= n; i++)
  29.     {
  30.         x *= i;
  31.     }
  32.     return x;
  33. }
  34.  
  35. double Myfunk(double x)
  36. {
  37.     return (x*x);
  38. }
  39.  
  40. double exponenta(double x)
  41. { // Экспонента
  42.     return exp(x);
  43. }
  44.  
  45. void ValueUniformTable(functiontype* f, Node* Array, double Initial, double End, int Count)
  46. { // Создание равномерной таблицы значений
  47.     double step = abs(Initial - End) / (Count - 1);
  48.     Array[0].x = Initial;
  49.     Array[0].y = (*f)(Array[0].x);
  50.     //std::cout << Array[0].x << "      " << Array[0].y << endl;
  51.     for (int i = 1; i < Count; i++)
  52.     {
  53.         Array[i].x = Array[i - 1].x + step;
  54.         Array[i].y = (*f)(Array[i].x);
  55.         //std::cout << Array[i].x << "      " << Array[i].y << endl;
  56.     }
  57. }
  58.  
  59. void ValueChebyshevTable(functiontype* f, Node* Array, double Initial, double End, int Count)
  60. { // Создание таблицы Чебышевских значений
  61.     for (int i = 0; i < Count; i++)
  62.     {
  63.         Array[i].x = ((End + Initial) / 2)
  64.             + ((End - Initial) / 2) * cos(((2 * i + 1) * PI) / (2 * (Count + 1)));
  65.         Array[i].y = (*f)(Array[i].x);
  66.     }
  67. }
  68.  
  69. void get_koef_polynom(double* mas, double* res, int n, int k)
  70. { // Функция на вход берет массив из n-1 точек и
  71.   // возвращает кф полином получившегося при
  72.   // раскрытии скобок !!!(И еще надо домножить на
  73.   // игрик)!!!
  74.     int i;
  75.     double* anx = new double[n + 5];
  76.     double* ann = new double[n + 5];
  77.     res[0] = mas[0];
  78.     res[1] = 1;
  79.     int j;
  80.     for (j = 0; j <= n; j++)
  81.     {
  82.         anx[j] = 0.0;
  83.     }
  84.  
  85.     for (j = 0; j < n; j++)
  86.     {
  87.         ann[j] = 0.0;
  88.     }
  89.     for (i = 1; i < k; i++) //считаем коэффициенты
  90.         for (j = 0; j <= i + 1; j++)
  91.         {
  92.             anx[j + 1] = res[j];
  93.             ann[j] = res[j] * mas[i];
  94.             res[j] = anx[j] + ann[j];
  95.         }
  96. }
  97.  
  98. //Возвращает число, возведенное в cтепень i
  99. double get_degree(double x, int degree) {
  100.     int i;
  101.     double y = x;
  102.     if (degree == 0)
  103.         return 1;
  104.  
  105.     for (i = 0; i < degree - 1; i++)
  106.         y *= x;
  107.     return y;
  108. }
  109.  
  110. double round(double x) {
  111.     if (x < 0.0000000001)
  112.         x = 0.0;
  113.     return x;
  114. }
  115.  
  116. // Полином Лагранжа в точке
  117. double PolynomLG_dot(double x, Node *Array, int Count)
  118. {
  119.     double Polynom = 0;
  120.     for (int i = 0; i < Count; i++)
  121.     { // Счетчик по функциям l_i
  122.         double Li = 1;
  123.         for (int j = 0; j < Count; j++)
  124.         { // Счетчик по x_j
  125.             if (i != j) Li *= (x - Array[j].x) / (Array[i].x - Array[j].x);
  126.         }
  127.         Polynom += Array[i].y * Li;
  128.     }
  129.     return Polynom;
  130. }
  131.  
  132. //Полином Ньютона в точке
  133. double PolynomN_dot(double x, Node *Array, int Count)
  134. {
  135.     double Result = Array[0].y;
  136.     for (int i = 1; i < Count; i++)
  137.     {
  138.         double Polynom = 0;
  139.         for (int j = 0; j <= i; j++)
  140.         { // Следующее слагаемое полинома
  141.             double Composition = 1;
  142.             for (int k = 0; k <= i; k++)
  143.             { // Считаем знаменатель разделенной разности
  144.                 if (k != j) Composition *= (Array[j].x - Array[k].x);
  145.             }
  146.             Polynom += Array[j].y / Composition; // Считаем разделенную разность
  147.         }
  148.         for (int k = 0; k < i; k++) Polynom *= (x - Array[k].x); // Домножаем разделенную разность на скобки (x-x[0])...(x-x[i-1])
  149.         Result += Polynom; // Полином
  150.     }
  151.     return Result;
  152. }
  153.  
  154. //Подходит для построенных полиномов, считает их знач в данных нам n узлах, но если их слишком мало? Надо добавить!
  155. void table_in_file(Node* Array, int n, int z, double* polynom_koeff, string file_name, string file_name_pogr) { // Функция берет таблицу иксов и игриков, количество точек в которых считаем знач полинома (мб убрать) и коэфф полинома,
  156.                                                                 // По итоге имеем файл с 2 столбацами: х и у, по которому гну пло
  157.     int k, j;
  158.     double y_value, x_value;
  159.  
  160.     ofstream fout(file_name);
  161.     ofstream pogr(file_name_pogr);
  162.  
  163.  
  164.     for (k = 0; k < n; k++) { //n иксов подставляев в полином степени n-1
  165.         x_value = Array[k].x;
  166.         fout << x_value << " ";
  167.         pogr << x_value << " ";
  168.         y_value = 0.0;
  169.         for (j = 0; j < z; j++) { //убрал n+1 потому что вылезал за границы памяти но поч так хз
  170.             //cout << "x: " << x_value << " ";
  171.             //cout << polynom_koeff[j] << " ";
  172.             //cout << "x: ^  " << get_degree(x_value, j) << " ";  //Чтобы не умножать ахуенно маленькое число на икс в большой степени надо знать какой степени у нас многочлен , а то e^-17 умножаем на x^10
  173.             y_value += polynom_koeff[j] * get_degree(x_value, j); //На 0 индексе стоит свободные член, умножаем на икс в 0 стпени = 1
  174.             //cout << y_value << endl << endl << endl;
  175.  
  176.         }
  177.         fout << y_value << endl;
  178.         //cout << "y_value: " << y_value << endl;
  179.         //cout << "Array[k].y: " << Array[k].y << endl;
  180.         //cout << "Array[k].y - y_value:  " << Array[k].y - y_value << endl;
  181.  
  182.         pogr << abs(y_value - Array[k].y) << endl;
  183.  
  184.     }
  185.  
  186.     fout.close();
  187. }
  188.  
  189. //То же самое но значение считает сразу вточке
  190. void table_in_file2(Node* Array, int n, int z, double* polynom_koeff, string file_name, string file_name_pogr, string method_name) { // Функция берет таблицу иксов и игриков, количество точек в которых считаем знач полинома (мб убрать) и коэфф полинома,
  191.                                                                 // По итоге имеем файл с 2 столбацами: х и у, по которому гну пло
  192.     int k, j;
  193.     double y_value, x_value;
  194.  
  195.     ofstream fout(file_name);
  196.     ofstream pogr(file_name_pogr);
  197.  
  198.  
  199.  
  200.  
  201.     for (k = 0; k < n; k++) { //n иксов подставляев в полином степени n-1
  202.         x_value = Array[k].x;
  203.         fout << x_value << " ";
  204.         pogr << x_value << " ";
  205.        
  206.         if (method_name == "Lagrange")
  207.             y_value = PolynomLG_dot(x_value, Array, n);
  208.         else
  209.             y_value = PolynomN_dot(x_value, Array, n);
  210.  
  211.         fout << y_value << endl;
  212.         //cout << "y_value: " << y_value << endl;
  213.         //cout << "Array[k].y: " << Array[k].y << endl;
  214.         //cout << "Array[k].y - y_value:  " << Array[k].y - y_value << endl;
  215.  
  216.         pogr << abs(y_value - Array[k].y) << endl;
  217.  
  218.     }
  219.  
  220.     fout.close();
  221. }
  222.  
  223. void orig_table_in_file(Node* Array, int n) { // Функция берет таблицу иксов и игриков, количество точек в которых считаем знач полинома (мб убрать) и коэфф полинома,
  224.                                                                        // По итоге имеем файл с 2 столбацами: х и у, по которому гну пло
  225.     int k;
  226.     double y_value, x_value;
  227.  
  228.     ofstream fout("D:/Original_graphic.txt");
  229.  
  230.     for (k = 0; k < n; k++) { //n иксов подставляев в полином степени n-1
  231.         x_value = Array[k].x;
  232.         fout << x_value << " ";
  233.         y_value = Array[k].y;
  234.         fout << y_value << endl;
  235.     }
  236.  
  237.     fout.close();
  238. }
  239.  
  240.  
  241.  
  242. double W(double x, int n, Node* Array)
  243. { // Полином вида: (x - x1) * (x - x2) * ... * (x - xn)
  244.     double w = 1;
  245.     for (int i = 1; i <= n; i++)
  246.     {
  247.         w *= x - Array[i].x;
  248.     }
  249.     return w;
  250. }
  251.  
  252. void AbsoluteError(functiontype *Function, double Initial, double End, Node *Array, int Count)
  253. { // Абсолютная погрешность
  254.  
  255.     for (double x = Initial; x <= End; x += 0.01f)
  256.     {
  257.         abs((*Function)(x) - PolynomLG_dot(x, Array, Count));
  258.     }
  259. }
  260.  
  261. void ApproximateError(functiontype *Function, double Initial, double End, Node *Array, int Count)
  262. { // Приближенная погрешность
  263.  
  264.     for (double x = Initial; x <= End; x += 0.01f)
  265.     {
  266.         abs(exp(End) * W(x, Count, Array) / Factorial(Count + 1));
  267.         abs(exp(End) * W(x, Count, Array) / Factorial(Count + 1));
  268.     }
  269. }
  270.  
  271. void PolynomLG(Node* Array, int n, double* &konmas)
  272. {
  273.     int i, j, l, p, z, c;
  274.     double* massiv2 = new double[n]; // массив А0...An конечных коэфф для одного
  275.                                      // шага цикла сколько точек, столько и коэфф
  276.     double* massiv = new double[n - 1]; //массив X0,,без Хi,Хn домноженных на коэфф.  ПОЭТОМУ Н-1
  277.     //double* konmas = new double[n]; // будет коннечный массив коэфф      
  278.     double k;
  279.     for (j = 0; j < n; j++)
  280.     {
  281.         konmas[j] = 0.0;
  282.     }
  283.     for (i = 0; i < n; i++)
  284.     {
  285.         c = 0;
  286.         for (j = 0; j < n - 1; j++)
  287.         {
  288.             massiv[j] = 0.0;
  289.             massiv2[j] = 0.0;
  290.         }
  291.         massiv2[n - 1] = 0.0;
  292.         k = Array[i].y;
  293.         for (p = 0; p < n; p++)
  294.         {
  295.             if (p != i)
  296.             {
  297.                 k *= 1.0 / (Array[i].x - Array[p].x);
  298.                 massiv[c] = 0.0 - Array[p].x;
  299.                 c++;
  300.             }
  301.         }
  302.         cout << endl;
  303.         get_koef_polynom(massiv, massiv2, n - 1, n - 1);
  304.         for (l = 0; l < n; l++)
  305.         {
  306.             konmas[l] += massiv2[l] * k;
  307.         }
  308.         /*cout << "konmas  ";
  309.         for (z = 0; z < n; z++)
  310.         {
  311.             cout << konmas[z] << ' ';
  312.         }*/
  313.     }
  314.  
  315.     //table_in_file(Array, n, konmas); //                    
  316.     cout << endl;
  317. }
  318. double DividedDifference(int i, Node* Array)
  319. { // Разделенная разность
  320.     double DD = 0;
  321.     for (int j = 0; j <= i; j++)
  322.     {
  323.         double tmp = 1;
  324.         for (int k = 0; k <= i; k++)
  325.         {
  326.             if (k != j)
  327.                 tmp *= Array[j].x - Array[k].x;
  328.         }
  329.         DD += Array[j].y / tmp;
  330.     }
  331.  
  332.     return DD;
  333. }
  334.  
  335. void PolynomN(Node* Array, int n, double* &konmas)
  336. {
  337.     int j;
  338.     double dd;
  339.     double* massiv2 = new double[n]; // массив А0...An конечных коэфф для одного
  340.                                      // шага цикла сколько точек, столько и коэфф
  341.     double* massiv = new double[n - 1]; //массив X0,,,Хn                 +1 для зануления
  342.     //double* konmas = new double[n]; // будет коннечный массив коэфф
  343.     int i;
  344.  
  345.     for (int j = 0; j < n - 1; j++)
  346.     {
  347.         konmas[j] = 0.0;
  348.         massiv[j] = 0.0;
  349.     }
  350.  
  351.     konmas[n - 1] = 0.0;
  352.  
  353.     for (int j = 0; j < n - 1; j++)
  354.     { //Кладем все иксы
  355.         massiv[j] = 0.0 - Array[j].x;
  356.     }
  357.  
  358.     konmas[0] = Array[0].y; // 0 индекс хранит свободный член итого многочлена
  359.  
  360.     for (i = 1; i < n; i++)
  361.     {
  362.         for (j = 0; j < n; j++)
  363.         {
  364.             massiv2[j] = 0.0;
  365.         }
  366.  
  367.         dd = DividedDifference(i, Array); //Ищем итую РР
  368.     //  cout << "DD " << dd << endl << endl;
  369.         get_koef_polynom(massiv, massiv2, n - 1,
  370.             i); //Возвращает кф при перемножении (х-Х0)...(х-Хi+1),
  371.         for (j = 0; j < n; j++)
  372.         {
  373.             konmas[j] += massiv2[j] * dd;
  374.  
  375.         }
  376.  
  377.         cout << endl;
  378.  
  379.         cout << endl;
  380.     }
  381.  
  382.     /*for (j = 0; j < n; j++)
  383.     {
  384.         konmas[j] = round(konmas[j]);
  385.         cout << konmas[j] << "   ";
  386.     }*/
  387.     cout << endl;
  388.  
  389.  
  390. }
  391.  
  392. double DFunc(functiontype* func, double x,
  393.     int n) //возварщает проивзодную нго порядка как константу типа дабл
  394. { // Производная функции
  395.     double h = 0.00001;
  396.     if (n == 1)
  397.     {
  398.         return ((*func)(x + h) - (*func)(x)) / h;
  399.     }
  400.     else
  401.     {
  402.         return (DFunc(func, x + h, n - 1) - DFunc(func, x, n - 1)) / h;
  403.     }
  404. }
  405.  
  406. double test(functiontype* func, double x, int n, long double h)
  407. { // Производная функции
  408.     h = 0.0001;
  409.     while (n > 1)
  410.     {
  411.         return (test(func, x + h, n - 1, h / pow(10, -2))
  412.             - test(func, x - h, n - 1, h / pow(10, -2)))
  413.             / 2 * h;
  414.     }
  415.     if (n == 1)
  416.     {
  417.         return ((*func)(x + h) - (*func)(x - h)) / 2 * h;
  418.     }
  419. }
  420.  
  421.  
  422.  
  423. int main()
  424. {
  425.  
  426.     setlocale(LC_ALL,"RUS");
  427.  
  428.     //ПОСТРОЕНИЕ ДАННЫХ
  429.     Interval Interval;
  430.     int CountNodes, MyNodes = 100;
  431.     functiontype Func = &Myfunk;
  432.  
  433.     /*cout << "Enter the interval: " << endl;
  434.     cin >> Interval.InitialNode >> Interval.EndNode;
  435.     cout << "Enter the number of nodes: " << endl;
  436.     cin >> CountNodes;*/
  437.  
  438.     //Ввод вручную
  439.     Interval.InitialNode = -2;
  440.     Interval.EndNode = 2;
  441.     CountNodes = 25;
  442.  
  443.     double* konmas = new double[CountNodes];
  444.  
  445.     Node *ArrayUniformNodes = new Node[CountNodes];// Массив с равномерными // узлами
  446.     Node *ArrayUniformNodes2 = new Node[MyNodes];
  447.     //Node* ArrayChebyshevNodes = new Node[CountNodes]; // Массив с Чебышевскими узлами
  448.     Node *ArrayformNodes2 = new Node[100]; //Массив где будет много точек для построение ориг графика
  449.  
  450.     ValueUniformTable(&Func, ArrayUniformNodes, Interval.InitialNode, Interval.EndNode, CountNodes); // Заполнение таблицы равномерных значений
  451.     ValueUniformTable(&Func, ArrayUniformNodes2, Interval.InitialNode, Interval.EndNode, MyNodes);
  452.     //ValueChebyshevTable(&Func, ArrayChebyshevNodes, Interval.InitialNode, Interval.EndNode, CountNodes); // Заполнение таблицы Чебышевских значений
  453.  
  454.  
  455.     // ЗАПУСКИ ФУНКЦИЙ
  456.     //cout << "Лагранж в точке:" << PolynomLG_dot(5.00, ArrayUniformNodes, CountNodes);
  457.  
  458.  
  459.     cout << endl;
  460.     //PolynomLG(ArrayUniformNodes, CountNodes, konmas);
  461.     cout << endl;
  462.     //PolynomN(ArrayUniformNodes, CountNodes,konmas);
  463.     table_in_file2(ArrayUniformNodes2, MyNodes, CountNodes, konmas, "D:/Lagrange.txt", "D:/Pogr_Lagrange.txt", "Lagrange");
  464.     table_in_file2(ArrayUniformNodes2, MyNodes, CountNodes, konmas, "D:/Newton.txt", "D:/Pogr_Newton.txt", "Newton");
  465.     table_in_file(ArrayUniformNodes2, MyNodes, CountNodes, konmas, "D:/withkonmas.txt", "D:/Pogr_withkonmas.txt");
  466.     orig_table_in_file(ArrayUniformNodes2, MyNodes);
  467.  
  468.  
  469.     // Абсолютная погрешность
  470.     //AbsoluteError(&Func, Interval.InitialNode, Interval.EndNode, ArrayUniformNodes, CountNodes);
  471.     // Приближенная погрешность
  472.     //ApproximateError(&Func, Interval.InitialNode, Interval.EndNode, ArrayUniformNodes, CountNodes);
  473.  
  474.     //system("pause");
  475.     return 0;
  476. }
Advertisement
Add Comment
Please, Sign In to add comment