GCC Code Coverage Report


Directory: ./
File: tasks/gauss_jordan/seq/src/ops_seq.cpp
Date: 2026-01-10 02:40:41
Exec Total Coverage
Lines: 92 105 87.6%
Functions: 15 15 100.0%
Branches: 84 120 70.0%

Line Branch Exec Source
1 #include "gauss_jordan/seq/include/ops_seq.hpp"
2
3 #include <algorithm>
4 #include <cmath>
5 #include <cstddef>
6 #include <vector>
7
8 #include "gauss_jordan/common/include/common.hpp"
9
10 namespace gauss_jordan {
11
12 namespace {
13 constexpr double kEpsilon = 1e-12;
14
15 void ExchangeRows(std::vector<std::vector<double>> &augmented_matrix, int first_row, int second_row, int columns) {
16 if (first_row == second_row) {
17 return;
18 }
19
20
2/2
✓ Branch 0 taken 176 times.
✓ Branch 1 taken 56 times.
232 for (int col_idx = 0; col_idx < columns; ++col_idx) {
21 176 std::swap(augmented_matrix[first_row][col_idx], augmented_matrix[second_row][col_idx]);
22 }
23 }
24
25 inline bool IsNumericallyZero(double value) {
26
13/14
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 288 times.
✓ Branch 2 taken 64 times.
✓ Branch 3 taken 224 times.
✓ Branch 4 taken 64 times.
✓ Branch 5 taken 160 times.
✓ Branch 6 taken 64 times.
✓ Branch 7 taken 96 times.
✓ Branch 8 taken 80 times.
✓ Branch 9 taken 160 times.
✓ Branch 10 taken 208 times.
✓ Branch 11 taken 208 times.
✓ Branch 12 taken 240 times.
✗ Branch 13 not taken.
1248 return std::fabs(value) < kEpsilon;
27 }
28
29 496 void EliminateFromRow(std::vector<std::vector<double>> &augmented_matrix, int target_row, int source_row,
30 double elimination_coefficient, int columns) {
31
1/2
✓ Branch 0 taken 496 times.
✗ Branch 1 not taken.
496 if (IsNumericallyZero(elimination_coefficient)) {
32 return;
33 }
34
35
2/2
✓ Branch 0 taken 3224 times.
✓ Branch 1 taken 496 times.
3720 for (int col_idx = 0; col_idx < columns; ++col_idx) {
36 3224 augmented_matrix[target_row][col_idx] -= elimination_coefficient * augmented_matrix[source_row][col_idx];
37 }
38 }
39
40 void NormalizeRow(std::vector<std::vector<double>> &augmented_matrix, int row_index, double normalizer, int columns) {
41
1/2
✓ Branch 0 taken 392 times.
✗ Branch 1 not taken.
392 if (IsNumericallyZero(normalizer)) {
42 return;
43 }
44
45
2/2
✓ Branch 0 taken 1920 times.
✓ Branch 1 taken 392 times.
2312 for (int col_idx = 0; col_idx < columns; ++col_idx) {
46 1920 augmented_matrix[row_index][col_idx] /= normalizer;
47 }
48 }
49
50 // Разбиваем сложную функцию на более простые
51 int FindPivotRow(const std::vector<std::vector<double>> &augmented_matrix, int current_row, int current_col,
52 int equations_count) {
53 int pivot_row = current_row;
54 392 double max_val = std::abs(augmented_matrix[current_row][current_col]);
55
56
2/2
✓ Branch 0 taken 568 times.
✓ Branch 1 taken 392 times.
960 for (int i = current_row + 1; i < equations_count; i++) {
57
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 504 times.
568 double val = std::abs(augmented_matrix[i][current_col]);
58
2/2
✓ Branch 0 taken 64 times.
✓ Branch 1 taken 504 times.
568 if (val > max_val) {
59 max_val = val;
60 pivot_row = i;
61 }
62 }
63
64 return pivot_row;
65 }
66
67 bool ShouldSkipColumn(double max_val) {
68 return IsNumericallyZero(max_val);
69 }
70
71 392 void ProcessPivotRow(std::vector<std::vector<double>> &augmented_matrix, int current_row, int current_col,
72 int pivot_row, int augmented_columns) {
73
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 336 times.
392 if (pivot_row != current_row) {
74 ExchangeRows(augmented_matrix, current_row, pivot_row, augmented_columns);
75 }
76
77
1/2
✓ Branch 0 taken 392 times.
✗ Branch 1 not taken.
392 double pivot_value = augmented_matrix[current_row][current_col];
78 NormalizeRow(augmented_matrix, current_row, pivot_value, augmented_columns);
79 392 }
80
81 392 void EliminateFromOtherRows(std::vector<std::vector<double>> &augmented_matrix, int current_row, int current_col,
82 int equations_count, int augmented_columns) {
83
2/2
✓ Branch 0 taken 1528 times.
✓ Branch 1 taken 392 times.
1920 for (int row_idx = 0; row_idx < equations_count; row_idx++) {
84
2/2
✓ Branch 0 taken 392 times.
✓ Branch 1 taken 1136 times.
1528 if (row_idx == current_row) {
85 392 continue;
86 }
87
88
2/2
✓ Branch 0 taken 496 times.
✓ Branch 1 taken 640 times.
1136 double coefficient = augmented_matrix[row_idx][current_col];
89
2/2
✓ Branch 0 taken 496 times.
✓ Branch 1 taken 640 times.
1136 if (!IsNumericallyZero(coefficient)) {
90 496 EliminateFromRow(augmented_matrix, row_idx, current_row, coefficient, augmented_columns);
91 }
92 }
93 392 }
94
95 // Упрощенная основная функция с меньшей когнитивной сложностью
96 128 void TransformToReducedRowEchelonForm(std::vector<std::vector<double>> &augmented_matrix, int equations_count,
97 int augmented_columns) {
98 int current_row = 0;
99
100
3/4
✓ Branch 0 taken 392 times.
✓ Branch 1 taken 128 times.
✓ Branch 2 taken 392 times.
✗ Branch 3 not taken.
520 for (int current_col = 0; current_col < augmented_columns - 1 && current_row < equations_count; current_col++) {
101 int pivot_row = FindPivotRow(augmented_matrix, current_row, current_col, equations_count);
102
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 392 times.
392 double max_val = std::abs(augmented_matrix[pivot_row][current_col]);
103
104
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 392 times.
392 if (ShouldSkipColumn(max_val)) {
105 continue;
106 }
107
108 392 ProcessPivotRow(augmented_matrix, current_row, current_col, pivot_row, augmented_columns);
109 392 EliminateFromOtherRows(augmented_matrix, current_row, current_col, equations_count, augmented_columns);
110
111 current_row++;
112 }
113 128 }
114
115 784 bool IsZeroRow(const std::vector<double> &row, int columns_minus_one) {
116 return std::all_of(row.begin(), row.begin() + columns_minus_one,
117 784 [](double element) { return IsNumericallyZero(element); });
118 }
119
120 128 bool HasInconsistentEquation(const std::vector<std::vector<double>> &augmented_matrix, int equations_count,
121 int augmented_columns) {
122
2/2
✓ Branch 0 taken 392 times.
✓ Branch 1 taken 128 times.
520 for (int row_idx = 0; row_idx < equations_count; ++row_idx) {
123
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 392 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
392 if (IsZeroRow(augmented_matrix[row_idx], augmented_columns - 1) &&
124 !IsNumericallyZero(augmented_matrix[row_idx][augmented_columns - 1])) {
125 return true;
126 }
127 }
128 return false;
129 }
130
131 128 int ComputeMatrixRank(const std::vector<std::vector<double>> &augmented_matrix, int equations_count,
132 int augmented_columns) {
133 int rank = 0;
134
2/2
✓ Branch 0 taken 392 times.
✓ Branch 1 taken 128 times.
520 for (int row_idx = 0; row_idx < equations_count; ++row_idx) {
135
1/2
✓ Branch 0 taken 392 times.
✗ Branch 1 not taken.
392 if (!IsZeroRow(augmented_matrix[row_idx], augmented_columns - 1)) {
136 392 ++rank;
137 }
138 }
139 128 return rank;
140 }
141
142
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 bool ValidateMatrixDimensions(const std::vector<std::vector<double>> &matrix) {
143
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 if (matrix.empty()) {
144 return false;
145 }
146
147 size_t expected_cols = matrix[0].size();
148
2/2
✓ Branch 0 taken 264 times.
✓ Branch 1 taken 128 times.
392 for (size_t i = 1; i < matrix.size(); ++i) {
149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 264 times.
264 if (matrix[i].size() != expected_cols) {
150 return false;
151 }
152 }
153 return true;
154 }
155
156 bool CheckIfZeroMatrix(const std::vector<std::vector<double>> &matrix) {
157
1/2
✓ Branch 0 taken 128 times.
✗ Branch 1 not taken.
128 for (const auto &row : matrix) {
158
3/4
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 128 times.
✓ Branch 2 taken 144 times.
✗ Branch 3 not taken.
144 for (double val : row) {
159
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 128 times.
144 if (std::abs(val) > kEpsilon) {
160 return false;
161 }
162 }
163 }
164 return true;
165 }
166
167 128 bool CanSystemBeSolved(const std::vector<std::vector<double>> &matrix, int equations_count, int augmented_columns) {
168
1/2
✓ Branch 0 taken 128 times.
✗ Branch 1 not taken.
128 if (HasInconsistentEquation(matrix, equations_count, augmented_columns)) {
169 return false;
170 }
171
172 128 int matrix_rank = ComputeMatrixRank(matrix, equations_count, augmented_columns);
173 128 int variable_count = augmented_columns - 1;
174
175 // Исправлено: упрощение булевого выражения по Де Моргану
176 128 return matrix_rank >= variable_count || matrix_rank >= equations_count;
177 }
178
179 128 std::vector<double> ComputeSolutionVector(const std::vector<std::vector<double>> &matrix, int n, int m) {
180 128 std::vector<double> solution(m - 1, 0.0);
181 int vars = m - 1;
182 128 int rows_to_process = (n < vars) ? n : vars;
183
184
2/2
✓ Branch 0 taken 392 times.
✓ Branch 1 taken 128 times.
520 for (int i = 0; i < rows_to_process; ++i) {
185 int pivot_col = -1;
186
187
1/2
✓ Branch 0 taken 960 times.
✗ Branch 1 not taken.
960 for (int j = 0; j < vars; ++j) {
188
2/2
✓ Branch 0 taken 568 times.
✓ Branch 1 taken 392 times.
960 if (std::abs(matrix[i][j]) > 1e-10) {
189 pivot_col = j;
190 break;
191 }
192 }
193
1/2
✓ Branch 0 taken 392 times.
✗ Branch 1 not taken.
392 if (pivot_col >= 0) {
194 392 solution[pivot_col] = matrix[i][vars];
195 } else {
196 solution[i] = 0.0;
197 }
198 }
199
200 128 return solution;
201 }
202
203 } // namespace
204
205
1/2
✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
128 GaussJordanSEQ::GaussJordanSEQ(const InType &input) {
206 SetTypeOfTask(GetStaticTypeOfTask());
207
1/2
✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
128 InType matrix_copy(input);
208 GetInput().swap(matrix_copy);
209 128 }
210
211
1/2
✓ Branch 0 taken 128 times.
✗ Branch 1 not taken.
128 bool GaussJordanSEQ::ValidationImpl() {
212 const auto &input_matrix = GetInput();
213
214
1/2
✓ Branch 0 taken 128 times.
✗ Branch 1 not taken.
128 if (input_matrix.empty()) {
215 return true;
216 }
217
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 if (!GetOutput().empty()) {
218 return false;
219 }
220
221 size_t column_count = input_matrix[0].size();
222
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 if (column_count == 0) {
223 return false;
224 }
225
226 size_t total_elements = 0;
227
2/2
✓ Branch 0 taken 392 times.
✓ Branch 1 taken 128 times.
520 for (const auto &row : input_matrix) {
228 392 total_elements += row.size();
229
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 392 times.
392 if (row.size() != column_count) {
230 return false;
231 }
232 }
233
234 128 return total_elements == (column_count * input_matrix.size());
235 }
236
237
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 bool GaussJordanSEQ::PreProcessingImpl() {
238 GetOutput().clear();
239 128 return true;
240 }
241
242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 bool GaussJordanSEQ::RunImpl() {
243 const auto &input_matrix = GetInput();
244
245
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 if (input_matrix.empty()) {
246 GetOutput() = std::vector<double>();
247 return true;
248 }
249
250
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 if (!ValidateMatrixDimensions(input_matrix)) {
251 GetOutput() = std::vector<double>();
252 return true;
253 }
254
255 128 int equations_count = static_cast<int>(input_matrix.size());
256 128 int augmented_columns = static_cast<int>(input_matrix[0].size());
257
258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 if (augmented_columns <= 1) {
259 GetOutput() = std::vector<double>();
260 return true;
261 }
262
263
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 if (CheckIfZeroMatrix(input_matrix)) {
264 GetOutput() = std::vector<double>();
265 return true;
266 }
267
268 128 std::vector<std::vector<double>> augmented_matrix = input_matrix;
269
270 128 TransformToReducedRowEchelonForm(augmented_matrix, equations_count, augmented_columns);
271
272
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 128 times.
128 if (!CanSystemBeSolved(augmented_matrix, equations_count, augmented_columns)) {
273 GetOutput() = std::vector<double>();
274 return true;
275 }
276
277
1/2
✓ Branch 1 taken 128 times.
✗ Branch 2 not taken.
128 GetOutput() = ComputeSolutionVector(augmented_matrix, equations_count, augmented_columns);
278 128 return true;
279 128 }
280
281 128 bool GaussJordanSEQ::PostProcessingImpl() {
282 128 return true;
283 }
284 } // namespace gauss_jordan
285