| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "shkryleva_s_seidel_method/seq/include/ops_seq.hpp" | ||
| 2 | |||
| 3 | #include <algorithm> | ||
| 4 | #include <cmath> | ||
| 5 | #include <numeric> | ||
| 6 | #include <random> | ||
| 7 | #include <vector> | ||
| 8 | |||
| 9 | #include "shkryleva_s_seidel_method/common/include/common.hpp" | ||
| 10 | |||
| 11 | namespace shkryleva_s_seidel_method { | ||
| 12 | |||
| 13 | 80 | ShkrylevaSSeidelMethodSEQ::ShkrylevaSSeidelMethodSEQ(const InType &in) { | |
| 14 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 15 | 80 | GetInput() = in; | |
| 16 | GetOutput() = 0; | ||
| 17 | 80 | } | |
| 18 | |||
| 19 | 80 | bool ShkrylevaSSeidelMethodSEQ::ValidationImpl() { | |
| 20 | 80 | n_ = GetInput(); | |
| 21 | 80 | return (n_ > 0); | |
| 22 | } | ||
| 23 | |||
| 24 | 80 | bool ShkrylevaSSeidelMethodSEQ::PreProcessingImpl() { | |
| 25 | 80 | GetOutput() = 0; | |
| 26 | 80 | return true; | |
| 27 | } | ||
| 28 | |||
| 29 | 80 | bool ShkrylevaSSeidelMethodSEQ::RunImpl() { | |
| 30 | 80 | GenerateRandomMatrix(n_, A_, b_); | |
| 31 | |||
| 32 | 80 | ComputeRightHandSide(n_, A_, b_); | |
| 33 | |||
| 34 | 80 | epsilon_ = 1e-6; | |
| 35 | 80 | max_iterations_ = 10000; | |
| 36 | 80 | x_.assign(n_, 0.0); | |
| 37 | |||
| 38 | int iteration = 0; | ||
| 39 | bool converged = false; | ||
| 40 | |||
| 41 |
3/4✓ Branch 0 taken 981 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 901 times.
✓ Branch 3 taken 80 times.
|
981 | while (iteration < max_iterations_ && !converged) { |
| 42 | 901 | double max_diff = PerformSeidelIteration(n_, A_, b_, x_); | |
| 43 | 901 | converged = (max_diff < epsilon_); | |
| 44 | 901 | ++iteration; | |
| 45 | } | ||
| 46 | |||
| 47 | double sum = std::accumulate(x_.begin(), x_.end(), 0.0); | ||
| 48 | 80 | GetOutput() = static_cast<int>(std::round(sum)); | |
| 49 | |||
| 50 | 80 | return true; | |
| 51 | } | ||
| 52 | |||
| 53 | 80 | bool ShkrylevaSSeidelMethodSEQ::PostProcessingImpl() { | |
| 54 | 80 | return true; | |
| 55 | } | ||
| 56 | |||
| 57 | 80 | void ShkrylevaSSeidelMethodSEQ::GenerateRandomMatrix(int size, std::vector<std::vector<double>> &matrix, | |
| 58 | std::vector<double> &vector) { | ||
| 59 | 80 | matrix.resize(size); | |
| 60 |
2/2✓ Branch 0 taken 1168 times.
✓ Branch 1 taken 80 times.
|
1248 | for (int i = 0; i < size; ++i) { |
| 61 | 1168 | matrix[i].assign(size, 0.0); | |
| 62 | } | ||
| 63 | 80 | vector.resize(size, 0.0); | |
| 64 | |||
| 65 | 80 | std::random_device rd; | |
| 66 | 80 | std::mt19937 gen(rd()); | |
| 67 | std::uniform_int_distribution<> dist(1, 10); | ||
| 68 | std::uniform_int_distribution<> dist_diag(1, 5); | ||
| 69 | |||
| 70 |
2/2✓ Branch 0 taken 1168 times.
✓ Branch 1 taken 80 times.
|
1248 | for (int i = 0; i < size; ++i) { |
| 71 | double row_sum = 0.0; | ||
| 72 |
2/2✓ Branch 0 taken 28112 times.
✓ Branch 1 taken 1168 times.
|
29280 | for (int j = 0; j < size; ++j) { |
| 73 |
2/2✓ Branch 0 taken 26944 times.
✓ Branch 1 taken 1168 times.
|
28112 | if (i != j) { |
| 74 | 26944 | matrix[i][j] = static_cast<double>(dist(gen)); | |
| 75 | 26944 | row_sum += std::abs(matrix[i][j]); | |
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | 1168 | matrix[i][i] = row_sum + static_cast<double>(dist_diag(gen)); | |
| 80 | } | ||
| 81 | 80 | } | |
| 82 | |||
| 83 | 80 | void ShkrylevaSSeidelMethodSEQ::ComputeRightHandSide(int n, const std::vector<std::vector<double>> &a, | |
| 84 | std::vector<double> &b) { | ||
| 85 | 80 | std::vector<double> x_exact(n, 1.0); | |
| 86 |
1/4✓ Branch 1 taken 80 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
|
80 | b.assign(n, 0.0); |
| 87 | |||
| 88 |
2/2✓ Branch 0 taken 1168 times.
✓ Branch 1 taken 80 times.
|
1248 | for (int i = 0; i < n; ++i) { |
| 89 |
2/2✓ Branch 0 taken 28112 times.
✓ Branch 1 taken 1168 times.
|
29280 | for (int j = 0; j < n; ++j) { |
| 90 | 28112 | b[i] += a[i][j] * x_exact[j]; | |
| 91 | } | ||
| 92 | } | ||
| 93 | 80 | } | |
| 94 | |||
| 95 | 901 | double ShkrylevaSSeidelMethodSEQ::PerformSeidelIteration(int n, const std::vector<std::vector<double>> &a, | |
| 96 | const std::vector<double> &b, std::vector<double> &x) { | ||
| 97 | 901 | double max_diff = 0.0; | |
| 98 | |||
| 99 |
2/2✓ Branch 0 taken 13370 times.
✓ Branch 1 taken 901 times.
|
14271 | for (int i = 0; i < n; ++i) { |
| 100 | 13370 | const double old = x[i]; | |
| 101 | double sum_off_diag = 0.0; | ||
| 102 | |||
| 103 |
2/2✓ Branch 0 taken 319904 times.
✓ Branch 1 taken 13370 times.
|
333274 | for (int j = 0; j < n; ++j) { |
| 104 |
2/2✓ Branch 0 taken 306534 times.
✓ Branch 1 taken 13370 times.
|
319904 | if (i != j) { |
| 105 | 306534 | sum_off_diag += a[i][j] * x[j]; | |
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | 13370 | x[i] = (b[i] - sum_off_diag) / a[i][i]; | |
| 110 | 13370 | const double diff = std::abs(x[i] - old); | |
| 111 | 13370 | max_diff = std::max(diff, max_diff); | |
| 112 | } | ||
| 113 | |||
| 114 | 901 | return max_diff; | |
| 115 | } | ||
| 116 | |||
| 117 | } // namespace shkryleva_s_seidel_method | ||
| 118 |