| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #include "lobanov_d_multi_matrix_crs/seq/include/ops_seq.hpp" | ||
| 2 | |||
| 3 | #include <cmath> | ||
| 4 | #include <cstddef> | ||
| 5 | #include <exception> | ||
| 6 | #include <vector> | ||
| 7 | |||
| 8 | #include "lobanov_d_multi_matrix_crs/common/include/common.hpp" | ||
| 9 | |||
| 10 | namespace lobanov_d_multi_matrix_crs { | ||
| 11 | |||
| 12 | constexpr double kEpsilonThreshold = 1e-12; | ||
| 13 | |||
| 14 | ✗ | LobanovMultyMatrixSEQ::LobanovMultyMatrixSEQ(const InType &input_matrices) { | |
| 15 | SetTypeOfTask(GetStaticTypeOfTask()); | ||
| 16 | GetInput() = input_matrices; | ||
| 17 | ✗ | CompressedRowMatrix empty_matrix; | |
| 18 | empty_matrix.row_count = 0; | ||
| 19 | empty_matrix.column_count = 0; | ||
| 20 | empty_matrix.non_zero_count = 0; | ||
| 21 | ✗ | GetOutput() = empty_matrix; | |
| 22 | ✗ | } | |
| 23 | |||
| 24 | ✗ | bool LobanovMultyMatrixSEQ::ValidationImpl() { | |
| 25 | const auto &[matrix_a, matrix_b] = GetInput(); | ||
| 26 | ✗ | return (matrix_a.row_count > 0 && matrix_a.column_count > 0 && matrix_b.row_count > 0 && matrix_b.column_count > 0 && | |
| 27 | ✗ | matrix_a.column_count == matrix_b.row_count); | |
| 28 | } | ||
| 29 | |||
| 30 | ✗ | bool LobanovMultyMatrixSEQ::PreProcessingImpl() { | |
| 31 | ✗ | return true; | |
| 32 | } | ||
| 33 | |||
| 34 | namespace { | ||
| 35 | |||
| 36 | ✗ | void MultiplyRowByMatrix(const std::vector<double> &a_row_values, const std::vector<int> &a_row_columns, | |
| 37 | const CompressedRowMatrix &matrix_b, std::vector<double> &temp_row, | ||
| 38 | std::vector<int> &temp_col_markers, int row_index, std::vector<double> &result_values, | ||
| 39 | std::vector<int> &result_col_indices, int &result_row_start) { | ||
| 40 | ✗ | for (size_t i = 0; i < temp_row.size(); ++i) { | |
| 41 | ✗ | if (temp_col_markers[i] == row_index) { | |
| 42 | ✗ | temp_row[i] = 0.0; | |
| 43 | ✗ | temp_col_markers[i] = -1; | |
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | // Умножаем строку A на матрицу B | ||
| 48 | ✗ | for (size_t k = 0; k < a_row_columns.size(); ++k) { | |
| 49 | ✗ | int b_row = a_row_columns[k]; | |
| 50 | ✗ | double a_value = a_row_values[k]; | |
| 51 | |||
| 52 | ✗ | for (int b_ptr = matrix_b.row_pointer_data[b_row]; b_ptr < matrix_b.row_pointer_data[b_row + 1]; ++b_ptr) { | |
| 53 | ✗ | int b_col = matrix_b.column_index_data[b_ptr]; | |
| 54 | ✗ | double b_value = matrix_b.value_data[b_ptr]; | |
| 55 | |||
| 56 | ✗ | if (temp_col_markers[b_col] != row_index) { | |
| 57 | ✗ | temp_col_markers[b_col] = row_index; | |
| 58 | ✗ | temp_row[b_col] = a_value * b_value; | |
| 59 | } else { | ||
| 60 | ✗ | temp_row[b_col] += a_value * b_value; | |
| 61 | } | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | ✗ | for (int col = 0; col < matrix_b.column_count; ++col) { | |
| 66 | ✗ | if (temp_col_markers[col] == row_index && std::abs(temp_row[col]) > kEpsilonThreshold) { | |
| 67 | result_values.push_back(temp_row[col]); | ||
| 68 | result_col_indices.push_back(col); | ||
| 69 | } | ||
| 70 | } | ||
| 71 | |||
| 72 | ✗ | result_row_start = static_cast<int>(result_values.size()); | |
| 73 | ✗ | } | |
| 74 | |||
| 75 | } // namespace | ||
| 76 | |||
| 77 | ✗ | void LobanovMultyMatrixSEQ::PerformMatrixMultiplication(const CompressedRowMatrix &first_matrix, | |
| 78 | const CompressedRowMatrix &second_matrix, | ||
| 79 | CompressedRowMatrix &product_result) { | ||
| 80 | ✗ | product_result.row_count = first_matrix.row_count; | |
| 81 | ✗ | product_result.column_count = second_matrix.column_count; | |
| 82 | |||
| 83 | product_result.row_pointer_data.clear(); | ||
| 84 | ✗ | product_result.row_pointer_data.push_back(0); | |
| 85 | |||
| 86 | product_result.value_data.clear(); | ||
| 87 | product_result.column_index_data.clear(); | ||
| 88 | |||
| 89 | ✗ | int cols = second_matrix.column_count; | |
| 90 | ✗ | std::vector<double> temp_row(cols, 0.0); | |
| 91 | ✗ | std::vector<int> temp_col_markers(cols, -1); | |
| 92 | |||
| 93 | ✗ | for (int i = 0; i < first_matrix.row_count; ++i) { | |
| 94 | ✗ | int row_start = first_matrix.row_pointer_data[i]; | |
| 95 | ✗ | int row_end = first_matrix.row_pointer_data[i + 1]; | |
| 96 | |||
| 97 | ✗ | if (row_start == row_end) { | |
| 98 | ✗ | product_result.row_pointer_data.push_back(static_cast<int>(product_result.value_data.size())); | |
| 99 | ✗ | continue; | |
| 100 | } | ||
| 101 | |||
| 102 | ✗ | std::vector<double> a_row_values; | |
| 103 | ✗ | std::vector<int> a_row_columns; | |
| 104 | |||
| 105 | ✗ | for (int ptr = row_start; ptr < row_end; ++ptr) { | |
| 106 | ✗ | a_row_values.push_back(first_matrix.value_data[ptr]); | |
| 107 | a_row_columns.push_back(first_matrix.column_index_data[ptr]); | ||
| 108 | } | ||
| 109 | |||
| 110 | ✗ | int result_row_start = 0; | |
| 111 | ✗ | MultiplyRowByMatrix(a_row_values, a_row_columns, second_matrix, temp_row, temp_col_markers, i, | |
| 112 | ✗ | product_result.value_data, product_result.column_index_data, result_row_start); | |
| 113 | |||
| 114 | ✗ | product_result.row_pointer_data.push_back(static_cast<int>(product_result.value_data.size())); | |
| 115 | } | ||
| 116 | |||
| 117 | ✗ | product_result.non_zero_count = static_cast<int>(product_result.value_data.size()); | |
| 118 | ✗ | } | |
| 119 | |||
| 120 | ✗ | bool LobanovMultyMatrixSEQ::RunImpl() { | |
| 121 | const auto &[matrix_a, matrix_b] = GetInput(); | ||
| 122 | |||
| 123 | try { | ||
| 124 | ✗ | CompressedRowMatrix result_matrix; | |
| 125 | result_matrix.row_count = 0; | ||
| 126 | result_matrix.column_count = 0; | ||
| 127 | result_matrix.non_zero_count = 0; | ||
| 128 | |||
| 129 | ✗ | PerformMatrixMultiplication(matrix_a, matrix_b, result_matrix); | |
| 130 | ✗ | GetOutput() = result_matrix; | |
| 131 | return true; | ||
| 132 | ✗ | } catch (const std::exception &) { | |
| 133 | return false; | ||
| 134 | ✗ | } | |
| 135 | } | ||
| 136 | |||
| 137 | ✗ | bool LobanovMultyMatrixSEQ::PostProcessingImpl() { | |
| 138 | const auto &result_matrix = GetOutput(); | ||
| 139 | ✗ | return result_matrix.row_count > 0 && result_matrix.column_count > 0 && | |
| 140 | ✗ | result_matrix.row_pointer_data.size() == static_cast<size_t>(result_matrix.row_count) + 1; | |
| 141 | } | ||
| 142 | |||
| 143 | } // namespace lobanov_d_multi_matrix_crs | ||
| 144 |