HICONT

gauss(other, finished)

Nov 22nd, 2023 (edited)
657
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.26 KB | None | 0 0
  1. // Copyright 2023 Soloninko Andrey
  2.  
  3. #include <iostream>
  4. #include <random>
  5. #include <vector>
  6. #include "task_2/soloninko_a_gauss_horizontal/Gauss.h"
  7.  
  8.  
  9. int get_slice(int size, int proc_count, int rank) {
  10.     int q = size / proc_count;
  11.     if (size % proc_count)
  12.         q++;
  13.     int r = proc_count * q - size;
  14.  
  15.     int slice = q;
  16.     if (rank >= proc_count - r)
  17.         slice = q - 1;
  18.     return slice;
  19. }
  20.  
  21. bool check_res(std::vector<double>& matrix, std::vector<double>& x, int size) {
  22.     for (int i = 0; i < size; i++) {
  23.         double sum = 0;
  24.         for (int j = 0; j < size; j++)
  25.             sum += matrix[i * (size + 1) + j] * x[j];
  26.  
  27.         if (std::abs(sum - matrix[i * (size + 1) + size]) > 0.0001)
  28.             return false;
  29.     }
  30.     return true;
  31. }
  32.  
  33. std::vector<double> rand_matr(int size) {
  34.     std::random_device rd;
  35.     std::uniform_int_distribution<int> unif(-100, 100);
  36.     std::vector<double> matrix((size + 1) * size);
  37.     int i, j;
  38.     for (i = 0; i < size; i++)
  39.         for (j = 0; j < size + 1; j++)
  40.             matrix[i * (size + 1) + j] = unif(rd);
  41.  
  42.     return matrix;
  43. }
  44.  
  45. std::vector<double> Gauss(std::vector<double>& matrix, int size) {
  46.     int rank, comm_size;
  47.     MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  48.     MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
  49.  
  50.     std::vector<double> Xi(size, 0.0);  // Инициализация вектора нулями
  51.  
  52.     int nrows = get_slice(size, comm_size, rank);
  53.     std::vector<int> rows(nrows);
  54.     std::vector<double> tmp(size + 1);
  55.  
  56.     for (int i = 0; i < nrows; i++)
  57.         rows[i] = rank + comm_size * i;
  58.  
  59.     MPI_Bcast(matrix.data(), size * (size + 1), MPI_DOUBLE, 0, MPI_COMM_WORLD);
  60.  
  61.     int row = 0;
  62.     for (int i = 0; i < size - 1; i++) {
  63.         if (i == rows[row]) {
  64.             MPI_Bcast(&matrix.data()[rows[row] * (size + 1)], size + 1, MPI_DOUBLE, rank, MPI_COMM_WORLD);
  65.             for (int j = 0; j <= size; j++)
  66.                 tmp[j] = matrix[rows[row] * (size + 1) + j];
  67.             row++;
  68.         } else {
  69.             MPI_Bcast(tmp.data(), size + 1, MPI_DOUBLE, i % comm_size, MPI_COMM_WORLD);
  70.         }
  71.  
  72.         for (int j = row; j < nrows; j++) {
  73.             double scaling = matrix[rows[j] * (size + 1) + i] / tmp[i];
  74.             for (int k = i; k < size + 1; k++)
  75.                 matrix[rows[j] * (size + 1) + k] -= scaling * tmp[k];
  76.         }
  77.     }
  78.  
  79.     row = 0;
  80.     for (int i = 0; i < size; i++) {
  81.         if (i == rows[row]) {
  82.             Xi[i] = matrix[i * (size + 1) + size];
  83.             row++;
  84.         }
  85.     }
  86.  
  87.     row = nrows - 1;
  88.     for (int i = size - 1; i > 0; i--) {
  89.         if (row >= 0) {
  90.             if (i == rows[row]) {
  91.                 Xi[i] /= matrix[i * (size + 1) + i];
  92.                 MPI_Bcast(&(Xi.data())[i], 1, MPI_DOUBLE, rank, MPI_COMM_WORLD);
  93.                 row--;
  94.             } else {
  95.                 MPI_Bcast(&(Xi.data())[i], 1, MPI_DOUBLE, i % comm_size, MPI_COMM_WORLD);
  96.             }
  97.         } else {
  98.             MPI_Bcast(&(Xi.data())[i], 1, MPI_DOUBLE, i % comm_size, MPI_COMM_WORLD);
  99.         }
  100.  
  101.         for (int j = 0; j <= row; j++)
  102.             Xi[rows[j]] -= matrix[rows[j] * (size + 1) + i] * Xi[i];
  103.     }
  104.  
  105.     if (rank == 0)
  106.         Xi[0] /= matrix[rows[row] * (size + 1)];
  107.  
  108.     return Xi;
  109. }
Advertisement
Add Comment
Please, Sign In to add comment