Advertisement
vatman

mmn_test_main

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