0.4.1
Loading...
Searching...
No Matches
KeyedMatrix.hpp
Go to the documentation of this file.
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"
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
34namespace NAV
35{
36namespace internal
37{
38/// @brief All type to request all rows or columns in KeyedMatrices
39struct 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
49template<typename Scalar, int Rows, int Cols>
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
72template<typename Scalar, typename RowKeyType, int Rows, int Cols>
73class KeyedMatrixRowsBase : virtual public KeyedMatrixStorage<Scalar, Rows, Cols>
74{
75 public:
76 /// @brief Return the rows of the underlying Eigen matrix
77 [[nodiscard]] decltype(auto) rows() const { return this->matrix.rows(); }
78
79 /// @brief Returns the row keys
80 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 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 bool hasRows(std::span<const RowKeyType> keys) const
89 {
90 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 bool hasAnyRows(std::span<const RowKeyType> keys) const
96 {
97 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 void replaceRowKey(const RowKeyType& oldKey, const RowKeyType& newKey)
104 {
105 auto iter = std::ranges::find(rowKeysVector, oldKey);
106 INS_ASSERT_USER_ERROR(iter != rowKeysVector.end(), "You cannot replace keys, which are not in the vector/matrix.");
107
108 *iter = newKey;
109 rowIndices[newKey] = rowIndices.at(oldKey);
110 rowIndices.erase(oldKey);
111 }
112
113 protected:
114 /// RowKey to Row Index mapping
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
134template<typename Scalar, typename RowKeyType, int Rows, int Cols>
135class 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
142template<typename Scalar, typename RowKeyType, int Cols>
143class 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 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 void addRows(std::span<const RowKeyType> rowKeys)
153 {
154 INS_ASSERT_USER_ERROR(!this->hasAnyRows(rowKeys), "You cannot add a row key which is already in the matrix.");
155 INS_ASSERT_USER_ERROR(std::unordered_set<RowKeyType>(rowKeys.begin(), rowKeys.end()).size() == rowKeys.size(), "Each row key must be unique");
156
157 auto initialSize = static_cast<Eigen::Index>(this->rowIndices.size());
158 for (const auto& rowKey : rowKeys) { this->rowIndices.insert({ rowKey, static_cast<Eigen::Index>(this->rowIndices.size()) }); }
159 this->rowKeysVector.reserve(this->rowKeysVector.size() + rowKeys.size());
160 std::copy(rowKeys.begin(), rowKeys.end(), std::back_inserter(this->rowKeysVector));
161 auto finalSize = static_cast<Eigen::Index>(this->rowIndices.size());
162
163 if (finalSize > initialSize)
164 {
165 this->matrix.conservativeResize(finalSize, Eigen::NoChange);
166 this->matrix.block(initialSize, 0, finalSize - initialSize, this->matrix.cols()) = Eigen::MatrixX<Scalar>::Zero(finalSize - initialSize, this->matrix.cols());
167 }
168 std::lock_guard<std::mutex> lg{ this->_sliceMutex };
169 this->rowSlice.reserve(this->rowKeysVector.size());
170 }
171
172 /// @brief Removes the row from the matrix
173 /// @param rowKey Row Key
174 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 void removeRows(std::span<const RowKeyType> rowKeys)
179 {
180 std::vector<int> indices;
181 for (const auto& rowKey : rowKeys)
182 {
183 auto iter = this->rowIndices.find(rowKey);
184 INS_ASSERT_USER_ERROR(iter != this->rowIndices.end(), "You tried removing a row key, which did not exist.");
185 if (iter != this->rowIndices.end())
186 {
187 indices.push_back(static_cast<int>(iter->second));
188 }
189 }
190 NAV::removeRows(this->matrix, indices);
191
192 for (const auto& rowKey : rowKeys)
193 {
194 auto iter = this->rowIndices.find(rowKey);
195 if (iter != this->rowIndices.end())
196 {
197 std::erase_if(this->rowKeysVector, [&](const auto& item) { return item == rowKey; });
198
199 auto idx = iter->second;
200 for (auto& rowIndex : this->rowIndices)
201 {
202 if (rowIndex.second > idx) { rowIndex.second--; }
203 }
204 this->rowIndices.erase(iter);
205 }
206 }
207 }
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
217template<typename Scalar, typename ColKeyType, int Rows, int Cols>
218class KeyedMatrixColsBase : virtual public KeyedMatrixStorage<Scalar, Rows, Cols>
219{
220 public:
221 /// @brief Return the cols of the underlying Eigen matrix
222 [[nodiscard]] decltype(auto) cols() const { return this->matrix.cols(); }
223
224 /// @brief Returns the col keys
225 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 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 bool hasCols(std::span<const ColKeyType> keys) const
234 {
235 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 bool hasAnyCols(std::span<const ColKeyType> keys) const
241 {
242 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 void replaceColKey(const ColKeyType& oldKey, const ColKeyType& newKey)
249 {
250 auto iter = std::ranges::find(colKeysVector, oldKey);
251 INS_ASSERT_USER_ERROR(iter != colKeysVector.end(), "You cannot replace keys, which are not in the vector/matrix.");
252
253 *iter = newKey;
254 colIndices[newKey] = colIndices.at(oldKey);
255 colIndices.erase(oldKey);
256 }
257
258 protected:
259 /// ColKey to Col Index mapping
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
279template<typename Scalar, typename ColKeyType, int Rows, int Cols>
280class 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
287template<typename Scalar, typename ColKeyType, int Rows>
288class 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 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 void addCols(std::span<const ColKeyType> colKeys)
298 {
299 INS_ASSERT_USER_ERROR(!this->hasAnyCols(colKeys), "You cannot add a col key which is already in the matrix.");
300 INS_ASSERT_USER_ERROR(std::unordered_set<ColKeyType>(colKeys.begin(), colKeys.end()).size() == colKeys.size(), "Each col key must be unique");
301
302 auto initialSize = static_cast<Eigen::Index>(this->colIndices.size());
303 for (const auto& colKey : colKeys) { this->colIndices.insert({ colKey, static_cast<Eigen::Index>(this->colIndices.size()) }); }
304 this->colKeysVector.reserve(this->colKeysVector.size() + colKeys.size());
305 std::copy(colKeys.begin(), colKeys.end(), std::back_inserter(this->colKeysVector));
306 auto finalSize = static_cast<Eigen::Index>(this->colIndices.size());
307
308 if (finalSize > initialSize)
309 {
310 this->matrix.conservativeResize(Eigen::NoChange, finalSize);
311 this->matrix.block(0, initialSize, this->matrix.rows(), finalSize - initialSize) = Eigen::MatrixX<Scalar>::Zero(this->matrix.rows(), finalSize - initialSize);
312 }
313 std::lock_guard<std::mutex> lg{ this->_sliceMutex };
314 this->colSlice.reserve(this->colKeysVector.size());
315 }
316
317 /// @brief Removes the col from the matrix
318 /// @param colKey Col Key
319 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 void removeCols(std::span<const ColKeyType> colKeys)
324 {
325 std::vector<int> indices;
326 for (const auto& colKey : colKeys)
327 {
328 auto iter = this->colIndices.find(colKey);
329 INS_ASSERT_USER_ERROR(iter != this->colIndices.end(), "You tried removing a col key, which did not exist.");
330 if (iter != this->colIndices.end())
331 {
332 indices.push_back(static_cast<int>(iter->second));
333 }
334 }
335 NAV::removeCols(this->matrix, indices);
336
337 for (const auto& colKey : colKeys)
338 {
339 auto iter = this->colIndices.find(colKey);
340 if (iter != this->colIndices.end())
341 {
342 std::erase_if(this->colKeysVector, [&](const auto& item) { return item == colKey; });
343
344 auto idx = iter->second;
345 for (auto& colIndex : this->colIndices)
346 {
347 if (colIndex.second > idx) { colIndex.second--; }
348 }
349 this->colIndices.erase(iter);
350 }
351 }
352 }
353};
354
355// ###########################################################################################################
356
357template<typename Scalar, typename ColKeyType, int Cols>
358class 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
364template<typename Scalar, typename RowKeyType, int Rows>
365class 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 explicit KeyedVectorBase(const Eigen::MatrixBase<Derived>& vector)
372 {
373 this->matrix = vector;
374 }
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 KeyedVectorBase(const Eigen::MatrixBase<Derived>& vector, std::span<const RowKeyType> rowKeys)
381 {
382 INS_ASSERT_USER_ERROR(std::unordered_set<RowKeyType>(rowKeys.begin(), rowKeys.end()).size() == rowKeys.size(), "Each row key must be unique");
383
384 INS_ASSERT_USER_ERROR(vector.cols() == 1, "Only vectors with 1 column are allowed.");
385 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 for (size_t i = 0; i < rowKeys.size(); i++) { this->rowIndices.insert({ rowKeys[i], static_cast<Eigen::Index>(i) }); }
388
389 this->matrix = vector;
390 std::ranges::copy(rowKeys, std::back_inserter(this->rowKeysVector));
391 this->rowSlice.reserve(this->rowKeysVector.size());
392 }
393
394 // #######################################################################################################
395 // Special member functions
396 // #######################################################################################################
397
398 /// @brief Destructor
399 ~KeyedVectorBase() = default;
400 /// @brief Copy constructor
401 /// @param other The other object
403 {
404 this->matrix = other.matrix;
405 this->rowIndices = other.rowIndices;
406 this->rowKeysVector = other.rowKeysVector;
407 this->rowSlice.reserve(this->rowKeysVector.size());
408 }
409 /// @brief Copy assignment operator
410 /// @param other The other object
412 {
413 if (this == &other) { return *this; } // Guard self assignment
414
415 this->matrix = other.matrix;
416 this->rowIndices = other.rowIndices;
417 this->rowKeysVector = other.rowKeysVector;
418 this->rowSlice.reserve(this->rowKeysVector.size());
419
420 return *this;
421 }
422 /// @brief Move constructor
423 /// @param other The other object
425 {
426 this->matrix = std::move(other.matrix);
427 this->rowIndices = std::move(other.rowIndices);
428 this->rowKeysVector = std::move(other.rowKeysVector);
429 this->rowSlice.reserve(this->rowKeysVector.size());
430 }
431 /// @brief Move assignment operator
432 /// @param other The other object
434 {
435 if (this == &other) { return *this; } // Guard self assignment
436
437 this->matrix = std::move(other.matrix);
438 this->rowIndices = std::move(other.rowIndices);
439 this->rowKeysVector = std::move(other.rowKeysVector);
440 this->rowSlice.reserve(this->rowKeysVector.size());
441
442 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 KeyedVectorBase(const KeyedVectorBase<Scalar, RowKeyType, oRows>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
453 {
454 INS_ASSERT_USER_ERROR(Rows == Eigen::Dynamic || other.rows() == Rows, "Can only copy construct dynamic<=>static matrices if the rows match");
455
456 this->matrix = other.matrix;
457 this->rowIndices = other.rowIndices;
458 this->rowKeysVector = other.rowKeysVector;
459 this->rowSlice.reserve(this->rowKeysVector.size());
460 }
461 /// @brief Copy assignment operator
462 /// @param other The other object
463 template<int oRows>
465 {
466 // No need to guard self assignment, as the types are different, so it cannot be the same object
467
468 INS_ASSERT_USER_ERROR(other.rowKeys() == this->rowKeys(), "Can only copy assign matrices if the row keys match");
469
470 this->matrix = other.matrix;
471 this->rowIndices = other.rowIndices;
472 this->rowKeysVector = other.rowKeysVector;
473 this->rowSlice.reserve(this->rowKeysVector.size());
474
475 return *this;
476 }
477 /// @brief Move constructor
478 /// @param other The other object
479 template<int oRows>
480 KeyedVectorBase(KeyedVectorBase<Scalar, RowKeyType, oRows>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
481 {
482 INS_ASSERT_USER_ERROR(Rows == Eigen::Dynamic || other.rows() == Rows, "Can only copy construct dynamic<=>static matrices if the rows match");
483
484 this->matrix = std::move(other.matrix);
485 this->rowIndices = std::move(other.rowIndices);
486 this->rowKeysVector = std::move(other.rowKeysVector);
487 this->rowSlice.reserve(this->rowKeysVector.size());
488 }
489 /// @brief Move assignment operator
490 /// @param other The other object
491 template<int oRows>
493 {
494 // No need to guard self assignment, as the types are different, so it cannot be the same object
495
496 INS_ASSERT_USER_ERROR(other.rowKeys() == this->rowKeys(), "Can only copy assign matrices if the row keys match");
497
498 this->matrix = std::move(other.matrix);
499 this->rowIndices = std::move(other.rowIndices);
500 this->rowKeysVector = std::move(other.rowKeysVector);
501 this->rowSlice.reserve(this->rowKeysVector.size());
502
503 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 const Scalar& operator()(const RowKeyType& rowKey) const
514 {
515 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 Scalar& operator()(const RowKeyType& rowKey)
521 {
522 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 decltype(auto) operator()(std::span<const RowKeyType> rowKeys)
540 {
541 std::lock_guard<std::mutex> lg{ this->_sliceMutex };
542 this->rowSlice.clear();
543 for (const auto& rowKey : rowKeys) { this->rowSlice.push_back(this->rowIndices.at(rowKey)); }
544
545 return this->matrix(this->rowSlice, 0);
546 }
547
548 /// @brief Requests the full vector
549 const Eigen::Matrix<Scalar, Rows, 1>& operator()(all_t /* all */) const { return this->matrix; }
550 /// @brief Requests the full vector
551 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 decltype(auto) segment(std::span<const RowKeyType> rowKeys) const // NOLINT(readability-const-return-type)
564 {
566
567 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 decltype(auto) segment(std::span<const RowKeyType> rowKeys)
574 {
576
577 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 {
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 decltype(auto) segment(std::span<const RowKeyType> rowKeys)
592 {
594
595 return this->matrix.middleRows(this->rowIndices.at(rowKeys.front()), rowKeys.size());
596 }
597
598 // #######################################################################################################
599 // Methods
600 // #######################################################################################################
601
602 /// @brief Calculates the transposed vector
604 {
605 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 void checkContinuousSegment([[maybe_unused]] std::span<const RowKeyType> rowKeys, [[maybe_unused]] size_t P) const
613 {
614#ifndef NDEBUG
615 INS_ASSERT_USER_ERROR(P == rowKeys.size(), "The block size must be equivalent to the amount of row keys.");
616
617 std::vector<Eigen::Index> consecutiveRows(rowKeys.size());
618 std::iota(std::begin(consecutiveRows), std::end(consecutiveRows), this->rowIndices.at(rowKeys.front()));
619 std::vector<Eigen::Index> rowIndices;
620 rowIndices.reserve(rowKeys.size());
621 for (const auto& rowKey : rowKeys) { rowIndices.push_back(this->rowIndices.at(rowKey)); }
622 INS_ASSERT_USER_ERROR(rowIndices == consecutiveRows, "The given rowKeys must describe a consecutive part in the matrix.");
623#endif
624 }
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
631template<typename Scalar, typename ColKeyType, int Cols>
632class 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 KeyedRowVectorBase(const Eigen::MatrixBase<Derived>& vector, std::span<const ColKeyType> colKeys)
648 {
649 INS_ASSERT_USER_ERROR(std::unordered_set<ColKeyType>(colKeys.begin(), colKeys.end()).size() == colKeys.size(), "Each col key must be unique");
650
651 INS_ASSERT_USER_ERROR(vector.rows() == 1, "Only vectors with 1 row are allowed.");
652 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 for (size_t i = 0; i < colKeys.size(); i++) { this->colIndices.insert({ colKeys[i], static_cast<Eigen::Index>(i) }); }
655
656 this->matrix = vector;
657 std::ranges::copy(colKeys, std::back_inserter(this->colKeysVector));
658 this->colSlice.reserve(this->colKeysVector.size());
659 }
660
661 // #######################################################################################################
662 // Special member functions
663 // #######################################################################################################
664
665 /// @brief Destructor
667 /// @brief Copy constructor
668 /// @param other The other object
670 {
671 this->matrix = other.matrix;
672 this->colIndices = other.colIndices;
673 this->colKeysVector = other.colKeysVector;
674 this->colSlice.reserve(this->colKeysVector.size());
675 }
676 /// @brief Copy assignment operator
677 /// @param other The other object
679 {
680 if (this == &other) { return *this; } // Guard self assignment
681
682 this->matrix = other.matrix;
683 this->colIndices = other.colIndices;
684 this->colKeysVector = other.colKeysVector;
685 this->colSlice.reserve(this->colKeysVector.size());
686
687 return *this;
688 }
689 /// @brief Move constructor
690 /// @param other The other object
692 {
693 this->matrix = std::move(other.matrix);
694 this->colIndices = std::move(other.colIndices);
695 this->colKeysVector = std::move(other.colKeysVector);
696 this->colSlice.reserve(this->colKeysVector.size());
697 }
698 /// @brief Move assignment operator
699 /// @param other The other object
701 {
702 if (this == &other) { return *this; } // Guard self assignment
703
704 this->matrix = std::move(other.matrix);
705 this->colIndices = std::move(other.colIndices);
706 this->colKeysVector = std::move(other.colKeysVector);
707 this->colSlice.reserve(this->colKeysVector.size());
708
709 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 KeyedRowVectorBase(const KeyedRowVectorBase<Scalar, ColKeyType, oCols>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
720 {
721 INS_ASSERT_USER_ERROR(Cols == Eigen::Dynamic || other.cols() == Cols, "Can only copy construct dynamic<=>static matrices if the cols match");
722
723 this->matrix = other.matrix;
724 this->colIndices = other.colIndices;
725 this->colKeysVector = other.colKeysVector;
726 this->colSlice.reserve(this->colKeysVector.size());
727 }
728 /// @brief Copy assignment operator
729 /// @param other The other object
730 template<int oCols>
732 {
733 // No need to guard self assignment, as the types are different, so it cannot be the same object
734
735 INS_ASSERT_USER_ERROR(other.colKeys() == this->colKeys(), "Can only copy assign matrices if the col keys match");
736
737 this->matrix = other.matrix;
738 this->colIndices = other.colIndices;
739 this->colKeysVector = other.colKeysVector;
740 this->colSlice.reserve(this->colKeysVector.size());
741
742 return *this;
743 }
744 /// @brief Move constructor
745 /// @param other The other object
746 template<int oCols>
747 KeyedRowVectorBase(KeyedRowVectorBase<Scalar, ColKeyType, oCols>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
748 {
749 INS_ASSERT_USER_ERROR(Cols == Eigen::Dynamic || other.cols() == Cols, "Can only copy construct dynamic<=>static matrices if the cols match");
750
751 this->matrix = std::move(other.matrix);
752 this->colIndices = std::move(other.colIndices);
753 this->colKeysVector = std::move(other.colKeysVector);
754 this->colSlice.reserve(this->colKeysVector.size());
755 }
756 /// @brief Move assignment operator
757 /// @param other The other object
758 template<int oCols>
760 {
761 // No need to guard self assignment, as the types are different, so it cannot be the same object
762
763 INS_ASSERT_USER_ERROR(other.colKeys() == this->colKeys(), "Can only copy assign matrices if the col keys match");
764
765 this->matrix = std::move(other.matrix);
766 this->colIndices = std::move(other.colIndices);
767 this->colKeysVector = std::move(other.colKeysVector);
768 this->colSlice.reserve(this->colKeysVector.size());
769
770 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 const Eigen::Matrix<Scalar, 1, Cols>& operator()(all_t /* all */) const { return this->matrix; }
817 /// @brief Requests the full vector
818 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 {
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 decltype(auto) segment(std::span<const ColKeyType> colKeys)
841 {
843
844 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 {
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 decltype(auto) segment(std::span<const ColKeyType> colKeys)
859 {
861
862 return this->matrix.middleCols(this->colIndices.at(colKeys.front()), colKeys.size());
863 }
864
865 // #######################################################################################################
866 // Methods
867 // #######################################################################################################
868
869 /// @brief Calculates the transposed vector
871 {
872 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 void checkContinuousSegment([[maybe_unused]] std::span<const ColKeyType> colKeys, [[maybe_unused]] size_t Q) const
880 {
881#ifndef NDEBUG
882 INS_ASSERT_USER_ERROR(Q == colKeys.size(), "The block size must be equivalent to the amount of col keys.");
883
884 std::vector<Eigen::Index> consecutiveCols(colKeys.size());
885 std::iota(std::begin(consecutiveCols), std::end(consecutiveCols), this->colIndices.at(colKeys.front()));
886 std::vector<Eigen::Index> colIndices;
887 colIndices.reserve(colKeys.size());
888 for (const auto& colKey : colKeys) { colIndices.push_back(this->colIndices.at(colKey)); }
889 INS_ASSERT_USER_ERROR(colIndices == consecutiveCols, "The given colKeys must describe a consecutive part in the matrix.");
890#endif
891 }
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
900template<typename Scalar, typename RowKeyType, typename ColKeyType, int Rows, int Cols>
901class 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 explicit KeyedMatrixBase(const Eigen::MatrixBase<Derived>& matrix)
908 {
909 this->matrix = matrix;
910 }
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 KeyedMatrixBase(const Eigen::MatrixBase<Derived>& matrix, std::span<const RowKeyType> rowKeys, std::span<const ColKeyType> colKeys)
917 {
918 INS_ASSERT_USER_ERROR(std::unordered_set<RowKeyType>(rowKeys.begin(), rowKeys.end()).size() == rowKeys.size(), "Each row key must be unique");
919 INS_ASSERT_USER_ERROR(std::unordered_set<ColKeyType>(colKeys.begin(), colKeys.end()).size() == colKeys.size(), "Each col key must be unique");
920
921 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 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 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 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 for (size_t i = 0; i < rowKeys.size(); i++) { this->rowIndices.insert({ rowKeys[i], static_cast<Eigen::Index>(i) }); }
928 for (size_t i = 0; i < colKeys.size(); i++) { this->colIndices.insert({ colKeys[i], static_cast<Eigen::Index>(i) }); }
929
930 this->matrix = matrix;
931 std::ranges::copy(rowKeys, std::back_inserter(this->rowKeysVector));
932 std::ranges::copy(colKeys, std::back_inserter(this->colKeysVector));
933 this->colSlice.reserve(this->colKeysVector.size());
934 this->rowSlice.reserve(this->rowKeysVector.size());
935 }
936
937 // #######################################################################################################
938 // Special member functions
939 // #######################################################################################################
940
941 /// @brief Destructor
942 ~KeyedMatrixBase() = default;
943 /// @brief Copy constructor
944 /// @param other The other object
946 {
947 this->matrix = other.matrix;
948 this->rowIndices = other.rowIndices;
949 this->rowKeysVector = other.rowKeysVector;
950 this->colIndices = other.colIndices;
951 this->colKeysVector = other.colKeysVector;
952 this->colSlice.reserve(this->colKeysVector.size());
953 this->rowSlice.reserve(this->rowKeysVector.size());
954 }
955 /// @brief Copy assignment operator
956 /// @param other The other object
958 {
959 if (this == &other) { return *this; } // Guard self assignment
960
961 this->matrix = other.matrix;
962 this->rowIndices = other.rowIndices;
963 this->rowKeysVector = other.rowKeysVector;
964 this->colIndices = other.colIndices;
965 this->colKeysVector = other.colKeysVector;
966 this->colSlice.reserve(this->colKeysVector.size());
967 this->rowSlice.reserve(this->rowKeysVector.size());
968
969 return *this;
970 }
971 /// @brief Move constructor
972 /// @param other The other object
974 {
975 this->matrix = std::move(other.matrix);
976 this->rowIndices = std::move(other.rowIndices);
977 this->rowKeysVector = std::move(other.rowKeysVector);
978 this->colIndices = std::move(other.colIndices);
979 this->colKeysVector = std::move(other.colKeysVector);
980 this->colSlice.reserve(this->colKeysVector.size());
981 this->rowSlice.reserve(this->rowKeysVector.size());
982 }
983 /// @brief Move assignment operator
984 /// @param other The other object
986 {
987 if (this == &other) { return *this; } // Guard self assignment
988
989 this->matrix = std::move(other.matrix);
990 this->rowIndices = std::move(other.rowIndices);
991 this->rowKeysVector = std::move(other.rowKeysVector);
992 this->colIndices = std::move(other.colIndices);
993 this->colKeysVector = std::move(other.colKeysVector);
994 this->colSlice.reserve(this->colKeysVector.size());
995 this->rowSlice.reserve(this->rowKeysVector.size());
996
997 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 KeyedMatrixBase(const KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, oRows, oCols>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1008 {
1009 INS_ASSERT_USER_ERROR(Rows == Eigen::Dynamic || other.rows() == Rows, "Can only copy construct dynamic<=>static matrices if the rows match");
1010 INS_ASSERT_USER_ERROR(Cols == Eigen::Dynamic || other.cols() == Cols, "Can only copy construct dynamic<=>static matrices if the cols match");
1011
1012 this->matrix = other.matrix;
1013 this->rowIndices = other.rowIndices;
1014 this->rowKeysVector = other.rowKeysVector;
1015 this->colIndices = other.colIndices;
1016 this->colKeysVector = other.colKeysVector;
1017 this->colSlice.reserve(this->colKeysVector.size());
1018 this->rowSlice.reserve(this->rowKeysVector.size());
1019 }
1020 /// @brief Copy assignment operator
1021 /// @param other The other object
1022 template<int oRows, int oCols>
1024 {
1025 // No need to guard self assignment, as the types are different, so it cannot be the same object
1026
1027 INS_ASSERT_USER_ERROR(other.rowKeys() == this->rowKeys(), "Can only copy assign matrices if the row keys match");
1028 INS_ASSERT_USER_ERROR(other.colKeys() == this->colKeys(), "Can only copy assign matrices if the col keys match");
1029
1030 this->matrix = other.matrix;
1031 this->rowIndices = other.rowIndices;
1032 this->rowKeysVector = other.rowKeysVector;
1033 this->colIndices = other.colIndices;
1034 this->colKeysVector = other.colKeysVector;
1035 this->colSlice.reserve(this->colKeysVector.size());
1036 this->rowSlice.reserve(this->rowKeysVector.size());
1037
1038 return *this;
1039 }
1040 /// @brief Move constructor
1041 /// @param other The other object
1042 template<int oRows, int oCols>
1043 KeyedMatrixBase(KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, oRows, oCols>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1044 {
1045 INS_ASSERT_USER_ERROR(Rows == Eigen::Dynamic || other.rows() == Rows, "Can only copy construct dynamic<=>static matrices if the rows match");
1046 INS_ASSERT_USER_ERROR(Cols == Eigen::Dynamic || other.cols() == Cols, "Can only copy construct dynamic<=>static matrices if the cols match");
1047
1048 this->matrix = std::move(other.matrix);
1049 this->rowIndices = std::move(other.rowIndices);
1050 this->rowKeysVector = std::move(other.rowKeysVector);
1051 this->colIndices = std::move(other.colIndices);
1052 this->colKeysVector = std::move(other.colKeysVector);
1053 this->colSlice.reserve(this->colKeysVector.size());
1054 this->rowSlice.reserve(this->rowKeysVector.size());
1055 }
1056 /// @brief Move assignment operator
1057 /// @param other The other object
1058 template<int oRows, int oCols>
1060 {
1061 // No need to guard self assignment, as the types are different, so it cannot be the same object
1062
1063 INS_ASSERT_USER_ERROR(other.rowKeys() == this->rowKeys(), "Can only copy assign matrices if the row keys match");
1064 INS_ASSERT_USER_ERROR(other.colKeys() == this->colKeys(), "Can only copy assign matrices if the col keys match");
1065
1066 this->matrix = std::move(other.matrix);
1067 this->rowIndices = std::move(other.rowIndices);
1068 this->rowKeysVector = std::move(other.rowKeysVector);
1069 this->colIndices = std::move(other.colIndices);
1070 this->colKeysVector = std::move(other.colKeysVector);
1071 this->colSlice.reserve(this->colKeysVector.size());
1072 this->rowSlice.reserve(this->rowKeysVector.size());
1073
1074 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 const Scalar& operator()(const RowKeyType& rowKey, const ColKeyType& colKey) const
1086 {
1087 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 Scalar& operator()(const RowKeyType& rowKey, const ColKeyType& colKey)
1094 {
1095 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 decltype(auto) operator()(std::span<const RowKeyType> rowKeys, std::span<const ColKeyType> colKeys) const
1103 {
1104 std::lock_guard<std::mutex> lg{ this->_sliceMutex };
1105 this->rowSlice.clear();
1106 for (const auto& rowKey : rowKeys) { this->rowSlice.push_back(this->rowIndices.at(rowKey)); }
1107
1108 this->colSlice.clear();
1109 for (const auto& colKey : colKeys) { this->colSlice.push_back(this->colIndices.at(colKey)); }
1110
1111 return this->matrix(this->rowSlice, this->colSlice);
1112 }
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 decltype(auto) operator()(std::span<const RowKeyType> rowKeys, std::span<const ColKeyType> colKeys)
1118 {
1119 std::lock_guard<std::mutex> lg{ this->_sliceMutex };
1120 this->rowSlice.clear();
1121 for (const auto& rowKey : rowKeys) { this->rowSlice.push_back(this->rowIndices.at(rowKey)); }
1122
1123 this->colSlice.clear();
1124 for (const auto& colKey : colKeys) { this->colSlice.push_back(this->colIndices.at(colKey)); }
1125
1126 return this->matrix(this->rowSlice, this->colSlice);
1127 }
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 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 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 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 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 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 decltype(auto) operator()(all_t /* all */, std::span<const ColKeyType> colKeys) { return (*this)(this->rowKeys(), colKeys); }
1181
1182 /// @brief Requests the full matrix
1183 const Eigen::Matrix<Scalar, Rows, Cols>& operator()(all_t /* all */, all_t /* all */) const { return this->matrix; }
1184 /// @brief Requests the full matrix
1185 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 {
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 decltype(auto) block(std::span<const RowKeyType> rowKeys, std::span<const ColKeyType> colKeys)
1210 {
1212
1213 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 decltype(auto) block(std::span<const RowKeyType> rowKeys, const ColKeyType& colKey)
1230 {
1231 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 decltype(auto) block(const RowKeyType& rowKey, std::span<const ColKeyType> colKeys)
1248 {
1249 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 decltype(auto) middleRows(std::span<const RowKeyType> rowKeys)
1267 {
1268 checkContinuousBlock(rowKeys, this->colKeys(), P, this->colKeys().size());
1269
1270 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 decltype(auto) middleCols(std::span<const ColKeyType> colKeys)
1287 {
1288 checkContinuousBlock(this->rowKeys(), colKeys, this->rowKeys().size(), Q);
1289
1290 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 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 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 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 {
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 decltype(auto) block(std::span<const RowKeyType> rowKeys, std::span<const ColKeyType> colKeys)
1333 {
1335
1336 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 decltype(auto) block(std::span<const RowKeyType> rowKeys, const ColKeyType& colKey)
1351 {
1352 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 decltype(auto) block(const RowKeyType& rowKey, std::span<const ColKeyType> colKeys)
1367 {
1368 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 decltype(auto) middleRows(std::span<const RowKeyType> rowKeys)
1384 {
1385 checkContinuousBlock(rowKeys, this->colKeys(), rowKeys.size(), this->colKeys().size());
1386
1387 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 decltype(auto) middleCols(std::span<const ColKeyType> colKeys)
1402 {
1403 checkContinuousBlock(this->rowKeys(), colKeys, this->rowKeys().size(), colKeys.size());
1404
1405 return this->matrix.middleCols(this->colIndices.at(colKeys.front()), colKeys.size());
1406 }
1407
1408 // #######################################################################################################
1409 // Methods
1410 // #######################################################################################################
1411
1412 /// @brief Calculates the transposed matrix
1414 {
1415 return { this->matrix.transpose(), this->colKeys(), this->rowKeys() };
1416 }
1417
1418 /// @brief Calculates the inverse matrix
1420 {
1421 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 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 INS_ASSERT_USER_ERROR(P == rowKeys.size(), "The block size must be equivalent to the amount of row keys.");
1435 INS_ASSERT_USER_ERROR(Q == colKeys.size(), "The block size must be equivalent to the amount of col keys.");
1436
1437 std::vector<Eigen::Index> consecutiveRows(rowKeys.size());
1438 std::iota(std::begin(consecutiveRows), std::end(consecutiveRows), this->rowIndices.at(rowKeys.front()));
1439 std::vector<Eigen::Index> rowIndices;
1440 rowIndices.reserve(rowKeys.size());
1441 for (const auto& rowKey : rowKeys) { rowIndices.push_back(this->rowIndices.at(rowKey)); }
1442 INS_ASSERT_USER_ERROR(rowIndices == consecutiveRows, "The given rowKeys must describe a consecutive part in the matrix.");
1443
1444 std::vector<Eigen::Index> consecutiveCols(colKeys.size());
1445 std::iota(std::begin(consecutiveCols), std::end(consecutiveCols), this->colIndices.at(colKeys.front()));
1446 std::vector<Eigen::Index> colIndices;
1447 colIndices.reserve(colKeys.size());
1448 for (const auto& colKey : colKeys) { colIndices.push_back(this->colIndices.at(colKey)); }
1449 INS_ASSERT_USER_ERROR(colIndices == consecutiveCols, "The given colKeys must describe a consecutive part in the matrix.");
1450#endif
1451 }
1452};
1453
1454} // namespace internal
1455
1456/// @brief Used to request all rows or columns in KeyedMatrices
1458
1459template<typename Scalar, typename ColKeyType, int Cols>
1460class 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
1466template<typename Scalar, typename RowKeyType, int Rows>
1467class 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 KeyedVector(const Eigen::MatrixBase<Derived>& vector, std::span<const RowKeyType> rowKeys)
1476 : internal::KeyedVectorBase<Scalar, RowKeyType, Rows>(vector, rowKeys)
1477 {}
1478
1479 // #######################################################################################################
1480 // Special member functions
1481 // #######################################################################################################
1482
1483 /// @brief Destructor
1484 ~KeyedVector() = default;
1485 /// @brief Copy constructor
1486 /// @param other The other object
1488 : internal::KeyedVectorBase<Scalar, RowKeyType, Rows>(other)
1489 {}
1490 /// @brief Copy assignment operator
1491 /// @param other The other object
1493 {
1494 if (this == &other) { return *this; } // Guard self assignment
1495
1497 static_cast<const internal::KeyedVectorBase<Scalar, RowKeyType, Rows>&>(other);
1498
1499 return *this;
1500 }
1501 /// @brief Move constructor
1502 /// @param other The other object
1503 KeyedVector(KeyedVector&& other) noexcept
1505 {}
1506 /// @brief Move assignment operator
1507 /// @param other The other object
1509 {
1510 if (this == &other) { return *this; } // Guard self assignment
1511
1513 std::move(static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Rows>&>(other));
1514
1515 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 KeyedVector(const KeyedVector<Scalar, RowKeyType, Eigen::Dynamic>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1525 : internal::KeyedVectorBase<Scalar, RowKeyType, Rows>(other)
1526 {
1527 INS_ASSERT_USER_ERROR(other.rows() == Rows, "Can only copy assign dynamic matrices from static ones if the size matches");
1528 }
1529 /// @brief Copy assignment operator
1530 /// @param other The other object
1532 {
1533 // No need to guard self assignment, as the types are different, so it cannot be the same object
1534
1535 INS_ASSERT_USER_ERROR(other.rows() == Rows, "Can only copy assign dynamic matrices from static ones if the size matches");
1536
1539
1540 return *this;
1541 }
1542 /// @brief Move constructor
1543 /// @param other The other object
1544 KeyedVector(KeyedVector<Scalar, RowKeyType, Eigen::Dynamic>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1546 {
1547 INS_ASSERT_USER_ERROR(this->rows() == Rows, "Can only move construct dynamic matrices from static ones if the size matches");
1548 }
1549 /// @brief Move assignment operator
1550 /// @param other The other object
1552 {
1553 // No need to guard self assignment, as the types are different, so it cannot be the same object
1554
1555 INS_ASSERT_USER_ERROR(other.rows() == Rows, "Can only move assign dynamic matrices from static ones if the size matches");
1556
1559
1560 return *this;
1561 }
1562
1563 // #######################################################################################################
1564 // Methods
1565 // #######################################################################################################
1566
1567 /// @brief Calculates the transposed vector
1569 {
1570 auto transpose = static_cast<const internal::KeyedVectorBase<Scalar, RowKeyType, Rows>&>(*this).transposed();
1571 return { transpose(all), transpose.colKeys() };
1572 }
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
1578template<typename Scalar, typename RowKeyType>
1579class KeyedVector<Scalar, RowKeyType, Eigen::Dynamic> : public internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>
1580{
1581 public:
1582 /// @brief Default Constructor
1583 KeyedVector()
1584 : 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 KeyedVector(const Eigen::MatrixBase<Derived>& vector, std::span<const RowKeyType> rowKeys)
1592 : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(vector, rowKeys)
1593 {}
1594
1595 // #######################################################################################################
1596 // Special member functions
1597 // #######################################################################################################
1598
1599 /// @brief Destructor
1600 ~KeyedVector() = default;
1601 /// @brief Copy constructor
1602 /// @param other The other object
1603 KeyedVector(const KeyedVector& other)
1604 : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(other)
1605 {}
1606 /// @brief Copy assignment operator
1607 /// @param other The other object
1608 KeyedVector& operator=(const KeyedVector& other)
1609 {
1610 if (this == &other) { return *this; } // Guard self assignment
1611
1612 static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>&>(*this) =
1613 static_cast<const internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>&>(other);
1614
1615 return *this;
1616 }
1617 /// @brief Move constructor
1618 /// @param other The other object
1619 KeyedVector(KeyedVector&& other) noexcept
1620 : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(std::move(other))
1621 {}
1622 /// @brief Move assignment operator
1623 /// @param other The other object
1624 KeyedVector& operator=(KeyedVector&& other) noexcept
1625 {
1626 if (this == &other) { return *this; } // Guard self assignment
1627
1628 static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>&>(*this) =
1629 std::move(static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>&>(other));
1630
1631 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 KeyedVector(const KeyedVector<Scalar, RowKeyType, oRows>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1642 : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(other)
1643 {}
1644 /// @brief Copy assignment operator
1645 /// @param other The other object
1646 template<int oRows>
1648 {
1649 // No need to guard self assignment, as the types are different, so it cannot be the same object
1650
1651 static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>&>(*this) =
1652 static_cast<const internal::KeyedVectorBase<Scalar, RowKeyType, oRows>&>(other);
1653
1654 return *this;
1655 }
1656 /// @brief Move constructor
1657 /// @param other The other object
1658 template<int oRows>
1659 KeyedVector(KeyedVector<Scalar, RowKeyType, oRows>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1660 : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(std::move(other))
1661 {}
1662 /// @brief Move assignment operator
1663 /// @param other The other object
1664 template<int oRows>
1666 {
1667 // No need to guard self assignment, as the types are different, so it cannot be the same object
1668
1669 static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>&>(*this) =
1670 std::move(static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, oRows>&>(other));
1671
1672 return *this;
1673 }
1674
1675 // #######################################################################################################
1676 // Methods
1677 // #######################################################################################################
1678
1679 /// @brief Calculates the transposed vector
1680 [[nodiscard]] KeyedRowVector<Scalar, RowKeyType, Eigen::Dynamic> transposed() const
1681 {
1682 auto transpose = static_cast<const internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>&>(*this).transposed();
1683 return { transpose(all), transpose.colKeys() };
1684 }
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
1691template<typename Scalar, typename ColKeyType, int Cols>
1692class 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 KeyedRowVector(const Eigen::MatrixBase<Derived>& vector, std::span<const ColKeyType> colKeys)
1701 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>(vector, colKeys)
1702 {}
1703
1704 // #######################################################################################################
1705 // Special member functions
1706 // #######################################################################################################
1707
1708 /// @brief Destructor
1709 ~KeyedRowVector() = default;
1710 /// @brief Copy constructor
1711 /// @param other The other object
1713 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>(other)
1714 {}
1715 /// @brief Copy assignment operator
1716 /// @param other The other object
1718 {
1719 if (this == &other) { return *this; } // Guard self assignment
1720
1723
1724 return *this;
1725 }
1726 /// @brief Move constructor
1727 /// @param other The other object
1731 /// @brief Move assignment operator
1732 /// @param other The other object
1734 {
1735 if (this == &other) { return *this; } // Guard self assignment
1736
1738 std::move(static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>&>(other));
1739
1740 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 KeyedRowVector(const KeyedRowVector<Scalar, ColKeyType, Eigen::Dynamic>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1750 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>(other)
1751 {
1752 INS_ASSERT_USER_ERROR(other.cols() == Cols, "Can only copy assign dynamic matrices from static ones if the size matches");
1753 }
1754 /// @brief Copy assignment operator
1755 /// @param other The other object
1757 {
1758 // No need to guard self assignment, as the types are different, so it cannot be the same object
1759
1760 INS_ASSERT_USER_ERROR(other.cols() == Cols, "Can only copy assign dynamic matrices from static ones if the size matches");
1761
1764
1765 return *this;
1766 }
1767 /// @brief Move constructor
1768 /// @param other The other object
1769 KeyedRowVector(KeyedRowVector<Scalar, ColKeyType, Eigen::Dynamic>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1771 {
1772 INS_ASSERT_USER_ERROR(this->cols() == Cols, "Can only move construct dynamic matrices from static ones if the size matches");
1773 }
1774 /// @brief Move assignment operator
1775 /// @param other The other object
1777 {
1778 // No need to guard self assignment, as the types are different, so it cannot be the same object
1779
1780 INS_ASSERT_USER_ERROR(other.cols() == Cols, "Can only move assign dynamic matrices from static ones if the size matches");
1781
1784
1785 return *this;
1786 }
1787
1788 // #######################################################################################################
1789 // Methods
1790 // #######################################################################################################
1791
1792 /// @brief Calculates the transposed vector
1794 {
1795 auto transpose = static_cast<const internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>&>(*this).transposed();
1796 return { transpose(all), transpose.rowKeys() };
1797 }
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
1803template<typename Scalar, typename ColKeyType>
1804class KeyedRowVector<Scalar, ColKeyType, Eigen::Dynamic>
1805 : public internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>
1806{
1807 public:
1808 /// @brief Default Constructor
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 KeyedRowVector(const Eigen::MatrixBase<Derived>& vector, std::span<const ColKeyType> colKeys)
1818 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(vector, colKeys)
1819 {}
1820
1821 // #######################################################################################################
1822 // Special member functions
1823 // #######################################################################################################
1824
1825 /// @brief Destructor
1826 ~KeyedRowVector() = default;
1827 /// @brief Copy constructor
1828 /// @param other The other object
1829 KeyedRowVector(const KeyedRowVector& other)
1830 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(other)
1831 {}
1832 /// @brief Copy assignment operator
1833 /// @param other The other object
1835 {
1836 if (this == &other) { return *this; } // Guard self assignment
1837
1838 static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>&>(*this) =
1839 static_cast<const internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>&>(other);
1840
1841 return *this;
1842 }
1843 /// @brief Move constructor
1844 /// @param other The other object
1845 KeyedRowVector(KeyedRowVector&& other) noexcept
1846 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(std::move(other))
1847 {}
1848 /// @brief Move assignment operator
1849 /// @param other The other object
1850 KeyedRowVector& operator=(KeyedRowVector&& other) noexcept
1851 {
1852 if (this == &other) { return *this; } // Guard self assignment
1853
1854 static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>&>(*this) =
1855 std::move(static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>&>(other));
1856
1857 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 KeyedRowVector(const KeyedRowVector<Scalar, ColKeyType, oCols>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1868 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(other)
1869 {}
1870 /// @brief Copy assignment operator
1871 /// @param other The other object
1872 template<int oCols>
1874 {
1875 // No need to guard self assignment, as the types are different, so it cannot be the same object
1876
1877 static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>&>(*this) =
1878 static_cast<const internal::KeyedRowVectorBase<Scalar, ColKeyType, oCols>&>(other);
1879
1880 return *this;
1881 }
1882 /// @brief Move constructor
1883 /// @param other The other object
1884 template<int oCols>
1885 KeyedRowVector(KeyedRowVector<Scalar, ColKeyType, oCols>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1886 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(std::move(other))
1887 {}
1888 /// @brief Move assignment operator
1889 /// @param other The other object
1890 template<int oCols>
1892 {
1893 // No need to guard self assignment, as the types are different, so it cannot be the same object
1894
1895 static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>&>(*this) =
1896 std::move(static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, oCols>&>(other));
1897
1898 return *this;
1899 }
1900
1901 // #######################################################################################################
1902 // Methods
1903 // #######################################################################################################
1904
1905 /// @brief Calculates the transposed vector
1906 [[nodiscard]] KeyedVector<Scalar, ColKeyType, Eigen::Dynamic> transposed() const
1907 {
1908 auto transpose = static_cast<const internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>&>(*this).transposed();
1909 return { transpose(all), transpose.rowKeys() };
1910 }
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
1919template<typename Scalar, typename RowKeyType, typename ColKeyType, int Rows, int Cols>
1920class 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 KeyedMatrix(const Eigen::MatrixBase<Derived>& matrix, std::span<const RowKeyType> rowKeys, std::span<const ColKeyType> colKeys)
1930 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>(matrix, rowKeys, colKeys)
1931 {}
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 KeyedMatrix(const Eigen::MatrixBase<Derived>& matrix, std::span<const RowKeyType> keys)
1939 : KeyedMatrix<Scalar, RowKeyType, ColKeyType, Rows, Cols>(matrix, keys, keys)
1940 {}
1941
1942 // #######################################################################################################
1943 // Special member functions
1944 // #######################################################################################################
1945
1946 /// @brief Destructor
1947 ~KeyedMatrix() = default;
1948 /// @brief Copy constructor
1949 /// @param other The other object
1951 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>(other)
1952 {}
1953 /// @brief Copy assignment operator
1954 /// @param other The other object
1956 {
1957 if (this == &other) { return *this; } // Guard self assignment
1958
1961
1962 return *this;
1963 }
1964 /// @brief Move constructor
1965 /// @param other The other object
1969 /// @brief Move assignment operator
1970 /// @param other The other object
1972 {
1973 if (this == &other) { return *this; } // Guard self assignment
1974
1977
1978 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 KeyedMatrix(const KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1988 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>(other)
1989 {
1990 INS_ASSERT_USER_ERROR(other.rows() == Rows && other.cols() == Cols, "Can only copy assign dynamic matrices from static ones if the size matches");
1991 }
1992 /// @brief Copy assignment operator
1993 /// @param other The other object
1995 {
1996 // No need to guard self assignment, as the types are different, so it cannot be the same object
1997
1998 INS_ASSERT_USER_ERROR(other.rows() == Rows && other.cols() == Cols, "Can only copy assign dynamic matrices from static ones if the size matches");
1999
2002
2003 return *this;
2004 }
2005 /// @brief Move constructor
2006 /// @param other The other object
2007 KeyedMatrix(KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
2009 {
2010 INS_ASSERT_USER_ERROR(this->rows() == Rows && this->cols() == Cols, "Can only move construct dynamic matrices from static ones if the size matches");
2011 }
2012 /// @brief Move assignment operator
2013 /// @param other The other object
2015 {
2016 // No need to guard self assignment, as the types are different, so it cannot be the same object
2017
2018 INS_ASSERT_USER_ERROR(other.rows() == Rows && other.cols() == Cols, "Can only move assign dynamic matrices from static ones if the size matches");
2019
2022
2023 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
2034 getSubMatrix(std::span<const RowKeyType> rowKeys, std::span<const ColKeyType> colKeys) const
2035 {
2036 if (rowKeys == this->rowKeysVector && colKeys == this->colKeysVector)
2037 {
2038 return *this;
2039 }
2040
2041 return { (*this)(rowKeys, colKeys), rowKeys, colKeys };
2042 }
2043
2044 /// @brief Calculates the transposed matrix
2046 {
2047 auto transpose = static_cast<const internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>&>(*this).transposed();
2048 return { transpose(all, all), transpose.rowKeys(), transpose.colKeys() };
2049 }
2050
2051 /// @brief Calculates the inverse matrix
2053 {
2055 return { inv(all, all), inv.rowKeys(), inv.colKeys() };
2056 }
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
2063template<typename Scalar, typename RowKeyType, typename ColKeyType>
2064class 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 KeyedMatrix()
2070 : 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 KeyedMatrix(const Eigen::MatrixBase<Derived>& matrix, std::span<const RowKeyType> rowKeys, std::span<const ColKeyType> colKeys)
2079 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(matrix, rowKeys, colKeys)
2080 {}
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 KeyedMatrix(const Eigen::MatrixBase<Derived>& matrix, std::span<const RowKeyType> keys)
2088 : KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(matrix, keys, keys)
2089 {}
2090
2091 // #######################################################################################################
2092 // Special member functions
2093 // #######################################################################################################
2094
2095 /// @brief Destructor
2096 ~KeyedMatrix() = default;
2097 /// @brief Copy constructor
2098 /// @param other The other object
2099 KeyedMatrix(const KeyedMatrix& other)
2100 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(other)
2101 {}
2102 /// @brief Copy assignment operator
2103 /// @param other The other object
2104 KeyedMatrix& operator=(const KeyedMatrix& other)
2105 {
2106 if (this == &other) { return *this; } // Guard self assignment
2107
2108 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 return *this;
2112 }
2113 /// @brief Move constructor
2114 /// @param other The other object
2115 KeyedMatrix(KeyedMatrix&& other) noexcept
2116 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(std::move(other))
2117 {}
2118 /// @brief Move assignment operator
2119 /// @param other The other object
2120 KeyedMatrix& operator=(KeyedMatrix&& other) noexcept
2121 {
2122 if (this == &other) { return *this; } // Guard self assignment
2123
2124 static_cast<internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&>(*this) =
2125 std::move(static_cast<internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&>(other));
2126
2127 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 KeyedMatrix(const KeyedMatrix<Scalar, RowKeyType, ColKeyType, oRows, oCols>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
2138 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(other)
2139 {}
2140 /// @brief Copy assignment operator
2141 /// @param other The other object
2142 template<int oRows, int oCols>
2144 {
2145 // No need to guard self assignment, as the types are different, so it cannot be the same object
2146
2147 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 return *this;
2151 }
2152 /// @brief Move constructor
2153 /// @param other The other object
2154 template<int oRows, int oCols>
2155 KeyedMatrix(KeyedMatrix<Scalar, RowKeyType, ColKeyType, oRows, oCols>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
2156 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(std::move(other))
2157 {}
2158 /// @brief Move assignment operator
2159 /// @param other The other object
2160 template<int oRows, int oCols>
2162 {
2163 // No need to guard self assignment, as the types are different, so it cannot be the same object
2164
2165 static_cast<internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&>(*this) =
2166 std::move(static_cast<internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, oRows, oCols>&>(other));
2167
2168 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 void addRowsCols(std::span<const RowKeyType> rowKeys, std::span<const ColKeyType> colKeys)
2179 {
2180 INS_ASSERT_USER_ERROR(!this->hasAnyRows(rowKeys), "You cannot add a row key which is already in the matrix.");
2181 INS_ASSERT_USER_ERROR(!this->hasAnyCols(colKeys), "You cannot add a col key which is already in the matrix.");
2182 INS_ASSERT_USER_ERROR(std::unordered_set<RowKeyType>(rowKeys.begin(), rowKeys.end()).size() == rowKeys.size(), "Each row key must be unique");
2183 INS_ASSERT_USER_ERROR(std::unordered_set<ColKeyType>(colKeys.begin(), colKeys.end()).size() == colKeys.size(), "Each col key must be unique");
2184
2185 auto initialRowSize = static_cast<Eigen::Index>(this->rowIndices.size());
2186 for (const auto& rowKey : rowKeys) { this->rowIndices.insert({ rowKey, static_cast<Eigen::Index>(this->rowIndices.size()) }); }
2187 this->rowKeysVector.reserve(this->rowKeysVector.size() + rowKeys.size());
2188 std::copy(rowKeys.begin(), rowKeys.end(), std::back_inserter(this->rowKeysVector));
2189 auto finalRowSize = static_cast<Eigen::Index>(this->rowIndices.size());
2190
2191 auto initialColSize = static_cast<Eigen::Index>(this->colIndices.size());
2192 for (const auto& colKey : colKeys) { this->colIndices.insert({ colKey, static_cast<Eigen::Index>(this->colIndices.size()) }); }
2193 this->colKeysVector.reserve(this->colKeysVector.size() + colKeys.size());
2194 std::copy(colKeys.begin(), colKeys.end(), std::back_inserter(this->colKeysVector));
2195 auto finalColSize = static_cast<Eigen::Index>(this->colIndices.size());
2196
2197 auto rows = finalRowSize - initialRowSize;
2198 auto cols = finalColSize - initialColSize;
2199 if (rows > 0 || cols > 0)
2200 {
2201 this->matrix.conservativeResize(finalRowSize, finalColSize);
2202 this->matrix.block(initialRowSize, 0, rows, this->matrix.cols()) = Eigen::MatrixX<Scalar>::Zero(rows, this->matrix.cols());
2203 this->matrix.block(0, initialColSize, this->matrix.rows(), cols) = Eigen::MatrixX<Scalar>::Zero(this->matrix.rows(), cols);
2204 }
2205 std::lock_guard<std::mutex> lg{ this->_sliceMutex };
2206 this->colSlice.reserve(this->colKeysVector.size());
2207 this->rowSlice.reserve(this->rowKeysVector.size());
2208 }
2209
2210 /// @brief Removes the rows and cols from the matrix
2211 /// @param rowKeys Row Keys
2212 /// @param colKeys Col Keys
2213 void removeRowsCols(std::span<const RowKeyType> rowKeys, std::span<const ColKeyType> colKeys)
2214 {
2215 std::vector<int> rowIndices;
2216 for (const auto& rowKey : rowKeys)
2217 {
2218 auto iter = this->rowIndices.find(rowKey);
2219 INS_ASSERT_USER_ERROR(iter != this->rowIndices.end(), "You tried removing a row key, which did not exist.");
2220 if (iter != this->rowIndices.end())
2221 {
2222 rowIndices.push_back(static_cast<int>(iter->second));
2223 }
2224 }
2225 std::vector<int> colIndices;
2226 for (const auto& colKey : colKeys)
2227 {
2228 auto iter = this->colIndices.find(colKey);
2229 INS_ASSERT_USER_ERROR(iter != this->colIndices.end(), "You tried removing a col key, which did not exist.");
2230 if (iter != this->colIndices.end())
2231 {
2232 colIndices.push_back(static_cast<int>(iter->second));
2233 }
2234 }
2235
2237
2238 for (const auto& rowKey : rowKeys)
2239 {
2240 auto iter = this->rowIndices.find(rowKey);
2241 if (iter != this->rowIndices.end())
2242 {
2243 std::erase_if(this->rowKeysVector, [&](const auto& item) { return item == rowKey; });
2244
2245 auto idx = iter->second;
2246 for (auto& rowIndex : this->rowIndices)
2247 {
2248 if (rowIndex.second > idx) { rowIndex.second--; }
2249 }
2250 this->rowIndices.erase(iter);
2251 }
2252 }
2253 for (const auto& colKey : colKeys)
2254 {
2255 auto iter = this->colIndices.find(colKey);
2256 if (iter != this->colIndices.end())
2257 {
2258 std::erase_if(this->colKeysVector, [&](const auto& item) { return item == colKey; });
2259
2260 auto idx = iter->second;
2261 for (auto& colIndex : this->colIndices)
2262 {
2263 if (colIndex.second > idx) { colIndex.second--; }
2264 }
2265 this->colIndices.erase(iter);
2266 }
2267 }
2268 }
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
2278 getSubMatrix(std::span<const RowKeyType> rowKeys, std::span<const ColKeyType> colKeys) const
2279 {
2280 if (rowKeys == this->rowKeysVector && colKeys == this->colKeysVector)
2281 {
2282 return *this;
2283 }
2284
2285 return { (*this)(rowKeys, colKeys), rowKeys, colKeys };
2286 }
2287
2288 /// @brief Calculates the transposed matrix
2290 {
2291 auto transpose = static_cast<const internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&>(*this).transposed();
2292 return { transpose(all, all), transpose.rowKeys(), transpose.colKeys() };
2293 }
2294
2295 /// @brief Calculates the inverse matrix
2297 {
2298 auto inv = static_cast<const internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&>(*this).inverse();
2299 return { inv(all, all), inv.rowKeys(), inv.colKeys() };
2300 }
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
2307template<typename Scalar, typename RowKeyType, typename ColKeyType = RowKeyType>
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
2312template<typename RowKeyType, typename ColKeyType = RowKeyType>
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
2317template<typename RowKeyType, typename ColKeyType = RowKeyType>
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
2322template<typename RowKeyType, typename ColKeyType = RowKeyType>
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
2327template<typename RowKeyType, typename ColKeyType = RowKeyType>
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
2332template<typename RowKeyType, typename ColKeyType = RowKeyType>
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
2337template<typename RowKeyType, typename ColKeyType = RowKeyType>
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
2343template<typename Scalar, typename RowKeyType>
2345/// @brief Dynamic size KeyedVector with double types
2346/// @tparam RowKeyType Type of the key used for row lookup
2347template<typename RowKeyType>
2349/// @brief Static 2 row KeyedVector with double types
2350/// @tparam RowKeyType Type of the key used for row lookup
2351template<typename RowKeyType>
2353/// @brief Static 3 row KeyedVector with double types
2354/// @tparam RowKeyType Type of the key used for row lookup
2355template<typename RowKeyType>
2357/// @brief Static 4 row KeyedVector with double types
2358/// @tparam RowKeyType Type of the key used for row lookup
2359template<typename RowKeyType>
2361/// @brief Static 5 row KeyedVector with double types
2362/// @tparam RowKeyType Type of the key used for row lookup
2363template<typename RowKeyType>
2365/// @brief Static 6 row KeyedVector with double types
2366/// @tparam RowKeyType Type of the key used for row lookup
2367template<typename RowKeyType>
2369
2370/// @brief Dynamic size KeyedRowVector
2371/// @tparam ColKeyType Type of the key used for col lookup
2372template<typename Scalar, typename ColKeyType>
2374/// @brief Dynamic size KeyedRowVector with double types
2375/// @tparam ColKeyType Type of the key used for col lookup
2376template<typename ColKeyType>
2378/// @brief Static 2 col KeyedRowVector with double types
2379/// @tparam ColKeyType Type of the key used for col lookup
2380template<typename ColKeyType>
2382/// @brief Static 3 col KeyedRowVector with double types
2383/// @tparam ColKeyType Type of the key used for col lookup
2384template<typename ColKeyType>
2386/// @brief Static 4 col KeyedRowVector with double types
2387/// @tparam ColKeyType Type of the key used for col lookup
2388template<typename ColKeyType>
2390/// @brief Static 5 col KeyedRowVector with double types
2391/// @tparam ColKeyType Type of the key used for col lookup
2392template<typename ColKeyType>
2394/// @brief Static 6 col KeyedRowVector with double types
2395/// @tparam ColKeyType Type of the key used for col lookup
2396template<typename ColKeyType>
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
2408template<typename Scalar, typename RowKeyType, typename ColKeyType, int Rows, int Cols>
2409struct 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 auto format(const NAV::KeyedMatrix<Scalar, RowKeyType, ColKeyType, Rows, Cols>& mat, format_context& ctx) const
2416 {
2417 std::string result;
2418 auto rows = static_cast<size_t>(mat.rows());
2419 auto cols = static_cast<size_t>(mat.cols());
2420
2421 if (rows > 0 && cols > 0)
2422 {
2423 std::vector<std::string> rowKeysStr;
2424 std::vector<size_t> rowKeysLength;
2425 rowKeysStr.reserve(rows);
2426 rowKeysLength.reserve(rows);
2427 size_t rowKeysColSpace = 0;
2428 for (const auto& rowKey : mat.rowKeys())
2429 {
2430 rowKeysStr.push_back(fmt::format("{}", rowKey));
2431 auto rowKeyLength = rowKeysStr.back().length();
2432 rowKeysColSpace = std::max(rowKeysColSpace, rowKeyLength);
2433 rowKeysLength.push_back(rowKeyLength);
2434 }
2435
2436 constexpr size_t colMinLength = 9UL;
2437
2438 std::vector<std::string> colKeysStr;
2439 std::vector<size_t> colKeysLength;
2440 size_t rowLineLength = rowKeysColSpace + 1; // '\n' at the end of line
2441 colKeysStr.reserve(cols);
2442 colKeysLength.reserve(cols);
2443 for (const auto& colKey : mat.colKeys())
2444 {
2445 colKeysStr.push_back(fmt::format("{}", colKey));
2446 auto colKeyLength = colKeysStr.back().length();
2447 colKeysLength.push_back(colKeyLength);
2448 rowLineLength += 2 + std::max(colKeysStr.back().length(), colMinLength); // 2 spaces before each column
2449 }
2450
2451 result.reserve((rows + 1) * rowLineLength);
2452 // ---------------------------------------- Column keys ------------------------------------------
2453 result += " " + std::string(rowKeysColSpace, ' ');
2454 for (size_t c = 0; c < cols; c++)
2455 {
2456 result += " ";
2457 if (colMinLength > colKeysLength.at(c))
2458 {
2459 result += std::string(colMinLength - colKeysLength.at(c), ' '); // Spaces in front of column name (if too short)
2460 }
2461 result += colKeysStr.at(c);
2462 }
2463 result += '\n';
2464 // ------------------------------------------- Rows ----------------------------------------------
2465 for (size_t r = 0; r < rows; r++)
2466 {
2467 if (rowKeysColSpace > rowKeysLength.at(r))
2468 {
2469 result += std::string(rowKeysColSpace - rowKeysLength.at(r), ' '); // Spaces in front of row name (if too short)
2470 }
2471 result += rowKeysStr.at(r) + " ";
2472 for (size_t c = 0; c < cols; c++)
2473 {
2474 auto colLength = std::max(colKeysStr.at(c).length(), colMinLength);
2475
2476 std::string tmp = fmt::format(" {:> {}.{}g}", mat(NAV::all, NAV::all)(static_cast<int>(r), static_cast<int>(c)), colLength, colLength - 2);
2477 if (tmp.length() > colLength)
2478 {
2479 tmp = fmt::format(" {:> {}.{}g}", mat(NAV::all, NAV::all)(static_cast<int>(r), static_cast<int>(c)), colLength, colLength - 6);
2480 }
2481 result += tmp;
2482 }
2483 if (r != rows - 1) { result += '\n'; }
2484 }
2485 }
2486
2487 return fmt::formatter<std::string>::format(result, ctx);
2488 }
2489};
2490
2491/// @brief Formatter for KeyedVector
2492template<typename Scalar, typename RowKeyType, int Rows>
2493struct 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 auto format(const NAV::KeyedVector<Scalar, RowKeyType, Rows>& vec, format_context& ctx) const
2500 {
2501 std::string result;
2502 auto rows = static_cast<size_t>(vec.rows());
2503
2504 if (rows > 0)
2505 {
2506 std::vector<std::string> rowKeysStr;
2507 std::vector<size_t> rowKeysLength;
2508 rowKeysStr.reserve(rows);
2509 rowKeysLength.reserve(rows);
2510 size_t rowKeysColSpace = 0;
2511 for (const auto& rowKey : vec.rowKeys())
2512 {
2513 rowKeysStr.push_back(fmt::format("{}", rowKey));
2514 auto rowKeyLength = rowKeysStr.back().length();
2515 rowKeysColSpace = std::max(rowKeysColSpace, rowKeyLength);
2516 rowKeysLength.push_back(rowKeyLength);
2517 }
2518
2519 size_t colLength = 9UL;
2520
2521 result.reserve(rows * (rowKeysColSpace + 2 + colLength));
2522 // ------------------------------------------- Rows ----------------------------------------------
2523 for (size_t r = 0; r < rows; r++)
2524 {
2525 if (rowKeysColSpace > rowKeysLength.at(r))
2526 {
2527 result += std::string(rowKeysColSpace - rowKeysLength.at(r), ' '); // Spaces in front of row name (if too short)
2528 }
2529 result += rowKeysStr.at(r);
2530
2531 std::string tmp = fmt::format(" {:> {}.{}g}", vec(NAV::all)(static_cast<int>(r)), colLength, colLength - 2);
2532 if (tmp.length() > colLength)
2533 {
2534 tmp = fmt::format(" {:> {}.{}g}", vec(NAV::all)(static_cast<int>(r)), colLength, colLength - 6);
2535 }
2536 result += tmp;
2537
2538 if (r != rows - 1) { result += '\n'; }
2539 }
2540 }
2541
2542 return fmt::formatter<std::string>::format(result, ctx);
2543 }
2544};
2545
2546/// @brief Formatter for KeyedRowVector
2547template<typename Scalar, typename ColKeyType, int Cols>
2548struct 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 auto format(const NAV::KeyedRowVector<Scalar, ColKeyType, Cols>& vec, format_context& ctx) const
2555 {
2556 std::string result;
2557 auto cols = static_cast<size_t>(vec.cols());
2558
2559 if (cols > 0)
2560 {
2561 size_t colMinLength = 9UL;
2562
2563 std::vector<std::string> colKeysStr;
2564 std::vector<size_t> colKeysLength;
2565 size_t rowLineLength = 1; // '\n' at the end of line
2566 colKeysStr.reserve(cols);
2567 colKeysLength.reserve(cols);
2568 for (const auto& colKey : vec.colKeys())
2569 {
2570 colKeysStr.push_back(fmt::format("{}", colKey));
2571 auto colKeyLength = colKeysStr.back().length();
2572 colKeysLength.push_back(colKeyLength);
2573 rowLineLength += 2 + std::max(colKeysStr.back().length(), colMinLength); // 2 spaces before each column
2574 }
2575
2576 result.reserve(2 * rowLineLength);
2577 // ---------------------------------------- Column keys ------------------------------------------
2578 for (size_t c = 0; c < cols; c++)
2579 {
2580 if (c != 0) { result += " "; }
2581 if (colMinLength > colKeysLength.at(c))
2582 {
2583 result += std::string(colMinLength - colKeysLength.at(c), ' '); // Spaces in front of column name (if too short)
2584 }
2585 result += colKeysStr.at(c);
2586 }
2587 result += '\n';
2588 // ------------------------------------------ Values ---------------------------------------------
2589
2590 for (size_t c = 0; c < cols; c++)
2591 {
2592 auto colLength = std::max(colKeysStr.at(c).length(), colMinLength);
2593 if (c != 0) { result += " "; }
2594 std::string tmp = fmt::format("{:> {}.{}g}", vec(NAV::all)(static_cast<int>(c)), colLength, colLength - 2);
2595 if (tmp.length() > colLength)
2596 {
2597 tmp = fmt::format("{:> {}.{}g}", vec(NAV::all)(static_cast<int>(c)), colLength, colLength - 6);
2598 }
2599 result += tmp;
2600 }
2601 }
2602
2603 return fmt::formatter<std::string>::format(result, ctx);
2604 }
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
2613template<typename Scalar, typename RowKeyType, typename ColKeyType, int Rows, int Cols>
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
2622template<typename Scalar, typename RowKeyType, int Rows>
2623std::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
2631template<typename Scalar, typename ColKeyType, int Cols>
2632std::ostream& operator<<(std::ostream& os, const NAV::KeyedRowVector<Scalar, ColKeyType, Cols>& obj)
2633{
2634 return os << fmt::format("{}", obj);
2635}
Assertion helpers.
#define INS_ASSERT_USER_ERROR(_EXP, _MSG)
Assert function with message.
Definition Assert.h:21
Vector space operations.
Unordered map wrapper.
ankerl::unordered_dense::map< Key, T > unordered_map
Unordered map type.
Vector Utility functions.
Static sized KeyedMatrix.
KeyedMatrix(const KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > &other)
Copy constructor.
KeyedMatrix(const KeyedMatrix &other)
Copy constructor.
KeyedMatrix & operator=(const KeyedMatrix &other)
Copy assignment operator.
~KeyedMatrix()=default
Destructor.
KeyedMatrix< Scalar, RowKeyType, ColKeyType, Rows, Cols > transposed() const
Calculates the transposed matrix.
KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > getSubMatrix(std::span< const RowKeyType > rowKeys, std::span< const ColKeyType > colKeys) const
Returns a submatrix specified by the row and col keys.
KeyedMatrix & operator=(const KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > &other)
Copy assignment operator.
KeyedMatrix & operator=(KeyedMatrix &&other) noexcept
Move assignment operator.
KeyedMatrix(const Eigen::MatrixBase< Derived > &matrix, std::span< const RowKeyType > rowKeys, std::span< const ColKeyType > colKeys)
Non-symmetric matrix constructor.
KeyedMatrix< Scalar, RowKeyType, ColKeyType, Rows, Cols > inverse() const
Calculates the inverse matrix.
KeyedMatrix(const Eigen::MatrixBase< Derived > &matrix, std::span< const RowKeyType > keys)
Symmetric matrix constructor.
KeyedMatrix(KeyedMatrix &&other) noexcept
Move constructor.
KeyedMatrix & operator=(KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > &&other) noexcept
Move assignment operator.
KeyedMatrix(KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > &&other) noexcept
Move constructor.
Static sized KeyedRowVector.
KeyedRowVector(KeyedRowVector &&other) noexcept
Move constructor.
~KeyedRowVector()=default
Destructor.
KeyedRowVector & operator=(KeyedRowVector &&other) noexcept
Move assignment operator.
KeyedRowVector(KeyedRowVector< Scalar, ColKeyType, Eigen::Dynamic > &&other) noexcept
Move constructor.
KeyedRowVector(const KeyedRowVector &other)
Copy constructor.
KeyedVector< Scalar, ColKeyType, Cols > transposed() const
Calculates the transposed vector.
KeyedRowVector(const Eigen::MatrixBase< Derived > &vector, std::span< const ColKeyType > colKeys)
RowVector constructor.
KeyedRowVector(const KeyedRowVector< Scalar, ColKeyType, Eigen::Dynamic > &other)
Copy constructor.
KeyedRowVector & operator=(const KeyedRowVector< Scalar, ColKeyType, Eigen::Dynamic > &other)
Copy assignment operator.
KeyedRowVector & operator=(const KeyedRowVector &other)
Copy assignment operator.
KeyedRowVector & operator=(KeyedRowVector< Scalar, ColKeyType, Eigen::Dynamic > &&other) noexcept
Move assignment operator.
Static sized KeyedVector.
KeyedVector(KeyedVector< Scalar, RowKeyType, Eigen::Dynamic > &&other) noexcept
Move constructor.
KeyedVector(const KeyedVector &other)
Copy constructor.
KeyedVector & operator=(KeyedVector &&other) noexcept
Move assignment operator.
KeyedVector(KeyedVector &&other) noexcept
Move constructor.
KeyedVector & operator=(KeyedVector< Scalar, RowKeyType, Eigen::Dynamic > &&other) noexcept
Move assignment operator.
KeyedVector(const KeyedVector< Scalar, RowKeyType, Eigen::Dynamic > &other)
Copy constructor.
KeyedVector & operator=(const KeyedVector &other)
Copy assignment operator.
KeyedRowVector< Scalar, RowKeyType, Rows > transposed() const
Calculates the transposed vector.
KeyedVector & operator=(const KeyedVector< Scalar, RowKeyType, Eigen::Dynamic > &other)
Copy assignment operator.
~KeyedVector()=default
Destructor.
KeyedVector(const Eigen::MatrixBase< Derived > &vector, std::span< const RowKeyType > rowKeys)
Vector constructor.
Class to inherit common methods for static and dynamic sized matrices.
decltype(auto) middleCols(std::span< const ColKeyType > colKeys)
Gets the values for the col keys.
decltype(auto) row(const RowKeyType &rowKey) const
Gets the values for the row key.
decltype(auto) middleRows(std::span< const RowKeyType > rowKeys) const
Gets the values for the row keys.
KeyedMatrixBase< Scalar, ColKeyType, RowKeyType, Cols, Rows > transposed() const
Calculates the transposed matrix.
decltype(auto) middleCols(std::span< const ColKeyType > colKeys)
Gets the values for the col keys.
decltype(auto) block(std::span< const RowKeyType > rowKeys, std::span< const ColKeyType > colKeys)
Gets the values for the row and col keys.
void checkContinuousBlock(std::span< const RowKeyType > rowKeys, std::span< const ColKeyType > colKeys, size_t P, size_t Q) const
Checks if the row and col keys are describing a continuous block.
KeyedMatrixBase(KeyedMatrixBase &&other) noexcept
Move constructor.
Scalar & operator()(const RowKeyType &rowKey, const ColKeyType &colKey)
Gets the value for the row and col key.
decltype(auto) block(std::span< const RowKeyType > rowKeys, std::span< const ColKeyType > colKeys)
Gets the values for the row and col keys.
KeyedMatrixBase(const Eigen::MatrixBase< Derived > &matrix)
Constructor.
const Eigen::Matrix< Scalar, Rows, Cols > & block(all_t, all_t) const
Requests the full matrix.
decltype(auto) block(std::span< const RowKeyType > rowKeys, const ColKeyType &colKey)
Gets the values for the row and col keys.
decltype(auto) row(const RowKeyType &rowKey)
Gets the values for the row key.
decltype(auto) middleRows(std::span< const RowKeyType > rowKeys)
Gets the values for the row keys.
KeyedMatrixBase(const KeyedMatrixBase &other)
Copy constructor.
Eigen::Matrix< Scalar, Rows, Cols > & operator()(all_t, all_t)
Requests the full matrix.
decltype(auto) middleCols(std::span< const ColKeyType > colKeys) const
Gets the values for the col keys.
KeyedMatrixBase(KeyedMatrixBase< Scalar, RowKeyType, ColKeyType, oRows, oCols > &&other) noexcept
Move constructor.
decltype(auto) block(std::span< const RowKeyType > rowKeys, const ColKeyType &colKey) const
Gets the values for the row and col keys.
decltype(auto) block(std::span< const RowKeyType > rowKeys, std::span< const ColKeyType > colKeys) const
Gets the values for the row and col keys.
decltype(auto) middleCols(std::span< const ColKeyType > colKeys) const
Gets the values for the col keys.
decltype(auto) middleRows(std::span< const RowKeyType > rowKeys)
Gets the values for the row keys.
KeyedMatrixBase & operator=(const KeyedMatrixBase &other)
Copy assignment operator.
~KeyedMatrixBase()=default
Destructor.
decltype(auto) block(const RowKeyType &rowKey, std::span< const ColKeyType > colKeys)
Gets the values for the row and col keys.
KeyedMatrixBase & operator=(KeyedMatrixBase< Scalar, RowKeyType, ColKeyType, oRows, oCols > &&other) noexcept
Move assignment operator.
decltype(auto) block(std::span< const RowKeyType > rowKeys, std::span< const ColKeyType > colKeys) const
Gets the values for the row and col keys.
const Scalar & operator()(const RowKeyType &rowKey, const ColKeyType &colKey) const
Gets the value for the row and col key.
decltype(auto) block(const RowKeyType &rowKey, std::span< const ColKeyType > colKeys) const
Gets the values for the row and col keys.
decltype(auto) block(std::span< const RowKeyType > rowKeys, const ColKeyType &colKey)
Gets the values for the row and col keys.
decltype(auto) block(const RowKeyType &rowKey, std::span< const ColKeyType > colKeys) const
Gets the values for the row and col keys.
decltype(auto) block(std::span< const RowKeyType > rowKeys, const ColKeyType &colKey) const
Gets the values for the row and col keys.
Eigen::Matrix< Scalar, Rows, Cols > & block(all_t, all_t)
Requests the full matrix.
decltype(auto) col(const ColKeyType &colKey) const
Gets the values for the col key.
decltype(auto) block(const RowKeyType &rowKey, std::span< const ColKeyType > colKeys)
Gets the values for the row and col keys.
KeyedMatrixBase & operator=(const KeyedMatrixBase< Scalar, RowKeyType, ColKeyType, oRows, oCols > &other)
Copy assignment operator.
decltype(auto) middleRows(std::span< const RowKeyType > rowKeys) const
Gets the values for the row keys.
KeyedMatrixBase(const Eigen::MatrixBase< Derived > &matrix, std::span< const RowKeyType > rowKeys, std::span< const ColKeyType > colKeys)
Non-symmetric matrix constructor.
decltype(auto) col(const ColKeyType &colKey)
Gets the values for the col key.
KeyedMatrixBase & operator=(KeyedMatrixBase &&other) noexcept
Move assignment operator.
KeyedMatrixBase< Scalar, RowKeyType, ColKeyType, Rows, Cols > inverse() const
Calculates the inverse matrix.
KeyedMatrixBase(const KeyedMatrixBase< Scalar, RowKeyType, ColKeyType, oRows, oCols > &other)
Copy constructor.
const Eigen::Matrix< Scalar, Rows, Cols > & operator()(all_t, all_t) const
Requests the full matrix.
Base class for Keyed matrices with multiple columns.
void replaceColKey(const ColKeyType &oldKey, const ColKeyType &newKey)
Replace the old with the new key.
bool hasCols(std::span< const ColKeyType > keys) const
Checks if the matrix has multiple keys.
std::vector< ColKeyType > colKeysVector
Col Keys.
std::vector< Eigen::Index > colSlice
Col Slice used for accessing.
const std::vector< ColKeyType > & colKeys() const
Returns the col keys.
unordered_map< ColKeyType, Eigen::Index > colIndices
ColKey to Col Index mapping.
decltype(auto) cols() const
Return the cols of the underlying Eigen matrix.
bool hasCol(const ColKeyType &key) const
Checks if the matrix has the key.
bool hasAnyCols(std::span< const ColKeyType > keys) const
Checks if the matrix has any keys.
void removeCol(const ColKeyType &colKey)
Removes the col from the matrix.
void removeCols(std::span< const ColKeyType > colKeys)
Removes the cols from the matrix.
void addCols(std::span< const ColKeyType > colKeys)
Adds new cols to the matrix.
void addCol(const ColKeyType &colKey)
Adds a new col to the matrix.
Base class for Keyed matrices with multiple columns of static size.
Base class for Keyed matrices with multiple rows.
bool hasRows(std::span< const RowKeyType > keys) const
Checks if the matrix has multiple keys.
std::vector< Eigen::Index > rowSlice
Row Slice used for accessing.
unordered_map< RowKeyType, Eigen::Index > rowIndices
RowKey to Row Index mapping.
decltype(auto) rows() const
Return the rows of the underlying Eigen matrix.
bool hasRow(const RowKeyType &key) const
Checks if the matrix has the key.
const std::vector< RowKeyType > & rowKeys() const
Returns the row keys.
bool hasAnyRows(std::span< const RowKeyType > keys) const
Checks if the matrix has any key.
std::vector< RowKeyType > rowKeysVector
Row Keys.
void replaceRowKey(const RowKeyType &oldKey, const RowKeyType &newKey)
Replace the old with the new key.
void removeRows(std::span< const RowKeyType > rowKeys)
Removes the rows from the matrix.
void addRow(const RowKeyType &rowKey)
Adds a new row to the matrix.
void addRows(std::span< const RowKeyType > rowKeys)
Adds new rows to the matrix.
void removeRow(const RowKeyType &rowKey)
Removes the row from the matrix.
Base class for Keyed matrices with multiple rows of static size.
KeyedMatrix storage class.
Eigen::Matrix< Scalar, Rows, Cols > matrix
Data storage of the type.
std::mutex _sliceMutex
Mutex for accessing the slices.
Class to inherit common methods for static and dynamic sized row vectors.
decltype(auto) segment(std::span< const ColKeyType > colKeys) const
Gets the values for the col keys.
KeyedRowVectorBase(const Eigen::MatrixBase< Derived > &vector)
Constructor.
Eigen::Matrix< Scalar, 1, Cols > & operator()(all_t)
Requests the full vector.
const Scalar & operator()(const ColKeyType &colKey) const
Gets the value for the col key.
decltype(auto) segment(std::span< const ColKeyType > colKeys)
Gets the values for the col keys.
decltype(auto) segment(std::span< const ColKeyType > colKeys) const
Gets the values for the col keys.
const Eigen::Matrix< Scalar, 1, Cols > & operator()(all_t) const
Requests the full vector.
KeyedRowVectorBase(KeyedRowVectorBase &&other) noexcept
Move constructor.
KeyedRowVectorBase(const KeyedRowVectorBase< Scalar, ColKeyType, oCols > &other)
Copy constructor.
KeyedRowVectorBase & operator=(KeyedRowVectorBase< Scalar, ColKeyType, oCols > &&other) noexcept
Move assignment operator.
KeyedRowVectorBase & operator=(const KeyedRowVectorBase &other)
Copy assignment operator.
void checkContinuousSegment(std::span< const ColKeyType > colKeys, size_t Q) const
Checks if the col keys are describing a continuous block.
KeyedRowVectorBase & operator=(const KeyedRowVectorBase< Scalar, ColKeyType, oCols > &other)
Copy assignment operator.
~KeyedRowVectorBase()=default
Destructor.
Scalar & operator()(const ColKeyType &colKey)
Gets the value for the col key.
decltype(auto) segment(std::span< const ColKeyType > colKeys)
Gets the values for the col keys.
KeyedRowVectorBase(const Eigen::MatrixBase< Derived > &vector, std::span< const ColKeyType > colKeys)
Constructor.
KeyedRowVectorBase & operator=(KeyedRowVectorBase &&other) noexcept
Move assignment operator.
KeyedRowVectorBase(const KeyedRowVectorBase &other)
Copy constructor.
KeyedRowVectorBase(KeyedRowVectorBase< Scalar, ColKeyType, oCols > &&other) noexcept
Move constructor.
KeyedVectorBase< Scalar, ColKeyType, Cols > transposed() const
Calculates the transposed vector.
Class to inherit common methods for static and dynamic sized vectors.
decltype(auto) segment(std::span< const RowKeyType > rowKeys) const
Gets the values for the row keys.
decltype(auto) segment(std::span< const RowKeyType > rowKeys) const
Gets the values for the row keys.
void checkContinuousSegment(std::span< const RowKeyType > rowKeys, size_t P) const
Checks if the row keys are describing a continuous block.
KeyedVectorBase & operator=(KeyedVectorBase &&other) noexcept
Move assignment operator.
decltype(auto) segment(std::span< const RowKeyType > rowKeys)
Gets the values for the row keys.
decltype(auto) segment(std::span< const RowKeyType > rowKeys)
Gets the values for the row keys.
~KeyedVectorBase()=default
Destructor.
Scalar & operator()(const RowKeyType &rowKey)
Gets the value for the row key.
Eigen::Matrix< Scalar, Rows, 1 > & operator()(all_t)
Requests the full vector.
KeyedVectorBase & operator=(const KeyedVectorBase< Scalar, RowKeyType, oRows > &other)
Copy assignment operator.
KeyedVectorBase & operator=(KeyedVectorBase< Scalar, RowKeyType, oRows > &&other) noexcept
Move assignment operator.
KeyedVectorBase(const Eigen::MatrixBase< Derived > &vector)
Constructor.
KeyedVectorBase(KeyedVectorBase &&other) noexcept
Move constructor.
const Eigen::Matrix< Scalar, Rows, 1 > & operator()(all_t) const
Requests the full vector.
KeyedVectorBase(const Eigen::MatrixBase< Derived > &vector, std::span< const RowKeyType > rowKeys)
Constructor.
const Scalar & operator()(const RowKeyType &rowKey) const
Gets the value for the row key.
KeyedVectorBase(KeyedVectorBase< Scalar, RowKeyType, oRows > &&other) noexcept
Move constructor.
KeyedVectorBase & operator=(const KeyedVectorBase &other)
Copy assignment operator.
KeyedVectorBase(const KeyedVectorBase< Scalar, RowKeyType, oRows > &other)
Copy constructor.
KeyedVectorBase(const KeyedVectorBase &other)
Copy constructor.
KeyedRowVectorBase< Scalar, RowKeyType, Rows > transposed() const
Calculates the transposed vector.
EGM96 coefficients.
Definition GMF.cpp:20
KeyedVector< double, RowKeyType, 2 > KeyedVector2d
Static 2 row KeyedVector with double types.
KeyedRowVectorX< double, ColKeyType > KeyedRowVectorXd
Dynamic size KeyedRowVector with double types.
KeyedRowVector< double, ColKeyType, 6 > KeyedRowVector6d
Static 6 col KeyedRowVector with double types.
KeyedRowVector< double, ColKeyType, 2 > KeyedRowVector2d
Static 2 col KeyedRowVector with double types.
void removeRows(Eigen::DenseBase< Derived > &matrix, size_t index, size_t length)
Removes rows from a matrix or vector.
Definition Eigen.hpp:149
KeyedMatrix< double, RowKeyType, ColKeyType, 3, 3 > KeyedMatrix3d
Static 3x3 squared size KeyedMatrix with double types.
KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > KeyedMatrixX
Dynamic size KeyedMatrix.
KeyedVectorX< double, RowKeyType > KeyedVectorXd
Dynamic size KeyedVector with double types.
KeyedMatrix< double, RowKeyType, ColKeyType, 4, 4 > KeyedMatrix4d
Static 4x4 squared size KeyedMatrix with double types.
KeyedMatrix< double, RowKeyType, ColKeyType, 5, 5 > KeyedMatrix5d
Static 5x5 squared size KeyedMatrix with double types.
KeyedVector< double, RowKeyType, 6 > KeyedVector6d
Static 6 row KeyedVector with double types.
KeyedVector< double, RowKeyType, 5 > KeyedVector5d
Static 5 row KeyedVector with double types.
KeyedRowVector< Scalar, ColKeyType, Eigen::Dynamic > KeyedRowVectorX
Dynamic size KeyedRowVector.
KeyedVector< double, RowKeyType, 4 > KeyedVector4d
Static 4 row KeyedVector with double types.
KeyedMatrix< double, RowKeyType, ColKeyType, 2, 2 > KeyedMatrix2d
Static 2x2 squared size KeyedMatrix with double types.
KeyedVector< Scalar, RowKeyType, Eigen::Dynamic > KeyedVectorX
Dynamic size KeyedVector.
KeyedRowVector< double, ColKeyType, 3 > KeyedRowVector3d
Static 3 col KeyedRowVector with double types.
static const internal::all_t all
Used to request all rows or columns in KeyedMatrices.
void removeCols(Eigen::DenseBase< Derived > &matrix, size_t index, size_t length)
Removes columns from a matrix or vector.
Definition Eigen.hpp:185
KeyedVector< double, RowKeyType, 3 > KeyedVector3d
Static 3 row KeyedVector with double types.
KeyedRowVector< double, ColKeyType, 4 > KeyedRowVector4d
Static 4 col KeyedRowVector with double types.
KeyedMatrixX< double, RowKeyType, ColKeyType > KeyedMatrixXd
Dynamic size KeyedMatrix with double types.
void removeRowsAndCols(Eigen::DenseBase< Derived > &matrix, size_t row, size_t rows, size_t col, size_t cols)
Removes rows and columns from a matrix or vector.
Definition Eigen.hpp:223
KeyedRowVector< double, ColKeyType, 5 > KeyedRowVector5d
Static 5 col KeyedRowVector with double types.
KeyedMatrix< double, RowKeyType, ColKeyType, 6, 6 > KeyedMatrix6d
Static 6x6 squared size KeyedMatrix with double types.
All type to request all rows or columns in KeyedMatrices.
all_t()=default
Default Constructor.
std::ostream & operator<<(std::ostream &os, const NAV::KeyedMatrix< Scalar, RowKeyType, ColKeyType, Rows, Cols > &obj)
Stream insertion operator overload.