Line | Branch | Exec | Source |
---|---|---|---|
1 | // This file is part of INSTINCT, the INS Toolkit for Integrated | ||
2 | // Navigation Concepts and Training by the Institute of Navigation of | ||
3 | // the University of Stuttgart, Germany. | ||
4 | // | ||
5 | // This Source Code Form is subject to the terms of the Mozilla Public | ||
6 | // License, v. 2.0. If a copy of the MPL was not distributed with this | ||
7 | // file, You can obtain one at https://mozilla.org/MPL/2.0/. | ||
8 | |||
9 | /// @file KeyedMatrix.hpp | ||
10 | /// @brief Matrix which can be accessed by keys | ||
11 | /// @author T. Topp (topp@ins.uni-stuttgart.de) | ||
12 | /// @note Based on ideas from Kevin Gutsche (kevin.gutsche@ins.uni-stuttgart.de) and Bayram Stucke (bayram.stucke@ins.uni-stuttgart.de) | ||
13 | /// @date 2023-07-06 | ||
14 | |||
15 | #pragma once | ||
16 | |||
17 | #include <unordered_set> | ||
18 | #include <vector> | ||
19 | #include <array> | ||
20 | #include <algorithm> | ||
21 | #include <ranges> | ||
22 | #include <type_traits> | ||
23 | #include "util/Assert.h" | ||
24 | #include "util/Eigen.hpp" | ||
25 | #include "util/Container/Unordered_map.hpp" | ||
26 | |||
27 | #if defined(__GNUC__) && !defined(__clang__) | ||
28 | #pragma GCC diagnostic push | ||
29 | #pragma GCC diagnostic ignored "-Wvirtual-move-assign" // NOLINT(clang-diagnostic-unknown-warning-option) | ||
30 | #endif | ||
31 | |||
32 | namespace NAV | ||
33 | { | ||
34 | namespace internal | ||
35 | { | ||
36 | /// @brief All type to request all rows or columns in KeyedMatrices | ||
37 | struct all_t | ||
38 | { | ||
39 | /// @brief Default Constructor | ||
40 | all_t() = default; | ||
41 | }; | ||
42 | |||
43 | /// @brief KeyedMatrix storage class | ||
44 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
45 | /// @tparam Rows Number of rows, or \b Dynamic | ||
46 | /// @tparam Cols Number of columns, or \b Dynamic | ||
47 | template<typename Scalar, int Rows, int Cols> | ||
48 | class KeyedMatrixStorage | ||
49 | { | ||
50 | protected: | ||
51 | Eigen::Matrix<Scalar, Rows, Cols> matrix; ///< Data storage of the type | ||
52 | |||
53 | private: | ||
54 | template<typename Scalar_, typename RowKeyType_, typename ColKeyType_, int Rows_, int Cols_> | ||
55 | friend class KeyedMatrixBase; | ||
56 | template<typename Scalar_, typename RowKeyType_, int Rows_> | ||
57 | friend class KeyedVectorBase; | ||
58 | template<typename Scalar_, typename ColKeyType_, int Cols_> | ||
59 | friend class KeyedRowVectorBase; | ||
60 | }; | ||
61 | |||
62 | // ########################################################################################################### | ||
63 | |||
64 | /// @brief Base class for Keyed matrices with multiple rows | ||
65 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
66 | /// @tparam RowKeyType Type of the key used for row lookup | ||
67 | /// @tparam Rows Number of rows, or \b Dynamic | ||
68 | /// @tparam Cols Number of columns, or \b Dynamic | ||
69 | template<typename Scalar, typename RowKeyType, int Rows, int Cols> | ||
70 | class KeyedMatrixRowsBase : virtual public KeyedMatrixStorage<Scalar, Rows, Cols> | ||
71 | { | ||
72 | public: | ||
73 | /// @brief Return the rows of the underlying Eigen matrix | ||
74 | 27672 | [[nodiscard]] decltype(auto) rows() const { return this->matrix.rows(); } | |
75 | |||
76 | /// @brief Returns the row keys | ||
77 | 2313490 | const std::vector<RowKeyType>& rowKeys() const { return rowKeysVector; } | |
78 | |||
79 | /// @brief Checks if the matrix has the key | ||
80 | /// @param key Row key to check for | ||
81 | 3790 | bool hasRow(const RowKeyType& key) const { return rowIndices.contains(key); } | |
82 | |||
83 | /// @brief Checks if the matrix has multiple keys | ||
84 | /// @param keys Row keys to check for | ||
85 | 416 | bool hasRows(const std::vector<RowKeyType>& keys) const | |
86 | { | ||
87 | 1645 | return std::ranges::all_of(keys, [&](const RowKeyType& key) { return hasRow(key); }); | |
88 | } | ||
89 | |||
90 | /// @brief Checks if the matrix has any key | ||
91 | /// @param keys Row keys to check for | ||
92 | 1096 | bool hasAnyRows(const std::vector<RowKeyType>& keys) const | |
93 | { | ||
94 | 1732 | return std::ranges::any_of(keys, [&](const RowKeyType& key) { return hasRow(key); }); | |
95 | } | ||
96 | |||
97 | /// @brief Replace the old with the new key | ||
98 | /// @param[in] oldKey Old key to replace | ||
99 | /// @param[in] newKey New key to use instead | ||
100 | 17 | void replaceRowKey(const RowKeyType& oldKey, const RowKeyType& newKey) | |
101 | { | ||
102 |
1/2✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
|
17 | auto iter = std::ranges::find(rowKeysVector, oldKey); |
103 |
1/2✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
|
17 | INS_ASSERT_USER_ERROR(iter != rowKeysVector.end(), "You cannot replace keys, which are not in the vector/matrix."); |
104 | |||
105 | 17 | *iter = newKey; | |
106 |
2/4✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✗ Branch 5 not taken.
|
17 | rowIndices[newKey] = rowIndices.at(oldKey); |
107 |
1/2✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
|
17 | rowIndices.erase(oldKey); |
108 | 17 | } | |
109 | |||
110 | protected: | ||
111 | /// RowKey to Row Index mapping | ||
112 | unordered_map<RowKeyType, Eigen::Index> rowIndices; | ||
113 | /// Row Keys | ||
114 | std::vector<RowKeyType> rowKeysVector; | ||
115 | |||
116 | /// Row Slice used for accessing | ||
117 | mutable std::vector<Eigen::Index> rowSlice; | ||
118 | |||
119 | private: | ||
120 | template<typename Scalar_, typename RowKeyType_, typename ColKeyType_, int Rows_, int Cols_> | ||
121 | friend class KeyedMatrixBase; | ||
122 | template<typename Scalar_, typename RowKeyType_, int Rows_> | ||
123 | friend class KeyedVectorBase; | ||
124 | }; | ||
125 | |||
126 | /// @brief Base class for Keyed matrices with multiple rows of static size | ||
127 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
128 | /// @tparam RowKeyType Type of the key used for row lookup | ||
129 | /// @tparam Rows Number of rows, or \b Dynamic | ||
130 | /// @tparam Cols Number of columns, or \b Dynamic | ||
131 | template<typename Scalar, typename RowKeyType, int Rows, int Cols> | ||
132 | class KeyedMatrixRows : public KeyedMatrixRowsBase<Scalar, RowKeyType, Rows, Cols> | ||
133 | {}; | ||
134 | |||
135 | /// @brief Base class for Keyed matrices with multiple rows of dynamic size | ||
136 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
137 | /// @tparam RowKeyType Type of the key used for row lookup | ||
138 | /// @tparam Cols Number of columns, or \b Dynamic | ||
139 | template<typename Scalar, typename RowKeyType, int Cols> | ||
140 | class KeyedMatrixRows<Scalar, RowKeyType, Eigen::Dynamic, Cols> : public KeyedMatrixRowsBase<Scalar, RowKeyType, Eigen::Dynamic, Cols> | ||
141 | { | ||
142 | public: | ||
143 | /// @brief Adds a new row to the matrix | ||
144 | /// @param rowKey Row key | ||
145 |
5/14✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 2 times.
✓ Branch 11 taken 2 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
|
16 | void addRow(const RowKeyType& rowKey) { addRows({ rowKey }); } |
146 | |||
147 | /// @brief Adds new rows to the matrix | ||
148 | /// @param rowKeys Row keys | ||
149 | 276 | void addRows(const std::vector<RowKeyType>& rowKeys) | |
150 | { | ||
151 |
1/2✓ Branch 1 taken 138 times.
✗ Branch 2 not taken.
|
276 | INS_ASSERT_USER_ERROR(!this->hasAnyRows(rowKeys), "You cannot add a row key which is already in the matrix."); |
152 |
4/12✓ Branch 3 taken 138 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 138 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 138 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 138 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
|
552 | INS_ASSERT_USER_ERROR(std::unordered_set<RowKeyType>(rowKeys.begin(), rowKeys.end()).size() == rowKeys.size(), "Each row key must be unique"); |
153 | |||
154 | 276 | auto initialSize = static_cast<Eigen::Index>(this->rowIndices.size()); | |
155 |
7/9✓ Branch 5 taken 8 times.
✓ Branch 6 taken 138 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 8 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 138 times.
✓ Branch 11 taken 134 times.
✓ Branch 13 taken 8 times.
✓ Branch 14 taken 4 times.
|
568 | for (const auto& rowKey : rowKeys) { this->rowIndices.insert({ rowKey, static_cast<Eigen::Index>(this->rowIndices.size()) }); } |
156 | 276 | this->rowKeysVector.reserve(this->rowKeysVector.size() + rowKeys.size()); | |
157 | 276 | std::copy(rowKeys.begin(), rowKeys.end(), std::back_inserter(this->rowKeysVector)); | |
158 | 276 | auto finalSize = static_cast<Eigen::Index>(this->rowIndices.size()); | |
159 | |||
160 |
1/2✓ Branch 0 taken 138 times.
✗ Branch 1 not taken.
|
276 | if (finalSize > initialSize) |
161 | { | ||
162 | 276 | this->matrix.conservativeResize(finalSize, Eigen::NoChange); | |
163 |
3/6✓ Branch 2 taken 138 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 138 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 138 times.
✗ Branch 10 not taken.
|
276 | this->matrix.block(initialSize, 0, finalSize - initialSize, this->matrix.cols()) = Eigen::MatrixX<Scalar>::Zero(finalSize - initialSize, this->matrix.cols()); |
164 | } | ||
165 | 276 | this->rowSlice.reserve(this->rowKeysVector.size()); | |
166 | 276 | } | |
167 | |||
168 | /// @brief Removes the row from the matrix | ||
169 | /// @param rowKey Row Key | ||
170 |
5/14✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
|
14 | void removeRow(const RowKeyType& rowKey) { removeRows({ rowKey }); } |
171 | |||
172 | /// @brief Removes the rows from the matrix | ||
173 | /// @param rowKeys Row Keys | ||
174 | 16 | void removeRows(const std::vector<RowKeyType>& rowKeys) | |
175 | { | ||
176 | 16 | std::vector<int> indices; | |
177 |
2/2✓ Branch 5 taken 14 times.
✓ Branch 6 taken 8 times.
|
44 | for (const auto& rowKey : rowKeys) |
178 | { | ||
179 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
28 | auto iter = this->rowIndices.find(rowKey); |
180 |
1/2✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
|
28 | INS_ASSERT_USER_ERROR(iter != this->rowIndices.end(), "You tried removing a row key, which did not exist."); |
181 |
1/2✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
|
28 | if (iter != this->rowIndices.end()) |
182 | { | ||
183 |
1/2✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
|
28 | indices.push_back(static_cast<int>(iter->second)); |
184 | } | ||
185 | } | ||
186 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
16 | NAV::removeRows(this->matrix, indices); |
187 | |||
188 |
2/2✓ Branch 5 taken 14 times.
✓ Branch 6 taken 8 times.
|
44 | for (const auto& rowKey : rowKeys) |
189 | { | ||
190 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
28 | auto iter = this->rowIndices.find(rowKey); |
191 |
1/2✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
|
28 | if (iter != this->rowIndices.end()) |
192 | { | ||
193 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
118 | std::erase_if(this->rowKeysVector, [&](const auto& item) { return item == rowKey; }); |
194 | |||
195 | 28 | auto idx = iter->second; | |
196 |
2/2✓ Branch 5 taken 90 times.
✓ Branch 6 taken 14 times.
|
208 | for (auto& rowIndex : this->rowIndices) |
197 | { | ||
198 |
2/2✓ Branch 0 taken 40 times.
✓ Branch 1 taken 50 times.
|
180 | if (rowIndex.second > idx) { rowIndex.second--; } |
199 | } | ||
200 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
28 | this->rowIndices.erase(iter); |
201 | } | ||
202 | } | ||
203 | 16 | } | |
204 | }; | ||
205 | |||
206 | // ########################################################################################################### | ||
207 | |||
208 | /// @brief Base class for Keyed matrices with multiple columns | ||
209 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
210 | /// @tparam ColKeyType Type of the key used for col lookup | ||
211 | /// @tparam Rows Number of rows, or \b Dynamic | ||
212 | /// @tparam Cols Number of columns, or \b Dynamic | ||
213 | template<typename Scalar, typename ColKeyType, int Rows, int Cols> | ||
214 | class KeyedMatrixColsBase : virtual public KeyedMatrixStorage<Scalar, Rows, Cols> | ||
215 | { | ||
216 | public: | ||
217 | /// @brief Return the cols of the underlying Eigen matrix | ||
218 | 27144 | [[nodiscard]] decltype(auto) cols() const { return this->matrix.cols(); } | |
219 | |||
220 | /// @brief Returns the col keys | ||
221 | 1917023 | const std::vector<ColKeyType>& colKeys() const { return colKeysVector; } | |
222 | |||
223 | /// @brief Checks if the matrix has the key | ||
224 | /// @param key Col key to check for | ||
225 | 535 | bool hasCol(const ColKeyType& key) const { return colIndices.contains(key); } | |
226 | |||
227 | /// @brief Checks if the matrix has multiple keys | ||
228 | /// @param keys Col keys to check for | ||
229 | 10 | bool hasCols(const std::vector<ColKeyType>& keys) const | |
230 | { | ||
231 | 18 | return std::ranges::all_of(keys, [&](const ColKeyType& key) { return hasCol(key); }); | |
232 | } | ||
233 | |||
234 | /// @brief Checks if the matrix has any keys | ||
235 | /// @param keys Col keys to check for | ||
236 | 489 | bool hasAnyCols(const std::vector<ColKeyType>& keys) const | |
237 | { | ||
238 | 987 | return std::ranges::any_of(keys, [&](const ColKeyType& key) { return hasCol(key); }); | |
239 | } | ||
240 | |||
241 | /// @brief Replace the old with the new key | ||
242 | /// @param[in] oldKey Old key to replace | ||
243 | /// @param[in] newKey New key to use instead | ||
244 | 8 | void replaceColKey(const ColKeyType& oldKey, const ColKeyType& newKey) | |
245 | { | ||
246 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | auto iter = std::ranges::find(colKeysVector, oldKey); |
247 |
1/2✓ Branch 2 taken 8 times.
✗ Branch 3 not taken.
|
8 | INS_ASSERT_USER_ERROR(iter != colKeysVector.end(), "You cannot replace keys, which are not in the vector/matrix."); |
248 | |||
249 | 8 | *iter = newKey; | |
250 |
2/4✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
|
8 | colIndices[newKey] = colIndices.at(oldKey); |
251 |
1/2✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
|
8 | colIndices.erase(oldKey); |
252 | 8 | } | |
253 | |||
254 | protected: | ||
255 | /// ColKey to Col Index mapping | ||
256 | unordered_map<ColKeyType, Eigen::Index> colIndices; | ||
257 | /// Col Keys | ||
258 | std::vector<ColKeyType> colKeysVector; | ||
259 | |||
260 | /// Col Slice used for accessing | ||
261 | mutable std::vector<Eigen::Index> colSlice; | ||
262 | |||
263 | private: | ||
264 | template<typename Scalar_, typename RowKeyType_, typename ColKeyType_, int Rows_, int Cols_> | ||
265 | friend class KeyedMatrixBase; | ||
266 | template<typename Scalar_, typename ColKeyType_, int Cols_> | ||
267 | friend class KeyedRowVectorBase; | ||
268 | }; | ||
269 | |||
270 | /// @brief Base class for Keyed matrices with multiple columns of static size | ||
271 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
272 | /// @tparam ColKeyType Type of the key used for col lookup | ||
273 | /// @tparam Rows Number of rows, or \b Dynamic | ||
274 | /// @tparam Cols Number of columns, or \b Dynamic | ||
275 | template<typename Scalar, typename ColKeyType, int Rows, int Cols> | ||
276 | class KeyedMatrixCols : public KeyedMatrixColsBase<Scalar, ColKeyType, Rows, Cols> | ||
277 | {}; | ||
278 | |||
279 | /// @brief Base class for Keyed matrices with multiple columns of dynamic size | ||
280 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
281 | /// @tparam ColKeyType Type of the key used for col lookup | ||
282 | /// @tparam Rows Number of rows, or \b Dynamic | ||
283 | template<typename Scalar, typename ColKeyType, int Rows> | ||
284 | class KeyedMatrixCols<Scalar, ColKeyType, Rows, Eigen::Dynamic> : public KeyedMatrixColsBase<Scalar, ColKeyType, Rows, Eigen::Dynamic> | ||
285 | { | ||
286 | public: | ||
287 | /// @brief Adds a new col to the matrix | ||
288 | /// @param colKey Col key | ||
289 |
5/14✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
|
20 | void addCol(const ColKeyType& colKey) { addCols({ colKey }); } |
290 | |||
291 | /// @brief Adds new cols to the matrix | ||
292 | /// @param colKeys Col keys | ||
293 | 77 | void addCols(const std::vector<ColKeyType>& colKeys) | |
294 | { | ||
295 |
1/2✓ Branch 1 taken 72 times.
✗ Branch 2 not taken.
|
77 | INS_ASSERT_USER_ERROR(!this->hasAnyCols(colKeys), "You cannot add a col key which is already in the matrix."); |
296 |
4/12✓ Branch 3 taken 72 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 72 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 72 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 72 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
|
154 | INS_ASSERT_USER_ERROR(std::unordered_set<ColKeyType>(colKeys.begin(), colKeys.end()).size() == colKeys.size(), "Each col key must be unique"); |
297 | |||
298 | 77 | auto initialSize = static_cast<Eigen::Index>(this->colIndices.size()); | |
299 |
7/9✓ Branch 5 taken 5 times.
✓ Branch 6 taken 73 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 73 times.
✓ Branch 11 taken 70 times.
✓ Branch 13 taken 5 times.
✓ Branch 14 taken 2 times.
|
164 | for (const auto& colKey : colKeys) { this->colIndices.insert({ colKey, static_cast<Eigen::Index>(this->colIndices.size()) }); } |
300 | 77 | this->colKeysVector.reserve(this->colKeysVector.size() + colKeys.size()); | |
301 | 77 | std::copy(colKeys.begin(), colKeys.end(), std::back_inserter(this->colKeysVector)); | |
302 | 77 | auto finalSize = static_cast<Eigen::Index>(this->colIndices.size()); | |
303 | |||
304 |
1/2✓ Branch 0 taken 72 times.
✗ Branch 1 not taken.
|
77 | if (finalSize > initialSize) |
305 | { | ||
306 | 77 | this->matrix.conservativeResize(Eigen::NoChange, finalSize); | |
307 |
3/6✓ Branch 2 taken 72 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 72 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 72 times.
✗ Branch 10 not taken.
|
77 | this->matrix.block(0, initialSize, this->matrix.rows(), finalSize - initialSize) = Eigen::MatrixX<Scalar>::Zero(this->matrix.rows(), finalSize - initialSize); |
308 | } | ||
309 | 77 | this->colSlice.reserve(this->colKeysVector.size()); | |
310 | 77 | } | |
311 | |||
312 | /// @brief Removes the col from the matrix | ||
313 | /// @param colKey Col Key | ||
314 |
5/14✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
|
14 | void removeCol(const ColKeyType& colKey) { removeCols({ colKey }); } |
315 | |||
316 | /// @brief Removes the cols from the matrix | ||
317 | /// @param colKeys Col Keys | ||
318 | 10 | void removeCols(const std::vector<ColKeyType>& colKeys) | |
319 | { | ||
320 | 10 | std::vector<int> indices; | |
321 |
2/2✓ Branch 5 taken 10 times.
✓ Branch 6 taken 6 times.
|
26 | for (const auto& colKey : colKeys) |
322 | { | ||
323 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
16 | auto iter = this->colIndices.find(colKey); |
324 |
1/2✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
|
16 | INS_ASSERT_USER_ERROR(iter != this->colIndices.end(), "You tried removing a col key, which did not exist."); |
325 |
1/2✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
|
16 | if (iter != this->colIndices.end()) |
326 | { | ||
327 |
1/2✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
|
16 | indices.push_back(static_cast<int>(iter->second)); |
328 | } | ||
329 | } | ||
330 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
10 | NAV::removeCols(this->matrix, indices); |
331 | |||
332 |
2/2✓ Branch 5 taken 10 times.
✓ Branch 6 taken 6 times.
|
26 | for (const auto& colKey : colKeys) |
333 | { | ||
334 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
16 | auto iter = this->colIndices.find(colKey); |
335 |
1/2✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
|
16 | if (iter != this->colIndices.end()) |
336 | { | ||
337 |
2/3✓ Branch 1 taken 6 times.
✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
76 | std::erase_if(this->colKeysVector, [&](const auto& item) { return item == colKey; }); |
338 | |||
339 | 16 | auto idx = iter->second; | |
340 |
2/2✓ Branch 5 taken 60 times.
✓ Branch 6 taken 10 times.
|
106 | for (auto& colIndex : this->colIndices) |
341 | { | ||
342 |
2/2✓ Branch 0 taken 30 times.
✓ Branch 1 taken 30 times.
|
90 | if (colIndex.second > idx) { colIndex.second--; } |
343 | } | ||
344 |
1/2✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
|
16 | this->colIndices.erase(iter); |
345 | } | ||
346 | } | ||
347 | 10 | } | |
348 | }; | ||
349 | |||
350 | // ########################################################################################################### | ||
351 | |||
352 | template<typename Scalar, typename ColKeyType, int Cols> | ||
353 | class KeyedRowVectorBase; | ||
354 | |||
355 | /// @brief Class to inherit common methods for static and dynamic sized vectors | ||
356 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
357 | /// @tparam RowKeyType Type of the key used for row lookup | ||
358 | /// @tparam Rows Number of rows, or \b Dynamic | ||
359 | template<typename Scalar, typename RowKeyType, int Rows> | ||
360 | class KeyedVectorBase : public KeyedMatrixRows<Scalar, RowKeyType, Rows, 1> | ||
361 | { | ||
362 | public: | ||
363 | /// @brief Constructor | ||
364 | /// @param vector Eigen vector to initialize from | ||
365 | template<typename Derived> | ||
366 | 2842 | explicit KeyedVectorBase(const Eigen::MatrixBase<Derived>& vector) | |
367 | 2842 | { | |
368 |
1/2✓ Branch 1 taken 2030 times.
✗ Branch 2 not taken.
|
2842 | this->matrix = vector; |
369 | 2842 | } | |
370 | |||
371 | /// @brief Constructor | ||
372 | /// @param vector Eigen vector to initialize from | ||
373 | /// @param rowKeys Row keys describing the vector | ||
374 | template<typename Derived> | ||
375 | 58490 | KeyedVectorBase(const Eigen::MatrixBase<Derived>& vector, const std::vector<RowKeyType>& rowKeys) | |
376 | 58490 | { | |
377 |
4/12✓ Branch 3 taken 29245 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 29245 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 29245 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 29245 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
|
116980 | INS_ASSERT_USER_ERROR(std::unordered_set<RowKeyType>(rowKeys.begin(), rowKeys.end()).size() == rowKeys.size(), "Each row key must be unique"); |
378 | |||
379 |
1/2✓ Branch 1 taken 29245 times.
✗ Branch 2 not taken.
|
58490 | INS_ASSERT_USER_ERROR(vector.cols() == 1, "Only vectors with 1 column are allowed."); |
380 |
1/2✓ Branch 2 taken 26823 times.
✗ Branch 3 not taken.
|
53646 | INS_ASSERT_USER_ERROR(Rows == Eigen::Dynamic || vector.rows() == static_cast<int>(rowKeys.size()), "Number of vector rows doesn't correspond to the amount of row keys"); |
381 | |||
382 |
8/10✓ Branch 1 taken 236942 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 236929 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 13 times.
✓ Branch 8 taken 236929 times.
✓ Branch 9 taken 29242 times.
✓ Branch 11 taken 13 times.
✓ Branch 12 taken 3 times.
|
532374 | for (size_t i = 0; i < rowKeys.size(); i++) { this->rowIndices.insert({ rowKeys.at(i), static_cast<Eigen::Index>(i) }); } |
383 | |||
384 |
1/2✓ Branch 1 taken 29245 times.
✗ Branch 2 not taken.
|
58490 | this->matrix = vector; |
385 |
1/2✓ Branch 1 taken 29245 times.
✗ Branch 2 not taken.
|
58490 | this->rowKeysVector = rowKeys; |
386 |
1/2✓ Branch 2 taken 29245 times.
✗ Branch 3 not taken.
|
58490 | this->rowSlice.reserve(this->rowKeysVector.size()); |
387 | 58490 | } | |
388 | |||
389 | // ####################################################################################################### | ||
390 | // Special member functions | ||
391 | // ####################################################################################################### | ||
392 | |||
393 | /// @brief Destructor | ||
394 | 65994 | ~KeyedVectorBase() = default; | |
395 | /// @brief Copy constructor | ||
396 | /// @param other The other object | ||
397 | 3432 | KeyedVectorBase(const KeyedVectorBase& other) | |
398 | 3432 | { | |
399 |
1/2✓ Branch 1 taken 1716 times.
✗ Branch 2 not taken.
|
3432 | this->matrix = other.matrix; |
400 |
1/2✓ Branch 1 taken 1716 times.
✗ Branch 2 not taken.
|
3432 | this->rowIndices = other.rowIndices; |
401 |
1/2✓ Branch 1 taken 1716 times.
✗ Branch 2 not taken.
|
3432 | this->rowKeysVector = other.rowKeysVector; |
402 |
1/2✓ Branch 2 taken 1716 times.
✗ Branch 3 not taken.
|
3432 | this->rowSlice.reserve(this->rowKeysVector.size()); |
403 | 3432 | } | |
404 | /// @brief Copy assignment operator | ||
405 | /// @param other The other object | ||
406 | 4 | KeyedVectorBase& operator=(const KeyedVectorBase& other) | |
407 | { | ||
408 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
4 | if (this == &other) { return *this; } // Guard self assignment |
409 | |||
410 | 4 | this->matrix = other.matrix; | |
411 | 4 | this->rowIndices = other.rowIndices; | |
412 | 4 | this->rowKeysVector = other.rowKeysVector; | |
413 | 4 | this->rowSlice.reserve(this->rowKeysVector.size()); | |
414 | |||
415 | 4 | return *this; | |
416 | } | ||
417 | /// @brief Move constructor | ||
418 | /// @param other The other object | ||
419 | 4 | KeyedVectorBase(KeyedVectorBase&& other) noexcept | |
420 | 4 | { | |
421 | 4 | this->matrix = std::move(other.matrix); | |
422 | 4 | this->rowIndices = std::move(other.rowIndices); | |
423 | 4 | this->rowKeysVector = std::move(other.rowKeysVector); | |
424 | 4 | this->rowSlice.reserve(this->rowKeysVector.size()); | |
425 | 4 | } | |
426 | /// @brief Move assignment operator | ||
427 | /// @param other The other object | ||
428 | 2038 | KeyedVectorBase& operator=(KeyedVectorBase&& other) noexcept | |
429 | { | ||
430 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1580 times.
|
2038 | if (this == &other) { return *this; } // Guard self assignment |
431 | |||
432 | 2038 | this->matrix = std::move(other.matrix); | |
433 | 2038 | this->rowIndices = std::move(other.rowIndices); | |
434 | 2038 | this->rowKeysVector = std::move(other.rowKeysVector); | |
435 | 2038 | this->rowSlice.reserve(this->rowKeysVector.size()); | |
436 | |||
437 | 2038 | return *this; | |
438 | } | ||
439 | |||
440 | // ########################################################################################################### | ||
441 | // Special member functions with different Rows/Cols | ||
442 | // ########################################################################################################### | ||
443 | |||
444 | /// @brief Copy constructor | ||
445 | /// @param other The other object | ||
446 | template<int oRows> | ||
447 | 4 | KeyedVectorBase(const KeyedVectorBase<Scalar, RowKeyType, oRows>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
448 | 4 | { | |
449 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | INS_ASSERT_USER_ERROR(Rows == Eigen::Dynamic || other.rows() == Rows, "Can only copy construct dynamic<=>static matrices if the rows match"); |
450 | |||
451 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | this->matrix = other.matrix; |
452 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | this->rowIndices = other.rowIndices; |
453 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | this->rowKeysVector = other.rowKeysVector; |
454 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
4 | this->rowSlice.reserve(this->rowKeysVector.size()); |
455 | 4 | } | |
456 | /// @brief Copy assignment operator | ||
457 | /// @param other The other object | ||
458 | template<int oRows> | ||
459 | 4 | KeyedVectorBase& operator=(const KeyedVectorBase<Scalar, RowKeyType, oRows>& other) | |
460 | { | ||
461 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
462 | |||
463 |
1/2✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
4 | INS_ASSERT_USER_ERROR(other.rowKeys() == this->rowKeys(), "Can only copy assign matrices if the row keys match"); |
464 | |||
465 | 4 | this->matrix = other.matrix; | |
466 | 4 | this->rowIndices = other.rowIndices; | |
467 | 4 | this->rowKeysVector = other.rowKeysVector; | |
468 | 4 | this->rowSlice.reserve(this->rowKeysVector.size()); | |
469 | |||
470 | 4 | return *this; | |
471 | } | ||
472 | /// @brief Move constructor | ||
473 | /// @param other The other object | ||
474 | template<int oRows> | ||
475 | 4 | KeyedVectorBase(KeyedVectorBase<Scalar, RowKeyType, oRows>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
476 | 4 | { | |
477 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | INS_ASSERT_USER_ERROR(Rows == Eigen::Dynamic || other.rows() == Rows, "Can only copy construct dynamic<=>static matrices if the rows match"); |
478 | |||
479 | 4 | this->matrix = std::move(other.matrix); | |
480 | 4 | this->rowIndices = std::move(other.rowIndices); | |
481 | 4 | this->rowKeysVector = std::move(other.rowKeysVector); | |
482 | 4 | this->rowSlice.reserve(this->rowKeysVector.size()); | |
483 | 4 | } | |
484 | /// @brief Move assignment operator | ||
485 | /// @param other The other object | ||
486 | template<int oRows> | ||
487 | 26817 | KeyedVectorBase& operator=(KeyedVectorBase<Scalar, RowKeyType, oRows>&& other) noexcept | |
488 | { | ||
489 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
490 | |||
491 |
1/2✓ Branch 3 taken 26815 times.
✗ Branch 4 not taken.
|
26817 | INS_ASSERT_USER_ERROR(other.rowKeys() == this->rowKeys(), "Can only copy assign matrices if the row keys match"); |
492 | |||
493 | 26817 | this->matrix = std::move(other.matrix); | |
494 | 26817 | this->rowIndices = std::move(other.rowIndices); | |
495 | 26817 | this->rowKeysVector = std::move(other.rowKeysVector); | |
496 | 26817 | this->rowSlice.reserve(this->rowKeysVector.size()); | |
497 | |||
498 | 26817 | return *this; | |
499 | } | ||
500 | |||
501 | // ####################################################################################################### | ||
502 | // Access | ||
503 | // ####################################################################################################### | ||
504 | |||
505 | /// @brief Gets the value for the row key | ||
506 | /// @param rowKey Row Key | ||
507 | /// @return Scalar value | ||
508 | 3108 | const Scalar& operator()(const RowKeyType& rowKey) const | |
509 | { | ||
510 | 3108 | return this->matrix(this->rowIndices.at(rowKey), 0); | |
511 | } | ||
512 | /// @brief Gets the value for the row key | ||
513 | /// @param rowKey Row Key | ||
514 | /// @return Scalar value | ||
515 | 127445 | Scalar& operator()(const RowKeyType& rowKey) | |
516 | { | ||
517 | 127445 | return this->matrix(this->rowIndices.at(rowKey), 0); | |
518 | } | ||
519 | |||
520 | /// @brief Gets the values for the row keys | ||
521 | /// @param rowKeys Row Keys | ||
522 | /// @return View into the matrix for the row keys | ||
523 | ✗ | decltype(auto) operator()(const std::vector<RowKeyType>& rowKeys) const | |
524 | { | ||
525 | ✗ | this->rowSlice.clear(); | |
526 | ✗ | for (const auto& rowKey : rowKeys) { this->rowSlice.push_back(this->rowIndices.at(rowKey)); } | |
527 | |||
528 | ✗ | return this->matrix(this->rowSlice, 0); | |
529 | } | ||
530 | /// @brief Gets the values for the row keys | ||
531 | /// @param rowKeys Row Keys | ||
532 | /// @return View into the matrix for the row keys | ||
533 | 1 | decltype(auto) operator()(const std::vector<RowKeyType>& rowKeys) | |
534 | { | ||
535 | 1 | this->rowSlice.clear(); | |
536 |
4/6✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 3 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 3 times.
✓ Branch 12 taken 1 times.
|
4 | for (const auto& rowKey : rowKeys) { this->rowSlice.push_back(this->rowIndices.at(rowKey)); } |
537 | |||
538 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | return this->matrix(this->rowSlice, 0); |
539 | } | ||
540 | |||
541 | /// @brief Requests the full vector | ||
542 | 2846 | const Eigen::Matrix<Scalar, Rows, 1>& operator()(all_t /* all */) const { return this->matrix; } | |
543 | /// @brief Requests the full vector | ||
544 | 416736 | Eigen::Matrix<Scalar, Rows, 1>& operator()(all_t /* all */) { return this->matrix; } | |
545 | /// @brief Conversion into Eigen::Vector | ||
546 | explicit operator Eigen::Vector<Scalar, Rows>() { return this->matrix; } | ||
547 | |||
548 | // ####################################################################################################### | ||
549 | // Block operations | ||
550 | // ####################################################################################################### | ||
551 | |||
552 | /// @brief Gets the values for the row keys | ||
553 | /// @param rowKeys Row Keys | ||
554 | /// @return View into the matrix for the row keys | ||
555 | template<size_t P> | ||
556 | 1860 | decltype(auto) segment(const std::vector<RowKeyType>& rowKeys) const // NOLINT(readability-const-return-type) | |
557 | { | ||
558 | 1860 | checkContinuousSegment(rowKeys, P); | |
559 | |||
560 | 1860 | return this->matrix.template middleRows<P>(this->rowIndices.at(rowKeys.at(0))); | |
561 | } | ||
562 | /// @brief Gets the values for the row keys | ||
563 | /// @param rowKeys Row Keys | ||
564 | /// @return View into the matrix for the row keys | ||
565 | template<size_t P> | ||
566 | 134069 | decltype(auto) segment(const std::vector<RowKeyType>& rowKeys) | |
567 | { | ||
568 | 134069 | checkContinuousSegment(rowKeys, P); | |
569 | |||
570 | 134069 | return this->matrix.template middleRows<P>(this->rowIndices.at(rowKeys.at(0))); | |
571 | } | ||
572 | /// @brief Gets the values for the row keys | ||
573 | /// @param rowKeys Row Keys | ||
574 | /// @return View into the matrix for the row keys | ||
575 | decltype(auto) segment(const std::vector<RowKeyType>& rowKeys) const // NOLINT(readability-const-return-type) | ||
576 | { | ||
577 | checkContinuousSegment(rowKeys, rowKeys.size()); | ||
578 | |||
579 | return this->matrix.middleRows(this->rowIndices.at(rowKeys.at(0)), rowKeys.size()); | ||
580 | } | ||
581 | /// @brief Gets the values for the row keys | ||
582 | /// @param rowKeys Row Keys | ||
583 | /// @return View into the matrix for the row keys | ||
584 | 4 | decltype(auto) segment(const std::vector<RowKeyType>& rowKeys) | |
585 | { | ||
586 | 4 | checkContinuousSegment(rowKeys, rowKeys.size()); | |
587 | |||
588 | 4 | return this->matrix.middleRows(this->rowIndices.at(rowKeys.at(0)), rowKeys.size()); | |
589 | } | ||
590 | |||
591 | // ####################################################################################################### | ||
592 | // Methods | ||
593 | // ####################################################################################################### | ||
594 | |||
595 | /// @brief Calculates the transposed vector | ||
596 | 4 | [[nodiscard]] KeyedRowVectorBase<Scalar, RowKeyType, Rows> transposed() const | |
597 | { | ||
598 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
4 | return { this->matrix.transpose(), this->rowKeys() }; |
599 | } | ||
600 | |||
601 | private: | ||
602 | /// @brief Checks if the row keys are describing a continuous block | ||
603 | /// @param rowKeys Row keys | ||
604 | /// @param P Size of the row keys | ||
605 | 135933 | void checkContinuousSegment([[maybe_unused]] const std::vector<RowKeyType>& rowKeys, [[maybe_unused]] size_t P) const | |
606 | { | ||
607 | #ifndef NDEBUG | ||
608 |
1/2✓ Branch 1 taken 135929 times.
✗ Branch 2 not taken.
|
135933 | INS_ASSERT_USER_ERROR(P == rowKeys.size(), "The block size must be equivalent to the amount of row keys."); |
609 | |||
610 |
1/2✓ Branch 2 taken 135929 times.
✗ Branch 3 not taken.
|
135933 | std::vector<Eigen::Index> consecutiveRows(rowKeys.size()); |
611 |
2/4✓ Branch 1 taken 135929 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 135929 times.
✗ Branch 5 not taken.
|
271866 | std::iota(std::begin(consecutiveRows), std::end(consecutiveRows), this->rowIndices.at(rowKeys.at(0))); |
612 | 135933 | std::vector<Eigen::Index> rowIndices; | |
613 |
1/2✓ Branch 2 taken 135929 times.
✗ Branch 3 not taken.
|
135933 | rowIndices.reserve(rowKeys.size()); |
614 |
4/6✓ Branch 4 taken 407783 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 407783 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 407783 times.
✓ Branch 12 taken 135929 times.
|
543724 | for (const auto& rowKey : rowKeys) { rowIndices.push_back(this->rowIndices.at(rowKey)); } |
615 |
2/4✓ Branch 1 taken 135929 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 135929 times.
✗ Branch 4 not taken.
|
135933 | INS_ASSERT_USER_ERROR(rowIndices == consecutiveRows, "The given rowKeys must describe a consecutive part in the matrix."); |
616 | #endif | ||
617 | 135933 | } | |
618 | }; | ||
619 | |||
620 | /// @brief Class to inherit common methods for static and dynamic sized row vectors | ||
621 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
622 | /// @tparam ColKeyType Type of the key used for col lookup | ||
623 | /// @tparam Cols Number of columns, or \b Dynamic | ||
624 | template<typename Scalar, typename ColKeyType, int Cols> | ||
625 | class KeyedRowVectorBase : public KeyedMatrixCols<Scalar, ColKeyType, 1, Cols> | ||
626 | { | ||
627 | public: | ||
628 | /// @brief Constructor | ||
629 | /// @param vector Eigen vector to initialize from | ||
630 | template<typename Derived> | ||
631 | explicit KeyedRowVectorBase(const Eigen::MatrixBase<Derived>& vector) | ||
632 | { | ||
633 | this->matrix = vector; | ||
634 | } | ||
635 | |||
636 | /// @brief Constructor | ||
637 | /// @param vector Eigen vector to initialize from | ||
638 | /// @param colKeys Col keys describing the vector | ||
639 | template<typename Derived> | ||
640 | 40 | KeyedRowVectorBase(const Eigen::MatrixBase<Derived>& vector, const std::vector<ColKeyType>& colKeys) | |
641 | 40 | { | |
642 |
4/12✓ Branch 3 taken 20 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 20 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 20 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 20 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
|
80 | INS_ASSERT_USER_ERROR(std::unordered_set<ColKeyType>(colKeys.begin(), colKeys.end()).size() == colKeys.size(), "Each col key must be unique"); |
643 | |||
644 |
1/2✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
|
40 | INS_ASSERT_USER_ERROR(vector.rows() == 1, "Only vectors with 1 row are allowed."); |
645 |
1/2✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
|
20 | INS_ASSERT_USER_ERROR(Cols == Eigen::Dynamic || vector.cols() == static_cast<Eigen::Index>(colKeys.size()), "Number of vector cols doesn't correspond to the amount of col keys"); |
646 | |||
647 |
8/10✓ Branch 1 taken 68 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✓ Branch 5 taken 55 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 13 times.
✓ Branch 8 taken 55 times.
✓ Branch 9 taken 17 times.
✓ Branch 11 taken 13 times.
✓ Branch 12 taken 3 times.
|
176 | for (size_t i = 0; i < colKeys.size(); i++) { this->colIndices.insert({ colKeys.at(i), static_cast<Eigen::Index>(i) }); } |
648 | |||
649 |
1/2✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
|
40 | this->matrix = vector; |
650 |
1/2✓ Branch 1 taken 20 times.
✗ Branch 2 not taken.
|
40 | this->colKeysVector = colKeys; |
651 |
1/2✓ Branch 2 taken 20 times.
✗ Branch 3 not taken.
|
40 | this->colSlice.reserve(this->colKeysVector.size()); |
652 | 40 | } | |
653 | |||
654 | // ####################################################################################################### | ||
655 | // Special member functions | ||
656 | // ####################################################################################################### | ||
657 | |||
658 | /// @brief Destructor | ||
659 | 56 | ~KeyedRowVectorBase() = default; | |
660 | /// @brief Copy constructor | ||
661 | /// @param other The other object | ||
662 | 4 | KeyedRowVectorBase(const KeyedRowVectorBase& other) | |
663 | 4 | { | |
664 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | this->matrix = other.matrix; |
665 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | this->colIndices = other.colIndices; |
666 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | this->colKeysVector = other.colKeysVector; |
667 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
4 | this->colSlice.reserve(this->colKeysVector.size()); |
668 | 4 | } | |
669 | /// @brief Copy assignment operator | ||
670 | /// @param other The other object | ||
671 | 4 | KeyedRowVectorBase& operator=(const KeyedRowVectorBase& other) | |
672 | { | ||
673 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
4 | if (this == &other) { return *this; } // Guard self assignment |
674 | |||
675 | 4 | this->matrix = other.matrix; | |
676 | 4 | this->colIndices = other.colIndices; | |
677 | 4 | this->colKeysVector = other.colKeysVector; | |
678 | 4 | this->colSlice.reserve(this->colKeysVector.size()); | |
679 | |||
680 | 4 | return *this; | |
681 | } | ||
682 | /// @brief Move constructor | ||
683 | /// @param other The other object | ||
684 | 4 | KeyedRowVectorBase(KeyedRowVectorBase&& other) noexcept | |
685 | 4 | { | |
686 | 4 | this->matrix = std::move(other.matrix); | |
687 | 4 | this->colIndices = std::move(other.colIndices); | |
688 | 4 | this->colKeysVector = std::move(other.colKeysVector); | |
689 | 4 | this->colSlice.reserve(this->colKeysVector.size()); | |
690 | 4 | } | |
691 | /// @brief Move assignment operator | ||
692 | /// @param other The other object | ||
693 | 4 | KeyedRowVectorBase& operator=(KeyedRowVectorBase&& other) noexcept | |
694 | { | ||
695 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
4 | if (this == &other) { return *this; } // Guard self assignment |
696 | |||
697 | 4 | this->matrix = std::move(other.matrix); | |
698 | 4 | this->colIndices = std::move(other.colIndices); | |
699 | 4 | this->colKeysVector = std::move(other.colKeysVector); | |
700 | 4 | this->colSlice.reserve(this->colKeysVector.size()); | |
701 | |||
702 | 4 | return *this; | |
703 | } | ||
704 | |||
705 | // ########################################################################################################### | ||
706 | // Special member functions with different Rows/Cols | ||
707 | // ########################################################################################################### | ||
708 | |||
709 | /// @brief Copy constructor | ||
710 | /// @param other The other object | ||
711 | template<int oCols> | ||
712 | 4 | KeyedRowVectorBase(const KeyedRowVectorBase<Scalar, ColKeyType, oCols>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
713 | 4 | { | |
714 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | INS_ASSERT_USER_ERROR(Cols == Eigen::Dynamic || other.cols() == Cols, "Can only copy construct dynamic<=>static matrices if the cols match"); |
715 | |||
716 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | this->matrix = other.matrix; |
717 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | this->colIndices = other.colIndices; |
718 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | this->colKeysVector = other.colKeysVector; |
719 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
4 | this->colSlice.reserve(this->colKeysVector.size()); |
720 | 4 | } | |
721 | /// @brief Copy assignment operator | ||
722 | /// @param other The other object | ||
723 | template<int oCols> | ||
724 | 4 | KeyedRowVectorBase& operator=(const KeyedRowVectorBase<Scalar, ColKeyType, oCols>& other) | |
725 | { | ||
726 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
727 | |||
728 |
1/2✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
4 | INS_ASSERT_USER_ERROR(other.colKeys() == this->colKeys(), "Can only copy assign matrices if the col keys match"); |
729 | |||
730 | 4 | this->matrix = other.matrix; | |
731 | 4 | this->colIndices = other.colIndices; | |
732 | 4 | this->colKeysVector = other.colKeysVector; | |
733 | 4 | this->colSlice.reserve(this->colKeysVector.size()); | |
734 | |||
735 | 4 | return *this; | |
736 | } | ||
737 | /// @brief Move constructor | ||
738 | /// @param other The other object | ||
739 | template<int oCols> | ||
740 | 4 | KeyedRowVectorBase(KeyedRowVectorBase<Scalar, ColKeyType, oCols>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
741 | 4 | { | |
742 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | INS_ASSERT_USER_ERROR(Cols == Eigen::Dynamic || other.cols() == Cols, "Can only copy construct dynamic<=>static matrices if the cols match"); |
743 | |||
744 | 4 | this->matrix = std::move(other.matrix); | |
745 | 4 | this->colIndices = std::move(other.colIndices); | |
746 | 4 | this->colKeysVector = std::move(other.colKeysVector); | |
747 | 4 | this->colSlice.reserve(this->colKeysVector.size()); | |
748 | 4 | } | |
749 | /// @brief Move assignment operator | ||
750 | /// @param other The other object | ||
751 | template<int oCols> | ||
752 | 4 | KeyedRowVectorBase& operator=(KeyedRowVectorBase<Scalar, ColKeyType, oCols>&& other) noexcept | |
753 | { | ||
754 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
755 | |||
756 |
1/2✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
4 | INS_ASSERT_USER_ERROR(other.colKeys() == this->colKeys(), "Can only copy assign matrices if the col keys match"); |
757 | |||
758 | 4 | this->matrix = std::move(other.matrix); | |
759 | 4 | this->colIndices = std::move(other.colIndices); | |
760 | 4 | this->colKeysVector = std::move(other.colKeysVector); | |
761 | 4 | this->colSlice.reserve(this->colKeysVector.size()); | |
762 | |||
763 | 4 | return *this; | |
764 | } | ||
765 | |||
766 | // ####################################################################################################### | ||
767 | // Access | ||
768 | // ####################################################################################################### | ||
769 | |||
770 | /// @brief Gets the value for the col key | ||
771 | /// @param colKey Col Key | ||
772 | /// @return Scalar value | ||
773 | const Scalar& operator()(const ColKeyType& colKey) const | ||
774 | { | ||
775 | return this->matrix(0, this->colIndices.at(colKey)); | ||
776 | } | ||
777 | /// @brief Gets the value for the col key | ||
778 | /// @param colKey Col Key | ||
779 | /// @return Scalar value | ||
780 | Scalar& operator()(const ColKeyType& colKey) | ||
781 | { | ||
782 | return this->matrix(0, this->colIndices.at(colKey)); | ||
783 | } | ||
784 | |||
785 | /// @brief Gets the values for the col keys | ||
786 | /// @param colKeys Col Keys | ||
787 | /// @return View into the matrix for the col keys | ||
788 | decltype(auto) operator()(const std::vector<ColKeyType>& colKeys) const | ||
789 | { | ||
790 | this->colSlice.clear(); | ||
791 | for (const auto& colKey : colKeys) { this->colSlice.push_back(this->colIndices.at(colKey)); } | ||
792 | |||
793 | return this->matrix(0, this->colSlice); | ||
794 | } | ||
795 | /// @brief Gets the values for the col keys | ||
796 | /// @param colKeys Col Keys | ||
797 | /// @return View into the matrix for the col keys | ||
798 | decltype(auto) operator()(const std::vector<ColKeyType>& colKeys) | ||
799 | { | ||
800 | this->colSlice.clear(); | ||
801 | for (const auto& colKey : colKeys) { this->colSlice.push_back(this->colIndices.at(colKey)); } | ||
802 | |||
803 | return this->matrix(0, this->colSlice); | ||
804 | } | ||
805 | |||
806 | /// @brief Requests the full vector | ||
807 | 42 | const Eigen::Matrix<Scalar, 1, Cols>& operator()(all_t /* all */) const { return this->matrix; } | |
808 | /// @brief Requests the full vector | ||
809 | 74 | Eigen::Matrix<Scalar, 1, Cols>& operator()(all_t /* all */) { return this->matrix; } | |
810 | /// @brief Conversion into Eigen::RowVector | ||
811 | explicit operator Eigen::RowVector<Scalar, Cols>() { return this->matrix; } | ||
812 | |||
813 | // ####################################################################################################### | ||
814 | // Block operations | ||
815 | // ####################################################################################################### | ||
816 | |||
817 | /// @brief Gets the values for the col keys | ||
818 | /// @param colKeys Col Keys | ||
819 | /// @return View into the matrix for the col keys | ||
820 | template<size_t Q> | ||
821 | decltype(auto) segment(const std::vector<ColKeyType>& colKeys) const | ||
822 | { | ||
823 | checkContinuousSegment(colKeys, Q); | ||
824 | |||
825 | return this->matrix.template middleCols<Q>(this->colIndices.at(colKeys.at(0))); | ||
826 | } | ||
827 | /// @brief Gets the values for the col keys | ||
828 | /// @param colKeys Col Keys | ||
829 | /// @return View into the matrix for the col keys | ||
830 | template<size_t Q> | ||
831 | 4 | decltype(auto) segment(const std::vector<ColKeyType>& colKeys) | |
832 | { | ||
833 | 4 | checkContinuousSegment(colKeys, Q); | |
834 | |||
835 | 4 | return this->matrix.template middleCols<Q>(this->colIndices.at(colKeys.at(0))); | |
836 | } | ||
837 | /// @brief Gets the values for the col keys | ||
838 | /// @param colKeys Col Keys | ||
839 | /// @return View into the matrix for the col keys | ||
840 | decltype(auto) segment(const std::vector<ColKeyType>& colKeys) const | ||
841 | { | ||
842 | checkContinuousSegment(colKeys, colKeys.size()); | ||
843 | |||
844 | return this->matrix.middleCols(this->colIndices.at(colKeys.at(0)), colKeys.size()); | ||
845 | } | ||
846 | /// @brief Gets the values for the col keys | ||
847 | /// @param colKeys Col Keys | ||
848 | /// @return View into the matrix for the col keys | ||
849 | 4 | decltype(auto) segment(const std::vector<ColKeyType>& colKeys) | |
850 | { | ||
851 | 4 | checkContinuousSegment(colKeys, colKeys.size()); | |
852 | |||
853 | 4 | return this->matrix.middleCols(this->colIndices.at(colKeys.at(0)), colKeys.size()); | |
854 | } | ||
855 | |||
856 | // ####################################################################################################### | ||
857 | // Methods | ||
858 | // ####################################################################################################### | ||
859 | |||
860 | /// @brief Calculates the transposed vector | ||
861 | 4 | [[nodiscard]] KeyedVectorBase<Scalar, ColKeyType, Cols> transposed() const | |
862 | { | ||
863 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
|
4 | return { this->matrix.transpose(), this->colKeys() }; |
864 | } | ||
865 | |||
866 | private: | ||
867 | /// @brief Checks if the col keys are describing a continuous block | ||
868 | /// @param colKeys Col keys | ||
869 | /// @param Q Size of the col keys | ||
870 | 8 | void checkContinuousSegment([[maybe_unused]] const std::vector<ColKeyType>& colKeys, [[maybe_unused]] size_t Q) const | |
871 | { | ||
872 | #ifndef NDEBUG | ||
873 |
1/2✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
|
8 | INS_ASSERT_USER_ERROR(Q == colKeys.size(), "The block size must be equivalent to the amount of col keys."); |
874 | |||
875 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
8 | std::vector<Eigen::Index> consecutiveCols(colKeys.size()); |
876 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
|
16 | std::iota(std::begin(consecutiveCols), std::end(consecutiveCols), this->colIndices.at(colKeys.at(0))); |
877 | 8 | std::vector<Eigen::Index> colIndices; | |
878 |
1/2✓ Branch 2 taken 4 times.
✗ Branch 3 not taken.
|
8 | colIndices.reserve(colKeys.size()); |
879 |
4/6✓ Branch 4 taken 8 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 8 times.
✓ Branch 12 taken 4 times.
|
24 | for (const auto& colKey : colKeys) { colIndices.push_back(this->colIndices.at(colKey)); } |
880 |
2/4✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
8 | INS_ASSERT_USER_ERROR(colIndices == consecutiveCols, "The given colKeys must describe a consecutive part in the matrix."); |
881 | #endif | ||
882 | 8 | } | |
883 | }; | ||
884 | |||
885 | /// @brief Class to inherit common methods for static and dynamic sized matrices | ||
886 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
887 | /// @tparam RowKeyType Type of the key used for row lookup | ||
888 | /// @tparam ColKeyType Type of the key used for col lookup | ||
889 | /// @tparam Rows Number of rows, or \b Dynamic | ||
890 | /// @tparam Cols Number of columns, or \b Dynamic | ||
891 | template<typename Scalar, typename RowKeyType, typename ColKeyType, int Rows, int Cols> | ||
892 | class KeyedMatrixBase : public KeyedMatrixRows<Scalar, RowKeyType, Rows, Cols>, public KeyedMatrixCols<Scalar, ColKeyType, Rows, Cols> | ||
893 | { | ||
894 | public: | ||
895 | /// @brief Constructor | ||
896 | /// @param matrix Eigen Matrix to initialize from | ||
897 | template<typename Derived> | ||
898 | 13678 | explicit KeyedMatrixBase(const Eigen::MatrixBase<Derived>& matrix) | |
899 | 13678 | { | |
900 |
1/2✓ Branch 1 taken 6839 times.
✗ Branch 2 not taken.
|
13678 | this->matrix = matrix; |
901 | 13678 | } | |
902 | /// @brief Non-symmetric matrix constructor | ||
903 | /// @param matrix Eigen Matrix to initialize from | ||
904 | /// @param rowKeys Row keys describing the matrix | ||
905 | /// @param colKeys Col keys describing the matrix | ||
906 | template<typename Derived> | ||
907 | 573012 | KeyedMatrixBase(const Eigen::MatrixBase<Derived>& matrix, const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) | |
908 | 573012 | { | |
909 |
4/12✓ Branch 3 taken 288935 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 288920 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 288920 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 288922 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
|
1146020 | INS_ASSERT_USER_ERROR(std::unordered_set<RowKeyType>(rowKeys.begin(), rowKeys.end()).size() == rowKeys.size(), "Each row key must be unique"); |
910 |
4/12✓ Branch 3 taken 288934 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 288932 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 288932 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 288931 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
|
1145996 | INS_ASSERT_USER_ERROR(std::unordered_set<ColKeyType>(colKeys.begin(), colKeys.end()).size() == colKeys.size(), "Each col key must be unique"); |
911 | |||
912 |
1/2✓ Branch 2 taken 288930 times.
✗ Branch 3 not taken.
|
573016 | INS_ASSERT_USER_ERROR(matrix.rows() == static_cast<Eigen::Index>(rowKeys.size()), "Number of matrix rows doesn't correspond to the amount of row keys"); |
913 |
1/2✓ Branch 2 taken 288926 times.
✗ Branch 3 not taken.
|
573014 | INS_ASSERT_USER_ERROR(matrix.cols() == static_cast<Eigen::Index>(colKeys.size()), "Number of matrix cols doesn't correspond to the amount of col keys"); |
914 | |||
915 |
1/2✓ Branch 1 taken 153689 times.
✗ Branch 2 not taken.
|
307378 | INS_ASSERT_USER_ERROR(Rows == Eigen::Dynamic || Rows == static_cast<int>(rowKeys.size()), "Number of matrix rows doesn't correspond to the static amount of row keys"); |
916 |
1/2✓ Branch 1 taken 153689 times.
✗ Branch 2 not taken.
|
307378 | INS_ASSERT_USER_ERROR(Cols == Eigen::Dynamic || Cols == static_cast<int>(colKeys.size()), "Number of matrix cols doesn't correspond to the static amount of col keys"); |
917 | |||
918 |
8/10✓ Branch 1 taken 2980230 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 20 times.
✓ Branch 5 taken 2980216 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 20 times.
✓ Branch 8 taken 2980200 times.
✓ Branch 9 taken 288924 times.
✓ Branch 11 taken 20 times.
✓ Branch 12 taken 7 times.
|
6518896 | for (size_t i = 0; i < rowKeys.size(); i++) { this->rowIndices.insert({ rowKeys.at(i), static_cast<Eigen::Index>(i) }); } |
919 |
8/10✓ Branch 1 taken 3166532 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 9 times.
✓ Branch 5 taken 3166522 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 9 times.
✓ Branch 8 taken 3166523 times.
✓ Branch 9 taken 288923 times.
✓ Branch 11 taken 9 times.
✓ Branch 12 taken 3 times.
|
6891526 | for (size_t i = 0; i < colKeys.size(); i++) { this->colIndices.insert({ colKeys.at(i), static_cast<Eigen::Index>(i) }); } |
920 | |||
921 |
1/2✓ Branch 1 taken 288922 times.
✗ Branch 2 not taken.
|
573006 | this->matrix = matrix; |
922 |
1/2✓ Branch 1 taken 288924 times.
✗ Branch 2 not taken.
|
572998 | this->rowKeysVector = rowKeys; |
923 |
1/2✓ Branch 1 taken 288929 times.
✗ Branch 2 not taken.
|
573002 | this->colKeysVector = colKeys; |
924 |
1/2✓ Branch 2 taken 288926 times.
✗ Branch 3 not taken.
|
573012 | this->colSlice.reserve(this->colKeysVector.size()); |
925 |
1/2✓ Branch 2 taken 288928 times.
✗ Branch 3 not taken.
|
573006 | this->rowSlice.reserve(this->rowKeysVector.size()); |
926 | 573010 | } | |
927 | |||
928 | // ####################################################################################################### | ||
929 | // Special member functions | ||
930 | // ####################################################################################################### | ||
931 | |||
932 | /// @brief Destructor | ||
933 | 1033988 | ~KeyedMatrixBase() = default; | |
934 | /// @brief Copy constructor | ||
935 | /// @param other The other object | ||
936 | 226036 | KeyedMatrixBase(const KeyedMatrixBase& other) | |
937 | 226036 | { | |
938 |
1/2✓ Branch 1 taken 113038 times.
✗ Branch 2 not taken.
|
226070 | this->matrix = other.matrix; |
939 |
1/2✓ Branch 1 taken 113030 times.
✗ Branch 2 not taken.
|
226076 | this->rowIndices = other.rowIndices; |
940 |
1/2✓ Branch 1 taken 113030 times.
✗ Branch 2 not taken.
|
226060 | this->rowKeysVector = other.rowKeysVector; |
941 |
1/2✓ Branch 1 taken 113032 times.
✗ Branch 2 not taken.
|
226060 | this->colIndices = other.colIndices; |
942 |
1/2✓ Branch 1 taken 113033 times.
✗ Branch 2 not taken.
|
226064 | this->colKeysVector = other.colKeysVector; |
943 |
1/2✓ Branch 2 taken 113034 times.
✗ Branch 3 not taken.
|
226066 | this->colSlice.reserve(this->colKeysVector.size()); |
944 |
1/2✓ Branch 2 taken 113033 times.
✗ Branch 3 not taken.
|
226068 | this->rowSlice.reserve(this->rowKeysVector.size()); |
945 | 226066 | } | |
946 | /// @brief Copy assignment operator | ||
947 | /// @param other The other object | ||
948 | 4 | KeyedMatrixBase& operator=(const KeyedMatrixBase& other) | |
949 | { | ||
950 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
4 | if (this == &other) { return *this; } // Guard self assignment |
951 | |||
952 | 4 | this->matrix = other.matrix; | |
953 | 4 | this->rowIndices = other.rowIndices; | |
954 | 4 | this->rowKeysVector = other.rowKeysVector; | |
955 | 4 | this->colIndices = other.colIndices; | |
956 | 4 | this->colKeysVector = other.colKeysVector; | |
957 | 4 | this->colSlice.reserve(this->colKeysVector.size()); | |
958 | 4 | this->rowSlice.reserve(this->rowKeysVector.size()); | |
959 | |||
960 | 4 | return *this; | |
961 | } | ||
962 | /// @brief Move constructor | ||
963 | /// @param other The other object | ||
964 | 211512 | KeyedMatrixBase(KeyedMatrixBase&& other) noexcept | |
965 | 211512 | { | |
966 | 211526 | this->matrix = std::move(other.matrix); | |
967 | 211518 | this->rowIndices = std::move(other.rowIndices); | |
968 | 211512 | this->rowKeysVector = std::move(other.rowKeysVector); | |
969 | 211516 | this->colIndices = std::move(other.colIndices); | |
970 | 211520 | this->colKeysVector = std::move(other.colKeysVector); | |
971 | 211520 | this->colSlice.reserve(this->colKeysVector.size()); | |
972 | 211522 | this->rowSlice.reserve(this->rowKeysVector.size()); | |
973 | 211522 | } | |
974 | /// @brief Move assignment operator | ||
975 | /// @param other The other object | ||
976 | 48866 | KeyedMatrixBase& operator=(KeyedMatrixBase&& other) noexcept | |
977 | { | ||
978 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24433 times.
|
48866 | if (this == &other) { return *this; } // Guard self assignment |
979 | |||
980 | 48866 | this->matrix = std::move(other.matrix); | |
981 | 48866 | this->rowIndices = std::move(other.rowIndices); | |
982 | 48866 | this->rowKeysVector = std::move(other.rowKeysVector); | |
983 | 48866 | this->colIndices = std::move(other.colIndices); | |
984 | 48866 | this->colKeysVector = std::move(other.colKeysVector); | |
985 | 48866 | this->colSlice.reserve(this->colKeysVector.size()); | |
986 | 48866 | this->rowSlice.reserve(this->rowKeysVector.size()); | |
987 | |||
988 | 48866 | return *this; | |
989 | } | ||
990 | |||
991 | // ########################################################################################################### | ||
992 | // Special member functions with different Rows/Cols | ||
993 | // ########################################################################################################### | ||
994 | |||
995 | /// @brief Copy constructor | ||
996 | /// @param other The other object | ||
997 | template<int oRows, int oCols> | ||
998 | 4 | KeyedMatrixBase(const KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, oRows, oCols>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
999 | 4 | { | |
1000 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | INS_ASSERT_USER_ERROR(Rows == Eigen::Dynamic || other.rows() == Rows, "Can only copy construct dynamic<=>static matrices if the rows match"); |
1001 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | INS_ASSERT_USER_ERROR(Cols == Eigen::Dynamic || other.cols() == Cols, "Can only copy construct dynamic<=>static matrices if the cols match"); |
1002 | |||
1003 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | this->matrix = other.matrix; |
1004 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | this->rowIndices = other.rowIndices; |
1005 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | this->rowKeysVector = other.rowKeysVector; |
1006 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | this->colIndices = other.colIndices; |
1007 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | this->colKeysVector = other.colKeysVector; |
1008 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
4 | this->colSlice.reserve(this->colKeysVector.size()); |
1009 |
1/2✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
4 | this->rowSlice.reserve(this->rowKeysVector.size()); |
1010 | 4 | } | |
1011 | /// @brief Copy assignment operator | ||
1012 | /// @param other The other object | ||
1013 | template<int oRows, int oCols> | ||
1014 | 4 | KeyedMatrixBase& operator=(const KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, oRows, oCols>& other) | |
1015 | { | ||
1016 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
1017 | |||
1018 |
1/2✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
4 | INS_ASSERT_USER_ERROR(other.rowKeys() == this->rowKeys(), "Can only copy assign matrices if the row keys match"); |
1019 |
1/2✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
|
4 | INS_ASSERT_USER_ERROR(other.colKeys() == this->colKeys(), "Can only copy assign matrices if the col keys match"); |
1020 | |||
1021 | 4 | this->matrix = other.matrix; | |
1022 | 4 | this->rowIndices = other.rowIndices; | |
1023 | 4 | this->rowKeysVector = other.rowKeysVector; | |
1024 | 4 | this->colIndices = other.colIndices; | |
1025 | 4 | this->colKeysVector = other.colKeysVector; | |
1026 | 4 | this->colSlice.reserve(this->colKeysVector.size()); | |
1027 | 4 | this->rowSlice.reserve(this->rowKeysVector.size()); | |
1028 | |||
1029 | 4 | return *this; | |
1030 | } | ||
1031 | /// @brief Move constructor | ||
1032 | /// @param other The other object | ||
1033 | template<int oRows, int oCols> | ||
1034 | 4 | KeyedMatrixBase(KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, oRows, oCols>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
1035 | 4 | { | |
1036 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | INS_ASSERT_USER_ERROR(Rows == Eigen::Dynamic || other.rows() == Rows, "Can only copy construct dynamic<=>static matrices if the rows match"); |
1037 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
2 | INS_ASSERT_USER_ERROR(Cols == Eigen::Dynamic || other.cols() == Cols, "Can only copy construct dynamic<=>static matrices if the cols match"); |
1038 | |||
1039 | 4 | this->matrix = std::move(other.matrix); | |
1040 | 4 | this->rowIndices = std::move(other.rowIndices); | |
1041 | 4 | this->rowKeysVector = std::move(other.rowKeysVector); | |
1042 | 4 | this->colIndices = std::move(other.colIndices); | |
1043 | 4 | this->colKeysVector = std::move(other.colKeysVector); | |
1044 | 4 | this->colSlice.reserve(this->colKeysVector.size()); | |
1045 | 4 | this->rowSlice.reserve(this->rowKeysVector.size()); | |
1046 | 4 | } | |
1047 | /// @brief Move assignment operator | ||
1048 | /// @param other The other object | ||
1049 | template<int oRows, int oCols> | ||
1050 | 307346 | KeyedMatrixBase& operator=(KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, oRows, oCols>&& other) noexcept | |
1051 | { | ||
1052 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
1053 | |||
1054 |
1/2✓ Branch 3 taken 153673 times.
✗ Branch 4 not taken.
|
307346 | INS_ASSERT_USER_ERROR(other.rowKeys() == this->rowKeys(), "Can only copy assign matrices if the row keys match"); |
1055 |
1/2✓ Branch 3 taken 153673 times.
✗ Branch 4 not taken.
|
307346 | INS_ASSERT_USER_ERROR(other.colKeys() == this->colKeys(), "Can only copy assign matrices if the col keys match"); |
1056 | |||
1057 | 307346 | this->matrix = std::move(other.matrix); | |
1058 | 307346 | this->rowIndices = std::move(other.rowIndices); | |
1059 | 307346 | this->rowKeysVector = std::move(other.rowKeysVector); | |
1060 | 307346 | this->colIndices = std::move(other.colIndices); | |
1061 | 307346 | this->colKeysVector = std::move(other.colKeysVector); | |
1062 | 307346 | this->colSlice.reserve(this->colKeysVector.size()); | |
1063 | 307346 | this->rowSlice.reserve(this->rowKeysVector.size()); | |
1064 | |||
1065 | 307346 | return *this; | |
1066 | } | ||
1067 | |||
1068 | // ####################################################################################################### | ||
1069 | // Access | ||
1070 | // ####################################################################################################### | ||
1071 | |||
1072 | /// @brief Gets the value for the row and col key | ||
1073 | /// @param rowKey Row Key | ||
1074 | /// @param colKey Col Key | ||
1075 | /// @return Scalar value | ||
1076 | 12449 | const Scalar& operator()(const RowKeyType& rowKey, const ColKeyType& colKey) const | |
1077 | { | ||
1078 | 12449 | return this->matrix(this->rowIndices.at(rowKey), this->colIndices.at(colKey)); | |
1079 | } | ||
1080 | /// @brief Gets the value for the row and col key | ||
1081 | /// @param rowKey Row Key | ||
1082 | /// @param colKey Col Key | ||
1083 | /// @return Scalar value | ||
1084 | 286366 | Scalar& operator()(const RowKeyType& rowKey, const ColKeyType& colKey) | |
1085 | { | ||
1086 | 286366 | return this->matrix(this->rowIndices.at(rowKey), this->colIndices.at(colKey)); | |
1087 | } | ||
1088 | |||
1089 | /// @brief Gets the values for the row and col keys | ||
1090 | /// @param rowKeys Row Keys | ||
1091 | /// @param colKeys Col Keys | ||
1092 | /// @return View into the matrix for the row and col keys | ||
1093 | 77332 | decltype(auto) operator()(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) const | |
1094 | { | ||
1095 | 77332 | this->rowSlice.clear(); | |
1096 |
4/6✓ Branch 4 taken 309316 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 309316 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 309316 times.
✓ Branch 12 taken 77330 times.
|
386652 | for (const auto& rowKey : rowKeys) { this->rowSlice.push_back(this->rowIndices.at(rowKey)); } |
1097 | |||
1098 | 77332 | this->colSlice.clear(); | |
1099 |
4/6✓ Branch 4 taken 309316 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 309316 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 309316 times.
✓ Branch 12 taken 77330 times.
|
386652 | for (const auto& colKey : colKeys) { this->colSlice.push_back(this->colIndices.at(colKey)); } |
1100 | |||
1101 | 77332 | return this->matrix(this->rowSlice, this->colSlice); | |
1102 | } | ||
1103 | /// @brief Gets the values for the row and col keys | ||
1104 | /// @param rowKeys Row Keys | ||
1105 | /// @param colKeys Col Keys | ||
1106 | /// @return View into the matrix for the row and col keys | ||
1107 | 1291622 | decltype(auto) operator()(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) | |
1108 | { | ||
1109 | 1291622 | this->rowSlice.clear(); | |
1110 |
4/6✓ Branch 4 taken 2172726 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2172717 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 2172732 times.
✓ Branch 12 taken 647038 times.
|
5629751 | for (const auto& rowKey : rowKeys) { this->rowSlice.push_back(this->rowIndices.at(rowKey)); } |
1111 | |||
1112 | 1291650 | this->colSlice.clear(); | |
1113 |
4/6✓ Branch 4 taken 2172778 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2172751 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 2172783 times.
✓ Branch 12 taken 647038 times.
|
5629877 | for (const auto& colKey : colKeys) { this->colSlice.push_back(this->colIndices.at(colKey)); } |
1114 | |||
1115 | 1291650 | return this->matrix(this->rowSlice, this->colSlice); | |
1116 | } | ||
1117 | /// @brief Gets the values for the row and col keys | ||
1118 | /// @param rowKeys Row Keys | ||
1119 | /// @param colKey Col Key | ||
1120 | /// @return View into the matrix for the row and col keys | ||
1121 | decltype(auto) operator()(const std::vector<RowKeyType>& rowKeys, const ColKeyType& colKey) const { return (*this)(rowKeys, std::vector{ colKey }); } | ||
1122 | /// @brief Gets the values for the row and col keys | ||
1123 | /// @param rowKeys Row Keys | ||
1124 | /// @param colKey Col Key | ||
1125 | /// @return View into the matrix for the row and col keys | ||
1126 |
5/14✓ Branch 1 taken 4 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 4 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
|
26 | decltype(auto) operator()(const std::vector<RowKeyType>& rowKeys, const ColKeyType& colKey) { return (*this)(rowKeys, std::vector{ colKey }); } |
1127 | /// @brief Gets the values for the row and col keys | ||
1128 | /// @param rowKey Row Key | ||
1129 | /// @param colKeys Col Keys | ||
1130 | /// @return View into the matrix for the row and col keys | ||
1131 | decltype(auto) operator()(const RowKeyType& rowKey, const std::vector<ColKeyType>& colKeys) const { return (*this)(std::vector{ rowKey }, colKeys); } | ||
1132 | /// @brief Gets the values for the row and col keys | ||
1133 | /// @param rowKey Row Key | ||
1134 | /// @param colKeys Col Keys | ||
1135 | /// @return View into the matrix for the row and col keys | ||
1136 |
5/14✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 3 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
|
20 | decltype(auto) operator()(const RowKeyType& rowKey, const std::vector<ColKeyType>& colKeys) { return (*this)(std::vector{ rowKey }, colKeys); } |
1137 | |||
1138 | /// @brief Gets the values for the row key | ||
1139 | /// @param rowKey Row Key | ||
1140 | /// @return View into the matrix for the row key | ||
1141 | decltype(auto) operator()(const RowKeyType& rowKey, all_t /* all */) const { return (*this)(std::vector{ rowKey }, this->colKeys()); } | ||
1142 | /// @brief Gets the values for the row key | ||
1143 | /// @param rowKey Row Key | ||
1144 | /// @return View into the matrix for the row key | ||
1145 |
5/14✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✓ Branch 12 taken 1 times.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
|
18 | decltype(auto) operator()(const RowKeyType& rowKey, all_t /* all */) { return (*this)(std::vector{ rowKey }, this->colKeys()); } |
1146 | /// @brief Gets the values for the col key | ||
1147 | /// @param colKey Col Key | ||
1148 | /// @return View into the matrix for the col key | ||
1149 | decltype(auto) operator()(all_t /* all */, const ColKeyType& colKey) const { return *this(this->rowKeys(), std::vector{ colKey }); } | ||
1150 | /// @brief Gets the values for the col keys | ||
1151 | /// @param colKey Col Key | ||
1152 | /// @return View into the matrix for the col key | ||
1153 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
|
3 | decltype(auto) operator()(all_t /* all */, const ColKeyType& colKey) { return (*this)(this->rowKeys(), std::vector{ colKey }); } |
1154 | /// @brief Gets the values for the row keys | ||
1155 | /// @param rowKeys Row Keys | ||
1156 | /// @return View into the matrix for the row keys | ||
1157 | decltype(auto) operator()(const std::vector<RowKeyType>& rowKeys, all_t /* all */) const { return (*this)(rowKeys, this->colKeys()); } | ||
1158 | /// @brief Gets the values for the row keys | ||
1159 | /// @param rowKeys Row Keys | ||
1160 | /// @return View into the matrix for the row keys | ||
1161 | 6 | decltype(auto) operator()(const std::vector<RowKeyType>& rowKeys, all_t /* all */) { return (*this)(rowKeys, this->colKeys()); } | |
1162 | /// @brief Gets the values for the col keys | ||
1163 | /// @param colKeys Col Keys | ||
1164 | /// @return View into the matrix for the col keys | ||
1165 | decltype(auto) operator()(all_t /* all */, const std::vector<ColKeyType>& colKeys) const { return (*this)(this->rowKeys(), colKeys); } | ||
1166 | /// @brief Gets the values for the col keys | ||
1167 | /// @param colKeys Col Keys | ||
1168 | /// @return View into the matrix for the col keys | ||
1169 | 1 | decltype(auto) operator()(all_t /* all */, const std::vector<ColKeyType>& colKeys) { return (*this)(this->rowKeys(), colKeys); } | |
1170 | |||
1171 | /// @brief Requests the full matrix | ||
1172 | 103072 | const Eigen::Matrix<Scalar, Rows, Cols>& operator()(all_t /* all */, all_t /* all */) const { return this->matrix; } | |
1173 | /// @brief Requests the full matrix | ||
1174 | 3124648 | Eigen::Matrix<Scalar, Rows, Cols>& operator()(all_t /* all */, all_t /* all */) { return this->matrix; } | |
1175 | /// @brief Conversion into Eigen::Matrix | ||
1176 | explicit operator Eigen::Matrix<Scalar, Rows, Cols>() { return this->matrix; } | ||
1177 | |||
1178 | // ########################################################################################################### | ||
1179 | // Static Block operations | ||
1180 | // ########################################################################################################### | ||
1181 | |||
1182 | /// @brief Gets the values for the row and col keys | ||
1183 | /// @param rowKeys Row Keys | ||
1184 | /// @param colKeys Col Keys | ||
1185 | /// @return View into the matrix for the row and col keys | ||
1186 | template<size_t P, size_t Q = P> | ||
1187 | ✗ | decltype(auto) block(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) const // NOLINT(readability-const-return-type) | |
1188 | { | ||
1189 | ✗ | checkContinuousBlock(rowKeys, colKeys, P, Q); | |
1190 | |||
1191 | ✗ | return this->matrix.template block<P, Q>(this->rowIndices.at(rowKeys.at(0)), this->colIndices.at(colKeys.at(0))); | |
1192 | } | ||
1193 | /// @brief Gets the values for the row and col keys | ||
1194 | /// @param rowKeys Row Keys | ||
1195 | /// @param colKeys Col Keys | ||
1196 | /// @return View into the matrix for the row and col keys | ||
1197 | template<size_t P, size_t Q = P> | ||
1198 | 2759642 | decltype(auto) block(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) | |
1199 | { | ||
1200 | 2759642 | checkContinuousBlock(rowKeys, colKeys, P, Q); | |
1201 | |||
1202 | 2759642 | return this->matrix.template block<P, Q>(this->rowIndices.at(rowKeys.at(0)), this->colIndices.at(colKeys.at(0))); | |
1203 | } | ||
1204 | /// @brief Gets the values for the row and col keys | ||
1205 | /// @param rowKeys Row Keys | ||
1206 | /// @param colKey Col Key | ||
1207 | /// @return View into the matrix for the row and col keys | ||
1208 | template<size_t P> | ||
1209 | decltype(auto) block(const std::vector<RowKeyType>& rowKeys, const ColKeyType& colKey) const // NOLINT(readability-const-return-type) | ||
1210 | { | ||
1211 | return this->block<P, 1>(rowKeys, std::vector{ colKey }); | ||
1212 | } | ||
1213 | /// @brief Gets the values for the row and col keys | ||
1214 | /// @param rowKeys Row Keys | ||
1215 | /// @param colKey Col Key | ||
1216 | /// @return View into the matrix for the row and col keys | ||
1217 | template<size_t P> | ||
1218 | 4 | decltype(auto) block(const std::vector<RowKeyType>& rowKeys, const ColKeyType& colKey) | |
1219 | { | ||
1220 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
12 | return this->block<P, 1>(rowKeys, std::vector{ colKey }); |
1221 | } | ||
1222 | /// @brief Gets the values for the row and col keys | ||
1223 | /// @param rowKey Row Key | ||
1224 | /// @param colKeys Col Keys | ||
1225 | /// @return View into the matrix for the row and col keys | ||
1226 | template<size_t Q> | ||
1227 | decltype(auto) block(const RowKeyType& rowKey, const std::vector<ColKeyType>& colKeys) const // NOLINT(readability-const-return-type) | ||
1228 | { | ||
1229 | return this->block<1, Q>(std::vector{ rowKey }, colKeys); | ||
1230 | } | ||
1231 | /// @brief Gets the values for the row and col keys | ||
1232 | /// @param rowKey Row Key | ||
1233 | /// @param colKeys Col Keys | ||
1234 | /// @return View into the matrix for the row and col keys | ||
1235 | template<size_t Q> | ||
1236 | 95149 | decltype(auto) block(const RowKeyType& rowKey, const std::vector<ColKeyType>& colKeys) | |
1237 | { | ||
1238 |
2/4✓ Branch 1 taken 95147 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 95147 times.
✗ Branch 5 not taken.
|
285447 | return this->block<1, Q>(std::vector{ rowKey }, colKeys); |
1239 | } | ||
1240 | |||
1241 | /// @brief Gets the values for the row keys | ||
1242 | /// @param rowKeys Row Keys | ||
1243 | /// @return View into the matrix for the row keys | ||
1244 | template<size_t P> | ||
1245 | decltype(auto) middleRows(const std::vector<RowKeyType>& rowKeys) const // NOLINT(readability-const-return-type) | ||
1246 | { | ||
1247 | checkContinuousBlock(rowKeys, this->colKeys(), P, this->colKeys().size()); | ||
1248 | |||
1249 | return this->matrix.template middleRows<P>(this->rowIndices.at(rowKeys.at(0))); | ||
1250 | } | ||
1251 | /// @brief Gets the values for the row keys | ||
1252 | /// @param rowKeys Row Keys | ||
1253 | /// @return View into the matrix for the row keys | ||
1254 | template<size_t P> | ||
1255 | 515454 | decltype(auto) middleRows(const std::vector<RowKeyType>& rowKeys) | |
1256 | { | ||
1257 | 515454 | checkContinuousBlock(rowKeys, this->colKeys(), P, this->colKeys().size()); | |
1258 | |||
1259 | 515454 | return this->matrix.template middleRows<P>(this->rowIndices.at(rowKeys.at(0))); | |
1260 | } | ||
1261 | /// @brief Gets the values for the col keys | ||
1262 | /// @param colKeys Col Keys | ||
1263 | /// @return View into the matrix for the col keys | ||
1264 | template<size_t Q> | ||
1265 | decltype(auto) middleCols(const std::vector<ColKeyType>& colKeys) const // NOLINT(readability-const-return-type) | ||
1266 | { | ||
1267 | checkContinuousBlock(this->rowKeys(), colKeys, this->rowKeys().size(), Q); | ||
1268 | |||
1269 | return this->matrix.template middleCols<Q>(this->colIndices.at(colKeys.at(0))); | ||
1270 | } | ||
1271 | /// @brief Gets the values for the col keys | ||
1272 | /// @param colKeys Col Keys | ||
1273 | /// @return View into the matrix for the col keys | ||
1274 | template<size_t Q> | ||
1275 | 622706 | decltype(auto) middleCols(const std::vector<ColKeyType>& colKeys) | |
1276 | { | ||
1277 | 622706 | checkContinuousBlock(this->rowKeys(), colKeys, this->rowKeys().size(), Q); | |
1278 | |||
1279 | 622706 | return this->matrix.template middleCols<Q>(this->colIndices.at(colKeys.at(0))); | |
1280 | } | ||
1281 | /// @brief Gets the values for the row key | ||
1282 | /// @param rowKey Row Key | ||
1283 | /// @return View into the matrix for the row key | ||
1284 | decltype(auto) row(const RowKeyType& rowKey) const { return this->matrix.row(this->rowIndices.at(rowKey)); } | ||
1285 | /// @brief Gets the values for the row key | ||
1286 | /// @param rowKey Row Key | ||
1287 | /// @return View into the matrix for the row key | ||
1288 | 4 | decltype(auto) row(const RowKeyType& rowKey) { return this->matrix.row(this->rowIndices.at(rowKey)); } | |
1289 | /// @brief Gets the values for the col key | ||
1290 | /// @param colKey Col Key | ||
1291 | /// @return View into the matrix for the col key | ||
1292 | decltype(auto) col(const ColKeyType& colKey) const { return this->matrix.col(this->colIndices.at(colKey)); } | ||
1293 | /// @brief Gets the values for the col key | ||
1294 | /// @param colKey Col Key | ||
1295 | /// @return View into the matrix for the col key | ||
1296 | 4 | decltype(auto) col(const ColKeyType& colKey) { return this->matrix.col(this->colIndices.at(colKey)); } | |
1297 | |||
1298 | /// @brief Requests the full matrix | ||
1299 | const Eigen::Matrix<Scalar, Rows, Cols>& block(all_t /* all */, all_t /* all */) const { return this->matrix; } | ||
1300 | /// @brief Requests the full matrix | ||
1301 | 4 | Eigen::Matrix<Scalar, Rows, Cols>& block(all_t /* all */, all_t /* all */) { return this->matrix; } | |
1302 | |||
1303 | // ########################################################################################################### | ||
1304 | // Dynamic block operations | ||
1305 | // ########################################################################################################### | ||
1306 | |||
1307 | /// @brief Gets the values for the row and col keys | ||
1308 | /// @param rowKeys Row Keys | ||
1309 | /// @param colKeys Col Keys | ||
1310 | /// @return View into the matrix for the row and col keys | ||
1311 | decltype(auto) block(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) const | ||
1312 | { | ||
1313 | checkContinuousBlock(rowKeys, colKeys, rowKeys.size(), colKeys.size()); | ||
1314 | |||
1315 | return this->matrix.block(this->rowIndices.at(rowKeys.at(0)), this->colIndices.at(colKeys.at(0)), rowKeys.size(), colKeys.size()); | ||
1316 | } | ||
1317 | /// @brief Gets the values for the row and col keys | ||
1318 | /// @param rowKeys Row Keys | ||
1319 | /// @param colKeys Col Keys | ||
1320 | /// @return View into the matrix for the row and col keys | ||
1321 | 16 | decltype(auto) block(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) | |
1322 | { | ||
1323 | 16 | checkContinuousBlock(rowKeys, colKeys, rowKeys.size(), colKeys.size()); | |
1324 | |||
1325 | 16 | return this->matrix.block(this->rowIndices.at(rowKeys.at(0)), this->colIndices.at(colKeys.at(0)), rowKeys.size(), colKeys.size()); | |
1326 | } | ||
1327 | /// @brief Gets the values for the row and col keys | ||
1328 | /// @param rowKeys Row Keys | ||
1329 | /// @param colKey Col Key | ||
1330 | /// @return View into the matrix for the row and col keys | ||
1331 | decltype(auto) block(const std::vector<RowKeyType>& rowKeys, const ColKeyType& colKey) const | ||
1332 | { | ||
1333 | return this->block(rowKeys, std::vector{ colKey }); | ||
1334 | } | ||
1335 | /// @brief Gets the values for the row and col keys | ||
1336 | /// @param rowKeys Row Keys | ||
1337 | /// @param colKey Col Key | ||
1338 | /// @return View into the matrix for the row and col keys | ||
1339 | 4 | decltype(auto) block(const std::vector<RowKeyType>& rowKeys, const ColKeyType& colKey) | |
1340 | { | ||
1341 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
12 | return this->block(rowKeys, std::vector{ colKey }); |
1342 | } | ||
1343 | /// @brief Gets the values for the row and col keys | ||
1344 | /// @param rowKey Row Key | ||
1345 | /// @param colKeys Col Keys | ||
1346 | /// @return View into the matrix for the row and col keys | ||
1347 | decltype(auto) block(const RowKeyType& rowKey, const std::vector<ColKeyType>& colKeys) const | ||
1348 | { | ||
1349 | return this->block(std::vector{ rowKey }, colKeys); | ||
1350 | } | ||
1351 | /// @brief Gets the values for the row and col keys | ||
1352 | /// @param rowKey Row Key | ||
1353 | /// @param colKeys Col Keys | ||
1354 | /// @return View into the matrix for the row and col keys | ||
1355 | 4 | decltype(auto) block(const RowKeyType& rowKey, const std::vector<ColKeyType>& colKeys) | |
1356 | { | ||
1357 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
|
12 | return this->block(std::vector{ rowKey }, colKeys); |
1358 | } | ||
1359 | |||
1360 | /// @brief Gets the values for the row keys | ||
1361 | /// @param rowKeys Row Keys | ||
1362 | /// @return View into the matrix for the row keys | ||
1363 | decltype(auto) middleRows(const std::vector<RowKeyType>& rowKeys) const | ||
1364 | { | ||
1365 | checkContinuousBlock(rowKeys, this->colKeys(), rowKeys.size(), this->colKeys().size()); | ||
1366 | |||
1367 | return this->matrix.middleRows(this->rowIndices.at(rowKeys.at(0)), rowKeys.size()); | ||
1368 | } | ||
1369 | /// @brief Gets the values for the row keys | ||
1370 | /// @param rowKeys Row Keys | ||
1371 | /// @return View into the matrix for the row keys | ||
1372 | 4 | decltype(auto) middleRows(const std::vector<RowKeyType>& rowKeys) | |
1373 | { | ||
1374 | 4 | checkContinuousBlock(rowKeys, this->colKeys(), rowKeys.size(), this->colKeys().size()); | |
1375 | |||
1376 | 4 | return this->matrix.middleRows(this->rowIndices.at(rowKeys.at(0)), rowKeys.size()); | |
1377 | } | ||
1378 | /// @brief Gets the values for the col keys | ||
1379 | /// @param colKeys Col Keys | ||
1380 | /// @return View into the matrix for the col keys | ||
1381 | decltype(auto) middleCols(const std::vector<ColKeyType>& colKeys) const | ||
1382 | { | ||
1383 | checkContinuousBlock(this->rowKeys(), colKeys, this->rowKeys().size(), colKeys.size()); | ||
1384 | |||
1385 | return this->matrix.middleCols(this->colIndices.at(colKeys.at(0)), colKeys.size()); | ||
1386 | } | ||
1387 | /// @brief Gets the values for the col keys | ||
1388 | /// @param colKeys Col Keys | ||
1389 | /// @return View into the matrix for the col keys | ||
1390 | 4 | decltype(auto) middleCols(const std::vector<ColKeyType>& colKeys) | |
1391 | { | ||
1392 | 4 | checkContinuousBlock(this->rowKeys(), colKeys, this->rowKeys().size(), colKeys.size()); | |
1393 | |||
1394 | 4 | return this->matrix.middleCols(this->colIndices.at(colKeys.at(0)), colKeys.size()); | |
1395 | } | ||
1396 | |||
1397 | // ####################################################################################################### | ||
1398 | // Methods | ||
1399 | // ####################################################################################################### | ||
1400 | |||
1401 | /// @brief Calculates the transposed matrix | ||
1402 | 4 | [[nodiscard]] KeyedMatrixBase<Scalar, ColKeyType, RowKeyType, Cols, Rows> transposed() const | |
1403 | { | ||
1404 |
2/4✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
|
4 | return { this->matrix.transpose(), this->colKeys(), this->rowKeys() }; |
1405 | } | ||
1406 | |||
1407 | /// @brief Calculates the inverse matrix | ||
1408 | 410 | [[nodiscard]] KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols> inverse() const | |
1409 | { | ||
1410 |
2/4✓ Branch 1 taken 408 times.
✗ Branch 2 not taken.
✓ Branch 6 taken 408 times.
✗ Branch 7 not taken.
|
410 | return { this->matrix.inverse(), this->rowKeys(), this->colKeys() }; |
1411 | } | ||
1412 | |||
1413 | private: | ||
1414 | /// @brief Checks if the row and col keys are describing a continuous block | ||
1415 | /// @param rowKeys Row keys | ||
1416 | /// @param colKeys Col keys | ||
1417 | /// @param P Size of the row keys | ||
1418 | /// @param Q Size of the col keys | ||
1419 | 3897826 | void checkContinuousBlock([[maybe_unused]] const std::vector<RowKeyType>& rowKeys, [[maybe_unused]] const std::vector<ColKeyType>& colKeys, | |
1420 | [[maybe_unused]] size_t P, [[maybe_unused]] size_t Q) const | ||
1421 | { | ||
1422 | #ifndef NDEBUG | ||
1423 |
1/2✓ Branch 1 taken 1948913 times.
✗ Branch 2 not taken.
|
3897826 | INS_ASSERT_USER_ERROR(P == rowKeys.size(), "The block size must be equivalent to the amount of row keys."); |
1424 |
1/2✓ Branch 1 taken 1948913 times.
✗ Branch 2 not taken.
|
3897826 | INS_ASSERT_USER_ERROR(Q == colKeys.size(), "The block size must be equivalent to the amount of col keys."); |
1425 | |||
1426 |
1/2✓ Branch 2 taken 1948913 times.
✗ Branch 3 not taken.
|
3897826 | std::vector<Eigen::Index> consecutiveRows(rowKeys.size()); |
1427 |
2/4✓ Branch 1 taken 1948913 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1948913 times.
✗ Branch 5 not taken.
|
7795652 | std::iota(std::begin(consecutiveRows), std::end(consecutiveRows), this->rowIndices.at(rowKeys.at(0))); |
1428 | 3897826 | std::vector<Eigen::Index> rowIndices; | |
1429 |
1/2✓ Branch 2 taken 1948913 times.
✗ Branch 3 not taken.
|
3897826 | rowIndices.reserve(rowKeys.size()); |
1430 |
4/6✓ Branch 4 taken 8585767 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8585767 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 8585767 times.
✓ Branch 12 taken 1948913 times.
|
21069360 | for (const auto& rowKey : rowKeys) { rowIndices.push_back(this->rowIndices.at(rowKey)); } |
1431 |
2/4✓ Branch 1 taken 1948913 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1948913 times.
✗ Branch 4 not taken.
|
3897826 | INS_ASSERT_USER_ERROR(rowIndices == consecutiveRows, "The given rowKeys must describe a consecutive part in the matrix."); |
1432 | |||
1433 |
1/2✓ Branch 2 taken 1948913 times.
✗ Branch 3 not taken.
|
3897826 | std::vector<Eigen::Index> consecutiveCols(colKeys.size()); |
1434 |
2/4✓ Branch 1 taken 1948913 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1948913 times.
✗ Branch 5 not taken.
|
7795652 | std::iota(std::begin(consecutiveCols), std::end(consecutiveCols), this->colIndices.at(colKeys.at(0))); |
1435 | 3897826 | std::vector<Eigen::Index> colIndices; | |
1436 |
1/2✓ Branch 2 taken 1948913 times.
✗ Branch 3 not taken.
|
3897826 | colIndices.reserve(colKeys.size()); |
1437 |
4/6✓ Branch 4 taken 8844828 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8844828 times.
✗ Branch 8 not taken.
✓ Branch 11 taken 8844828 times.
✓ Branch 12 taken 1948913 times.
|
21587482 | for (const auto& colKey : colKeys) { colIndices.push_back(this->colIndices.at(colKey)); } |
1438 |
2/4✓ Branch 1 taken 1948913 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1948913 times.
✗ Branch 4 not taken.
|
3897826 | INS_ASSERT_USER_ERROR(colIndices == consecutiveCols, "The given colKeys must describe a consecutive part in the matrix."); |
1439 | #endif | ||
1440 | 3897826 | } | |
1441 | }; | ||
1442 | |||
1443 | } // namespace internal | ||
1444 | |||
1445 | /// @brief Used to request all rows or columns in KeyedMatrices | ||
1446 | static const internal::all_t all; | ||
1447 | |||
1448 | template<typename Scalar, typename ColKeyType, int Cols> | ||
1449 | class KeyedRowVector; | ||
1450 | |||
1451 | /// @brief Static sized KeyedVector | ||
1452 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
1453 | /// @tparam RowKeyType Type of the key used for row lookup | ||
1454 | /// @tparam Rows Number of rows, or \b Dynamic | ||
1455 | template<typename Scalar, typename RowKeyType, int Rows> | ||
1456 | class KeyedVector : public internal::KeyedVectorBase<Scalar, RowKeyType, Rows> | ||
1457 | { | ||
1458 | public: | ||
1459 | /// @brief Vector constructor | ||
1460 | /// @tparam Derived Derived Eigen Type | ||
1461 | /// @param vector Eigen vector to initialize from | ||
1462 | /// @param rowKeys Row keys describing the vector | ||
1463 | template<typename Derived> | ||
1464 | 26831 | KeyedVector(const Eigen::MatrixBase<Derived>& vector, const std::vector<RowKeyType>& rowKeys) | |
1465 | 26831 | : internal::KeyedVectorBase<Scalar, RowKeyType, Rows>(vector, rowKeys) | |
1466 | 26831 | {} | |
1467 | |||
1468 | // ####################################################################################################### | ||
1469 | // Special member functions | ||
1470 | // ####################################################################################################### | ||
1471 | |||
1472 | /// @brief Destructor | ||
1473 | 26839 | ~KeyedVector() = default; | |
1474 | /// @brief Copy constructor | ||
1475 | /// @param other The other object | ||
1476 | 1 | KeyedVector(const KeyedVector& other) | |
1477 | 1 | : internal::KeyedVectorBase<Scalar, RowKeyType, Rows>(other) | |
1478 | 1 | {} | |
1479 | /// @brief Copy assignment operator | ||
1480 | /// @param other The other object | ||
1481 | 1 | KeyedVector& operator=(const KeyedVector& other) | |
1482 | { | ||
1483 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (this == &other) { return *this; } // Guard self assignment |
1484 | |||
1485 | 1 | static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Rows>&>(*this) = | |
1486 | static_cast<const internal::KeyedVectorBase<Scalar, RowKeyType, Rows>&>(other); | ||
1487 | |||
1488 | 1 | return *this; | |
1489 | } | ||
1490 | /// @brief Move constructor | ||
1491 | /// @param other The other object | ||
1492 | 1 | KeyedVector(KeyedVector&& other) noexcept | |
1493 | 1 | : internal::KeyedVectorBase<Scalar, RowKeyType, Rows>(std::move(other)) | |
1494 | 1 | {} | |
1495 | /// @brief Move assignment operator | ||
1496 | /// @param other The other object | ||
1497 | 1 | KeyedVector& operator=(KeyedVector&& other) noexcept | |
1498 | { | ||
1499 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (this == &other) { return *this; } // Guard self assignment |
1500 | |||
1501 | 1 | static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Rows>&>(*this) = | |
1502 | 1 | std::move(static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Rows>&>(other)); | |
1503 | |||
1504 | 1 | return *this; | |
1505 | } | ||
1506 | |||
1507 | // ########################################################################################################### | ||
1508 | // Special member functions with different Rows/Cols | ||
1509 | // ########################################################################################################### | ||
1510 | |||
1511 | /// @brief Copy constructor | ||
1512 | /// @param other The other object | ||
1513 | 1 | KeyedVector(const KeyedVector<Scalar, RowKeyType, Eigen::Dynamic>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
1514 | 1 | : internal::KeyedVectorBase<Scalar, RowKeyType, Rows>(other) | |
1515 | { | ||
1516 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | INS_ASSERT_USER_ERROR(other.rows() == Rows, "Can only copy assign dynamic matrices from static ones if the size matches"); |
1517 | 1 | } | |
1518 | /// @brief Copy assignment operator | ||
1519 | /// @param other The other object | ||
1520 | 1 | KeyedVector& operator=(const KeyedVector<Scalar, RowKeyType, Eigen::Dynamic>& other) | |
1521 | { | ||
1522 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
1523 | |||
1524 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | INS_ASSERT_USER_ERROR(other.rows() == Rows, "Can only copy assign dynamic matrices from static ones if the size matches"); |
1525 | |||
1526 | 1 | static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Rows>&>(*this) = | |
1527 | static_cast<const internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>&>(other); | ||
1528 | |||
1529 | 1 | return *this; | |
1530 | } | ||
1531 | /// @brief Move constructor | ||
1532 | /// @param other The other object | ||
1533 | 1 | KeyedVector(KeyedVector<Scalar, RowKeyType, Eigen::Dynamic>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
1534 | 1 | : internal::KeyedVectorBase<Scalar, RowKeyType, Rows>(std::move(other)) | |
1535 | { | ||
1536 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | INS_ASSERT_USER_ERROR(this->rows() == Rows, "Can only move construct dynamic matrices from static ones if the size matches"); |
1537 | 1 | } | |
1538 | /// @brief Move assignment operator | ||
1539 | /// @param other The other object | ||
1540 | 1 | KeyedVector& operator=(KeyedVector<Scalar, RowKeyType, Eigen::Dynamic>&& other) noexcept | |
1541 | { | ||
1542 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
1543 | |||
1544 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | INS_ASSERT_USER_ERROR(other.rows() == Rows, "Can only move assign dynamic matrices from static ones if the size matches"); |
1545 | |||
1546 | 1 | static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Rows>&>(*this) = | |
1547 | 1 | std::move(static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>&>(other)); | |
1548 | |||
1549 | 1 | return *this; | |
1550 | } | ||
1551 | |||
1552 | // ####################################################################################################### | ||
1553 | // Methods | ||
1554 | // ####################################################################################################### | ||
1555 | |||
1556 | /// @brief Calculates the transposed vector | ||
1557 | 1 | [[nodiscard]] KeyedRowVector<Scalar, RowKeyType, Rows> transposed() const | |
1558 | { | ||
1559 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | auto transpose = static_cast<const internal::KeyedVectorBase<Scalar, RowKeyType, Rows>&>(*this).transposed(); |
1560 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | return { transpose(all), transpose.colKeys() }; |
1561 | 1 | } | |
1562 | }; | ||
1563 | |||
1564 | /// @brief Dynamic sized KeyedVector | ||
1565 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
1566 | /// @tparam RowKeyType Type of the key used for row lookup | ||
1567 | template<typename Scalar, typename RowKeyType> | ||
1568 | class KeyedVector<Scalar, RowKeyType, Eigen::Dynamic> : public internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic> | ||
1569 | { | ||
1570 | public: | ||
1571 | /// @brief Default Constructor | ||
1572 | 2842 | KeyedVector() | |
1573 |
2/4✓ Branch 2 taken 2030 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 2030 times.
✗ Branch 6 not taken.
|
2842 | : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(Eigen::VectorX<Scalar>()) {} |
1574 | |||
1575 | /// @brief Vector constructor | ||
1576 | /// @tparam Derived Derived Eigen Type | ||
1577 | /// @param vector Eigen vector to initialize from | ||
1578 | /// @param rowKeys Row keys describing the vector | ||
1579 | template<typename Derived> | ||
1580 | 4842 | KeyedVector(const Eigen::MatrixBase<Derived>& vector, const std::vector<RowKeyType>& rowKeys) | |
1581 |
1/2✓ Branch 2 taken 2421 times.
✗ Branch 3 not taken.
|
4842 | : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(vector, rowKeys) |
1582 | 4842 | {} | |
1583 | |||
1584 | // ####################################################################################################### | ||
1585 | // Special member functions | ||
1586 | // ####################################################################################################### | ||
1587 | |||
1588 | /// @brief Destructor | ||
1589 | 12338 | ~KeyedVector() = default; | |
1590 | /// @brief Copy constructor | ||
1591 | /// @param other The other object | ||
1592 | 3429 | KeyedVector(const KeyedVector& other) | |
1593 |
1/2✓ Branch 2 taken 1715 times.
✗ Branch 3 not taken.
|
3429 | : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(other) |
1594 | 3429 | {} | |
1595 | /// @brief Copy assignment operator | ||
1596 | /// @param other The other object | ||
1597 | 1 | KeyedVector& operator=(const KeyedVector& other) | |
1598 | { | ||
1599 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (this == &other) { return *this; } // Guard self assignment |
1600 | |||
1601 | 1 | static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>&>(*this) = | |
1602 | static_cast<const internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>&>(other); | ||
1603 | |||
1604 | 1 | return *this; | |
1605 | } | ||
1606 | /// @brief Move constructor | ||
1607 | /// @param other The other object | ||
1608 | 1 | KeyedVector(KeyedVector&& other) noexcept | |
1609 | 1 | : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(std::move(other)) | |
1610 | 1 | {} | |
1611 | /// @brief Move assignment operator | ||
1612 | /// @param other The other object | ||
1613 | 2035 | KeyedVector& operator=(KeyedVector&& other) noexcept | |
1614 | { | ||
1615 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1579 times.
|
2035 | if (this == &other) { return *this; } // Guard self assignment |
1616 | |||
1617 | 2035 | static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>&>(*this) = | |
1618 | 2035 | std::move(static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>&>(other)); | |
1619 | |||
1620 | 2035 | return *this; | |
1621 | } | ||
1622 | |||
1623 | // ########################################################################################################### | ||
1624 | // Special member functions with different Rows/Cols | ||
1625 | // ########################################################################################################### | ||
1626 | |||
1627 | /// @brief Copy constructor | ||
1628 | /// @param other The other object | ||
1629 | template<int oRows> | ||
1630 | 1 | KeyedVector(const KeyedVector<Scalar, RowKeyType, oRows>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
1631 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(other) |
1632 | 1 | {} | |
1633 | /// @brief Copy assignment operator | ||
1634 | /// @param other The other object | ||
1635 | template<int oRows> | ||
1636 | 1 | KeyedVector& operator=(const KeyedVector<Scalar, RowKeyType, oRows>& other) | |
1637 | { | ||
1638 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
1639 | |||
1640 | 1 | static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>&>(*this) = | |
1641 | static_cast<const internal::KeyedVectorBase<Scalar, RowKeyType, oRows>&>(other); | ||
1642 | |||
1643 | 1 | return *this; | |
1644 | } | ||
1645 | /// @brief Move constructor | ||
1646 | /// @param other The other object | ||
1647 | template<int oRows> | ||
1648 | 1 | KeyedVector(KeyedVector<Scalar, RowKeyType, oRows>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
1649 | 1 | : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(std::move(other)) | |
1650 | 1 | {} | |
1651 | /// @brief Move assignment operator | ||
1652 | /// @param other The other object | ||
1653 | template<int oRows> | ||
1654 | 26814 | KeyedVector& operator=(KeyedVector<Scalar, RowKeyType, oRows>&& other) noexcept | |
1655 | { | ||
1656 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
1657 | |||
1658 | 26814 | static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>&>(*this) = | |
1659 | 26814 | std::move(static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, oRows>&>(other)); | |
1660 | |||
1661 | 26814 | return *this; | |
1662 | } | ||
1663 | |||
1664 | // ####################################################################################################### | ||
1665 | // Methods | ||
1666 | // ####################################################################################################### | ||
1667 | |||
1668 | /// @brief Calculates the transposed vector | ||
1669 | 1 | [[nodiscard]] KeyedRowVector<Scalar, RowKeyType, Eigen::Dynamic> transposed() const | |
1670 | { | ||
1671 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | auto transpose = static_cast<const internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>&>(*this).transposed(); |
1672 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | return { transpose(all), transpose.colKeys() }; |
1673 | 1 | } | |
1674 | }; | ||
1675 | |||
1676 | /// @brief Static sized KeyedRowVector | ||
1677 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
1678 | /// @tparam ColKeyType Type of the key used for col lookup | ||
1679 | /// @tparam Cols Number of columns, or \b Dynamic | ||
1680 | template<typename Scalar, typename ColKeyType, int Cols> | ||
1681 | class KeyedRowVector : public internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols> | ||
1682 | { | ||
1683 | public: | ||
1684 | /// @brief RowVector constructor | ||
1685 | /// @tparam Derived Derived Eigen Type | ||
1686 | /// @param vector Eigen vector to initialize from | ||
1687 | /// @param colKeys Col keys describing the vector | ||
1688 | template<typename Derived> | ||
1689 | 18 | KeyedRowVector(const Eigen::MatrixBase<Derived>& vector, const std::vector<ColKeyType>& colKeys) | |
1690 | 18 | : internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>(vector, colKeys) | |
1691 | 18 | {} | |
1692 | |||
1693 | // ####################################################################################################### | ||
1694 | // Special member functions | ||
1695 | // ####################################################################################################### | ||
1696 | |||
1697 | /// @brief Destructor | ||
1698 | 26 | ~KeyedRowVector() = default; | |
1699 | /// @brief Copy constructor | ||
1700 | /// @param other The other object | ||
1701 | 1 | KeyedRowVector(const KeyedRowVector& other) | |
1702 | 1 | : internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>(other) | |
1703 | 1 | {} | |
1704 | /// @brief Copy assignment operator | ||
1705 | /// @param other The other object | ||
1706 | 1 | KeyedRowVector& operator=(const KeyedRowVector& other) | |
1707 | { | ||
1708 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (this == &other) { return *this; } // Guard self assignment |
1709 | |||
1710 | 1 | static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>&>(*this) = | |
1711 | static_cast<const internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>&>(other); | ||
1712 | |||
1713 | 1 | return *this; | |
1714 | } | ||
1715 | /// @brief Move constructor | ||
1716 | /// @param other The other object | ||
1717 | 1 | KeyedRowVector(KeyedRowVector&& other) noexcept | |
1718 | 1 | : internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>(std::move(other)) | |
1719 | 1 | {} | |
1720 | /// @brief Move assignment operator | ||
1721 | /// @param other The other object | ||
1722 | 1 | KeyedRowVector& operator=(KeyedRowVector&& other) noexcept | |
1723 | { | ||
1724 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (this == &other) { return *this; } // Guard self assignment |
1725 | |||
1726 | 1 | static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>&>(*this) = | |
1727 | 1 | std::move(static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>&>(other)); | |
1728 | |||
1729 | 1 | return *this; | |
1730 | } | ||
1731 | |||
1732 | // ########################################################################################################### | ||
1733 | // Special member functions with different Cols | ||
1734 | // ########################################################################################################### | ||
1735 | |||
1736 | /// @brief Copy constructor | ||
1737 | /// @param other The other object | ||
1738 | 1 | KeyedRowVector(const KeyedRowVector<Scalar, ColKeyType, Eigen::Dynamic>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
1739 | 1 | : internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>(other) | |
1740 | { | ||
1741 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | INS_ASSERT_USER_ERROR(other.cols() == Cols, "Can only copy assign dynamic matrices from static ones if the size matches"); |
1742 | 1 | } | |
1743 | /// @brief Copy assignment operator | ||
1744 | /// @param other The other object | ||
1745 | 1 | KeyedRowVector& operator=(const KeyedRowVector<Scalar, ColKeyType, Eigen::Dynamic>& other) | |
1746 | { | ||
1747 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
1748 | |||
1749 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | INS_ASSERT_USER_ERROR(other.cols() == Cols, "Can only copy assign dynamic matrices from static ones if the size matches"); |
1750 | |||
1751 | 1 | static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>&>(*this) = | |
1752 | static_cast<const internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>&>(other); | ||
1753 | |||
1754 | 1 | return *this; | |
1755 | } | ||
1756 | /// @brief Move constructor | ||
1757 | /// @param other The other object | ||
1758 | 1 | KeyedRowVector(KeyedRowVector<Scalar, ColKeyType, Eigen::Dynamic>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
1759 | 1 | : internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>(std::move(other)) | |
1760 | { | ||
1761 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | INS_ASSERT_USER_ERROR(this->cols() == Cols, "Can only move construct dynamic matrices from static ones if the size matches"); |
1762 | 1 | } | |
1763 | /// @brief Move assignment operator | ||
1764 | /// @param other The other object | ||
1765 | 1 | KeyedRowVector& operator=(KeyedRowVector<Scalar, ColKeyType, Eigen::Dynamic>&& other) noexcept | |
1766 | { | ||
1767 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
1768 | |||
1769 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | INS_ASSERT_USER_ERROR(other.cols() == Cols, "Can only move assign dynamic matrices from static ones if the size matches"); |
1770 | |||
1771 | 1 | static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>&>(*this) = | |
1772 | 1 | std::move(static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>&>(other)); | |
1773 | |||
1774 | 1 | return *this; | |
1775 | } | ||
1776 | |||
1777 | // ####################################################################################################### | ||
1778 | // Methods | ||
1779 | // ####################################################################################################### | ||
1780 | |||
1781 | /// @brief Calculates the transposed vector | ||
1782 | 1 | [[nodiscard]] KeyedVector<Scalar, ColKeyType, Cols> transposed() const | |
1783 | { | ||
1784 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | auto transpose = static_cast<const internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>&>(*this).transposed(); |
1785 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | return { transpose(all), transpose.rowKeys() }; |
1786 | 1 | } | |
1787 | }; | ||
1788 | |||
1789 | /// @brief Dynamic sized KeyedRowVector | ||
1790 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
1791 | /// @tparam ColKeyType Type of the key used for col lookup | ||
1792 | template<typename Scalar, typename ColKeyType> | ||
1793 | class KeyedRowVector<Scalar, ColKeyType, Eigen::Dynamic> | ||
1794 | : public internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic> | ||
1795 | { | ||
1796 | public: | ||
1797 | /// @brief Default Constructor | ||
1798 | KeyedRowVector() | ||
1799 | : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(Eigen::RowVectorX<Scalar>()) {} | ||
1800 | |||
1801 | /// @brief RowVector constructor | ||
1802 | /// @tparam Derived Derived Eigen Type | ||
1803 | /// @param vector Eigen vector to initialize from | ||
1804 | /// @param colKeys Col keys describing the vector | ||
1805 | template<typename Derived> | ||
1806 | 18 | KeyedRowVector(const Eigen::MatrixBase<Derived>& vector, const std::vector<ColKeyType>& colKeys) | |
1807 |
1/2✓ Branch 2 taken 9 times.
✗ Branch 3 not taken.
|
18 | : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(vector, colKeys) |
1808 | 18 | {} | |
1809 | |||
1810 | // ####################################################################################################### | ||
1811 | // Special member functions | ||
1812 | // ####################################################################################################### | ||
1813 | |||
1814 | /// @brief Destructor | ||
1815 | 26 | ~KeyedRowVector() = default; | |
1816 | /// @brief Copy constructor | ||
1817 | /// @param other The other object | ||
1818 | 1 | KeyedRowVector(const KeyedRowVector& other) | |
1819 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(other) |
1820 | 1 | {} | |
1821 | /// @brief Copy assignment operator | ||
1822 | /// @param other The other object | ||
1823 | 1 | KeyedRowVector& operator=(const KeyedRowVector& other) | |
1824 | { | ||
1825 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (this == &other) { return *this; } // Guard self assignment |
1826 | |||
1827 | 1 | static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>&>(*this) = | |
1828 | static_cast<const internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>&>(other); | ||
1829 | |||
1830 | 1 | return *this; | |
1831 | } | ||
1832 | /// @brief Move constructor | ||
1833 | /// @param other The other object | ||
1834 | 1 | KeyedRowVector(KeyedRowVector&& other) noexcept | |
1835 | 1 | : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(std::move(other)) | |
1836 | 1 | {} | |
1837 | /// @brief Move assignment operator | ||
1838 | /// @param other The other object | ||
1839 | 1 | KeyedRowVector& operator=(KeyedRowVector&& other) noexcept | |
1840 | { | ||
1841 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (this == &other) { return *this; } // Guard self assignment |
1842 | |||
1843 | 1 | static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>&>(*this) = | |
1844 | 1 | std::move(static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>&>(other)); | |
1845 | |||
1846 | 1 | return *this; | |
1847 | } | ||
1848 | |||
1849 | // ########################################################################################################### | ||
1850 | // Special member functions with different Cols | ||
1851 | // ########################################################################################################### | ||
1852 | |||
1853 | /// @brief Copy constructor | ||
1854 | /// @param other The other object | ||
1855 | template<int oCols> | ||
1856 | 1 | KeyedRowVector(const KeyedRowVector<Scalar, ColKeyType, oCols>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
1857 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(other) |
1858 | 1 | {} | |
1859 | /// @brief Copy assignment operator | ||
1860 | /// @param other The other object | ||
1861 | template<int oCols> | ||
1862 | 1 | KeyedRowVector& operator=(const KeyedRowVector<Scalar, ColKeyType, oCols>& other) | |
1863 | { | ||
1864 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
1865 | |||
1866 | 1 | static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>&>(*this) = | |
1867 | static_cast<const internal::KeyedRowVectorBase<Scalar, ColKeyType, oCols>&>(other); | ||
1868 | |||
1869 | 1 | return *this; | |
1870 | } | ||
1871 | /// @brief Move constructor | ||
1872 | /// @param other The other object | ||
1873 | template<int oCols> | ||
1874 | 1 | KeyedRowVector(KeyedRowVector<Scalar, ColKeyType, oCols>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
1875 | 1 | : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(std::move(other)) | |
1876 | 1 | {} | |
1877 | /// @brief Move assignment operator | ||
1878 | /// @param other The other object | ||
1879 | template<int oCols> | ||
1880 | 1 | KeyedRowVector& operator=(KeyedRowVector<Scalar, ColKeyType, oCols>&& other) noexcept | |
1881 | { | ||
1882 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
1883 | |||
1884 | 1 | static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>&>(*this) = | |
1885 | 1 | std::move(static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, oCols>&>(other)); | |
1886 | |||
1887 | 1 | return *this; | |
1888 | } | ||
1889 | |||
1890 | // ####################################################################################################### | ||
1891 | // Methods | ||
1892 | // ####################################################################################################### | ||
1893 | |||
1894 | /// @brief Calculates the transposed vector | ||
1895 | 1 | [[nodiscard]] KeyedVector<Scalar, ColKeyType, Eigen::Dynamic> transposed() const | |
1896 | { | ||
1897 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | auto transpose = static_cast<const internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>&>(*this).transposed(); |
1898 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
2 | return { transpose(all), transpose.rowKeys() }; |
1899 | 1 | } | |
1900 | }; | ||
1901 | |||
1902 | /// @brief Static sized KeyedMatrix | ||
1903 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
1904 | /// @tparam RowKeyType Type of the key used for row lookup | ||
1905 | /// @tparam ColKeyType Type of the key used for col lookup | ||
1906 | /// @tparam Rows Number of rows, or \b Dynamic | ||
1907 | /// @tparam Cols Number of columns, or \b Dynamic | ||
1908 | template<typename Scalar, typename RowKeyType, typename ColKeyType, int Rows, int Cols> | ||
1909 | class KeyedMatrix : public internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols> | ||
1910 | { | ||
1911 | public: | ||
1912 | /// @brief Non-symmetric matrix constructor | ||
1913 | /// @tparam Derived Derived Eigen Type | ||
1914 | /// @param matrix Eigen matrix to initialize from | ||
1915 | /// @param rowKeys Row keys describing the matrix | ||
1916 | /// @param colKeys Col keys describing the matrix | ||
1917 | template<typename Derived> | ||
1918 | 307374 | KeyedMatrix(const Eigen::MatrixBase<Derived>& matrix, const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) | |
1919 | 307374 | : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>(matrix, rowKeys, colKeys) | |
1920 | 307374 | {} | |
1921 | |||
1922 | /// @brief Symmetric matrix constructor | ||
1923 | /// @tparam Derived Derived Eigen Type | ||
1924 | /// @param matrix Eigen matrix to initialize from | ||
1925 | /// @param keys Row and col keys describing the matrix | ||
1926 | template<typename Derived> | ||
1927 | 153723 | KeyedMatrix(const Eigen::MatrixBase<Derived>& matrix, const std::vector<RowKeyType>& keys) | |
1928 | 153723 | : KeyedMatrix<Scalar, RowKeyType, ColKeyType, Rows, Cols>(matrix, keys, keys) | |
1929 | 153723 | {} | |
1930 | |||
1931 | // ####################################################################################################### | ||
1932 | // Special member functions | ||
1933 | // ####################################################################################################### | ||
1934 | |||
1935 | /// @brief Destructor | ||
1936 | 307382 | ~KeyedMatrix() = default; | |
1937 | /// @brief Copy constructor | ||
1938 | /// @param other The other object | ||
1939 | 1 | KeyedMatrix(const KeyedMatrix& other) | |
1940 | 1 | : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>(other) | |
1941 | 1 | {} | |
1942 | /// @brief Copy assignment operator | ||
1943 | /// @param other The other object | ||
1944 | 1 | KeyedMatrix& operator=(const KeyedMatrix& other) | |
1945 | { | ||
1946 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (this == &other) { return *this; } // Guard self assignment |
1947 | |||
1948 | 1 | static_cast<internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>&>(*this) = | |
1949 | static_cast<const internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>&>(other); | ||
1950 | |||
1951 | 1 | return *this; | |
1952 | } | ||
1953 | /// @brief Move constructor | ||
1954 | /// @param other The other object | ||
1955 | 1 | KeyedMatrix(KeyedMatrix&& other) noexcept | |
1956 | 1 | : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>(std::move(other)) | |
1957 | 1 | {} | |
1958 | /// @brief Move assignment operator | ||
1959 | /// @param other The other object | ||
1960 | 1 | KeyedMatrix& operator=(KeyedMatrix&& other) noexcept | |
1961 | { | ||
1962 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (this == &other) { return *this; } // Guard self assignment |
1963 | |||
1964 | 1 | static_cast<internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>&>(*this) = | |
1965 | 1 | std::move(static_cast<internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>&>(other)); | |
1966 | |||
1967 | 1 | return *this; | |
1968 | } | ||
1969 | |||
1970 | // ########################################################################################################### | ||
1971 | // Special member functions with different Rows/Cols | ||
1972 | // ########################################################################################################### | ||
1973 | |||
1974 | /// @brief Copy constructor | ||
1975 | /// @param other The other object | ||
1976 | 1 | KeyedMatrix(const KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
1977 | 1 | : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>(other) | |
1978 | { | ||
1979 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | INS_ASSERT_USER_ERROR(other.rows() == Rows && other.cols() == Cols, "Can only copy assign dynamic matrices from static ones if the size matches"); |
1980 | 1 | } | |
1981 | /// @brief Copy assignment operator | ||
1982 | /// @param other The other object | ||
1983 | 1 | KeyedMatrix& operator=(const KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>& other) | |
1984 | { | ||
1985 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
1986 | |||
1987 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | INS_ASSERT_USER_ERROR(other.rows() == Rows && other.cols() == Cols, "Can only copy assign dynamic matrices from static ones if the size matches"); |
1988 | |||
1989 | 1 | static_cast<internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>&>(*this) = | |
1990 | static_cast<const internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&>(other); | ||
1991 | |||
1992 | 1 | return *this; | |
1993 | } | ||
1994 | /// @brief Move constructor | ||
1995 | /// @param other The other object | ||
1996 | 1 | KeyedMatrix(KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
1997 | 1 | : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>(std::move(other)) | |
1998 | { | ||
1999 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | INS_ASSERT_USER_ERROR(this->rows() == Rows && this->cols() == Cols, "Can only move construct dynamic matrices from static ones if the size matches"); |
2000 | 1 | } | |
2001 | /// @brief Move assignment operator | ||
2002 | /// @param other The other object | ||
2003 | 1 | KeyedMatrix& operator=(KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&& other) noexcept | |
2004 | { | ||
2005 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
2006 | |||
2007 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | INS_ASSERT_USER_ERROR(other.rows() == Rows && other.cols() == Cols, "Can only move assign dynamic matrices from static ones if the size matches"); |
2008 | |||
2009 | 1 | static_cast<internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>&>(*this) = | |
2010 | 1 | std::move(static_cast<internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&>(other)); | |
2011 | |||
2012 | 1 | return *this; | |
2013 | } | ||
2014 | |||
2015 | // ####################################################################################################### | ||
2016 | // Methods | ||
2017 | // ####################################################################################################### | ||
2018 | |||
2019 | /// @brief Returns a submatrix specified by the row and col keys | ||
2020 | /// @param rowKeys Row keys | ||
2021 | /// @param colKeys Col keys | ||
2022 | [[nodiscard]] KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic> | ||
2023 | 1 | getSubMatrix(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) const | |
2024 | { | ||
2025 |
2/6✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
|
1 | if (rowKeys == this->rowKeysVector && colKeys == this->colKeysVector) |
2026 | { | ||
2027 | ✗ | return *this; | |
2028 | } | ||
2029 | |||
2030 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | return { (*this)(rowKeys, colKeys), rowKeys, colKeys }; |
2031 | } | ||
2032 | |||
2033 | /// @brief Calculates the transposed matrix | ||
2034 | 1 | [[nodiscard]] KeyedMatrix<Scalar, RowKeyType, ColKeyType, Rows, Cols> transposed() const | |
2035 | { | ||
2036 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | auto transpose = static_cast<const internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>&>(*this).transposed(); |
2037 |
1/2✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
2 | return { transpose(all, all), transpose.rowKeys(), transpose.colKeys() }; |
2038 | 1 | } | |
2039 | |||
2040 | /// @brief Calculates the inverse matrix | ||
2041 | 1 | [[nodiscard]] KeyedMatrix<Scalar, RowKeyType, ColKeyType, Rows, Cols> inverse() const | |
2042 | { | ||
2043 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | auto inv = static_cast<const internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>&>(*this).inverse(); |
2044 |
1/2✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
2 | return { inv(all, all), inv.rowKeys(), inv.colKeys() }; |
2045 | 1 | } | |
2046 | }; | ||
2047 | |||
2048 | /// @brief Dynamic sized KeyedMatrix | ||
2049 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
2050 | /// @tparam RowKeyType Type of the key used for row lookup | ||
2051 | /// @tparam ColKeyType Type of the key used for col lookup | ||
2052 | template<typename Scalar, typename RowKeyType, typename ColKeyType> | ||
2053 | class KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic> | ||
2054 | : public internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic> | ||
2055 | { | ||
2056 | public: | ||
2057 | /// @brief Default Constructor | ||
2058 | 13678 | KeyedMatrix() | |
2059 |
2/4✓ Branch 2 taken 6839 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 6839 times.
✗ Branch 6 not taken.
|
13678 | : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(Eigen::MatrixX<Scalar>()) {} |
2060 | |||
2061 | /// @brief Non-symmetric matrix constructor | ||
2062 | /// @tparam Derived Derived Eigen Type | ||
2063 | /// @param matrix Eigen matrix to initialize from | ||
2064 | /// @param rowKeys Row keys describing the matrix | ||
2065 | /// @param colKeys Col keys describing the matrix | ||
2066 | template<typename Derived> | ||
2067 | 264822 | KeyedMatrix(const Eigen::MatrixBase<Derived>& matrix, const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) | |
2068 |
1/2✓ Branch 2 taken 134834 times.
✗ Branch 3 not taken.
|
264822 | : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(matrix, rowKeys, colKeys) |
2069 | 264822 | {} | |
2070 | |||
2071 | /// @brief Symmetric matrix constructor | ||
2072 | /// @tparam Derived Derived Eigen Type | ||
2073 | /// @param matrix Eigen matrix to initialize from | ||
2074 | /// @param keys Row and col keys describing the matrix | ||
2075 | template<typename Derived> | ||
2076 | 216628 | KeyedMatrix(const Eigen::MatrixBase<Derived>& matrix, const std::vector<RowKeyType>& keys) | |
2077 | 216628 | : KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(matrix, keys, keys) | |
2078 | 216632 | {} | |
2079 | |||
2080 | // ####################################################################################################### | ||
2081 | // Special member functions | ||
2082 | // ####################################################################################################### | ||
2083 | |||
2084 | /// @brief Destructor | ||
2085 | 725808 | ~KeyedMatrix() = default; | |
2086 | /// @brief Copy constructor | ||
2087 | /// @param other The other object | ||
2088 | 226063 | KeyedMatrix(const KeyedMatrix& other) | |
2089 |
1/2✓ Branch 2 taken 113033 times.
✗ Branch 3 not taken.
|
226063 | : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(other) |
2090 | 226065 | {} | |
2091 | /// @brief Copy assignment operator | ||
2092 | /// @param other The other object | ||
2093 | 1 | KeyedMatrix& operator=(const KeyedMatrix& other) | |
2094 | { | ||
2095 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
|
1 | if (this == &other) { return *this; } // Guard self assignment |
2096 | |||
2097 | 1 | static_cast<internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&>(*this) = | |
2098 | static_cast<const internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&>(other); | ||
2099 | |||
2100 | 1 | return *this; | |
2101 | } | ||
2102 | /// @brief Move constructor | ||
2103 | /// @param other The other object | ||
2104 | 211519 | KeyedMatrix(KeyedMatrix&& other) noexcept | |
2105 | 211519 | : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(std::move(other)) | |
2106 | 211521 | {} | |
2107 | /// @brief Move assignment operator | ||
2108 | /// @param other The other object | ||
2109 | 48864 | KeyedMatrix& operator=(KeyedMatrix&& other) noexcept | |
2110 | { | ||
2111 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24432 times.
|
48864 | if (this == &other) { return *this; } // Guard self assignment |
2112 | |||
2113 | 48864 | static_cast<internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&>(*this) = | |
2114 | 48864 | std::move(static_cast<internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&>(other)); | |
2115 | |||
2116 | 48864 | return *this; | |
2117 | } | ||
2118 | |||
2119 | // ########################################################################################################### | ||
2120 | // Special member functions with different Rows/Cols | ||
2121 | // ########################################################################################################### | ||
2122 | |||
2123 | /// @brief Copy constructor | ||
2124 | /// @param other The other object | ||
2125 | template<int oRows, int oCols> | ||
2126 | 2 | KeyedMatrix(const KeyedMatrix<Scalar, RowKeyType, ColKeyType, oRows, oCols>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
2127 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
2 | : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(other) |
2128 | 2 | {} | |
2129 | /// @brief Copy assignment operator | ||
2130 | /// @param other The other object | ||
2131 | template<int oRows, int oCols> | ||
2132 | 1 | KeyedMatrix& operator=(const KeyedMatrix<Scalar, RowKeyType, ColKeyType, oRows, oCols>& other) | |
2133 | { | ||
2134 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
2135 | |||
2136 | 1 | static_cast<internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&>(*this) = | |
2137 | static_cast<const internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, oRows, oCols>&>(other); | ||
2138 | |||
2139 | 1 | return *this; | |
2140 | } | ||
2141 | /// @brief Move constructor | ||
2142 | /// @param other The other object | ||
2143 | template<int oRows, int oCols> | ||
2144 | 1 | KeyedMatrix(KeyedMatrix<Scalar, RowKeyType, ColKeyType, oRows, oCols>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions) | |
2145 | 1 | : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(std::move(other)) | |
2146 | 1 | {} | |
2147 | /// @brief Move assignment operator | ||
2148 | /// @param other The other object | ||
2149 | template<int oRows, int oCols> | ||
2150 | 153672 | KeyedMatrix& operator=(KeyedMatrix<Scalar, RowKeyType, ColKeyType, oRows, oCols>&& other) noexcept | |
2151 | { | ||
2152 | // No need to guard self assignment, as the types are different, so it cannot be the same object | ||
2153 | |||
2154 | 153672 | static_cast<internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&>(*this) = | |
2155 | 153672 | std::move(static_cast<internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, oRows, oCols>&>(other)); | |
2156 | |||
2157 | 153672 | return *this; | |
2158 | } | ||
2159 | |||
2160 | // ####################################################################################################### | ||
2161 | // Modifying methods | ||
2162 | // ####################################################################################################### | ||
2163 | |||
2164 | /// @brief Adds new rows and cols to the matrix | ||
2165 | /// @param rowKeys Row keys | ||
2166 | /// @param colKeys Col keys | ||
2167 | 403 | void addRowsCols(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) | |
2168 | { | ||
2169 |
1/2✓ Branch 1 taken 403 times.
✗ Branch 2 not taken.
|
403 | INS_ASSERT_USER_ERROR(!this->hasAnyRows(rowKeys), "You cannot add a row key which is already in the matrix."); |
2170 |
1/2✓ Branch 1 taken 403 times.
✗ Branch 2 not taken.
|
403 | INS_ASSERT_USER_ERROR(!this->hasAnyCols(colKeys), "You cannot add a col key which is already in the matrix."); |
2171 |
4/12✓ Branch 3 taken 403 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 403 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 403 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 403 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
|
806 | INS_ASSERT_USER_ERROR(std::unordered_set<RowKeyType>(rowKeys.begin(), rowKeys.end()).size() == rowKeys.size(), "Each row key must be unique"); |
2172 |
4/12✓ Branch 3 taken 403 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 403 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 403 times.
✗ Branch 11 not taken.
✓ Branch 13 taken 403 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
|
806 | INS_ASSERT_USER_ERROR(std::unordered_set<ColKeyType>(colKeys.begin(), colKeys.end()).size() == colKeys.size(), "Each col key must be unique"); |
2173 | |||
2174 | 403 | auto initialRowSize = static_cast<Eigen::Index>(this->rowIndices.size()); | |
2175 |
7/9✓ Branch 5 taken 2 times.
✓ Branch 6 taken 414 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✓ Branch 10 taken 414 times.
✓ Branch 11 taken 402 times.
✓ Branch 13 taken 2 times.
✓ Branch 14 taken 1 times.
|
819 | for (const auto& rowKey : rowKeys) { this->rowIndices.insert({ rowKey, static_cast<Eigen::Index>(this->rowIndices.size()) }); } |
2176 | 403 | this->rowKeysVector.reserve(this->rowKeysVector.size() + rowKeys.size()); | |
2177 | 403 | std::copy(rowKeys.begin(), rowKeys.end(), std::back_inserter(this->rowKeysVector)); | |
2178 | 403 | auto finalRowSize = static_cast<Eigen::Index>(this->rowIndices.size()); | |
2179 | |||
2180 | 403 | auto initialColSize = static_cast<Eigen::Index>(this->colIndices.size()); | |
2181 |
3/4✓ Branch 6 taken 416 times.
✗ Branch 7 not taken.
✓ Branch 10 taken 416 times.
✓ Branch 11 taken 403 times.
|
819 | for (const auto& colKey : colKeys) { this->colIndices.insert({ colKey, static_cast<Eigen::Index>(this->colIndices.size()) }); } |
2182 | 403 | this->colKeysVector.reserve(this->colKeysVector.size() + colKeys.size()); | |
2183 | 403 | std::copy(colKeys.begin(), colKeys.end(), std::back_inserter(this->colKeysVector)); | |
2184 | 403 | auto finalColSize = static_cast<Eigen::Index>(this->colIndices.size()); | |
2185 | |||
2186 | 403 | auto rows = finalRowSize - initialRowSize; | |
2187 | 403 | auto cols = finalColSize - initialColSize; | |
2188 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 403 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
403 | if (rows > 0 || cols > 0) |
2189 | { | ||
2190 | 403 | this->matrix.conservativeResize(finalRowSize, finalColSize); | |
2191 |
3/6✓ Branch 2 taken 403 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 403 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 403 times.
✗ Branch 10 not taken.
|
403 | this->matrix.block(initialRowSize, 0, rows, this->matrix.cols()) = Eigen::MatrixX<Scalar>::Zero(rows, this->matrix.cols()); |
2192 |
3/6✓ Branch 2 taken 403 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 403 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 403 times.
✗ Branch 10 not taken.
|
403 | this->matrix.block(0, initialColSize, this->matrix.rows(), cols) = Eigen::MatrixX<Scalar>::Zero(this->matrix.rows(), cols); |
2193 | } | ||
2194 | 403 | this->colSlice.reserve(this->colKeysVector.size()); | |
2195 | 403 | this->rowSlice.reserve(this->rowKeysVector.size()); | |
2196 | 403 | } | |
2197 | |||
2198 | /// @brief Removes the rows and cols from the matrix | ||
2199 | /// @param rowKeys Row Keys | ||
2200 | /// @param colKeys Col Keys | ||
2201 | 13 | void removeRowsCols(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) | |
2202 | { | ||
2203 | 13 | std::vector<int> rowIndices; | |
2204 |
2/2✓ Branch 5 taken 27 times.
✓ Branch 6 taken 13 times.
|
40 | for (const auto& rowKey : rowKeys) |
2205 | { | ||
2206 |
1/2✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
|
27 | auto iter = this->rowIndices.find(rowKey); |
2207 |
1/2✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
|
27 | INS_ASSERT_USER_ERROR(iter != this->rowIndices.end(), "You tried removing a row key, which did not exist."); |
2208 |
1/2✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
|
27 | if (iter != this->rowIndices.end()) |
2209 | { | ||
2210 |
1/2✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
|
27 | rowIndices.push_back(static_cast<int>(iter->second)); |
2211 | } | ||
2212 | } | ||
2213 | 13 | std::vector<int> colIndices; | |
2214 |
2/2✓ Branch 5 taken 26 times.
✓ Branch 6 taken 13 times.
|
39 | for (const auto& colKey : colKeys) |
2215 | { | ||
2216 |
1/2✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
|
26 | auto iter = this->colIndices.find(colKey); |
2217 |
1/2✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
|
26 | INS_ASSERT_USER_ERROR(iter != this->colIndices.end(), "You tried removing a col key, which did not exist."); |
2218 |
1/2✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
|
26 | if (iter != this->colIndices.end()) |
2219 | { | ||
2220 |
1/2✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
|
26 | colIndices.push_back(static_cast<int>(iter->second)); |
2221 | } | ||
2222 | } | ||
2223 | |||
2224 |
1/2✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
|
13 | NAV::removeRowsAndCols(this->matrix, rowIndices, colIndices); |
2225 | |||
2226 |
2/2✓ Branch 5 taken 27 times.
✓ Branch 6 taken 13 times.
|
40 | for (const auto& rowKey : rowKeys) |
2227 | { | ||
2228 |
1/2✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
|
27 | auto iter = this->rowIndices.find(rowKey); |
2229 |
1/2✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
|
27 | if (iter != this->rowIndices.end()) |
2230 | { | ||
2231 |
1/2✓ Branch 2 taken 27 times.
✗ Branch 3 not taken.
|
219 | std::erase_if(this->rowKeysVector, [&](const auto& item) { return item == rowKey; }); |
2232 | |||
2233 | 27 | auto idx = iter->second; | |
2234 |
2/2✓ Branch 5 taken 192 times.
✓ Branch 6 taken 27 times.
|
219 | for (auto& rowIndex : this->rowIndices) |
2235 | { | ||
2236 |
2/2✓ Branch 0 taken 67 times.
✓ Branch 1 taken 125 times.
|
192 | if (rowIndex.second > idx) { rowIndex.second--; } |
2237 | } | ||
2238 |
1/2✓ Branch 1 taken 27 times.
✗ Branch 2 not taken.
|
27 | this->rowIndices.erase(iter); |
2239 | } | ||
2240 | } | ||
2241 |
2/2✓ Branch 5 taken 26 times.
✓ Branch 6 taken 13 times.
|
39 | for (const auto& colKey : colKeys) |
2242 | { | ||
2243 |
1/2✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
|
26 | auto iter = this->colIndices.find(colKey); |
2244 |
1/2✓ Branch 2 taken 26 times.
✗ Branch 3 not taken.
|
26 | if (iter != this->colIndices.end()) |
2245 | { | ||
2246 |
2/3✓ Branch 1 taken 2 times.
✓ Branch 2 taken 24 times.
✗ Branch 3 not taken.
|
215 | std::erase_if(this->colKeysVector, [&](const auto& item) { return item == colKey; }); |
2247 | |||
2248 | 26 | auto idx = iter->second; | |
2249 |
2/2✓ Branch 5 taken 189 times.
✓ Branch 6 taken 26 times.
|
215 | for (auto& colIndex : this->colIndices) |
2250 | { | ||
2251 |
2/2✓ Branch 0 taken 64 times.
✓ Branch 1 taken 125 times.
|
189 | if (colIndex.second > idx) { colIndex.second--; } |
2252 | } | ||
2253 |
1/2✓ Branch 1 taken 26 times.
✗ Branch 2 not taken.
|
26 | this->colIndices.erase(iter); |
2254 | } | ||
2255 | } | ||
2256 | 13 | } | |
2257 | |||
2258 | // ####################################################################################################### | ||
2259 | // Methods | ||
2260 | // ####################################################################################################### | ||
2261 | |||
2262 | /// @brief Returns a submatrix specified by the row and col keys | ||
2263 | /// @param rowKeys Row keys | ||
2264 | /// @param colKeys Col keys | ||
2265 | [[nodiscard]] KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic> | ||
2266 | 1 | getSubMatrix(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) const | |
2267 | { | ||
2268 |
2/6✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 1 times.
|
1 | if (rowKeys == this->rowKeysVector && colKeys == this->colKeysVector) |
2269 | { | ||
2270 | ✗ | return *this; | |
2271 | } | ||
2272 | |||
2273 |
2/4✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
1 | return { (*this)(rowKeys, colKeys), rowKeys, colKeys }; |
2274 | } | ||
2275 | |||
2276 | /// @brief Calculates the transposed matrix | ||
2277 | 1 | [[nodiscard]] KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic> transposed() const | |
2278 | { | ||
2279 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | auto transpose = static_cast<const internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&>(*this).transposed(); |
2280 |
1/2✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
|
2 | return { transpose(all, all), transpose.rowKeys(), transpose.colKeys() }; |
2281 | 1 | } | |
2282 | |||
2283 | /// @brief Calculates the inverse matrix | ||
2284 | 407 | [[nodiscard]] KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic> inverse() const | |
2285 | { | ||
2286 |
1/2✓ Branch 1 taken 407 times.
✗ Branch 2 not taken.
|
407 | auto inv = static_cast<const internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&>(*this).inverse(); |
2287 |
1/2✓ Branch 4 taken 407 times.
✗ Branch 5 not taken.
|
814 | return { inv(all, all), inv.rowKeys(), inv.colKeys() }; |
2288 | 407 | } | |
2289 | }; | ||
2290 | |||
2291 | /// @brief Dynamic size KeyedMatrix | ||
2292 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
2293 | /// @tparam RowKeyType Type of the key used for row lookup | ||
2294 | /// @tparam ColKeyType Type of the key used for col lookup | ||
2295 | template<typename Scalar, typename RowKeyType, typename ColKeyType = RowKeyType> | ||
2296 | using KeyedMatrixX = KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>; | ||
2297 | /// @brief Dynamic size KeyedMatrix with double types | ||
2298 | /// @tparam RowKeyType Type of the key used for row lookup | ||
2299 | /// @tparam ColKeyType Type of the key used for col lookup | ||
2300 | template<typename RowKeyType, typename ColKeyType = RowKeyType> | ||
2301 | using KeyedMatrixXd = KeyedMatrixX<double, RowKeyType, ColKeyType>; | ||
2302 | /// @brief Static 2x2 squared size KeyedMatrix with double types | ||
2303 | /// @tparam RowKeyType Type of the key used for row lookup | ||
2304 | /// @tparam ColKeyType Type of the key used for col lookup | ||
2305 | template<typename RowKeyType, typename ColKeyType = RowKeyType> | ||
2306 | using KeyedMatrix2d = KeyedMatrix<double, RowKeyType, ColKeyType, 2, 2>; | ||
2307 | /// @brief Static 3x3 squared size KeyedMatrix with double types | ||
2308 | /// @tparam RowKeyType Type of the key used for row lookup | ||
2309 | /// @tparam ColKeyType Type of the key used for col lookup | ||
2310 | template<typename RowKeyType, typename ColKeyType = RowKeyType> | ||
2311 | using KeyedMatrix3d = KeyedMatrix<double, RowKeyType, ColKeyType, 3, 3>; | ||
2312 | /// @brief Static 4x4 squared size KeyedMatrix with double types | ||
2313 | /// @tparam RowKeyType Type of the key used for row lookup | ||
2314 | /// @tparam ColKeyType Type of the key used for col lookup | ||
2315 | template<typename RowKeyType, typename ColKeyType = RowKeyType> | ||
2316 | using KeyedMatrix4d = KeyedMatrix<double, RowKeyType, ColKeyType, 4, 4>; | ||
2317 | /// @brief Static 5x5 squared size KeyedMatrix with double types | ||
2318 | /// @tparam RowKeyType Type of the key used for row lookup | ||
2319 | /// @tparam ColKeyType Type of the key used for col lookup | ||
2320 | template<typename RowKeyType, typename ColKeyType = RowKeyType> | ||
2321 | using KeyedMatrix5d = KeyedMatrix<double, RowKeyType, ColKeyType, 5, 5>; | ||
2322 | /// @brief Static 6x6 squared size KeyedMatrix with double types | ||
2323 | /// @tparam RowKeyType Type of the key used for row lookup | ||
2324 | /// @tparam ColKeyType Type of the key used for col lookup | ||
2325 | template<typename RowKeyType, typename ColKeyType = RowKeyType> | ||
2326 | using KeyedMatrix6d = KeyedMatrix<double, RowKeyType, ColKeyType, 6, 6>; | ||
2327 | |||
2328 | /// @brief Dynamic size KeyedVector | ||
2329 | /// @tparam Scalar Numeric type, e.g. float, double, int or std::complex<float>. | ||
2330 | /// @tparam RowKeyType Type of the key used for row lookup | ||
2331 | template<typename Scalar, typename RowKeyType> | ||
2332 | using KeyedVectorX = KeyedVector<Scalar, RowKeyType, Eigen::Dynamic>; | ||
2333 | /// @brief Dynamic size KeyedVector with double types | ||
2334 | /// @tparam RowKeyType Type of the key used for row lookup | ||
2335 | template<typename RowKeyType> | ||
2336 | using KeyedVectorXd = KeyedVectorX<double, RowKeyType>; | ||
2337 | /// @brief Static 2 row KeyedVector with double types | ||
2338 | /// @tparam RowKeyType Type of the key used for row lookup | ||
2339 | template<typename RowKeyType> | ||
2340 | using KeyedVector2d = KeyedVector<double, RowKeyType, 2>; | ||
2341 | /// @brief Static 3 row KeyedVector with double types | ||
2342 | /// @tparam RowKeyType Type of the key used for row lookup | ||
2343 | template<typename RowKeyType> | ||
2344 | using KeyedVector3d = KeyedVector<double, RowKeyType, 3>; | ||
2345 | /// @brief Static 4 row KeyedVector with double types | ||
2346 | /// @tparam RowKeyType Type of the key used for row lookup | ||
2347 | template<typename RowKeyType> | ||
2348 | using KeyedVector4d = KeyedVector<double, RowKeyType, 4>; | ||
2349 | /// @brief Static 5 row KeyedVector with double types | ||
2350 | /// @tparam RowKeyType Type of the key used for row lookup | ||
2351 | template<typename RowKeyType> | ||
2352 | using KeyedVector5d = KeyedVector<double, RowKeyType, 5>; | ||
2353 | /// @brief Static 6 row KeyedVector with double types | ||
2354 | /// @tparam RowKeyType Type of the key used for row lookup | ||
2355 | template<typename RowKeyType> | ||
2356 | using KeyedVector6d = KeyedVector<double, RowKeyType, 6>; | ||
2357 | |||
2358 | /// @brief Dynamic size KeyedRowVector | ||
2359 | /// @tparam ColKeyType Type of the key used for col lookup | ||
2360 | template<typename Scalar, typename ColKeyType> | ||
2361 | using KeyedRowVectorX = KeyedRowVector<Scalar, ColKeyType, Eigen::Dynamic>; | ||
2362 | /// @brief Dynamic size KeyedRowVector with double types | ||
2363 | /// @tparam ColKeyType Type of the key used for col lookup | ||
2364 | template<typename ColKeyType> | ||
2365 | using KeyedRowVectorXd = KeyedRowVectorX<double, ColKeyType>; | ||
2366 | /// @brief Static 2 col KeyedRowVector with double types | ||
2367 | /// @tparam ColKeyType Type of the key used for col lookup | ||
2368 | template<typename ColKeyType> | ||
2369 | using KeyedRowVector2d = KeyedRowVector<double, ColKeyType, 2>; | ||
2370 | /// @brief Static 3 col KeyedRowVector with double types | ||
2371 | /// @tparam ColKeyType Type of the key used for col lookup | ||
2372 | template<typename ColKeyType> | ||
2373 | using KeyedRowVector3d = KeyedRowVector<double, ColKeyType, 3>; | ||
2374 | /// @brief Static 4 col KeyedRowVector with double types | ||
2375 | /// @tparam ColKeyType Type of the key used for col lookup | ||
2376 | template<typename ColKeyType> | ||
2377 | using KeyedRowVector4d = KeyedRowVector<double, ColKeyType, 4>; | ||
2378 | /// @brief Static 5 col KeyedRowVector with double types | ||
2379 | /// @tparam ColKeyType Type of the key used for col lookup | ||
2380 | template<typename ColKeyType> | ||
2381 | using KeyedRowVector5d = KeyedRowVector<double, ColKeyType, 5>; | ||
2382 | /// @brief Static 6 col KeyedRowVector with double types | ||
2383 | /// @tparam ColKeyType Type of the key used for col lookup | ||
2384 | template<typename ColKeyType> | ||
2385 | using KeyedRowVector6d = KeyedRowVector<double, ColKeyType, 6>; | ||
2386 | |||
2387 | } // namespace NAV | ||
2388 | |||
2389 | #if defined(__GNUC__) && !defined(__clang__) | ||
2390 | #pragma GCC diagnostic pop | ||
2391 | #endif | ||
2392 | |||
2393 | #ifndef DOXYGEN_IGNORE | ||
2394 | |||
2395 | /// @brief Formatter for KeyedMatrix | ||
2396 | template<typename Scalar, typename RowKeyType, typename ColKeyType, int Rows, int Cols> | ||
2397 | struct fmt::formatter<NAV::KeyedMatrix<Scalar, RowKeyType, ColKeyType, Rows, Cols>> : fmt::formatter<std::string> | ||
2398 | { | ||
2399 | /// @brief Defines how to format KeyedMatrix structs | ||
2400 | /// @param[in] mat Struct to format | ||
2401 | /// @param[in, out] ctx Format context | ||
2402 | /// @return Output iterator | ||
2403 | 4 | auto format(const NAV::KeyedMatrix<Scalar, RowKeyType, ColKeyType, Rows, Cols>& mat, format_context& ctx) const | |
2404 | { | ||
2405 | 4 | std::string result; | |
2406 | 4 | auto rows = static_cast<size_t>(mat.rows()); | |
2407 | 4 | auto cols = static_cast<size_t>(mat.cols()); | |
2408 | |||
2409 |
2/4✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
|
4 | if (rows > 0 && cols > 0) |
2410 | { | ||
2411 | 4 | std::vector<std::string> rowKeysStr; | |
2412 | 4 | std::vector<size_t> rowKeysLength; | |
2413 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | rowKeysStr.reserve(rows); |
2414 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | rowKeysLength.reserve(rows); |
2415 | 4 | size_t rowKeysColSpace = 0; | |
2416 |
2/2✓ Branch 6 taken 6 times.
✓ Branch 7 taken 2 times.
|
16 | for (const auto& rowKey : mat.rowKeys()) |
2417 | { | ||
2418 |
1/2✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
|
24 | rowKeysStr.push_back(fmt::format("{}", rowKey)); |
2419 | 12 | auto rowKeyLength = rowKeysStr.back().length(); | |
2420 | 12 | rowKeysColSpace = std::max(rowKeysColSpace, rowKeyLength); | |
2421 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
12 | rowKeysLength.push_back(rowKeyLength); |
2422 | } | ||
2423 | |||
2424 | 4 | constexpr size_t colMinLength = 9UL; | |
2425 | |||
2426 | 4 | std::vector<std::string> colKeysStr; | |
2427 | 4 | std::vector<size_t> colKeysLength; | |
2428 | 4 | size_t rowLineLength = rowKeysColSpace + 1; // '\n' at the end of line | |
2429 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | colKeysStr.reserve(cols); |
2430 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | colKeysLength.reserve(cols); |
2431 |
2/2✓ Branch 5 taken 6 times.
✓ Branch 6 taken 2 times.
|
16 | for (const auto& colKey : mat.colKeys()) |
2432 | { | ||
2433 |
1/2✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
|
24 | colKeysStr.push_back(fmt::format("{}", colKey)); |
2434 | 12 | auto colKeyLength = colKeysStr.back().length(); | |
2435 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
12 | colKeysLength.push_back(colKeyLength); |
2436 | 12 | rowLineLength += 2 + std::max(colKeysStr.back().length(), colMinLength); // 2 spaces before each column | |
2437 | } | ||
2438 | |||
2439 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | result.reserve((rows + 1) * rowLineLength); |
2440 | // ---------------------------------------- Column keys ------------------------------------------ | ||
2441 |
3/6✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
|
4 | result += " " + std::string(rowKeysColSpace, ' '); |
2442 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
|
16 | for (size_t c = 0; c < cols; c++) |
2443 | { | ||
2444 |
1/2✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
|
12 | result += " "; |
2445 |
3/4✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 5 times.
✓ Branch 4 taken 1 times.
|
12 | if (colMinLength > colKeysLength.at(c)) |
2446 | { | ||
2447 |
3/6✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 5 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 5 times.
✗ Branch 8 not taken.
|
20 | result += std::string(colMinLength - colKeysLength.at(c), ' '); // Spaces in front of column name (if too short) |
2448 | } | ||
2449 |
2/4✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
|
12 | result += colKeysStr.at(c); |
2450 | } | ||
2451 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | result += '\n'; |
2452 | // ------------------------------------------- Rows ---------------------------------------------- | ||
2453 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
|
16 | for (size_t r = 0; r < rows; r++) |
2454 | { | ||
2455 |
3/4✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 4 times.
|
12 | if (rowKeysColSpace > rowKeysLength.at(r)) |
2456 | { | ||
2457 |
3/6✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 2 times.
✗ Branch 8 not taken.
|
8 | result += std::string(rowKeysColSpace - rowKeysLength.at(r), ' '); // Spaces in front of row name (if too short) |
2458 | } | ||
2459 |
3/6✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
|
12 | result += rowKeysStr.at(r) + " "; |
2460 |
2/2✓ Branch 1 taken 18 times.
✓ Branch 2 taken 6 times.
|
48 | for (size_t c = 0; c < cols; c++) |
2461 | { | ||
2462 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
36 | auto colLength = std::max(colKeysStr.at(c).length(), colMinLength); |
2463 | |||
2464 |
1/2✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
|
36 | std::string tmp = fmt::format(" {:> {}.{}g}", mat(NAV::all, NAV::all)(static_cast<int>(r), static_cast<int>(c)), colLength, colLength - 2); |
2465 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
36 | if (tmp.length() > colLength) |
2466 | { | ||
2467 |
1/2✓ Branch 2 taken 18 times.
✗ Branch 3 not taken.
|
72 | tmp = fmt::format(" {:> {}.{}g}", mat(NAV::all, NAV::all)(static_cast<int>(r), static_cast<int>(c)), colLength, colLength - 6); |
2468 | } | ||
2469 |
1/2✓ Branch 1 taken 18 times.
✗ Branch 2 not taken.
|
36 | result += tmp; |
2470 | } | ||
2471 |
3/4✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2 times.
✓ Branch 3 taken 4 times.
✗ Branch 4 not taken.
|
12 | if (r != rows - 1) { result += '\n'; } |
2472 | } | ||
2473 | 4 | } | |
2474 | |||
2475 | 12 | return fmt::formatter<std::string>::format(result, ctx); | |
2476 | 4 | } | |
2477 | }; | ||
2478 | |||
2479 | /// @brief Formatter for KeyedVector | ||
2480 | template<typename Scalar, typename RowKeyType, int Rows> | ||
2481 | struct fmt::formatter<NAV::KeyedVector<Scalar, RowKeyType, Rows>> : fmt::formatter<std::string> | ||
2482 | { | ||
2483 | /// @brief Defines how to format KeyedVector structs | ||
2484 | /// @param[in] vec Struct to format | ||
2485 | /// @param[in, out] ctx Format context | ||
2486 | /// @return Output iterator | ||
2487 | 4 | auto format(const NAV::KeyedVector<Scalar, RowKeyType, Rows>& vec, format_context& ctx) const | |
2488 | { | ||
2489 | 4 | std::string result; | |
2490 | 4 | auto rows = static_cast<size_t>(vec.rows()); | |
2491 | |||
2492 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
4 | if (rows > 0) |
2493 | { | ||
2494 | 4 | std::vector<std::string> rowKeysStr; | |
2495 | 4 | std::vector<size_t> rowKeysLength; | |
2496 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | rowKeysStr.reserve(rows); |
2497 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | rowKeysLength.reserve(rows); |
2498 | 4 | size_t rowKeysColSpace = 0; | |
2499 |
2/2✓ Branch 6 taken 14 times.
✓ Branch 7 taken 2 times.
|
32 | for (const auto& rowKey : vec.rowKeys()) |
2500 | { | ||
2501 |
1/2✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
|
56 | rowKeysStr.push_back(fmt::format("{}", rowKey)); |
2502 | 28 | auto rowKeyLength = rowKeysStr.back().length(); | |
2503 | 28 | rowKeysColSpace = std::max(rowKeysColSpace, rowKeyLength); | |
2504 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
28 | rowKeysLength.push_back(rowKeyLength); |
2505 | } | ||
2506 | |||
2507 | 4 | size_t colLength = 9UL; | |
2508 | |||
2509 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | result.reserve(rows * (rowKeysColSpace + 2 + colLength)); |
2510 | // ------------------------------------------- Rows ---------------------------------------------- | ||
2511 |
2/2✓ Branch 1 taken 14 times.
✓ Branch 2 taken 2 times.
|
32 | for (size_t r = 0; r < rows; r++) |
2512 | { | ||
2513 |
3/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
✓ Branch 4 taken 8 times.
|
28 | if (rowKeysColSpace > rowKeysLength.at(r)) |
2514 | { | ||
2515 |
3/6✓ Branch 1 taken 6 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 6 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 6 times.
✗ Branch 8 not taken.
|
24 | result += std::string(rowKeysColSpace - rowKeysLength.at(r), ' '); // Spaces in front of row name (if too short) |
2516 | } | ||
2517 |
2/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
|
28 | result += rowKeysStr.at(r); |
2518 | |||
2519 |
1/2✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
|
28 | std::string tmp = fmt::format(" {:> {}.{}g}", vec(NAV::all)(static_cast<int>(r)), colLength, colLength - 2); |
2520 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
28 | if (tmp.length() > colLength) |
2521 | { | ||
2522 |
1/2✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
|
56 | tmp = fmt::format(" {:> {}.{}g}", vec(NAV::all)(static_cast<int>(r)), colLength, colLength - 6); |
2523 | } | ||
2524 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
28 | result += tmp; |
2525 | |||
2526 |
3/4✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
|
28 | if (r != rows - 1) { result += '\n'; } |
2527 | } | ||
2528 | 4 | } | |
2529 | |||
2530 | 12 | return fmt::formatter<std::string>::format(result, ctx); | |
2531 | 4 | } | |
2532 | }; | ||
2533 | |||
2534 | /// @brief Formatter for KeyedRowVector | ||
2535 | template<typename Scalar, typename ColKeyType, int Cols> | ||
2536 | struct fmt::formatter<NAV::KeyedRowVector<Scalar, ColKeyType, Cols>> : fmt::formatter<std::string> | ||
2537 | { | ||
2538 | /// @brief Defines how to format KeyedRowVector structs | ||
2539 | /// @param[in] vec Struct to format | ||
2540 | /// @param[in, out] ctx Format context | ||
2541 | /// @return Output iterator | ||
2542 | 4 | auto format(const NAV::KeyedRowVector<Scalar, ColKeyType, Cols>& vec, format_context& ctx) const | |
2543 | { | ||
2544 | 4 | std::string result; | |
2545 | 4 | auto cols = static_cast<size_t>(vec.cols()); | |
2546 | |||
2547 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
4 | if (cols > 0) |
2548 | { | ||
2549 | 4 | size_t colMinLength = 9UL; | |
2550 | |||
2551 | 4 | std::vector<std::string> colKeysStr; | |
2552 | 4 | std::vector<size_t> colKeysLength; | |
2553 | 4 | size_t rowLineLength = 1; // '\n' at the end of line | |
2554 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | colKeysStr.reserve(cols); |
2555 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | colKeysLength.reserve(cols); |
2556 |
2/2✓ Branch 5 taken 14 times.
✓ Branch 6 taken 2 times.
|
32 | for (const auto& colKey : vec.colKeys()) |
2557 | { | ||
2558 |
1/2✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
|
56 | colKeysStr.push_back(fmt::format("{}", colKey)); |
2559 | 28 | auto colKeyLength = colKeysStr.back().length(); | |
2560 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
28 | colKeysLength.push_back(colKeyLength); |
2561 | 28 | rowLineLength += 2 + std::max(colKeysStr.back().length(), colMinLength); // 2 spaces before each column | |
2562 | } | ||
2563 | |||
2564 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | result.reserve(2 * rowLineLength); |
2565 | // ---------------------------------------- Column keys ------------------------------------------ | ||
2566 |
2/2✓ Branch 0 taken 14 times.
✓ Branch 1 taken 2 times.
|
32 | for (size_t c = 0; c < cols; c++) |
2567 | { | ||
2568 |
3/4✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
|
28 | if (c != 0) { result += " "; } |
2569 |
3/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 13 times.
✓ Branch 4 taken 1 times.
|
28 | if (colMinLength > colKeysLength.at(c)) |
2570 | { | ||
2571 |
3/6✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 13 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 13 times.
✗ Branch 8 not taken.
|
52 | result += std::string(colMinLength - colKeysLength.at(c), ' '); // Spaces in front of column name (if too short) |
2572 | } | ||
2573 |
2/4✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 14 times.
✗ Branch 5 not taken.
|
28 | result += colKeysStr.at(c); |
2574 | } | ||
2575 |
1/2✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
|
4 | result += '\n'; |
2576 | // ------------------------------------------ Values --------------------------------------------- | ||
2577 | |||
2578 |
2/2✓ Branch 1 taken 14 times.
✓ Branch 2 taken 2 times.
|
32 | for (size_t c = 0; c < cols; c++) |
2579 | { | ||
2580 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
28 | auto colLength = std::max(colKeysStr.at(c).length(), colMinLength); |
2581 |
3/4✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
✓ Branch 3 taken 12 times.
✗ Branch 4 not taken.
|
28 | if (c != 0) { result += " "; } |
2582 |
1/2✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
|
28 | std::string tmp = fmt::format("{:> {}.{}g}", vec(NAV::all)(static_cast<int>(c)), colLength, colLength - 2); |
2583 |
2/2✓ Branch 1 taken 7 times.
✓ Branch 2 taken 7 times.
|
28 | if (tmp.length() > colLength) |
2584 | { | ||
2585 |
1/2✓ Branch 2 taken 7 times.
✗ Branch 3 not taken.
|
28 | tmp = fmt::format("{:> {}.{}g}", vec(NAV::all)(static_cast<int>(c)), colLength, colLength - 6); |
2586 | } | ||
2587 |
1/2✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
|
28 | result += tmp; |
2588 | } | ||
2589 | 4 | } | |
2590 | |||
2591 | 12 | return fmt::formatter<std::string>::format(result, ctx); | |
2592 | 4 | } | |
2593 | }; | ||
2594 | |||
2595 | #endif | ||
2596 | |||
2597 | /// @brief Stream insertion operator overload | ||
2598 | /// @param[in, out] os Output stream object to stream the time into | ||
2599 | /// @param[in] obj Object to print | ||
2600 | /// @return Returns the output stream object in order to chain stream insertions | ||
2601 | template<typename Scalar, typename RowKeyType, typename ColKeyType, int Rows, int Cols> | ||
2602 | std::ostream& operator<<(std::ostream& os, const NAV::KeyedMatrix<Scalar, RowKeyType, ColKeyType, Rows, Cols>& obj) | ||
2603 | { | ||
2604 | return os << fmt::format("{}", obj); | ||
2605 | } | ||
2606 | /// @brief Stream insertion operator overload | ||
2607 | /// @param[in, out] os Output stream object to stream the time into | ||
2608 | /// @param[in] obj Object to print | ||
2609 | /// @return Returns the output stream object in order to chain stream insertions | ||
2610 | template<typename Scalar, typename RowKeyType, int Rows> | ||
2611 | std::ostream& operator<<(std::ostream& os, const NAV::KeyedVector<Scalar, RowKeyType, Rows>& obj) | ||
2612 | { | ||
2613 | return os << fmt::format("{}", obj); | ||
2614 | } | ||
2615 | /// @brief Stream insertion operator overload | ||
2616 | /// @param[in, out] os Output stream object to stream the time into | ||
2617 | /// @param[in] obj Object to print | ||
2618 | /// @return Returns the output stream object in order to chain stream insertions | ||
2619 | template<typename Scalar, typename ColKeyType, int Cols> | ||
2620 | std::ostream& operator<<(std::ostream& os, const NAV::KeyedRowVector<Scalar, ColKeyType, Cols>& obj) | ||
2621 | { | ||
2622 | return os << fmt::format("{}", obj); | ||
2623 | } | ||
2624 |