Advertisement
vatman

mmn_test_func

May 26th, 2024
455
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.83 KB | None | 0 0
  1. #include <cmath>
  2. #include <iomanip>
  3. #include <iostream>
  4. #include <vector>
  5.  
  6. double f(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 u(double x, double y) {
  17.   return std::exp(std::pow(std::sin(M_PI * x * y), 2));
  18. }
  19.  
  20. std::vector<std::vector<double>> MinimalResiduals(const int nmax = 1000,
  21.                                                   const double _eps = 0.0000001,
  22.                                                   const int _n = 3,
  23.                                                   const int _m = 3) {
  24.   int Nmax = nmax; // максимальное число итераций (не менее 1)
  25.   std::vector<std::vector<double>> v; // сеточная функция ѵ (x, y)
  26.   v.resize(_n + 1);
  27.   for (size_t i = 0; i < _n + 1; i++) {
  28.     v[i].resize(_m + 1);
  29.     for (size_t j = 0; j < _m + 1; j++) {
  30.       v[i][j] = 0;
  31.     }
  32.   }
  33.   std::vector<std::vector<double>> r_vec; // вектор невязки
  34.   r_vec.resize(_n + 1);
  35.   for (size_t i = 0; i < _n + 1; i++) {
  36.     r_vec[i].resize(_m + 1);
  37.     for (size_t j = 0; j < _m + 1; j++) {
  38.       r_vec[i][j] = 0;
  39.     }
  40.   }
  41.   std::vector<std::vector<double>> ar; // вектор невязки
  42.   ar.resize(_n + 1);
  43.   for (size_t i = 0; i < _n + 1; i++) {
  44.     ar[i].resize(_m + 1);
  45.     for (size_t j = 0; j < _m + 1; j++) {
  46.       ar[i][j] = 0;
  47.     }
  48.   }
  49.   double r1 = 0;
  50.   int S = 0;         // счетчик итераций
  51.   double eps = _eps; // заданная точность
  52.   double eps_max = 0; // точность, достигнутая на текущей итерации
  53.   double eps_cur = 0; // для подсчета точности на текущей итерации
  54.   double a2, k2, h2; // ненулевые элементы матрицы (-А)
  55.   const int n = _n, m = _m; // размерность сетки
  56.   double r_max = 0;
  57.   double a = 0;
  58.   double b = 1;
  59.   double c = 0;
  60.   double d = 1; // границы области определения уравнения
  61.   int i, j; // индексы
  62.   double r = 0;
  63.   double v_old; // старое значение преобразуемой компоненты вектора
  64.   double v_new; // новое значение преобразуемой компоненты вектора и
  65.   bool flag = false; // условие остановки
  66.   double h = ((b - a) / n);
  67.   double k = ((d - c) / m);
  68.   double z = 0;
  69.   double z_max = 0;
  70.   double tau_s = 0;
  71.   double num = 0; // tau=num/denominator
  72.   double denominator = 1;
  73.   h2 = -std::pow((n / (b - a)), 2);
  74.   k2 = -std::pow((m / (d - c)), 2);
  75.   a2 = -2 * (h2 + k2);
  76.   for (int i = 0; i < n + 1; i++) {
  77.     v[i][0] = u(a + i * h, a);
  78.     v[i][m] = u(a + i * h, b);
  79.   }
  80.   for (int j = 0; j < m + 1; j++) {
  81.     v[0][j] = u(c, c + j * k);
  82.     v[n][j] = u(d, c + j * k);
  83.   }
  84.   do {
  85.     z = 0;
  86.     /* std::cout << "вектор невязки:" << std::endl; */
  87.     /* for (int i = n - 1; i >= 0; i--) { */
  88.     /*   for (int j = 0; j < m; j++) */
  89.     /*     std::cout << std::left << std::setw(10) << r_vec[i][j]; */
  90.     /*   std::cout << "\n"; */
  91.     /* } */
  92.     /* std::cout << "промежуточное решение:" << std::endl; */
  93.     /* for (int i = n - 1; i >= 0; i--) { */
  94.     /*   for (int j = 0; j < m; j++) */
  95.     /*     std::cout << std::left << std::setw(10) << v[i][j]; */
  96.     /*   std::cout << "\n"; */
  97.     /* } */
  98.     z_max = 0;
  99.     eps_max = 0;
  100.     r_max = -20;
  101.     num = 0;
  102.     denominator = 0;
  103.     for (j = 1; j < m; j++) {
  104.       for (i = n - 1; i > 0; i--) {
  105.         r_vec[i][j] = f(a + i * h, c + j * k) -
  106.                       (h2 * (v[i + 1][j] + v[i - 1][j]) +
  107.                        k2 * (v[i][j + 1] + v[i][j - 1]) + v[i][j] * a2);
  108.       }
  109.     }
  110.     for (j = 1; j < m; j++) {
  111.       for (i = n - 1; i > 0; i--) {
  112.         ar[i][j] =
  113.             (h2 * (r_vec[i + 1][j] + r_vec[i - 1][j]) +
  114.              k2 * (r_vec[i][j + 1] + r_vec[i][j - 1]) + r_vec[i][j] * a2);
  115.         num += ar[i][j] * r_vec[i][j];
  116.         denominator += ar[i][j] * ar[i][j];
  117.       }
  118.     }
  119.     tau_s = num / denominator;
  120.     for (j = 1; j < m; j++) {
  121.       for (i = n - 1; i > 0; i--) {
  122.         v_old = v[i][j];
  123.         v_new = v_old + tau_s * r_vec[i][j];
  124.         eps_cur = std::fabs(v_old - v_new);
  125.         if (eps_cur > eps_max) {
  126.           eps_max = eps_cur;
  127.         }
  128.         v[i][j] = v_new;
  129.         r = fabs(f(a + i * h, c + j * k) -
  130.                  (h2 * (v[i + 1][j] + v[i - 1][j]) +
  131.                   k2 * (v[i][j + 1] + v[i][j - 1]) + v_old * a2));
  132.         if (r > r_max)
  133.           r_max = r;
  134.         z = u(a + i * h, c + j * k) - v[i][j];
  135.         if (z > z_max)
  136.           z_max = z;
  137.       }
  138.     }
  139.  
  140.     S = S + 1;
  141.     if ((eps_max <= eps) or (S >= Nmax)) {
  142.       flag = true;
  143.     }
  144.   } while (!flag);
  145.  
  146.   std::cout << "\nСПРАВКА:" << std::endl;
  147.  
  148.   std::cout << "Количество выполненных итераций = " << S << std::endl;
  149.   std::cout << "Точность на выходе = " << eps_max << std::endl;
  150.   std::cout << "Невязка = " << r_max << std::endl;
  151.   std::cout << "Норма общей погрешности = " << z_max << std::endl;
  152.   return v;
  153. }
  154.  
  155. int main() {
  156.   int n = 100;
  157.   int m = 100;
  158.   std::vector<std::vector<double>> v(n, std::vector<double>(m, 0));
  159.   v = MinimalResiduals(100000, 0.000001, n, m);
  160.   n++;
  161.   m++;
  162.   /* std::cout << "Результат:" << std::endl; */
  163.   /* for (int i = n - 1; i >= 0; i--) { */
  164.   /*   for (int j = 0; j < m; j++) */
  165.   /*     std::cout << std::left << std::setw(10) << v[i][j]; */
  166.   /*   std::cout << "\n"; */
  167.   /* } */
  168.   return 0;
  169. }
  170.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement