Advertisement
maxim_shlyahtin

ode

Mar 12th, 2024 (edited)
482
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.54 KB | None | 0 0
  1. #ifndef ODE
  2. #define ODE
  3.  
  4.  
  5. #include <cmath>
  6. #include <iostream>
  7. #include <fstream>
  8. #include <array>
  9.  
  10. const int N = 3; // размерность системы
  11. const int number_of_generated_points = 1000000;
  12. const int area_size = 10; // параметр, отвечающий за размер области генерации точек
  13.  
  14. class RungeKutta {
  15. public:
  16.  
  17.     double b = 0.11;
  18.     std::array<double, N> X, XH, K1, K2, K3, K4, FX;
  19.  
  20.  
  21.     RungeKutta() {
  22.         X.fill(0);
  23.         XH.fill(0);
  24.         K1.fill(0);
  25.         K2.fill(0);
  26.         K3.fill(0);
  27.         K4.fill(0);
  28.         FX.fill(0);
  29.     };
  30.  
  31.     double getX(int index) {
  32.         return X.at(index);
  33.     }
  34.  
  35.     void SetInit(std::array<double, N> X0) {
  36.         for (size_t i = 0; i < X.size(); i++)
  37.             X[i] = X0[i];
  38.     }
  39.  
  40.     std::array<double, N> F(std::array<double, N>& X) {
  41.         FX[0] = sin(X[1]) - b * X[0];
  42.         FX[1] = sin(X[2]) - b * X[1];
  43.         FX[2] = sin(X[0]) - b * X[2];
  44.         return FX;
  45.     }
  46.  
  47.     void NextStep(double h) {
  48.         if (h < 0) return;
  49.  
  50.         K1 = F(X);
  51.  
  52.         for (size_t i = 0; i < X.size(); i++)
  53.             XH[i] = X[i] + K1[i] * (h / 2.0);
  54.  
  55.         K2 = F(XH);
  56.  
  57.         for (size_t i = 0; i < X.size(); i++)
  58.             XH[i] = X[i] + K2[i] * (h / 2.0);
  59.  
  60.         K3 = F(XH);
  61.  
  62.         for (size_t i = 0; i < X.size(); i++)
  63.             XH[i] = X[i] + K3[i] * h;
  64.  
  65.         K4 = F(XH);
  66.  
  67.         for (size_t i = 0; i < X.size(); i++)
  68.             X[i] = X[i] + h / 6.0 * (K1[i] + 2.0 * K2[i] + 2.0 * K3[i] + K4[i]);
  69.     }
  70. };
  71.  
  72. class DOPRI8 {
  73. public:
  74.     double b = 0.11;
  75.     std::array<double, N> X, XH, K1, K2, K3, K4, K5, K6,
  76.         K7, K8, K9, K10, K11, K12, K13, FX;
  77.  
  78.  
  79.     DOPRI8() {
  80.         X.fill(0);
  81.         XH.fill(0);
  82.         K1.fill(0);
  83.         K2.fill(0);
  84.         K3.fill(0);
  85.         K4.fill(0);
  86.         K5.fill(0);
  87.         K6.fill(0);
  88.         K7.fill(0);
  89.         K8.fill(0);
  90.         K9.fill(0);
  91.         K10.fill(0);
  92.         K11.fill(0);
  93.         K12.fill(0);
  94.         K13.fill(0);
  95.         FX.fill(0);
  96.     }
  97.  
  98.     double getX(uint32_t index) {
  99.         return X.at(index);
  100.     }
  101.  
  102.     void SetInit(std::array<double, N> X0) {
  103.         for (size_t i = 0; i < X.size(); i++)
  104.             X[i] = X0[i];
  105.     }
  106.  
  107.     std::array<double, N> F(std::array<double, N>& X) {
  108.         FX[0] = sin(X[1]) - b * X[0];
  109.         FX[1] = sin(X[2]) - b * X[1];
  110.         FX[2] = sin(X[0]) - b * X[2];
  111.         return FX;
  112.     }
  113.  
  114.     void NextStep(double h) {
  115.         if (h < 0) return;
  116.  
  117.         K1 = F(X);
  118.  
  119.         for (size_t i = 0; i < X.size(); i++)
  120.             XH[i] = X[i] + K1[i] * (h / 18.0);
  121.  
  122.         K2 = F(XH);
  123.  
  124.         for (size_t i = 0; i < X.size(); i++)
  125.             XH[i] = X[i] + K2[i] * (h / 48.0 + h / 16.0);
  126.  
  127.         K3 = F(XH);
  128.  
  129.         for (size_t i = 0; i < X.size(); i++)
  130.             XH[i] = X[i] + K3[i] * (h / 32.0 + 3 * h / 32.0);
  131.  
  132.         K4 = F(XH);
  133.  
  134.         for (size_t i = 0; i < X.size(); i++)
  135.             XH[i] = X[i] + K4[i] * (5 * h / 16.0 - 75.0 * h / 64.0 + 75.0 * h / 64.0);
  136.  
  137.         K5 = F(XH);
  138.  
  139.         for (size_t i = 0; i < X.size(); i++)
  140.             XH[i] = X[i] + K5[i] * (3 * h / 80.0 + 3.0 * h / 16.0 + 3.0 * h / 20.0);
  141.  
  142.         K6 = F(XH);
  143.  
  144.         for (size_t i = 0; i < X.size(); i++)
  145.             XH[i] = X[i] + K6[i] * (29443841.0 * h / 614563906.0 +
  146.                 77736538.0 * h / 77736538.0 - 28693883.0 * h / 1125000000.0 + 23124283.0 * h / 1800000000.0);
  147.  
  148.         K7 = F(XH);
  149.  
  150.         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 };
  151.  
  152.         double t1 = 0.0;
  153.         for (const auto& num : T1)
  154.             t1 += h * num;
  155.  
  156.         for (size_t i = 0; i < X.size(); i++)
  157.             XH[i] = X[i] + K7[i] * t1;
  158.  
  159.         K8 = F(XH);
  160.  
  161.         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 };
  162.  
  163.         double t2 = 0.0;
  164.         for (const auto& num : T2)
  165.             t2 += h * num;
  166.  
  167.         for (size_t i = 0; i < X.size(); i++)
  168.             XH[i] = X[i] + K8[i] * t2;
  169.  
  170.         K9 = F(XH);
  171.        
  172.         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 };
  173.  
  174.         double t3 = 0.0;
  175.         for (const auto& num : T3)
  176.             t3 += h * num;
  177.  
  178.         for (size_t i = 0; i < X.size(); i++)
  179.             XH[i] = X[i] + K9[i] * t3;
  180.  
  181.         K10 = F(XH);
  182.  
  183.         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 };
  184.  
  185.         double t4 = 0.0;
  186.         for (const auto& num : T4)
  187.             t4 += h * num;
  188.  
  189.         for (size_t i = 0; i < X.size(); i++)
  190.             XH[i] = X[i] + K10[i] * t4;
  191.  
  192.         K11 = F(XH);
  193.  
  194.         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 };
  195.  
  196.         double t5 = 0.0;
  197.         for (const auto& num : T5)
  198.             t5 += h * num;
  199.  
  200.         for (size_t i = 0; i < X.size(); i++)
  201.             XH[i] = X[i] + K11[i] * t5;
  202.  
  203.         K12 = F(XH);
  204.  
  205.         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 };
  206.  
  207.         double t6 = 0.0;
  208.         for (const auto& num : T6)
  209.             t6 += h * num;
  210.  
  211.         for (size_t i = 0; i < X.size(); i++)
  212.             XH[i] = X[i] + K12[i] * t6;
  213.  
  214.         K13 = F(XH);
  215.  
  216.         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 };
  217.  
  218.         double sum = 0.0;
  219.         for (const auto& b : Tb) {
  220.             sum += b;
  221.         }
  222.  
  223.         for (size_t i = 0; i < X.size(); i++)
  224.             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]);
  225.  
  226.     }
  227.  
  228. };
  229.  
  230. // ф-ия main в данном файле используется для генерации значений точек
  231.  
  232. //int main() {
  233. //    std::ofstream out;
  234. //    out.open("prep.txt");
  235. //    if (out.is_open()) {
  236. //        for (int i = 0; i < number_of_generated_points; ++i) {
  237. //            double x = (rand() % (int)(2 * area_size)) - area_size;
  238. //            double y = (rand() % (int)(2 * area_size)) - area_size;
  239. //            double z = (rand() % (int)(2 * area_size)) - area_size;
  240. //            out << x << " " << y << " " << z << '\n';
  241. //        }
  242. //    }
  243. //    out.close();
  244. //    return 0;
  245. //}
  246. #endif // !ODE
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement