Advertisement
Guest User

Untitled

a guest
Dec 8th, 2019
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.71 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.  
  11. using namespace std;
  12.  
  13.  
  14.  
  15.  
  16. typedef double(*functiontype)(double x);
  17. typedef struct Node
  18. {
  19.     double x, y;
  20. } Node;
  21. typedef double(*method)(double x, Node* Array, int Count, double* DD_massiv);
  22. typedef struct Interval
  23. {
  24.     double InitialNode, EndNode;
  25. } Interval;
  26. void ValueUniformTable(functiontype* f, Node* Array, double Initial, double End, int CountNodes)
  27.  
  28. {
  29.     double step = abs(Initial - End) / (CountNodes - 1);
  30.     Array[0].x = Initial;
  31.     Array[0].y = (*f)(Array[0].x);
  32.     for (int i = 1; i < CountNodes; i++)
  33.     {
  34.         Array[i].x = Array[i - 1].x + step;
  35.     }
  36. }
  37. double Myfunc(double x)
  38. {
  39.    
  40.     if (sin(x) < 0) return -sin(x);
  41.     else return sin(x);
  42.    
  43. }
  44. functiontype Func = &Myfunc;
  45. double trapeciya(Node* Array, functiontype* f, int CountSegments)
  46. { //Теор. порядок точности = 2
  47.     int i;
  48.     double area = 0;
  49.  
  50.     for (i = 0; i < CountSegments; i++) {
  51.         area += (Array[i + 1].x - Array[i].x) * ((*f)(Array[i + 1].x) + (*f)(Array[i].x)) / 2;
  52.     }
  53.     return area;
  54. }
  55. double Gauss_formula(Node* Array, functiontype* f, int CountSegments)
  56. { //Теор. порядок точности = 4
  57.     //clock_t time;
  58.     //time = clock();
  59.    
  60.    
  61.     int i;
  62.     double x1, x2, area = 0;
  63.     for (i = 0; i < CountSegments; i++)
  64.     {
  65.         x1 = (Array[i + 1].x + Array[i].x) / 2 + (Array[i + 1].x - Array[i].x) * sqrt(3) / 6;
  66.         x2 = (Array[i + 1].x + Array[i].x) / 2 - (Array[i + 1].x - Array[i].x) * sqrt(3) / 6;
  67.         area += (Array[i + 1].x - Array[i].x) * ((*f)(x1) + (*f)(x2)) / 2;
  68.     }
  69.     //time = clock() - time;
  70.     //cout << (double)time << "CLOCKS_PER_SEC"; //время выполнения "каких-то действий"
  71.     return area;
  72.    
  73. }
  74. double orig_integral(double Initial, double End)
  75. {
  76.    
  77.     return (2 - cos(Initial) - cos(End));
  78.     //return(cos(Initial) - cos(End));  //для обоих краев больших 0
  79.     //return (cos(End) - cos(Initial)); // для обоих краев меньших 0
  80. }
  81.  
  82. //Заполняет переданный массив эксп порядоком точности для трапец и Гаусса соот-но
  83. void exp_order_accuracy(int CountSegments, functiontype* f, double Initial, double End, double* massiv_exp_accuracy) {
  84.  
  85.     double orig_square_exp, R_G, R_G2, R_T, R_T2, exp_p_G, exp_p_T;
  86.     double Gauss_square_exp, Gauss_square_exp2, trapezoid_square_exp, trapezoid_square_exp2;
  87.  
  88.  
  89.     Node* Array2Nodes = new Node[2 * CountSegments + 1];
  90.     Node* ArrayNodes = new Node[CountSegments + 1];
  91.     ValueUniformTable(f, Array2Nodes, Initial, End, 2 * CountSegments + 1);
  92.     ValueUniformTable(f, ArrayNodes, Initial, End, CountSegments + 1);
  93.     Gauss_square_exp = Gauss_formula(ArrayNodes, f, CountSegments);
  94.     Gauss_square_exp2 = Gauss_formula(Array2Nodes, f, 2 * CountSegments);
  95.     trapezoid_square_exp = trapeciya(ArrayNodes, f, CountSegments);
  96.     trapezoid_square_exp2 = trapeciya(Array2Nodes, f, 2 * CountSegments);
  97.     orig_square_exp = orig_integral(Initial, End);
  98.  
  99.     R_G = abs(orig_square_exp - Gauss_square_exp);
  100.     R_G2 = abs(orig_square_exp - Gauss_square_exp2);
  101.     R_T = abs(orig_square_exp - trapezoid_square_exp);
  102.     R_T2 = abs(orig_square_exp - trapezoid_square_exp2);
  103.  
  104.     exp_p_G = log(abs(R_G / R_G2)) / log(2);
  105.     exp_p_T = log(abs(R_T / R_T2)) / log(2);
  106.  
  107.     massiv_exp_accuracy[0] = exp_p_T;
  108.     massiv_exp_accuracy[1] = exp_p_G;
  109.  
  110. }
  111.  
  112. //Заполняет переданный массив погрешностью полученной по правилу Рунге для трапец и Гаусса соот-но
  113. void Runge_Err(functiontype* f, int CountSegments, double* massiv_data, double Initial, double End)
  114. {
  115.     functiontype Func = &Myfunc;
  116.     int p_trap = 2, p_Gauss = 4;
  117.     double numerator_trap, numerator_Gauss, denominator_Gauss, denominator_Trap, R_trap, R_Gauss;
  118.  
  119.     Node* Array4 = new Node[4 * CountSegments + 1];
  120.     Node* Array2 = new Node[2 * CountSegments + 1];
  121.     Node* Array = new Node[CountSegments + 1];
  122.     ValueUniformTable(f, Array4, Initial, End, 4 * CountSegments + 1);
  123.     ValueUniformTable(f, Array2, Initial, End, 2 * CountSegments + 1);
  124.     ValueUniformTable(f, Array, Initial, End, CountSegments + 1);
  125.  
  126.     numerator_trap = abs((trapeciya(Array2, f, 2* CountSegments) - trapeciya(Array, f, CountSegments)))* pow(2, p_trap);
  127.     numerator_Gauss = abs((Gauss_formula(Array2, f, 2 * CountSegments) - Gauss_formula(Array, f, CountSegments)))* pow(2, p_Gauss);
  128.  
  129.     denominator_Gauss = (pow(2, p_Gauss) - 1);
  130.     denominator_Trap = (pow(2, p_trap) - 1);
  131.  
  132.     R_trap = numerator_trap / denominator_Trap;
  133.     R_Gauss = numerator_Gauss / denominator_Gauss;
  134.  
  135.     massiv_data[0] = R_trap;
  136.     massiv_data[1] = R_Gauss;
  137. }
  138.  
  139. //Заполняет переданный массив порядком точности на основе правила Рунге для трапец и Гаусса соот-но
  140. void Runge_order_accuracy(int CountSegments, functiontype* f, double Initial, double End, double* order_massiv) {
  141.  
  142.     double our_numerator_trap, our_numerator_Gauss, our_denominator_Gauss, our_denominator_trap, our_accuracy_trap, our_accuracy_Gauss;
  143.  
  144.     Node* Array4 = new Node[4 * CountSegments + 1];
  145.     Node* Array2 = new Node[2 * CountSegments + 1];
  146.     Node* Array = new Node[CountSegments + 1];
  147.     ValueUniformTable(f, Array4, Initial, End, 4 * CountSegments + 1);
  148.     ValueUniformTable(f, Array2, Initial, End, 2 * CountSegments + 1);
  149.     ValueUniformTable(f, Array, Initial, End, CountSegments + 1);
  150.  
  151.     our_numerator_trap = abs(trapeciya(Array2, f, 2 * CountSegments) - trapeciya(Array, f, CountSegments));
  152.     our_numerator_Gauss = abs(Gauss_formula(Array2, f, 2 * CountSegments) - Gauss_formula(Array, f, CountSegments));
  153.     our_denominator_Gauss = abs(Gauss_formula(Array2, f, 2 * CountSegments) - Gauss_formula(Array4, f, 4 * CountSegments));
  154.     our_denominator_trap = abs(trapeciya(Array2, f, 2 * CountSegments) - trapeciya(Array4, f, 4 * CountSegments));
  155.  
  156.     our_accuracy_trap = log(abs(our_numerator_trap / our_denominator_trap)) / log(2);
  157.     our_accuracy_Gauss = log(abs(our_numerator_Gauss / our_denominator_Gauss)) / log(2);
  158.  
  159.     order_massiv[0] = our_accuracy_trap;
  160.     order_massiv[1] = our_accuracy_Gauss;
  161.  
  162. }
  163.  
  164. //Строит график эксп точности
  165. void graphic_exp_acc(functiontype* f, double Initial, double End, int СountDots) {
  166.     ofstream Trap_File("D:/exp_accuracy_T.txt");
  167.     ofstream Gauss_File("D:/exp_accuracy_G.txt");
  168.     double* massiv_exp_accuracy = new double[2];
  169.     for (int n = 1; n < СountDots; n++) {
  170.         massiv_exp_accuracy[0] = 0;
  171.         massiv_exp_accuracy[1] = 0;
  172.         exp_order_accuracy(n, f, Initial, End, massiv_exp_accuracy);
  173.         Trap_File << n << " " << massiv_exp_accuracy[0] << endl;
  174.         Gauss_File << n << " " << massiv_exp_accuracy[1] << endl;
  175.     }
  176. }
  177.  
  178. //Строит график точности по Рунге
  179. void graphic_Runge_acc(functiontype* f, double Initial, double End, int СountDots) {
  180.     ofstream Trap_File("D:/Runge_accuracy_T.txt");
  181.     ofstream Gauss_File("D:/Runge_accuracy_G.txt");
  182.     double* massiv_Runge_accuracy = new double[2];
  183.     for (int n = 1; n < СountDots; n++) {
  184.         massiv_Runge_accuracy[0] = 0;
  185.         massiv_Runge_accuracy[1] = 0;
  186.         Runge_order_accuracy(n, f, Initial, End, massiv_Runge_accuracy);
  187.         Trap_File << n << " " << massiv_Runge_accuracy[0] << endl;
  188.         Gauss_File << n << " " << massiv_Runge_accuracy[1] << endl;
  189.     }
  190. }
  191.  
  192. //Строит график погрешности по Рунге
  193. void graph_Runge_error(functiontype* f, double Initial, double End, int СountDots) {
  194.     ofstream Trap_error_file("D:/Runge_error_T.txt");
  195.     ofstream Gauss_error_file("D:/Runge_error_G.txt");
  196.  
  197.     double* Runge_eror_massiv = new double[2];
  198.     for (int n = 1; n < СountDots; n++) {
  199.         Runge_eror_massiv[0] = 0;
  200.         Runge_eror_massiv[1] = 0;
  201.         Runge_Err(f, n, Runge_eror_massiv, Initial, End);
  202.         Trap_error_file << n << " " << Runge_eror_massiv[0] << endl;
  203.         Trap_error_file << n << " " << Runge_eror_massiv[1] << endl;
  204.     }
  205. }
  206.  
  207. //Строит график абсолютной погрешности
  208. void graph_abs_error(Node* Array, functiontype* f, double Initial, double End, int СountDots) {
  209.     ofstream Trap_error_file("D:/abs_error_T.txt");
  210.     ofstream Gauss_error_file("D:/abs_error_G.txt");
  211.  
  212.     for (int n = 1; n < СountDots; n++) {
  213.         Trap_error_file << n << " " << abs(orig_integral(Initial, End) - trapeciya(Array, f, n)) << endl;
  214.         Gauss_error_file << n << " " << abs(orig_integral(Initial, End) - Gauss_formula(Array, f, n)) << endl;
  215.     }
  216.     Trap_error_file.close();
  217.     Gauss_error_file.close();
  218. }
  219.  
  220.  
  221. void PrintNodes(Node* Array, int CountSegments)
  222. {
  223.     int i;
  224.     for (i = 0; i < CountSegments - 1; i++)
  225.         cout << "(" << (Array[i].x) << ":" << (Array[i + 1].x) << ")" << endl;
  226. }
  227.  
  228.  
  229. int main()
  230. {
  231.     setlocale(LC_ALL, "RUS");
  232.     functiontype Func = &Myfunc;
  233.     Interval Interval; Interval.InitialNode = -1; Interval.EndNode = 2;
  234.     int CountSegments, СountDots = 1000;
  235.     cout << "Введите число интервалов разбиения: " << endl; cin >> CountSegments; cout << endl;
  236.     int CountNodes = CountSegments + 1;
  237.     double start, end;
  238.     start = GetTickCount64();
  239.     Node* ArrayUniformNodes = new Node[CountNodes];
  240.     ValueUniformTable(&Func, ArrayUniformNodes, Interval.InitialNode, Interval.EndNode, CountNodes);
  241.  
  242.     cout << "Разбиение интервала на равные отрезки интегрирования:" << endl;
  243.     PrintNodes(ArrayUniformNodes, CountNodes);
  244.     cout << endl;
  245.  
  246.     cout << "Трапеция:" << endl;
  247.     double trapezoid_square = trapeciya(ArrayUniformNodes, &Func, CountSegments);
  248.     cout << trapezoid_square << endl << endl;
  249.  
  250.     cout << "Гаусс:" << endl;
  251.     double Gauss_square = Gauss_formula(ArrayUniformNodes, &Func, CountSegments);
  252.     cout << Gauss_square << endl << endl;
  253.  
  254.     cout << "Интеграл:" << endl;
  255.     double orig_square = orig_integral(Interval.InitialNode, Interval.EndNode);
  256.     cout << orig_square << endl << endl;
  257.  
  258.     cout << "Разность между значениям интеграла и значением по формуле Гаусса:" << endl;
  259.     cout << abs(orig_square - Gauss_square) << endl << endl;
  260.  
  261.     cout << "Разность между значениям интеграла и значением по формуле Трапеций:" << endl;
  262.     cout << abs(orig_square - trapezoid_square) << endl << endl;
  263.    
  264.  
  265.     /* -----------------Реализация правила Рунге для оценки погрешности -----------------------------*/
  266.     double* massiv_data = new double[4];
  267.     double* order_massiv = new double[4];
  268.     Runge_Err(&Func, CountSegments, massiv_data, Interval.InitialNode, Interval.EndNode);
  269.     Runge_order_accuracy(CountSegments, &Func, Interval.InitialNode, Interval.EndNode, order_massiv);
  270.  
  271.     cout << "Погрешность по Рунге для " << CountSegments << " частей по формуле трапеций:" << endl;
  272.     cout << massiv_data[0] << endl << endl;
  273.     cout << "Погрешность по Рунге для " << CountSegments << " частей по формуле Гаусса:" << endl;
  274.     cout << massiv_data[1] << endl << endl;
  275.     /* -----------------------Конец -----------------------------------*/
  276.  
  277.     /* -----------------Порядок точности на основе правила Рунге -----------------------------*/
  278.     cout << "Точность на основе правила Рунге для " << CountSegments << " частей по формуле трапеций:" << endl;
  279.     cout << order_massiv[0] << endl << endl;
  280.     cout << "Точность на основе правила Рунге для " << CountSegments << " частей по формуле Гаусса:" << endl;
  281.     cout << order_massiv[1] << endl << endl;
  282.  
  283.     //График
  284.     graph_Runge_error(&Func, Interval.InitialNode, Interval.EndNode, СountDots);
  285.     /* -----------------------Конец -----------------------------------*/
  286.  
  287.     /* -----------------Экспериментальный порядок точности   -----------------------------*/
  288.     double* massiv_exp_accuracy = new double[2];
  289.     exp_order_accuracy(CountSegments, &Func, Interval.InitialNode, Interval.EndNode, massiv_exp_accuracy);
  290.     cout << "Эксп. Порядок точности для Гаусса и Трапеций соответственно:" << endl;
  291.     cout << massiv_exp_accuracy[1] << " " << massiv_exp_accuracy[0] << endl << endl;
  292.  
  293.     //График
  294.     graphic_exp_acc(&Func, Interval.InitialNode, Interval.EndNode, СountDots);
  295.     /* -------------------------   Конец --------------------------------------*/
  296.  
  297.     //График абсолютной погрешности
  298.     graph_abs_error(ArrayUniformNodes, &Func, Interval.InitialNode, Interval.EndNode, СountDots);
  299.  
  300.     end = GetTickCount64();
  301.     cout << endl;
  302.     cout << end - start << "vremya progi";
  303.     cout << endl;
  304.     system("pause");
  305.     return 0;
  306. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement