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