HICONT

gauss.cpp

Nov 14th, 2023
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.69 KB | None | 0 0
  1. // Copyright 2023 Soloninko Andrey
  2.  
  3. #include "task_2/soloninko_a_gauss_horizontal/Gauss.h"
  4.  
  5. #include <random>
  6. #include <vector>
  7.  
  8. /*
  9. int GetRow(const int &rank, const int &comm_size, const int &size) {
  10. int segment = size / comm_size;
  11. if (size % comm_size) {
  12. segment++;
  13. }
  14. int m = comm_size * segment - size;
  15. int row = segment;
  16. if (rank >= comm_size - m) {
  17. row = segment - 1;
  18. }
  19. return row;
  20. }
  21. */
  22.  
  23. std::vector<double> set_matrix_rand(const int size) {
  24. std::vector<double> matrix(size * (size + 1));
  25. std::random_device random_device;
  26. std::uniform_int_distribution<int> unif(-100, 100);
  27.  
  28. for (int i = 0; i < size; i++) {
  29. for (int j = 0; j < size; j++) {
  30. matrix[i * (size + 1) + j] = unif(random_device);
  31. }
  32. }
  33.  
  34. return matrix;
  35. }
  36.  
  37. bool check_res(const std::vector<double>& matrix, const std::vector<double>& vec,
  38. const int& size) {
  39. for (int i = 0; i < size; i++) {
  40. double row_sum = 0;
  41. for (int j = 0; j < size; j++) {
  42. row_sum += matrix[i * (size + 1) + size] * vec[j];
  43. }
  44. if (std::abs(row_sum - matrix[i * (size + 1) + size]) > 0.0001) {
  45. return false;
  46. }
  47. }
  48. return true;
  49. }
  50.  
  51. std::vector<double> gauss(const std::vector<double>& matrix, int matrix_size) {
  52. int rank;
  53. int proc_c;
  54. MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  55. MPI_Comm_size(MPI_COMM_WORLD, &proc_c);
  56. std::vector<double> matrix_g = matrix;
  57. matrix_g = set_matrix_rand(matrix_size);
  58.  
  59. std::vector<double> res(matrix_size);
  60.  
  61. int segment = matrix_size / proc_c;
  62. if (matrix_size % proc_c != 0) {
  63. segment++;
  64. }
  65.  
  66. std::vector<int> rows(segment);
  67. std::vector<double> tmp(matrix_size + 1);
  68.  
  69. for (int i = 0; i < segment; i++) rows[i] = rank + proc_c * i;
  70.  
  71. int row = 0;
  72. for (int i = 0; i < matrix_size - 1; i++) {
  73. if (i == rows[row]) {
  74. MPI_Bcast(&matrix_g[rows[row] * (matrix_size + 1)], matrix_size + 1,
  75. MPI_DOUBLE, rank, MPI_COMM_WORLD);
  76. for (int j = 0; j <= matrix_size; j++)
  77. tmp[j] = matrix_g[rows[row] * (matrix_size + 1) + j];
  78. row++;
  79. } else {
  80. MPI_Bcast(tmp.data(), matrix_size + 1, MPI_DOUBLE, i % proc_c,
  81. MPI_COMM_WORLD);
  82. }
  83.  
  84. for (int j = row; j < segment; j++) {
  85. double scaling = matrix_g[rows[j] * (matrix_size + 1) + i] / tmp[i];
  86. for (int k = i; k < matrix_size + 1; k++)
  87. matrix_g[rows[j] * (matrix_size + 1) + k] -= scaling * tmp[k];
  88. }
  89. }
  90.  
  91. row = 0;
  92. for (int i = 0; i < matrix_size; i++) {
  93. res[i] = 0;
  94. if (i == rows[row]) {
  95. res[i] = matrix_g[i * (matrix_size + 1) + matrix_size];
  96. row++;
  97. }
  98. }
  99.  
  100. row = proc_c - 1;
  101. for (int i = matrix_size - 1; i > 0; i--) {
  102. if (row >= 0) {
  103. if (i == rows[row]) {
  104. res[i] /= matrix_g[i * (matrix_size + 1) + i];
  105. MPI_Bcast(&(res.data())[i], 1, MPI_DOUBLE, rank,
  106. MPI_COMM_WORLD);
  107. row--;
  108. } else {
  109. MPI_Bcast(&(res.data())[i], 1, MPI_DOUBLE, i % proc_c,
  110. MPI_COMM_WORLD);
  111. }
  112. } else {
  113. MPI_Bcast(&(res.data())[i], 1, MPI_DOUBLE, i % proc_c,
  114. MPI_COMM_WORLD);
  115. }
  116.  
  117. for (int j = 0; j <= row; j++)
  118. res[rows[j]] -= matrix_g[rows[j] * (matrix_size + 1) + i] * res[i];
  119. }
  120.  
  121. if (rank == 0) res[0] /= matrix_g[rows[row] * (matrix_size + 1)];
  122.  
  123. return res;
  124. }
  125.  
Advertisement
Add Comment
Please, Sign In to add comment