Advertisement
vatman

Untitled

Oct 4th, 2023
694
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.83 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <cmath>
  4. #include <iomanip>
  5.  
  6. // Определение функции, которую вы хотите интегрировать
  7. double f(const double &x, const double &y)
  8. {
  9.     // Здесь должна быть ваша функция
  10.     return y*y/(1+x*x*x*x)+y-y*y*y*std::sin(x*10);
  11. }
  12.  
  13. // Метод Рунге-Кутты четвертого порядка
  14. double rungeKuttaStep(const double &x, const double &y,const double &h)
  15. {
  16.     double k1 = h * f(x, y);
  17.     double k2 = h * f(x + h / 2, y + k1 / 2);
  18.     double k3 = h * f(x + h / 2, y + k2 / 2);
  19.     double k4 = h * f(x + h, y + k3);
  20.  
  21.     double y_next = y + (k1 + 2 * k2 + 2 * k3 + k4) / 6;
  22.     return y_next;
  23. }
  24.  
  25. void rungeKutta(const double &x0,const double &y0,const double &h,const double &xmax,const int &maxSteps)
  26. {
  27.     int steps = 0;
  28.     double x = x0;
  29.     double y = y0;
  30.  
  31.     while (x < xmax && steps < maxSteps) {
  32.         double k1 = h * f(x, y);
  33.         double k2 = h * f(x + h / 2, y + k1 / 2);
  34.         double k3 = h * f(x + h / 2, y + k2 / 2);
  35.         double k4 = h * f(x + h, y + k3);
  36.  
  37.         y = y + (k1 + 2 * k2 + 2 * k3 + k4) / 6;
  38.         x = x + h;
  39.  
  40.         std::cout << steps << '\t' << x<< '\t' << y << std::endl;
  41.  
  42.         ++steps;
  43.     }
  44. }
  45.  
  46. void rungeKuttaAdaptive(const double &x0,const double &y0,const double &h0,const double &xmax,const double &tolerance,const double &edge,const int &maxSteps)
  47.  {
  48.     double x = x0;
  49.     double y = y0;
  50.     double h = h0;
  51.     double y1;
  52.     double y2;
  53.     int c1 = 0;
  54.     int c2 = 0;
  55.     int sumC = 0;
  56.     int steps = 0;
  57.     int a=15;
  58.     std::cout <<std::setw(4) << "шаг" <<std::setw(a) <<"x" <<std::setw(a)<< "y" <<std::setw(a)<< "y^"<<std::setw(a) << "|y-y^|"
  59.             <<std::setw(a)<< "E" <<std::setw(a)<<"h" <<std::setw(a)<< "c1" <<std::setw(a)<< "c2" << std::endl;
  60.  
  61.     while (x < xmax&& std::abs(x-xmax)>edge&&steps < maxSteps)
  62.     {
  63.  
  64.         // Делаем два шага методом Рунге-Кутты с h и h/2
  65.         y1 = rungeKuttaStep(x, y, h);
  66.         y2 = rungeKuttaStep(x, y, h / 2);
  67.         y2 = rungeKuttaStep(x + h / 2, y2, h / 2);
  68.  
  69.         // Вычисляем оценку локальной погрешности
  70.         double num=std::abs(y1 - y2);
  71.         double error = num/15;
  72.  
  73.         // Проверяем, соответствует ли оценка погрешности заданной точности
  74.         if (error>tolerance)
  75.         {
  76.             h=h/2;
  77.             ++steps;
  78.             ++c1;
  79.         }
  80.         else if(error< tolerance/64)
  81.         {
  82.             //int a=15;
  83.             y = y1;
  84.             x += h;
  85.             std::cout <<std::setw(4) << steps+1<<std::setw(a) << x <<std::setw(a)<< y <<std::setw(a)<< y2<<std::setw(a) << num
  86.             <<std::setw(a)<< error <<std::setw(a)<< h <<std::setw(a)<< c1 <<std::setw(a)<< 1 << std::endl;
  87.             h*=2;
  88.             sumC=sumC+c1+1;
  89.             c1=0;
  90.             c2=0;
  91.             ++steps;
  92.         }
  93.         else
  94.         {
  95.             //int a=15;
  96.             y = y1;
  97.             x += h;
  98.             std::cout <<std::setw(4) << steps+1<<std::setw(a) << x <<std::setw(a)<< y <<std::setw(a)<< y2<<std::setw(a) << num
  99.             <<std::setw(a)<< error <<std::setw(a)<< h <<std::setw(a)<< c1 <<std::setw(a)<< 1 << std::endl;
  100.             sumC=sumC+c1;
  101.             c1=0;
  102.             c2=0;
  103.             ++steps;
  104.         }
  105.     }
  106. }
  107.  
  108. int main()
  109. {
  110.     setlocale(LC_ALL, "Russian");
  111.     double x0 = 0.0;            // Начальная точка x
  112.     double y0 = 10.0;            // Начальное значение y
  113.     double h0 = 0.01;            // Начальный размер шага
  114.     double xmax = 20.0;          // Граница x
  115.     double tolerance = 1e-6;   // Заданная точность
  116.     double edge = 0.01;
  117.     int maxSteps = 1000;         // Максимальное количество шагов
  118.  
  119.      // Ввод значений из консоли
  120.    /* std::cout << "Введите начальную точку x: ";
  121.     std::cin >> x0;
  122.  
  123.     std::cout << "Введите начальное значение y: ";
  124.     std::cin >> y0;
  125.  
  126.     std::cout << "Введите начальный размер шага h: ";
  127.     std::cin >> h0;
  128.  
  129.     std::cout << "Введите границу x: ";
  130.     std::cin >> xmax;
  131.  
  132.     std::cout << "Введите заданную точность tolerance: ";
  133.     std::cin >> tolerance;
  134.  
  135.     std::cout << "Введите значение edge: ";
  136.     std::cin >> edge;
  137.  
  138.     std::cout << "Введите максимальное количество шагов maxSteps: ";
  139.     std::cin >> maxSteps;*/
  140.  
  141.  
  142.      //
  143.     rungeKuttaAdaptive(x0, y0, h0, xmax, tolerance, edge,maxSteps);
  144.     //rungeKutta(x0, y0, h0, xmax, maxSteps);
  145.  
  146.     return 0;
  147. }
  148.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement