Advertisement
vatman

mmn_main_func

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