vadimk772336

Untitled

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