Advertisement
vatman

mmn_for_gui

May 27th, 2024
578
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.58 KB | None | 0 0
  1. #include <cmath>
  2. #include <fstream>
  3. #include <iomanip>
  4. #include <iostream>
  5. #include <vector>
  6.  
  7. extern "C" {
  8. double f_test(double x, double y) {
  9.   double T = M_PI * x * y;
  10.   double sin2T = std::pow(std::sin(T), 2);
  11.   double cos2T = std::pow(std::cos(T), 2);
  12.   double y2_x2 = y * y + x * x;
  13.   return -2 * M_PI * std::exp(std::pow(std::sin(T), 2)) *
  14.          (2 * M_PI * y2_x2 * cos2T * sin2T - M_PI * y2_x2 * sin2T +
  15.           M_PI * y2_x2 * cos2T);
  16. }
  17. }
  18.  
  19. extern "C" {
  20. double f_main(double x, double y) {
  21.   return -std::pow(std::sin(M_PI * y * x), 2);
  22. }
  23. }
  24. extern "C" {
  25. double u(double x, double y) {
  26.   return std::exp(std::pow(std::sin(M_PI * x * y), 2));
  27. }
  28. }
  29. extern "C" {
  30. void Write_test(std::vector<std::vector<double>> v, const int n, const int m,
  31.                 const int S, const double eps_max, const double r_max,
  32.                 const double z_max) // функция записи массива в бинарный файл
  33. {
  34.   std::ofstream in("/home/syatov430/VAZHNO/NM_labs_3kurs_2semestr/NM_lab2/lab2/"
  35.                    "data.txt"); // подключение текстового файла для записи в
  36.                                 // бинарном режиме
  37.   for (int i = 0; i < n; i++) {
  38.     for (int j = 0; j < m; j++) {
  39.       if (j != m - 1)
  40.         in << v[i][j] << ", "; // запись в файл поэлементно
  41.       else
  42.         in << v[i][j] << "\n";
  43.     }
  44.   }
  45.   in.close(); // закрываем файл
  46.  
  47.   std::ofstream in1("/home/syatov430/VAZHNO/NM_labs_3kurs_2semestr/NM_lab2/"
  48.                     "lab2/z_it.txt"); // подключение текстового файла для записи
  49.                                       // в бинарном режиме
  50.   for (int i = 0; i < n; i++) {
  51.     for (int j = 0; j < m; j++) {
  52.       if (j != m - 1)
  53.         in1 << fabs(v[i][j] - u(i * (1 / (n - 1)), j * (1 / (m - 1))))
  54.             << ", "; // запись в файл поэлементно
  55.       else
  56.         in1 << fabs(v[i][j] - u(i * (1 / (n - 1)), j * (1 / (m - 1)))) << "\n";
  57.     }
  58.   }
  59.   in1.close(); // закрываем файл
  60.  
  61.   std::ofstream in2("/home/syatov430/VAZHNO/NM_labs_3kurs_2semestr/NM_lab2/"
  62.                     "lab2/param.txt"); // подключение текстового файла для
  63.                                        // записи в бинарном режиме
  64.   in2 << S << ", " << eps_max << ", " << r_max << ", " << z_max;
  65.   in2.close(); // закрываем файл
  66. }
  67. }
  68.  
  69. extern "C" {
  70. void Write_main_v(std::vector<std::vector<double>> v, const int n, const int m,
  71.                   const double v_v2, const int n2,
  72.                   const int m2) // функция записи массива в бинарный файл
  73. {
  74.   std::ofstream in("/home/syatov430/VAZHNO/NM_labs_3kurs_2semestr/NM_lab2/lab2/"
  75.                    "data.txt"); // подключение текстового файла для записи в
  76.                                 // бинарном режиме
  77.   for (int i = 0; i < n; i++) {
  78.     for (int j = 0; j < m; j++) {
  79.       if (j != m - 1)
  80.         in << v[i][j] << ", "; // запись в файл поэлементно
  81.       else
  82.         in << v[i][j] << "\n";
  83.     }
  84.   }
  85.   in.close(); // закрываем файл
  86. }
  87. }
  88.  
  89. void Write_main_param(
  90.     const int n, const int m, const int S, const double eps_max,
  91.     const double r_max) // функция записи массива в бинарный файл
  92. {
  93.  
  94.   std::ofstream in2("/home/syatov430/VAZHNO/NM_labs_3kurs_2semestr/NM_lab2/"
  95.                     "lab2/param.txt"); // подключение текстового файла для
  96.                                        // записи в бинарном режиме
  97.   in2 << n << m << S << ", " << eps_max << ", " << r_max;
  98.   in2.close(); // закрываем файл
  99. }
  100. extern "C" {
  101. int MinimalResiduals_test(const int nmax = 1000, const double _eps = 0.0000001,
  102.                           const int _n = 3, const int _m = 3) {
  103.   int Nmax = nmax; // максимальное число итераций (не менее 1)
  104.   std::vector<std::vector<double>> v; // сеточная функция ѵ (x, y)
  105.   v.resize(_n + 1);
  106.   for (size_t i = 0; i < _n + 1; i++) {
  107.     v[i].resize(_m + 1);
  108.     for (size_t j = 0; j < _m + 1; j++) {
  109.       v[i][j] = 0;
  110.     }
  111.   }
  112.   std::vector<std::vector<double>> r_vec; // вектор невязки
  113.   r_vec.resize(_n + 1);
  114.   for (size_t i = 0; i < _n + 1; i++) {
  115.     r_vec[i].resize(_m + 1);
  116.     for (size_t j = 0; j < _m + 1; j++) {
  117.       r_vec[i][j] = 0;
  118.     }
  119.   }
  120.   std::vector<std::vector<double>> ar; // вектор невязки
  121.   ar.resize(_n + 1);
  122.   for (size_t i = 0; i < _n + 1; i++) {
  123.     ar[i].resize(_m + 1);
  124.     for (size_t j = 0; j < _m + 1; j++) {
  125.       ar[i][j] = 0;
  126.     }
  127.   }
  128.   double r1 = 0;
  129.   int S = 0;         // счетчик итераций
  130.   double eps = _eps; // заданная точность
  131.   double eps_max = 0; // точность, достигнутая на текущей итерации
  132.   double eps_cur = 0; // для подсчета точности на текущей итерации
  133.   double a2, k2, h2; // ненулевые элементы матрицы (-А)
  134.   const int n = _n, m = _m; // размерность сетки
  135.   double r_max = 0;
  136.   double a = 0;
  137.   double b = 1;
  138.   double c = 0;
  139.   double d = 1; // границы области определения уравнения
  140.   int i, j; // индексы
  141.   double r = 0;
  142.   double v_old; // старое значение преобразуемой компоненты вектора
  143.   double v_new; // новое значение преобразуемой компоненты вектора и
  144.   bool flag = false; // условие остановки
  145.   double h = ((b - a) / n);
  146.   double k = ((d - c) / m);
  147.   double z = 0;
  148.   double z_max = 0;
  149.   double tau_s = 0;
  150.   double num = 0; // tau=num/denominator
  151.   double denominator = 1;
  152.   h2 = -std::pow((n / (b - a)), 2);
  153.   k2 = -std::pow((m / (d - c)), 2);
  154.   a2 = -2 * (h2 + k2);
  155.   for (int i = 0; i < n + 1; i++) {
  156.     v[i][0] = u(a + i * h, a);
  157.     v[i][m] = u(a + i * h, b);
  158.   }
  159.   for (int j = 0; j < m + 1; j++) {
  160.     v[0][j] = u(c, c + j * k);
  161.     v[n][j] = u(d, c + j * k);
  162.   }
  163.   do {
  164.     z = 0;
  165.     z_max = 0;
  166.     eps_max = 0;
  167.     r_max = -20;
  168.     num = 0;
  169.     denominator = 0;
  170.     for (j = 1; j < m; j++) {
  171.       for (i = n - 1; i > 0; i--) {
  172.         r_vec[i][j] = f_test(a + i * h, c + j * k) -
  173.                       (h2 * (v[i + 1][j] + v[i - 1][j]) +
  174.                        k2 * (v[i][j + 1] + v[i][j - 1]) + v[i][j] * a2);
  175.       }
  176.     }
  177.     for (j = 1; j < m; j++) {
  178.       for (i = n - 1; i > 0; i--) {
  179.         ar[i][j] =
  180.             (h2 * (r_vec[i + 1][j] + r_vec[i - 1][j]) +
  181.              k2 * (r_vec[i][j + 1] + r_vec[i][j - 1]) + r_vec[i][j] * a2);
  182.         num += ar[i][j] * r_vec[i][j];
  183.         denominator += ar[i][j] * ar[i][j];
  184.       }
  185.     }
  186.     tau_s = num / denominator;
  187.     for (j = 1; j < m; j++) {
  188.       for (i = n - 1; i > 0; i--) {
  189.         v_old = v[i][j];
  190.         v_new = v_old + tau_s * r_vec[i][j];
  191.         eps_cur = std::fabs(v_old - v_new);
  192.         if (eps_cur > eps_max) {
  193.           eps_max = eps_cur;
  194.         }
  195.         v[i][j] = v_new;
  196.         r = fabs(f_test(a + i * h, c + j * k) -
  197.                  (h2 * (v[i + 1][j] + v[i - 1][j]) +
  198.                   k2 * (v[i][j + 1] + v[i][j - 1]) + v_old * a2));
  199.         if (r > r_max)
  200.           r_max = r;
  201.         z = u(a + i * h, c + j * k) - v[i][j];
  202.         if (z > z_max)
  203.           z_max = z;
  204.       }
  205.     }
  206.  
  207.     S = S + 1;
  208.     if ((eps_max <= eps) or (S >= Nmax)) {
  209.       flag = true;
  210.     }
  211.   } while (!flag);
  212.   Write_test(v, n + 1, m + 1, S, eps_max, r_max, z_max);
  213.   return 0;
  214. }
  215. }
  216.  
  217. std::vector<std::vector<double>>
  218. MinimalResiduals_main(const int nmax = 1000, const double _eps = 0.0000001,
  219.                       const int _n = 3, const int _m = 3) {
  220.   int Nmax = nmax; // максимальное число итераций (не менее 1)
  221.   std::vector<std::vector<double>> v; // сеточная функция ѵ (x, y)
  222.   v.resize(_n + 1);
  223.   for (size_t i = 0; i < _n + 1; i++) {
  224.     v[i].resize(_m + 1);
  225.     for (size_t j = 0; j < _m + 1; j++) {
  226.       v[i][j] = 0;
  227.     }
  228.   }
  229.   std::vector<std::vector<double>> v2; // сеточная функция ѵ (x, y)
  230.   v2.resize(2 * _n + 1);
  231.   for (size_t i = 0; i < 2 * _n + 1; i++) {
  232.     v2[i].resize(2 * _m + 1);
  233.     for (size_t j = 0; j < 2 * _m + 1; j++) {
  234.       v2[i][j] = 0;
  235.     }
  236.   }
  237.   std::vector<std::vector<double>> r_vec; // вектор невязки
  238.   r_vec.resize(_n + 1);
  239.   for (size_t i = 0; i < _n + 1; i++) {
  240.     r_vec[i].resize(_m + 1);
  241.     for (size_t j = 0; j < _m + 1; j++) {
  242.       r_vec[i][j] = 0;
  243.     }
  244.   }
  245.   std::vector<std::vector<double>> ar; // вектор невязки
  246.   ar.resize(_n + 1);
  247.   for (size_t i = 0; i < _n + 1; i++) {
  248.     ar[i].resize(_m + 1);
  249.     for (size_t j = 0; j < _m + 1; j++) {
  250.       ar[i][j] = 0;
  251.     }
  252.   }
  253.   double r1 = 0;
  254.   int S = 0;         // счетчик итераций
  255.   double eps = _eps; // заданная точность
  256.   double eps_max = 0; // точность, достигнутая на текущей итерации
  257.   double eps_cur = 0; // для подсчета точности на текущей итерации
  258.   double a2, k2, h2; // ненулевые элементы матрицы (-А)
  259.   const int n = _n, m = _m; // размерность сетки
  260.   double r_max = 0;
  261.   double a = 0;
  262.   double b = 1;
  263.   double c = 0;
  264.   double d = 1; // границы области определения уравнения
  265.   int i, j; // индексы
  266.   double r = 0;
  267.   double v_old; // старое значение преобразуемой компоненты вектора
  268.   double v_new; // новое значение преобразуемой компоненты вектора и
  269.   bool flag = false; // условие остановки
  270.   double h = ((b - a) / n);
  271.   double k = ((d - c) / m);
  272.   double z = 0;
  273.   double z_max = 0;
  274.   double tau_s = 0;
  275.   double num = 0; // tau=num/denominator
  276.   double denominator = 1;
  277.   h2 = -std::pow((n / (b - a)), 2);
  278.   k2 = -std::pow((m / (d - c)), 2);
  279.   a2 = -2 * (h2 + k2);
  280.   for (int i = 0; i < n + 1; i++) {
  281.     double x = a + i * h;
  282.     v[i][0] = x - x * x;
  283.     v[i][m] = x - x * x;
  284.   }
  285.   for (int j = 0; j < m + 1; j++) {
  286.     double y = c + j * k;
  287.     v[0][j] = std::sin(M_PI * y);
  288.     v[n][j] = std::sin(M_PI * y);
  289.   }
  290.   do {
  291.     z = 0;
  292.     z_max = 0;
  293.     eps_max = 0;
  294.     r_max = -20;
  295.     num = 0;
  296.     denominator = 0;
  297.     for (j = 1; j < m; j++) {
  298.       for (i = n - 1; i > 0; i--) {
  299.         r_vec[i][j] = f_main(a + i * h, c + j * k) -
  300.                       (h2 * (v[i + 1][j] + v[i - 1][j]) +
  301.                        k2 * (v[i][j + 1] + v[i][j - 1]) + v[i][j] * a2);
  302.       }
  303.     }
  304.     for (j = 1; j < m; j++) {
  305.       for (i = n - 1; i > 0; i--) {
  306.         ar[i][j] =
  307.             (h2 * (r_vec[i + 1][j] + r_vec[i - 1][j]) +
  308.              k2 * (r_vec[i][j + 1] + r_vec[i][j - 1]) + r_vec[i][j] * a2);
  309.         num += ar[i][j] * r_vec[i][j];
  310.         denominator += ar[i][j] * ar[i][j];
  311.       }
  312.     }
  313.     tau_s = num / denominator;
  314.     for (j = 1; j < m; j++) {
  315.       for (i = n - 1; i > 0; i--) {
  316.         v_old = v[i][j];
  317.         v_new = v_old + tau_s * r_vec[i][j];
  318.         eps_cur = std::fabs(v_old - v_new);
  319.         if (eps_cur > eps_max) {
  320.           eps_max = eps_cur;
  321.         }
  322.         v[i][j] = v_new;
  323.         r = fabs(f_main(a + i * h, c + j * k) -
  324.                  (h2 * (v[i + 1][j] + v[i - 1][j]) +
  325.                   k2 * (v[i][j + 1] + v[i][j - 1]) + v_old * a2));
  326.         if (r > r_max)
  327.           r_max = r;
  328.       }
  329.     }
  330.  
  331.     S = S + 1;
  332.     if ((eps_max <= eps) or (S >= Nmax)) {
  333.       flag = true;
  334.     }
  335.   } while (!flag);
  336.   Write_main_param(n + 1, m + 1, S, eps_max, r_max);
  337.   return v;
  338. }
  339.  
  340. int main() {
  341.   int n = 10;
  342.   int m = 10;
  343.   std::vector<std::vector<double>> v_1(n, std::vector<double>(m, 0));
  344.   std::vector<std::vector<double>> v_2(n, std::vector<double>(2 * m, 0));
  345.   v_1 = MinimalResiduals_main(100000, 0.000001, n, m);
  346.   v_2 = MinimalResiduals_main(100000, 0.000001, 2 * n, 2 * m);
  347.   n++;
  348.   m++;
  349.   double maxv_v2 = 0.0;
  350.   double v_v2 = 0.0;
  351.   int n2 = 0;
  352.   int m2 = 0;
  353.   for (int i = n - 1; i >= 0; i--) {
  354.     for (int j = 0; j < m; j++) {
  355.       v_v2 = std::fabs(v_1[i][j] - v_2[i * 2][j * 2]);
  356.       if (v_v2 > maxv_v2) {
  357.         maxv_v2 = v_v2;
  358.         n2 = i;
  359.         m2 = j;
  360.       }
  361.     }
  362.   }
  363.   Write_main_v(v_1, n, m, maxv_v2, n2, m2);
  364.   return 0;
  365. }
  366.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement