Advertisement
maxim_shlyahtin

RK-4_ode

Mar 21st, 2024 (edited)
461
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.50 KB | None | 0 0
  1. #include <cmath>
  2. #include <iostream>
  3. #include <fstream>
  4. #include <array>
  5.  
  6. const int N = 3; // размерность системы
  7. const int number_of_generated_points = 100000;
  8. const int area_size = 10; // параметр, отвечающий за размер области генерации точек
  9.  
  10. class RungeKutta {
  11. public:
  12.  
  13.     double b = 0.11;
  14.     std::array<double, N> X, XH, K1, K2, K3, K4, FX;
  15.  
  16.  
  17.     RungeKutta() {
  18.         X.fill(0);
  19.         XH.fill(0);
  20.         K1.fill(0);
  21.         K2.fill(0);
  22.         K3.fill(0);
  23.         K4.fill(0);
  24.         FX.fill(0);
  25.     };
  26.  
  27.     double getX(int index) {
  28.         return X.at(index);
  29.     }
  30.  
  31.     void SetInit(std::array<double, N> X0) {
  32.         for (size_t i = 0; i < X.size(); i++)
  33.             X[i] = X0[i];
  34.     }
  35.  
  36.     std::array<double, N> F(std::array<double, N>& X) {
  37.         FX[0] = sin(X[1]) - b * X[0];
  38.         FX[1] = sin(X[2]) - b * X[1];
  39.         FX[2] = sin(X[0]) - b * X[2];
  40.         return FX;
  41.     }
  42.  
  43.     void NextStep(double h) {
  44.         if (h < 0) return;
  45.  
  46.         K1 = F(X);
  47.  
  48.         for (size_t i = 0; i < X.size(); i++)
  49.             XH[i] = X[i] + K1[i] * (h / 2.0);
  50.  
  51.         K2 = F(XH);
  52.  
  53.         for (size_t i = 0; i < X.size(); i++)
  54.             XH[i] = X[i] + K2[i] * (h / 2.0);
  55.  
  56.         K3 = F(XH);
  57.  
  58.         for (size_t i = 0; i < X.size(); i++)
  59.             XH[i] = X[i] + K3[i] * h;
  60.  
  61.         K4 = F(XH);
  62.  
  63.         for (size_t i = 0; i < X.size(); i++)
  64.             X[i] = X[i] + h / 6.0 * (K1[i] + 2.0 * K2[i] + 2.0 * K3[i] + K4[i]);
  65.     }
  66. };
  67.  
  68. class DOPRI8 {
  69. public:
  70.     double b = 0.11;
  71.     std::array<double, N> X, XH, K1, K2, K3, K4, K5, K6,
  72.         K7, K8, K9, K10, K11, K12, K13, FX;
  73.  
  74.  
  75.     DOPRI8() {
  76.         X.fill(0);
  77.         XH.fill(0);
  78.         K1.fill(0);
  79.         K2.fill(0);
  80.         K3.fill(0);
  81.         K4.fill(0);
  82.         K5.fill(0);
  83.         K6.fill(0);
  84.         K7.fill(0);
  85.         K8.fill(0);
  86.         K9.fill(0);
  87.         K10.fill(0);
  88.         K11.fill(0);
  89.         K12.fill(0);
  90.         K13.fill(0);
  91.         FX.fill(0);
  92.     }
  93.  
  94.     double getX(uint32_t index) {
  95.         return X.at(index);
  96.     }
  97.  
  98.     void SetInit(std::array<double, N> X0) {
  99.         for (size_t i = 0; i < X.size(); i++)
  100.             X[i] = X0[i];
  101.     }
  102.  
  103.     std::array<double, N> F(std::array<double, N>& X) {
  104.         FX[0] = sin(X[1]) - b * X[0];
  105.         FX[1] = sin(X[2]) - b * X[1];
  106.         FX[2] = sin(X[0]) - b * X[2];
  107.         return FX;
  108.     }
  109.  
  110.     void NextStep(double h) {
  111.         if (h < 0) return;
  112.  
  113.         K1 = F(X);
  114.  
  115.         for (size_t i = 0; i < X.size(); i++)
  116.             XH[i] = X[i] + K1[i] * (h / 18.0);
  117.  
  118.         K2 = F(XH);
  119.  
  120.         for (size_t i = 0; i < X.size(); i++)
  121.             XH[i] = X[i] + K2[i] * (h / 48.0 + h / 16.0);
  122.  
  123.         K3 = F(XH);
  124.  
  125.         for (size_t i = 0; i < X.size(); i++)
  126.             XH[i] = X[i] + K3[i] * (h / 32.0 + 3 * h / 32.0);
  127.  
  128.         K4 = F(XH);
  129.  
  130.         for (size_t i = 0; i < X.size(); i++)
  131.             XH[i] = X[i] + K4[i] * (5 * h / 16.0 - 75.0 * h / 64.0 + 75.0 * h / 64.0);
  132.  
  133.         K5 = F(XH);
  134.  
  135.         for (size_t i = 0; i < X.size(); i++)
  136.             XH[i] = X[i] + K5[i] * (3 * h / 80.0 + 3.0 * h / 16.0 + 3.0 * h / 20.0);
  137.  
  138.         K6 = F(XH);
  139.  
  140.         for (size_t i = 0; i < X.size(); i++)
  141.             XH[i] = X[i] + K6[i] * (29443841.0 * h / 614563906.0 +
  142.                 77736538.0 * h / 77736538.0 - 28693883.0 * h / 1125000000.0 + 23124283.0 * h / 1800000000.0);
  143.  
  144.         K7 = F(XH);
  145.  
  146.         std::array<double, 7> T1 = { 16016141.0 / 946692911.0, 0.0, 0.0, 61564180.0 / 158732637.0, 22789713.0 / 633445777.0, 545815736.0 / 2771057229.0, -180193667.0 / 1043307555.0 };
  147.  
  148.         double t1 = 0.0;
  149.         for (const auto& num : T1)
  150.             t1 += h * num;
  151.  
  152.         for (size_t i = 0; i < X.size(); i++)
  153.             XH[i] = X[i] + K7[i] * t1;
  154.  
  155.         K8 = F(XH);
  156.  
  157.         std::array<double, 8> T2 = { 39632708.0 / 573591083.0, 0.0, 0.0, -433636366.0 / 683701615.0, -421739975.0 / 2616292301.0, 100302831.0 / 723423059.0, 790204164.0 / 839813087.0, 800635310.0 / 3783071287.0 };
  158.  
  159.         double t2 = 0.0;
  160.         for (const auto& num : T2)
  161.             t2 += h * num;
  162.  
  163.         for (size_t i = 0; i < X.size(); i++)
  164.             XH[i] = X[i] + K8[i] * t2;
  165.  
  166.         K9 = F(XH);
  167.        
  168.         std::array<double, 9> T3 = { 246121993.0 / 1340847787.0, 0.0, 0.0, -37695042795.0 / 15268766246.0, -309121744.0 / 1061227803.0, -12992083.0 / 490766935.0, 6005943493.0 / 2108947869.0, 393006217.0 / 1396673457.0, 123872331.0 / 1001029789.0 };
  169.  
  170.         double t3 = 0.0;
  171.         for (const auto& num : T3)
  172.             t3 += h * num;
  173.  
  174.         for (size_t i = 0; i < X.size(); i++)
  175.             XH[i] = X[i] + K9[i] * t3;
  176.  
  177.         K10 = F(XH);
  178.  
  179.         std::array<double, 10> T4 = { -1028468189.0 / 846180014.0, 0.0, 0.0, 8478235783.0 / 508512852.0, 1311729495.0 / 1432422823.0, -10304129995.0 / 1701304382.0, -48777925059.0 / 3047939560.0, 15336726248.0 / 1032824649.0, -45442868181.0 / 3398467696.0, 3065993473.0 / 597172653.0 };
  180.  
  181.         double t4 = 0.0;
  182.         for (const auto& num : T4)
  183.             t4 += h * num;
  184.  
  185.         for (size_t i = 0; i < X.size(); i++)
  186.             XH[i] = X[i] + K10[i] * t4;
  187.  
  188.         K11 = F(XH);
  189.  
  190.         std::array<double, 11> T5 = { 185892177.0 / 718116043.0, 0.0, 0.0, -3185094517.0 / 667107341.0, -477755414.0 / 1098053517.0, -703635378.0 / 230739211.0, 5731566787.0 / 1027545527.0, 5232866602.0 / 850066563.0, -4093664535.0 / 808688257.0, 3962137247.0 / 1805957418.0, 65686358.0 / 487910083.0 };
  191.  
  192.         double t5 = 0.0;
  193.         for (const auto& num : T5)
  194.             t5 += h * num;
  195.  
  196.         for (size_t i = 0; i < X.size(); i++)
  197.             XH[i] = X[i] + K11[i] * t5;
  198.  
  199.         K12 = F(XH);
  200.  
  201.         std::array<double, 12> T6 = { 403863854.0 / 491063109.0, 0.0, 0.0, -5068492393.0 / 434740067.0, -411421997.0 / 543043805.0, 652783627.0 / 914296604.0, 11173962825.0 / 925320556.0, -13158990841.0 / 6184727034.0, 3936647629.0 / 1978049680.0, -160528059.0 / 685178525.0, 248638103.0 / 1413531060.0, 0.0 };
  202.  
  203.         double t6 = 0.0;
  204.         for (const auto& num : T6)
  205.             t6 += h * num;
  206.  
  207.         for (size_t i = 0; i < X.size(); i++)
  208.             XH[i] = X[i] + K12[i] * t6;
  209.  
  210.         K13 = F(XH);
  211.  
  212.         std::array<double, 13> Tb = { 14005451.0 / 335480064.0, 0.0, 0.0, 0.0, 0.0, -59238493.0 / 1068277825.0, 181606767.0 / 758867731.0, 561292985.0 / 797845732.0, -1041891430.0 / 1371343529.0, 760417239.0 / 1151165299.0, 118820643.0 / 751138087.0, -528747749.0 / 2220607170.0, 1.0 / 4.0 };
  213.  
  214.         double sum = 0.0;
  215.         for (const auto& b : Tb) {
  216.             sum += b;
  217.         }
  218.  
  219.         for (size_t i = 0; i < X.size(); i++)
  220.             X[i] = X[i] + h * (K1[i] * Tb[0] + K2[i] * Tb[1] + K3[i] * Tb[2] + K4[i] * Tb[3] + K5[i] * Tb[4] + K6[i] * Tb[5] + K7[i] * Tb[6] + K8[i] * Tb[7] + K9[i] * Tb[8] + K10[i] * Tb[9] + K11[i] * Tb[10] + K12[i] * Tb[11] + K13[i] * Tb[12]);
  221.  
  222.     }
  223.  
  224. };
  225.  
  226. // ф-ия main в данном файле используется для генерации значений точек
  227.  
  228. //int main() {
  229. //    std::ofstream out;
  230. //    out.open("prep.txt");
  231. //    if (out.is_open()) {
  232. //        for (int i = 0; i < number_of_generated_points; ++i) {
  233. //            double x = (rand() % (int)(2 * area_size)) - area_size;
  234. //            double y = (rand() % (int)(2 * area_size)) - area_size;
  235. //            double z = (rand() % (int)(2 * area_size)) - area_size;
  236. //            out << x << " " << y << " " << z << '\n';
  237. //        }
  238. //    }
  239. //    out.close();
  240. //    return 0;
  241. //}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement