Advertisement
vadimk772336

Untitled

Feb 20th, 2020
164
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.22 KB | None | 0 0
  1. #include <iostream>
  2. #include <math.h>
  3. #include <cmath>
  4. #include <vector>
  5. #include <Windows.h>
  6. #include <stdlib.h>
  7. #include <fstream>
  8. #include <string.h>
  9. #include <time.h>
  10. #include <iomanip>
  11. using namespace std;
  12.  
  13. /* Рандом даёт ток целое число, поэтому отказались от этого
  14.     int flag = 0;
  15.     double r,h;
  16.  
  17.     h = (Array[CountSegments + 1].x - Array[0].x) / CountSegments;
  18.     if (CountSegments % 2 == 0)
  19.         flag = 1;
  20.  
  21.     if (flag == 1) {
  22.         for (int i = 1; i < CountSegments + 1; i=i+2) {
  23.             r = (rand() % h + 1);
  24.             Array[i].x = h + r;
  25.             Array[i].y = (*f)(Array[i].x);
  26.             Array[i + 1].x = h - r;
  27.             Array[i + 1].y = (*f)(Array[i + 1].x);
  28.         }
  29.     }
  30.     else {
  31.         Array[1].x = Array[0].x+h;
  32.         Array[1].y = (*f)(Array[1].x);
  33.         for (int i = 2; i < CountSegments; i=i+2) {
  34.             r = (rand() % 3 + 1);
  35.             Array[i].x = h+r;
  36.             Array[i].y = (*f)(Array[i].x);
  37.             Array[i+1].x = h-r;
  38.             Array[i+1].y = (*f)(Array[i+1].x);
  39.         }
  40.  
  41.     }
  42.  
  43. */
  44.  
  45. typedef double(*functiontype)(double x);
  46. typedef struct Node
  47. {
  48.     double x, y;
  49. } Node;
  50. typedef double(*method)(double x, Node* Array, int Count, double* DD_massiv);
  51. typedef struct Interval
  52. {
  53.     double InitialNode, EndNode;
  54. } Interval;
  55. const double PI = 3.141592653589793238463;
  56. double Myfunc(double x)
  57. {
  58.     return x*x;
  59. }
  60. functiontype Func = &Myfunc;
  61.  
  62.  
  63. double approximate_derivative_2(functiontype* f, double x) {
  64.     double delta = 1e-5;
  65.     return (((*f)(x) - 2 * (*f)(x + delta) + (*f)(x + 2 * delta)) / (delta*delta));
  66. }
  67.  
  68. double approximate_derivative_1(functiontype* f, double x) {
  69.     double delta = 1e-2;
  70.     return (((*f)(x + delta)- (*f)(x)) / (delta));
  71. }
  72.  
  73. //Возвращает значение сплайна в точке
  74. double Spline(double x, int i, double *Array_steps, double *x_massiv, Node* Array)
  75. {
  76.     double h1, h2, g1, g2, x1, x2, y1, y2;
  77.     h1 = Array_steps[i];
  78.     h2 = Array_steps[i + 1];
  79.     g1 = x_massiv[i];
  80.     g2 = x_massiv[i + 1];
  81.     x1 = Array[i].x;
  82.     x2 = Array[i + 1].x;
  83.     y1 = Array[i].x;
  84.     y2 = Array[i + 1].x;
  85.     return (x*x*x)*((g2 - g1) / (6 * h2)) + (x*x)*((3 * x2*g1 - 3 * x1*g2) / (6 * h2)) + x * (((y2 - y1) * 6 - 3 * g1*x2*x2 + g1 * h2*h2 + 3 * g2*x1*x1 - g2 * h2*h2) / (6 * h2))
  86.         + (((y1*x2 - y2 * x1) * 6 + g1 * x2*x2*x2 - g1 * h2*h2*x2 + g2 * h2*h2*x1 - g2 * x1*x1*x1) / (6 * h2));
  87. }
  88.  
  89. //Равномерная сетка
  90. void ValueUniformTable(functiontype* f, Node* Array, double Initial, double End, int CountSegments)
  91. {
  92.     int i;
  93.     double alpha, h;
  94.  
  95.     Array[0].x = Initial;
  96.     Array[CountSegments].x = End;
  97.     //Array[0].y = (*f)(Array[0].x);
  98.     //Array[CountSegments].y = (*f)(Array[CountSegments].x);
  99.  
  100.     h = (End-Initial) / CountSegments;
  101.  
  102.     cout << "(" << Array[0].x << ":" << Array[0].y << ")" << endl;
  103.     for (int i = 1; i <= CountSegments; i++)
  104.     {
  105.         Array[i].x = Array[i - 1].x + h;
  106.         Array[i].y = (*f)(Array[i].x);
  107.         cout << "(" << Array[i].x << ":" << Array[i].y << ")" << endl;
  108.     }
  109.     cout << "(" << Array[CountSegments].x << ":" << Array[CountSegments].y << ")" << endl;
  110. }
  111.  
  112. //Неравномерная сетка
  113. void ValueIrregularTable(functiontype* f, Node* Array, double Initial, double End, int CountSegments, double *Array_steps) //Инитиал и Енд запихать в Array
  114. {
  115.     int i;
  116.     double alpha, h;
  117.  
  118.     Array[0].x = Initial;
  119.     Array[CountSegments].x = End;
  120.     Array[0].y = (*f)(Array[0].x);
  121.     Array[CountSegments].y = (*f)(Array[CountSegments].x);
  122.     h = (Array[CountSegments].x - Array[0].x) / CountSegments;
  123.     Array_steps[0] = 0;
  124.     alpha = 2 * PI / CountSegments;
  125.  
  126.     cout << "(" << Array[0].x << ":" << Array[0].y << ")" << endl;
  127.     for (i = 1; i < CountSegments; i++) {
  128.         Array_steps[i] = h + (2*h/3)*cos(alpha*i);
  129.         Array[i].x = Array[i - 1].x + Array_steps[i];
  130.         Array[i].y = (*f)(Array[i].x);
  131.         cout << "(" << Array[i].x << ":" << Array[i].y << ")" << endl;
  132.     }
  133.     Array_steps[CountSegments] = Array[CountSegments].x - Array[CountSegments - 1].x;
  134.     cout << "(" << Array[CountSegments].x << ":" << Array[CountSegments].y << ")" << endl;
  135.  
  136. }
  137.  
  138. /* Принимает на вход коэффициенты матриц в виде массива. Заполняет массив прогоночных коэффициентов
  139. matrix_coeffs - двумерный массив вида [[a1,b1,c1,d1],[a2,b2,c2,d2],...,[an,bn,cn,dn] */
  140. void tridiagonal_matrix_algorithm(double** matrix_coeffs, int matrix_size, double* x_massiv) {
  141.     int i;
  142.     double denominator;
  143.     double K, E, K_prev = 0, E_prev = 0; //Прогоночные коэффициенты
  144. //  double* x_massiv = new double[matrix_size];
  145.  
  146.     double** coeffs_massiv; //Двумерный массив, хранящий прогоночные коэффициенты, 0 - Кси, 1 - Эта
  147.     coeffs_massiv = new double*[matrix_size + 1];
  148.     for (i = 0; i <= matrix_size; i++)
  149.         coeffs_massiv[i] = new double[2];
  150.  
  151.     coeffs_massiv[0][0] = 0; coeffs_massiv[0][1] = 0;
  152.     matrix_coeffs[0][0] = 0; matrix_coeffs[matrix_size - 1][2] = 0; //а1=с1=0
  153.  
  154.     //Прямой ход
  155.     for (i = 1; i <= matrix_size; i++) { //Ищем K_i+1 и E_i+1 на iом шаге
  156.         denominator = (matrix_coeffs[i - 1][0] * K_prev + matrix_coeffs[i - 1][1]);
  157.         K = -(matrix_coeffs[i - 1][2]) / denominator;
  158.         E = (matrix_coeffs[i - 1][3] - matrix_coeffs[i - 1][0] * E_prev) / denominator;
  159.         K_prev = K;
  160.         E_prev = E;
  161.         coeffs_massiv[i][0] = K; coeffs_massiv[i][1] = E;
  162.     }
  163.  
  164.     //Обратный ход
  165.     x_massiv[matrix_size - 1] = coeffs_massiv[matrix_size][1];
  166.     for (i = matrix_size - 2; i >= 0; i--) {
  167.         x_massiv[i] = coeffs_massiv[i + 1][0] * x_massiv[i + 1] + coeffs_massiv[i + 1][1];
  168.     }
  169.  
  170.     cout << endl << "Гаммы:" << endl;
  171.     for (i = 0; i < matrix_size; i++)
  172.         cout << x_massiv[i] << endl;
  173.  
  174. }
  175.  
  176. void get_matrix_coeffs(double Initial, double End, int matrix_size, functiontype* f, double** matrix_coeffs, Node* Array, double *Array_steps, double B) {
  177.     int i;
  178.     double h1, h2, h_prev, d2, g2;
  179.     double x1, x2, y1, y2, y3, denominator;
  180.     //double* gamma_massiv = new double[matrix_size]; //Гаммы яв решением ур, т.е. ответом.
  181.  
  182.  
  183.     for (i = 1; i <= matrix_size; i++) {
  184.         h1 = Array_steps[i]; //i
  185.         h2 = Array_steps[i + 1];; //i+1
  186.         h_prev = h2;
  187.         matrix_coeffs[i - 1][0] = h1;
  188.         matrix_coeffs[i - 1][1] = 2 * (h1 + h2);
  189.         matrix_coeffs[i - 1][2] = h2;
  190.         matrix_coeffs[i - 1][3] = 6 * ((Array[i + 1].y - Array[i].y) / h2 - (Array[i].y - Array[i - 1].y) / h1);
  191.     }
  192.     //matrix_coeffs[matrix_size][3] = 6 * ((Array[i + 1].y - Array[i].y) / h2 - (Array[i].y - Array[i - 1].y) / h1);
  193.     h1 = Array_steps[matrix_size];
  194.     h2 = Array_steps[matrix_size + 1];
  195.     y1 = Array[matrix_size - 1].y;
  196.     y2 = Array[matrix_size].y;
  197.     y3 = Array[matrix_size + 1].y;
  198.     x1 = Array[matrix_size].x;
  199.     x2 = Array[matrix_size + 1].x;
  200.     denominator = ((x2 - x1)*(x2 - x1)*((x2 - x1) - h2 * h2));
  201.     d2 = 6 * (B*h2 - y2 + y1) / denominator;
  202.     g2 = h2 * h2 / denominator;
  203.     matrix_coeffs[matrix_size - 1][0] = h1;
  204.     matrix_coeffs[matrix_size - 1][1] = 2 * (h1 + h2) - g2 * h2;
  205.     matrix_coeffs[matrix_size - 1][2] = 0;
  206.     matrix_coeffs[matrix_size - 1][3] = 6 * (y2 - y1) / h2 - (y2 - y1) / h1 + h2 * d2;
  207.     matrix_coeffs[0][0] = 0;
  208.  
  209.     for (i = 0; i <= matrix_size; i++) {
  210.         if (i != matrix_size)
  211.             cout << "(" << matrix_coeffs[i][0] << ")" << "  " << "(" << matrix_coeffs[i][1] << ")" << "  " << "(" << matrix_coeffs[i][2] << ")" << "  " << endl;
  212.     }
  213.  
  214. }
  215.  
  216. void orig_table_in_file(Node* Array, functiontype* f, int Count_dots, double Initial, double End) { // Функция берет таблицу иксов и игриков, количество точек в которых считаем знач полинома (мб убрать) и коэфф полинома,
  217.                                                   // По итоге имеем файл с 2 столбацами: х и у, по которому гну пло
  218.     int k;
  219.     double y_value, x_value, step;
  220.  
  221.     step = (End - Initial) / (Count_dots - 1);
  222.     x_value = Initial - step;
  223.     ofstream fout("D:/original_graphic.txt");
  224.  
  225.     while (x_value < End) {
  226.         x_value += step;
  227.         fout << x_value << " ";
  228.         y_value = (*f)(x_value);
  229.         fout << y_value << endl;
  230.     }
  231.     fout.close();
  232. }
  233.  
  234. void spline_table_in_file(Node* Array, int Count_dots, int Count_Segments, double Initial, double End, double *Array_steps, double *x_massiv) { // Функция берет таблицу иксов и игриков, количество точек в которых считаем знач полинома (мб убрать) и коэфф полинома,
  235.                                                   // По итоге имеем файл с 2 столбацами: х и у, по которому гну пло
  236.     int k, i = 0;
  237.     double step = (End - Initial) / (Count_dots - 1), y_value, x_value;
  238.  
  239.     ofstream fout("D:/spline_graphic.txt");
  240.     x_value = Initial;
  241.     for (i = 0; i <= Count_Segments; i++) {
  242.         while (x_value < Array[i + 1].x) {
  243.             fout << x_value << " ";
  244.             y_value = Spline(x_value, i, Array_steps, x_massiv, Array);
  245.             fout << y_value << endl;
  246.             x_value += step;
  247.         }
  248.     }
  249.     fout << End << " ";
  250.     fout << Spline(End, Count_Segments, Array_steps, x_massiv, Array) << endl;
  251.  
  252.     fout.close();
  253. }
  254.  
  255. int main()
  256. {
  257.     setlocale(LC_ALL, "RUS");
  258.     functiontype Func = &Myfunc;
  259.     double Initial = 0, End =9, B = 5;
  260.     int CountSegments, i, Countdots = 5000;
  261.     cout << "Введите N: ";
  262.     //cin >> CountSegments;
  263.     CountSegments = 10;
  264.     cout << "Точек: " << CountSegments + 1 << endl << endl;
  265.     double *Array_steps = new double[CountSegments + 1];
  266.  
  267.     //Построение сетки
  268.     cout << "Равномерная Сетка: " << endl;
  269.     Node* ArrayUniformNodes = new Node[CountSegments + 1];
  270.     ValueUniformTable(&Func, ArrayUniformNodes, Initial, End, CountSegments);
  271.  
  272.     cout << endl << "Неравномерная Сетка: " << endl;
  273.     Node* ArrayIrregularNodes = new Node[CountSegments + 1];
  274.     ValueIrregularTable(&Func, ArrayIrregularNodes, Initial, End, CountSegments, Array_steps);
  275.     cout << endl;
  276.  
  277.     //Заполнение массива коэффициентами матрицы
  278.     double** matrix_coeffs;
  279.     matrix_coeffs = new double*[CountSegments - 1];
  280.     for (i = 0; i < CountSegments - 1; i++)
  281.         matrix_coeffs[i] = new double[3];
  282.  
  283.     cout << "Полученная матрица: " << endl;
  284.     get_matrix_coeffs(Initial, End, CountSegments - 1, &Func, matrix_coeffs, ArrayIrregularNodes, Array_steps, B);
  285.  
  286.  
  287.     //Получение ответа в x_massiv
  288.     double* x_massiv = new double[CountSegments + 1];
  289.     tridiagonal_matrix_algorithm(matrix_coeffs, CountSegments - 1, x_massiv);
  290.  
  291.     //Вывод интерполируемой функции
  292.     orig_table_in_file(ArrayIrregularNodes, &Func, Countdots, Initial, End);
  293.  
  294.     //Вывод сплайна на экран
  295.     spline_table_in_file(ArrayIrregularNodes, Countdots, CountSegments, Initial, End, Array_steps, x_massiv);
  296.  
  297.     //Приближение производных на кроях
  298.     cout << endl;
  299.     cout << "1 производная на левом конце: " << approximate_derivative_1(&Func, Initial) << endl;
  300.     cout << "2 производная на левом конце: " << approximate_derivative_1(&Func, Initial) << endl;
  301.     cout << "1 производная на правом конце: " << approximate_derivative_2(&Func, End) << endl;
  302.     cout << "2 производная на правом конце: " << approximate_derivative_2(&Func, End) << endl;
  303.  
  304.  
  305.     cout << endl;
  306.     system("pause");
  307.     return 0;
  308. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement