Advertisement
Guest User

Untitled

a guest
Feb 27th, 2020
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.92 KB | None | 0 0
  1. #include <iostream>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5.  
  6. #include <mpi.h>
  7.  
  8. using namespace std;
  9.  
  10. int main(int argc, char** argv)
  11. {
  12. int rank, commSize;
  13.  
  14. MPI_Init(&argc, &argv);
  15. MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  16. MPI_Comm_size(MPI_COMM_WORLD, &commSize);
  17.  
  18.  
  19. double** A, * x, * b, * xnew, eps, min, max, tau = 0.01, norm = 0, norm_b = 0, sum = 0;
  20. int i, j, n, t = 0;
  21.  
  22. cin >> n;
  23. cin >> eps; // 10^-5
  24.  
  25. A = (double**)malloc(n * sizeof(double*)); // матрица указателей на указатели-заполняем матрицу по строчкам, у нас двумерная,поэтому **
  26. x = (double*)calloc(n, sizeof(double));
  27. b = (double*)malloc(n * sizeof(double));
  28. xnew = (double*)malloc(n * sizeof(double));
  29.  
  30. for (i = 0; i < n; i++)
  31. A[i] = (double*)malloc(n * sizeof(double));//выделение памяти для указателей
  32.  
  33. for (i = 0; i < n; i++)
  34. for (j = 0; j < n; j++)
  35. cin >> A[i][j];
  36. for(i = 0; i < n; i++)
  37. cin >> b[i];
  38.  
  39. for (i = 0; i < n; i++)
  40. sum += b[i] * b[i];
  41. norm_b = sqrt(sum); // норма b
  42. double norm_0;
  43.  
  44. //
  45.  
  46. int *index = new int[commSize];
  47. int *count = new int[commSize];
  48.  
  49. int rest_rows = n;
  50. int row_number = n / commSize;
  51.  
  52. count[0] = row_number * n;
  53. index[0] = 0;
  54.  
  55. for (int i = 1; i < commSize; i++)
  56. {
  57. rest_rows -= row_number;
  58. row_number = rest_rows / (commSize - i);
  59. count[i] = row_number * n;
  60. index[i] = index[i - 1] + count[i - 1];
  61. }
  62.  
  63.  
  64. double *cur_row = new double[count[rank]];
  65.  
  66. MPI_Scatterv(A, count, index, MPI_DOUBLE, cur_row, count[rank], MPI_DOUBLE, 0, MPI_COMM_WORLD);
  67.  
  68.  
  69. double *res_part = new double[count[rank]];
  70.  
  71. for (int i = 0; i < count[rank] / n; i++)
  72. {
  73. res_part[i] = 0;
  74.  
  75. for (int j = 0; j < n; j++)
  76. {
  77. res_part[i] += cur_row[j + i * n] * x[j];
  78. }
  79. }
  80.  
  81. for (int i = 0; i < commSize; i++)
  82. {
  83. index[i] /= n;
  84. count[i] /= n;
  85. }
  86.  
  87. MPI_Allgatherv(res_part, count[rank], MPI_DOUBLE, xnew, count, index, MPI_DOUBLE, MPI_COMM_WORLD);
  88.  
  89.  
  90. delete[] index;
  91. delete[] cur_row;
  92. delete[] res_part;
  93. delete[] count;
  94.  
  95. //
  96.  
  97. for (i = 0; i < n; i++)
  98. xnew[i] = xnew[i] - b[i];
  99. for (i = 0; i < n; i++)
  100. sum += xnew[i] * xnew[i];
  101. norm_0 = sqrt(sum); // ||Ax_0 - b||
  102. for (i = 0; i < n; i++)
  103. xnew[i] = -tau * xnew[i];
  104. for (i = 0; i < n; i++)
  105. xnew[i] = x[i] + xnew[i];
  106. for (i = 0; i < n; i++)
  107. x[i] = xnew[i];
  108.  
  109. sum = 0;
  110. for(i = 0; i < n; i++)
  111. {
  112. xnew[i] = 0;// обнуляем
  113. for (j = 0; j < n; j++)
  114. xnew[i] += A[i][j] * x[j];
  115. }
  116. for (i = 0; i < n; i++)
  117. xnew[i] = xnew[i] - b[i];
  118. for (i = 0; i < n; i++)
  119. sum += xnew[i] * xnew[i];
  120. norm = sqrt(sum); // ||Ax_1 - b||
  121.  
  122. if (norm_0 <= norm)
  123. tau = -tau;
  124.  
  125. norm /= norm_b;
  126. while (norm >= eps)
  127. {
  128. sum = 0;
  129. for (i = 0; i < n; i++)
  130. {
  131. xnew[i] = 0;// обнуляем
  132. for (j = 0; j < n; j++)
  133. xnew[i] += A[i][j] * x[j];
  134. }
  135. for (i = 0; i < n; i++)
  136. xnew[i] = xnew[i] - b[i];
  137. for (i = 0; i < n; i++)
  138. sum += xnew[i] * xnew[i];
  139. norm = sqrt(sum)/norm_b;
  140. for (i = 0; i < n; i++)
  141. xnew[i] = -tau * xnew[i];
  142. for (i = 0; i < n; i++)
  143. xnew[i] = x[i] + xnew[i];
  144. for (i = 0; i < n; i++)
  145. x[i] = xnew[i];
  146. }
  147.  
  148. cout << "Решения уравнений: " << "\n";
  149. for (i = 0; i < n; i++)
  150. cout << "x[" << i << "] = " << xnew[i] << "\n";
  151.  
  152. MPI_Finalize();
  153. return 0;
  154. }
  155. //
  156. //3
  157. //0.001
  158. //1 0 0 1
  159. //0 1 0 2
  160. //0 0 1 3
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement