codisinmyvines

Yacobi_OpenMP

May 21st, 2021
947
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.79 KB | None | 0 0
  1. #include <iostream>
  2. #include <omp.h>
  3. #include <cmath>
  4. #include <complex>
  5. #define pi 3.14159265
  6. #define eps 0.000001
  7. using namespace std;
  8.  
  9. complex<double> gamma(double n, const double& K)
  10. {
  11.     complex<double> res;
  12.     if (K * K >= pi * pi * n * n)
  13.     {
  14.         res = sqrt(K * K - pi * pi * n * n);
  15.     }
  16.     else
  17.     {
  18.         res = 1i * sqrt(pi * pi * n * n - K * K);
  19.     }
  20.     return res;
  21. }
  22. complex<double> Jnm(double n, double m, const double& a0, const double& a1)
  23. {
  24.     complex<double> res;
  25.     if (n == m)
  26.     {
  27.         res = a1 - a0 - ((sin((n + m) * pi * a1) - sin((n + m) * pi * a0)) / ((n + m) * pi));
  28.     }
  29.     else
  30.     {
  31.         res = (sin((n - m) * pi * a1) - sin((n - m) * pi * a0)) / ((n - m) * pi) - ((sin((n + m) * pi * a1) - sin((n + m) * pi * a0)) / ((n + m) * pi));
  32.     }
  33.     return res;
  34. }
  35. complex<double> Inm(double n, double m, const double& a0, const double& a1)
  36. {
  37.     complex<double> res;
  38.     if (n == m)
  39.     {
  40.         res = 1.0 - Jnm(n, m, a0, a1);
  41.     }
  42.     else
  43.     {
  44.         res = -Jnm(n, m, a0, a1);
  45.     }
  46.     return res;
  47. }
  48. complex<double> sumM(int i, int j, const int& N, const double& c, const double& a0, const double& a1, const double& K)
  49. {
  50.     complex<double>s;
  51.     for (int l = 0; l < N; l++)
  52.         s += gamma(l + 1, K) * Jnm(j + 1, l + 1, a0, a1) * Inm(l + 1, i + 1, a0, a1) / (1.0 - exp(2.0 * 1i * gamma(l + 1, K) * c));
  53.     return s;
  54. }
  55. void getAandb(const int&n, complex<double>** matrA, complex<double>* vecb, const int& N, const double& l, const double& K, const double& a0, const double& a1, const double& c)
  56. {
  57.     int i, j;
  58.     #pragma omp parallel num_threads(n) private(i,j)
  59.     {
  60.         #pragma omp for schedule(dynamic)
  61.         for (i = 0; i < N; i++)
  62.         {
  63.             for (j = 0; j < N; j++)
  64.             {
  65.                 if (i == j)
  66.                 {
  67.                     matrA[i][j] = gamma(i + 1, K) - (1.0 - exp(2.0 * 1i * gamma(i + 1, K) * c)) * sumM(i, j, N, c, a0, a1, K);
  68.                 }
  69.                 else
  70.                 {
  71.                     matrA[i][j] = -(1.0 - exp(2.0 * 1i * gamma(j + 1, K) * c)) * sumM(i, j, N, c, a0, a1, K);
  72.                 }
  73.             }
  74.         }
  75.         #pragma omp for
  76.         for (int i = 0; i < N; i++)
  77.             vecb[i] = gamma(l, K) * Inm(l, i + 1, a0, a1);
  78.     }
  79. }
  80. void show(complex<double>* x, int N)
  81. {
  82.     for (int i = 0; i < N; i++)
  83.         cout << abs(x[i]) << "\n";
  84.     cout << "\n";
  85. }
  86. void Yacobi(const int& n, const int& N, const double& c, const double& l, const double& a0, const double& a1, const double& K)
  87. {
  88.     complex<double>** matrA = new complex<double>* [N];//матрица коэффициентов
  89.     for (int i = 0; i < N; i++)
  90.         matrA[i] = new complex<double>[N];
  91.     complex<double>* F = new complex<double>[N];//столбец свободных членов
  92.     getAandb(n, matrA, F, N, l, K, a0, a1, c);
  93.     complex<double>* x = new complex<double>[N]; //начальное приближение, ответ также записывается в х
  94.     complex<double>* tempx = new complex<double>[N];
  95.     double norm;
  96.     do
  97.     {  
  98.         for (int i = 0; i < N; i++)
  99.         {  
  100.             tempx[i] = F[i];
  101.             for (int g = 0; g < N; g++)
  102.             {
  103.                 if (i != g)
  104.                     tempx[i] -= matrA[i][g] * x[g];
  105.             }
  106.             tempx[i] /= matrA[i][i];
  107.         }
  108.         norm = abs(x[0] - tempx[0]);
  109.         for (int h = 0; h < N; h++)
  110.         {
  111.             if (abs(x[h] - tempx[h]) > norm)
  112.                 norm = abs(x[h] - tempx[h]);
  113.             x[h] = tempx[h];
  114.         }
  115.     } while (norm > eps);
  116.     show(x, N);
  117.     delete[]x;
  118.     delete[]tempx;
  119.     delete[]F;
  120.     for (int i = 0; i < N; i++)
  121.         delete[]matrA[i];
  122.     delete[]matrA;
  123. }
  124. int main()
  125. {
  126.     setlocale(LC_ALL, "RU");
  127.     double c, l, a0, a1, K;
  128.     cout << "Введите параметры с, l, a0, a1, к cоответственно: \n";
  129.     cin >> c >> l >> a0 >> a1 >> K;
  130.     int n, N;
  131.     cout << "Введите размерность системы N: \n";
  132.     cin >> N;
  133.     cout << "Задайте количество потоков: \n";
  134.     cin >> n;
  135.     double start_time, end_time;
  136.     start_time = omp_get_wtime();
  137.     Yacobi(n, N, c, l, a0, a1, K);
  138.     end_time = omp_get_wtime();
  139.     cout << end_time - start_time << "\n";
  140.     return 0;
  141. }
Advertisement
Add Comment
Please, Sign In to add comment