Advertisement
maxim_shlyahtin

new_ode

Mar 16th, 2024
605
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.05 KB | None | 0 0
  1. #include <cmath>
  2. #include <cstdio>
  3. #include <iostream>
  4. #include <vector>
  5. #include <chrono>
  6.  
  7. class RungeKutta {
  8. protected:
  9.     double t;
  10.     std::vector<double> X, XH, K1, K2, K3, K4, FX;
  11.  
  12. public:
  13.     RungeKutta(uint32_t N) {
  14.         Init(N);
  15.     }
  16.  
  17.     double getX(uint32_t index) {
  18.         return X.at(index);
  19.     }
  20.  
  21.     void Init(uint32_t N) {
  22.         X.resize(N);
  23.         XH.resize(N);
  24.         K1.resize(N);
  25.         K2.resize(N);
  26.         K3.resize(N);
  27.         K4.resize(N);
  28.         FX.resize(N);
  29.     }
  30.  
  31.     void SetInit(double t0, std::vector<double> X0) {
  32.         t = t0;
  33.         if (X.empty()) Init(X0.size());
  34.         for (size_t i = 0; i < X.size(); i++)
  35.             X[i] = X0[i];
  36.     }
  37.  
  38.     virtual std::vector<double> F(double t, std::vector<double> X) = 0;
  39.  
  40.     void NextStep(double h) {
  41.         if (h < 0) return;
  42.  
  43.         K1 = F(t, X);
  44.  
  45.         for (size_t i = 0; i < X.size(); i++)
  46.             XH[i] = X[i] + K1[i] * (h / 2.0);
  47.  
  48.         K2 = F(t + h / 2.0, XH);
  49.  
  50.         for (size_t i = 0; i < X.size(); i++)
  51.             XH[i] = X[i] + K2[i] * (h / 2.0);
  52.  
  53.         K3 = F(t + h / 2.0, XH);
  54.  
  55.         for (size_t i = 0; i < X.size(); i++)
  56.             XH[i] = X[i] + K3[i] * h;
  57.  
  58.         K4 = F(t + h, XH);
  59.  
  60.         for (size_t i = 0; i < X.size(); i++)
  61.             X[i] = X[i] + h / 6.0 * (K1[i] + 2.0 * K2[i] + 2.0 * K3[i] + K4[i]);
  62.  
  63.         t = t + h;
  64.     }
  65. };
  66.  
  67. class DOPRI8 {
  68. protected:
  69.     double t;
  70.     std::vector<double> X, XH, K1, K2, K3, K4, K5, K6,
  71.         K7, K8, K9, K10, K11, K12, K13, FX;
  72.  
  73. public:
  74.     DOPRI8(uint32_t N) {
  75.         Init(N);
  76.     }
  77.  
  78.     double getX(uint32_t index) {
  79.         return X.at(index);
  80.     }
  81.  
  82.     void Init(uint32_t N) {
  83.         X.resize(N);
  84.         XH.resize(N);
  85.         K1.resize(N);
  86.         K2.resize(N);
  87.         K3.resize(N);
  88.         K4.resize(N);
  89.         K5.resize(N);
  90.         K6.resize(N);
  91.         K7.resize(N);
  92.         K8.resize(N);
  93.         K9.resize(N);
  94.         K10.resize(N);
  95.         K11.resize(N);
  96.         K12.resize(N);
  97.         K13.resize(N);
  98.         FX.resize(N);
  99.     }
  100.  
  101.     void SetInit(double t0, std::vector<double> X0) {
  102.         t = t0;
  103.         if (X.empty()) Init(X0.size());
  104.         for (size_t i = 0; i < X.size(); i++)
  105.             X[i] = X0[i];
  106.     }
  107.  
  108.     virtual std::vector<double> F(double t, std::vector<double> X) = 0;
  109.  
  110.     void NextStep(double h) {
  111.         if (h < 0) return;
  112.  
  113.         K1 = F(t + h, 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(t + h / 18.0, 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(t + h / 48.0 + h / 16.0, 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(t + h / 32.0 + 3 * h / 32.0, 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(t + 5 * h / 16.0 - 75.0 * h / 64.0 + 75.0 * h / 64.0, 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(t + 3 * h / 80.0 + 3.0 * h / 16.0 + 3.0 * h / 20.0, XH);
  139.  
  140.         for (size_t i = 0; i < X.size(); i++)
  141.             XH[i] = X[i] + K7[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(t + 29443841.0 * h / 614563906.0 +
  145.             77736538.0 * h / 77736538.0 - 28693883.0 * h / 1125000000.0 + 23124283.0 * h / 1800000000.0, XH);
  146.  
  147.         std::vector<double> 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 };
  148.  
  149.         double t1 = 0.0;
  150.         for (const auto& num : T1)
  151.             t1 += h * num;
  152.  
  153.         for (size_t i = 0; i < X.size(); i++)
  154.             XH[i] = X[i] + K8[i] * t1;
  155.  
  156.         K8 = F(t + t1, XH);
  157.  
  158.         std::vector<double> 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 };
  159.  
  160.         double t2 = 0.0;
  161.         for (const auto& num : T2)
  162.             t2 += h * num;
  163.  
  164.         for (size_t i = 0; i < X.size(); i++)
  165.             XH[i] = X[i] + K9[i] * t2;
  166.  
  167.         K9 = F(t + t2, XH);
  168.  
  169.         std::vector<double> 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 };
  170.  
  171.         double t3 = 0.0;
  172.         for (const auto& num : T3)
  173.             t3 += h * num;
  174.  
  175.         for (size_t i = 0; i < X.size(); i++)
  176.             XH[i] = X[i] + K10[i] * t3;
  177.  
  178.         K10 = F(t + t3, XH);
  179.  
  180.         std::vector<double> 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 };
  181.  
  182.         double t4 = 0.0;
  183.         for (const auto& num : T4)
  184.             t4 += h * num;
  185.  
  186.         for (size_t i = 0; i < X.size(); i++)
  187.             XH[i] = X[i] + K11[i] * t4;
  188.  
  189.         K11 = F(t + t4, XH);
  190.  
  191.         std::vector<double> 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 };
  192.  
  193.         double t5 = 0.0;
  194.         for (const auto& num : T5)
  195.             t5 += h * num;
  196.  
  197.         for (size_t i = 0; i < X.size(); i++)
  198.             XH[i] = X[i] + K12[i] * t5;
  199.  
  200.         K12 = F(t + t5, XH);
  201.  
  202.         std::vector<double> 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 };
  203.  
  204.         double t6 = 0.0;
  205.         for (const auto& num : T6)
  206.             t6 += h * num;
  207.  
  208.         for (size_t i = 0; i < X.size(); i++)
  209.             XH[i] = X[i] + K13[i] * t6;
  210.  
  211.         K13 = F(t + t6, XH);
  212.  
  213.         std::vector<double> 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 };
  214.  
  215.         for (size_t i = 0; i < X.size(); i++)
  216.             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]);
  217.  
  218.         t = t + h;
  219.     }
  220. };
  221.  
  222. class TA : public DOPRI8 {
  223. private:
  224.  
  225.     const double b = 0.15; // bifurcation parameter
  226.  
  227. public:
  228.     TA(uint32_t N) : DOPRI8(N) {}
  229.  
  230.     std::vector<double> F(double h, std::vector<double> X) override {
  231.         FX[0] = sin(X[1]) - b * X[0];
  232.         FX[1] = sin(X[2]) - b * X[1];
  233.         FX[2] = sin(X[0]) - b * X[2];
  234.         return FX;
  235.     }
  236.  
  237.     static void Test() {
  238.         double dt = 0.001;
  239.         TA task(3);
  240.         int n = 0;
  241.         std::vector<double> X0 = { 0, 1, 0 };
  242.         task.SetInit(0, X0);
  243.         while (n < 20000) {
  244.             n++;
  245.             std::cout << n <<" Time = " << task.t << "; x = " << task.X[0] << "; y = " << task.X[1] << "; z = " << task.X[2] << '\n';
  246.             task.NextStep(dt);
  247.         }
  248.     }
  249. };
  250.  
  251.  
  252.  
  253. int main() {
  254.     auto start = std::chrono::steady_clock::now();
  255.     TA::Test();
  256.     auto end = std::chrono::steady_clock::now();
  257.     std::cout << "time " << std::chrono::duration_cast<std::chrono::seconds>(end - start).count() << " sec\n";
  258.     return 0;
  259. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement