Advertisement
Guest User

Untitled

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