0.3.0
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
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{
39struct all_t
40{
42 all_t() = default;
43};
44
49template<typename Scalar, int Rows, int Cols>
51{
52 protected:
53 Eigen::Matrix<Scalar, Rows, Cols> matrix;
54 mutable std::mutex _sliceMutex;
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
72template<typename Scalar, typename RowKeyType, int Rows, int Cols>
73class KeyedMatrixRowsBase : virtual public KeyedMatrixStorage<Scalar, Rows, Cols>
74{
75 public:
77 [[nodiscard]] decltype(auto) rows() const { return this->matrix.rows(); }
78
80 const std::vector<RowKeyType>& rowKeys() const { return rowKeysVector; }
81
84 bool hasRow(const RowKeyType& key) const { return rowIndices.contains(key); }
85
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
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
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:
117 std::vector<RowKeyType> rowKeysVector;
118
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
134template<typename Scalar, typename RowKeyType, int Rows, int Cols>
135class KeyedMatrixRows : public KeyedMatrixRowsBase<Scalar, RowKeyType, Rows, Cols>
136{};
137
142template<typename Scalar, typename RowKeyType, int Cols>
143class KeyedMatrixRows<Scalar, RowKeyType, Eigen::Dynamic, Cols> : public KeyedMatrixRowsBase<Scalar, RowKeyType, Eigen::Dynamic, Cols>
144{
145 public:
148 void addRow(const RowKeyType& rowKey) { addRows(std::initializer_list<RowKeyType>{ rowKey }); }
149
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
174 void removeRow(const RowKeyType& rowKey) { removeRows(std::initializer_list<RowKeyType>{ rowKey }); }
175
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
217template<typename Scalar, typename ColKeyType, int Rows, int Cols>
218class KeyedMatrixColsBase : virtual public KeyedMatrixStorage<Scalar, Rows, Cols>
219{
220 public:
222 [[nodiscard]] decltype(auto) cols() const { return this->matrix.cols(); }
223
225 const std::vector<ColKeyType>& colKeys() const { return colKeysVector; }
226
229 bool hasCol(const ColKeyType& key) const { return colIndices.contains(key); }
230
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
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
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:
262 std::vector<ColKeyType> colKeysVector;
263
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
279template<typename Scalar, typename ColKeyType, int Rows, int Cols>
280class KeyedMatrixCols : public KeyedMatrixColsBase<Scalar, ColKeyType, Rows, Cols>
281{};
282
287template<typename Scalar, typename ColKeyType, int Rows>
288class KeyedMatrixCols<Scalar, ColKeyType, Rows, Eigen::Dynamic> : public KeyedMatrixColsBase<Scalar, ColKeyType, Rows, Eigen::Dynamic>
289{
290 public:
293 void addCol(const ColKeyType& colKey) { addCols(std::initializer_list<ColKeyType>{ colKey }); }
294
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
319 void removeCol(const ColKeyType& colKey) { removeCols(std::initializer_list<ColKeyType>{ colKey }); }
320
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
364template<typename Scalar, typename RowKeyType, int Rows>
365class KeyedVectorBase : public KeyedMatrixRows<Scalar, RowKeyType, Rows, 1>
366{
367 public:
370 template<typename Derived>
371 explicit KeyedVectorBase(const Eigen::MatrixBase<Derived>& vector)
372 {
373 this->matrix = vector;
374 }
375
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
399 ~KeyedVectorBase() = default;
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
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
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
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
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
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
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
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
513 const Scalar& operator()(const RowKeyType& rowKey) const
514 {
515 return this->matrix(this->rowIndices.at(rowKey), 0);
516 }
517
520 Scalar& operator()(const RowKeyType& rowKey)
521 {
522 return this->matrix(this->rowIndices.at(rowKey), 0);
523 }
524
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
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
549 const Eigen::Matrix<Scalar, Rows, 1>& operator()(all_t /* all */) const { return this->matrix; }
551 Eigen::Matrix<Scalar, Rows, 1>& operator()(all_t /* all */) { return this->matrix; }
553 explicit operator Eigen::Vector<Scalar, Rows>() { return this->matrix; }
554
555 // #######################################################################################################
556 // Block operations
557 // #######################################################################################################
558
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
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
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
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
604 {
605 return { this->matrix.transpose(), this->rowKeys() };
606 }
607
608 private:
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
631template<typename Scalar, typename ColKeyType, int Cols>
632class KeyedRowVectorBase : public KeyedMatrixCols<Scalar, ColKeyType, 1, Cols>
633{
634 public:
637 template<typename Derived>
638 explicit KeyedRowVectorBase(const Eigen::MatrixBase<Derived>& vector)
639 {
640 this->matrix = vector;
641 }
642
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
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
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
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
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
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
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
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
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
780 const Scalar& operator()(const ColKeyType& colKey) const
781 {
782 return this->matrix(0, this->colIndices.at(colKey));
783 }
784
787 Scalar& operator()(const ColKeyType& colKey)
788 {
789 return this->matrix(0, this->colIndices.at(colKey));
790 }
791
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
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
816 const Eigen::Matrix<Scalar, 1, Cols>& operator()(all_t /* all */) const { return this->matrix; }
818 Eigen::Matrix<Scalar, 1, Cols>& operator()(all_t /* all */) { return this->matrix; }
820 explicit operator Eigen::RowVector<Scalar, Cols>() { return this->matrix; }
821
822 // #######################################################################################################
823 // Block operations
824 // #######################################################################################################
825
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
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
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
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
871 {
872 return { this->matrix.transpose(), this->colKeys() };
873 }
874
875 private:
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
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:
906 template<typename Derived>
907 explicit KeyedMatrixBase(const Eigen::MatrixBase<Derived>& matrix)
908 {
909 this->matrix = matrix;
910 }
911
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
942 ~KeyedMatrixBase() = default;
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
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
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
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
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
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
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
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
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
1093 Scalar& operator()(const RowKeyType& rowKey, const ColKeyType& colKey)
1094 {
1095 return this->matrix(this->rowIndices.at(rowKey), this->colIndices.at(colKey));
1096 }
1097
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
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
1132 decltype(auto) operator()(std::span<const RowKeyType> rowKeys, const ColKeyType& colKey) const { return (*this)(rowKeys, std::initializer_list<ColKeyType>{ colKey }); }
1137 decltype(auto) operator()(std::span<const RowKeyType> rowKeys, const ColKeyType& colKey) { return (*this)(rowKeys, std::initializer_list<ColKeyType>{ colKey }); }
1142 decltype(auto) operator()(const RowKeyType& rowKey, std::span<const ColKeyType> colKeys) const { return (*this)(std::initializer_list<RowKeyType>{ rowKey }, colKeys); }
1147 decltype(auto) operator()(const RowKeyType& rowKey, std::span<const ColKeyType> colKeys) { return (*this)(std::initializer_list<RowKeyType>{ rowKey }, colKeys); }
1148
1152 decltype(auto) operator()(const RowKeyType& rowKey, all_t /* all */) const { return (*this)(std::initializer_list<RowKeyType>{ rowKey }, this->colKeys()); }
1156 decltype(auto) operator()(const RowKeyType& rowKey, all_t /* all */) { return (*this)(std::initializer_list<RowKeyType>{ rowKey }, this->colKeys()); }
1160 decltype(auto) operator()(all_t /* all */, const ColKeyType& colKey) const { return *this(this->rowKeys(), std::initializer_list<ColKeyType>{ colKey }); }
1164 decltype(auto) operator()(all_t /* all */, const ColKeyType& colKey) { return (*this)(this->rowKeys(), std::initializer_list<ColKeyType>{ colKey }); }
1168 decltype(auto) operator()(std::span<const RowKeyType> rowKeys, all_t /* all */) const { return (*this)(rowKeys, this->colKeys()); }
1172 decltype(auto) operator()(std::span<const RowKeyType> rowKeys, all_t /* all */) { return (*this)(rowKeys, this->colKeys()); }
1176 decltype(auto) operator()(all_t /* all */, std::span<const ColKeyType> colKeys) const { return (*this)(this->rowKeys(), colKeys); }
1180 decltype(auto) operator()(all_t /* all */, std::span<const ColKeyType> colKeys) { return (*this)(this->rowKeys(), colKeys); }
1181
1183 const Eigen::Matrix<Scalar, Rows, Cols>& operator()(all_t /* all */, all_t /* all */) const { return this->matrix; }
1185 Eigen::Matrix<Scalar, Rows, Cols>& operator()(all_t /* all */, all_t /* all */) { return this->matrix; }
1187 explicit operator Eigen::Matrix<Scalar, Rows, Cols>() { return this->matrix; }
1188
1189 // ###########################################################################################################
1190 // Static Block operations
1191 // ###########################################################################################################
1192
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
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
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
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
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
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
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
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
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
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
1295 decltype(auto) row(const RowKeyType& rowKey) const { return this->matrix.row(this->rowIndices.at(rowKey)); }
1299 decltype(auto) row(const RowKeyType& rowKey) { return this->matrix.row(this->rowIndices.at(rowKey)); }
1303 decltype(auto) col(const ColKeyType& colKey) const { return this->matrix.col(this->colIndices.at(colKey)); }
1307 decltype(auto) col(const ColKeyType& colKey) { return this->matrix.col(this->colIndices.at(colKey)); }
1308
1310 const Eigen::Matrix<Scalar, Rows, Cols>& block(all_t /* all */, all_t /* all */) const { return this->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
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
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
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
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
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
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
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
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
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
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
1414 {
1415 return { this->matrix.transpose(), this->colKeys(), this->rowKeys() };
1416 }
1417
1420 {
1421 return { this->matrix.inverse(), this->rowKeys(), this->colKeys() };
1422 }
1423
1424 private:
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
1458
1459template<typename Scalar, typename ColKeyType, int Cols>
1460class KeyedRowVector;
1461
1466template<typename Scalar, typename RowKeyType, int Rows>
1467class KeyedVector : public internal::KeyedVectorBase<Scalar, RowKeyType, Rows>
1468{
1469 public:
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
1484 ~KeyedVector() = default;
1488 : internal::KeyedVectorBase<Scalar, RowKeyType, Rows>(other)
1489 {}
1490
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
1503 KeyedVector(KeyedVector&& other) noexcept
1505 {}
1506
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
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
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
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
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
1569 {
1570 auto transpose = static_cast<const internal::KeyedVectorBase<Scalar, RowKeyType, Rows>&>(*this).transposed();
1571 return { transpose(all), transpose.colKeys() };
1572 }
1573};
1574
1578template<typename Scalar, typename RowKeyType>
1579class KeyedVector<Scalar, RowKeyType, Eigen::Dynamic> : public internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>
1580{
1581 public:
1583 KeyedVector()
1584 : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(Eigen::VectorX<Scalar>()) {}
1585
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
1600 ~KeyedVector() = default;
1603 KeyedVector(const KeyedVector& other)
1604 : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(other)
1605 {}
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 }
1619 KeyedVector(KeyedVector&& other) noexcept
1620 : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(std::move(other))
1621 {}
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
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 {}
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 }
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 {}
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
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
1691template<typename Scalar, typename ColKeyType, int Cols>
1692class KeyedRowVector : public internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>
1693{
1694 public:
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
1709 ~KeyedRowVector() = default;
1713 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>(other)
1714 {}
1715
1718 {
1719 if (this == &other) { return *this; } // Guard self assignment
1720
1723
1724 return *this;
1725 }
1726
1731
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
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
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
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
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
1794 {
1795 auto transpose = static_cast<const internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>&>(*this).transposed();
1796 return { transpose(all), transpose.rowKeys() };
1797 }
1798};
1799
1803template<typename Scalar, typename ColKeyType>
1804class KeyedRowVector<Scalar, ColKeyType, Eigen::Dynamic>
1805 : public internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>
1806{
1807 public:
1810 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(Eigen::RowVectorX<Scalar>()) {}
1811
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
1826 ~KeyedRowVector() = default;
1829 KeyedRowVector(const KeyedRowVector& other)
1830 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(other)
1831 {}
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 }
1845 KeyedRowVector(KeyedRowVector&& other) noexcept
1846 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(std::move(other))
1847 {}
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
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 {}
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 }
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 {}
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
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
1919template<typename Scalar, typename RowKeyType, typename ColKeyType, int Rows, int Cols>
1920class KeyedMatrix : public internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>
1921{
1922 public:
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
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
1947 ~KeyedMatrix() = default;
1951 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>(other)
1952 {}
1953
1956 {
1957 if (this == &other) { return *this; } // Guard self assignment
1958
1961
1962 return *this;
1963 }
1964
1969
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
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
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
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
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
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
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
2053 {
2055 return { inv(all, all), inv.rowKeys(), inv.colKeys() };
2056 }
2057};
2058
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:
2069 KeyedMatrix()
2070 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(Eigen::MatrixX<Scalar>()) {}
2071
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
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
2096 ~KeyedMatrix() = default;
2099 KeyedMatrix(const KeyedMatrix& other)
2100 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(other)
2101 {}
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 }
2115 KeyedMatrix(KeyedMatrix&& other) noexcept
2116 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(std::move(other))
2117 {}
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
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 {}
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 }
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 {}
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
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
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
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
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
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
2307template<typename Scalar, typename RowKeyType, typename ColKeyType = RowKeyType>
2312template<typename RowKeyType, typename ColKeyType = RowKeyType>
2317template<typename RowKeyType, typename ColKeyType = RowKeyType>
2322template<typename RowKeyType, typename ColKeyType = RowKeyType>
2327template<typename RowKeyType, typename ColKeyType = RowKeyType>
2332template<typename RowKeyType, typename ColKeyType = RowKeyType>
2337template<typename RowKeyType, typename ColKeyType = RowKeyType>
2339
2343template<typename Scalar, typename RowKeyType>
2347template<typename RowKeyType>
2351template<typename RowKeyType>
2355template<typename RowKeyType>
2359template<typename RowKeyType>
2363template<typename RowKeyType>
2367template<typename RowKeyType>
2369
2372template<typename Scalar, typename ColKeyType>
2376template<typename ColKeyType>
2380template<typename ColKeyType>
2384template<typename ColKeyType>
2388template<typename ColKeyType>
2392template<typename ColKeyType>
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
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{
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
2492template<typename Scalar, typename RowKeyType, int Rows>
2493struct fmt::formatter<NAV::KeyedVector<Scalar, RowKeyType, Rows>> : fmt::formatter<std::string>
2494{
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
2547template<typename Scalar, typename ColKeyType, int Cols>
2548struct fmt::formatter<NAV::KeyedRowVector<Scalar, ColKeyType, Cols>> : fmt::formatter<std::string>
2549{
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
2613template<typename Scalar, typename RowKeyType, typename ColKeyType, int Rows, int Cols>
2615{
2616 return os << fmt::format("{}", obj);
2617}
2618
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
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.
void removeRows(Eigen::DenseBase< Derived > &matrix, size_t index, size_t length)
Removes rows from a matrix or vector.
Definition Eigen.hpp:149
void removeCols(Eigen::DenseBase< Derived > &matrix, size_t index, size_t length)
Removes columns from a matrix or vector.
Definition Eigen.hpp:185
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
Unordered map wrapper.
ankerl::unordered_dense::map< Key, T > unordered_map
Unordered map type.
Definition Unordered_map.hpp:34
Vector Utility functions.
Static sized KeyedMatrix.
Definition KeyedMatrix.hpp:1921
KeyedMatrix(const KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > &other)
Copy constructor.
Definition KeyedMatrix.hpp:1987
KeyedMatrix(const KeyedMatrix &other)
Copy constructor.
Definition KeyedMatrix.hpp:1950
KeyedMatrix & operator=(const KeyedMatrix &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1955
~KeyedMatrix()=default
Destructor.
KeyedMatrix< Scalar, RowKeyType, ColKeyType, Rows, Cols > transposed() const
Calculates the transposed matrix.
Definition KeyedMatrix.hpp:2045
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.
Definition KeyedMatrix.hpp:2034
KeyedMatrix & operator=(const KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1994
KeyedMatrix & operator=(KeyedMatrix &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:1971
KeyedMatrix(const Eigen::MatrixBase< Derived > &matrix, std::span< const RowKeyType > rowKeys, std::span< const ColKeyType > colKeys)
Non-symmetric matrix constructor.
Definition KeyedMatrix.hpp:1929
KeyedMatrix< Scalar, RowKeyType, ColKeyType, Rows, Cols > inverse() const
Calculates the inverse matrix.
Definition KeyedMatrix.hpp:2052
KeyedMatrix(const Eigen::MatrixBase< Derived > &matrix, std::span< const RowKeyType > keys)
Symmetric matrix constructor.
Definition KeyedMatrix.hpp:1938
KeyedMatrix(KeyedMatrix &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:1966
KeyedMatrix & operator=(KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:2014
KeyedMatrix(KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:2007
Static sized KeyedRowVector.
Definition KeyedMatrix.hpp:1693
KeyedRowVector(KeyedRowVector &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:1728
~KeyedRowVector()=default
Destructor.
KeyedRowVector & operator=(KeyedRowVector &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:1733
KeyedRowVector(KeyedRowVector< Scalar, ColKeyType, Eigen::Dynamic > &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:1769
KeyedRowVector(const KeyedRowVector &other)
Copy constructor.
Definition KeyedMatrix.hpp:1712
KeyedVector< Scalar, ColKeyType, Cols > transposed() const
Calculates the transposed vector.
Definition KeyedMatrix.hpp:1793
KeyedRowVector(const Eigen::MatrixBase< Derived > &vector, std::span< const ColKeyType > colKeys)
RowVector constructor.
Definition KeyedMatrix.hpp:1700
KeyedRowVector(const KeyedRowVector< Scalar, ColKeyType, Eigen::Dynamic > &other)
Copy constructor.
Definition KeyedMatrix.hpp:1749
KeyedRowVector & operator=(const KeyedRowVector< Scalar, ColKeyType, Eigen::Dynamic > &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1756
KeyedRowVector & operator=(const KeyedRowVector &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1717
KeyedRowVector & operator=(KeyedRowVector< Scalar, ColKeyType, Eigen::Dynamic > &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:1776
Static sized KeyedVector.
Definition KeyedMatrix.hpp:1468
KeyedVector(KeyedVector< Scalar, RowKeyType, Eigen::Dynamic > &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:1544
KeyedVector(const KeyedVector &other)
Copy constructor.
Definition KeyedMatrix.hpp:1487
KeyedVector & operator=(KeyedVector &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:1508
KeyedVector(KeyedVector &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:1503
KeyedVector & operator=(KeyedVector< Scalar, RowKeyType, Eigen::Dynamic > &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:1551
KeyedVector(const KeyedVector< Scalar, RowKeyType, Eigen::Dynamic > &other)
Copy constructor.
Definition KeyedMatrix.hpp:1524
KeyedVector & operator=(const KeyedVector &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1492
KeyedRowVector< Scalar, RowKeyType, Rows > transposed() const
Calculates the transposed vector.
Definition KeyedMatrix.hpp:1568
KeyedVector & operator=(const KeyedVector< Scalar, RowKeyType, Eigen::Dynamic > &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1531
~KeyedVector()=default
Destructor.
KeyedVector(const Eigen::MatrixBase< Derived > &vector, std::span< const RowKeyType > rowKeys)
Vector constructor.
Definition KeyedMatrix.hpp:1475
Class to inherit common methods for static and dynamic sized matrices.
Definition KeyedMatrix.hpp:902
decltype(auto) middleCols(std::span< const ColKeyType > colKeys)
Gets the values for the col keys.
Definition KeyedMatrix.hpp:1286
decltype(auto) row(const RowKeyType &rowKey) const
Gets the values for the row key.
Definition KeyedMatrix.hpp:1295
decltype(auto) middleRows(std::span< const RowKeyType > rowKeys) const
Gets the values for the row keys.
Definition KeyedMatrix.hpp:1374
KeyedMatrixBase< Scalar, ColKeyType, RowKeyType, Cols, Rows > transposed() const
Calculates the transposed matrix.
Definition KeyedMatrix.hpp:1413
decltype(auto) middleCols(std::span< const ColKeyType > colKeys)
Gets the values for the col keys.
Definition KeyedMatrix.hpp:1401
decltype(auto) block(std::span< const RowKeyType > rowKeys, std::span< const ColKeyType > colKeys)
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1209
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.
Definition KeyedMatrix.hpp:1430
KeyedMatrixBase(KeyedMatrixBase &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:973
Scalar & operator()(const RowKeyType &rowKey, const ColKeyType &colKey)
Gets the value for the row and col key.
Definition KeyedMatrix.hpp:1093
decltype(auto) block(std::span< const RowKeyType > rowKeys, std::span< const ColKeyType > colKeys)
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1332
KeyedMatrixBase(const Eigen::MatrixBase< Derived > &matrix)
Constructor.
Definition KeyedMatrix.hpp:907
const Eigen::Matrix< Scalar, Rows, Cols > & block(all_t, all_t) const
Requests the full matrix.
Definition KeyedMatrix.hpp:1310
decltype(auto) block(std::span< const RowKeyType > rowKeys, const ColKeyType &colKey)
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1229
decltype(auto) row(const RowKeyType &rowKey)
Gets the values for the row key.
Definition KeyedMatrix.hpp:1299
decltype(auto) middleRows(std::span< const RowKeyType > rowKeys)
Gets the values for the row keys.
Definition KeyedMatrix.hpp:1383
KeyedMatrixBase(const KeyedMatrixBase &other)
Copy constructor.
Definition KeyedMatrix.hpp:945
Eigen::Matrix< Scalar, Rows, Cols > & operator()(all_t, all_t)
Requests the full matrix.
Definition KeyedMatrix.hpp:1185
decltype(auto) middleCols(std::span< const ColKeyType > colKeys) const
Gets the values for the col keys.
Definition KeyedMatrix.hpp:1392
KeyedMatrixBase(KeyedMatrixBase< Scalar, RowKeyType, ColKeyType, oRows, oCols > &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:1043
decltype(auto) block(std::span< const RowKeyType > rowKeys, const ColKeyType &colKey) const
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1220
decltype(auto) block(std::span< const RowKeyType > rowKeys, std::span< const ColKeyType > colKeys) const
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1322
decltype(auto) middleCols(std::span< const ColKeyType > colKeys) const
Gets the values for the col keys.
Definition KeyedMatrix.hpp:1276
decltype(auto) middleRows(std::span< const RowKeyType > rowKeys)
Gets the values for the row keys.
Definition KeyedMatrix.hpp:1266
KeyedMatrixBase & operator=(const KeyedMatrixBase &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:957
~KeyedMatrixBase()=default
Destructor.
decltype(auto) block(const RowKeyType &rowKey, std::span< const ColKeyType > colKeys)
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1247
KeyedMatrixBase & operator=(KeyedMatrixBase< Scalar, RowKeyType, ColKeyType, oRows, oCols > &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:1059
decltype(auto) block(std::span< const RowKeyType > rowKeys, std::span< const ColKeyType > colKeys) const
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1198
const Scalar & operator()(const RowKeyType &rowKey, const ColKeyType &colKey) const
Gets the value for the row and col key.
Definition KeyedMatrix.hpp:1085
decltype(auto) block(const RowKeyType &rowKey, std::span< const ColKeyType > colKeys) const
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1238
decltype(auto) block(std::span< const RowKeyType > rowKeys, const ColKeyType &colKey)
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1350
decltype(auto) block(const RowKeyType &rowKey, std::span< const ColKeyType > colKeys) const
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1358
decltype(auto) block(std::span< const RowKeyType > rowKeys, const ColKeyType &colKey) const
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1342
Eigen::Matrix< Scalar, Rows, Cols > & block(all_t, all_t)
Requests the full matrix.
Definition KeyedMatrix.hpp:1312
decltype(auto) col(const ColKeyType &colKey) const
Gets the values for the col key.
Definition KeyedMatrix.hpp:1303
decltype(auto) block(const RowKeyType &rowKey, std::span< const ColKeyType > colKeys)
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1366
KeyedMatrixBase & operator=(const KeyedMatrixBase< Scalar, RowKeyType, ColKeyType, oRows, oCols > &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1023
decltype(auto) middleRows(std::span< const RowKeyType > rowKeys) const
Gets the values for the row keys.
Definition KeyedMatrix.hpp:1256
KeyedMatrixBase(const Eigen::MatrixBase< Derived > &matrix, std::span< const RowKeyType > rowKeys, std::span< const ColKeyType > colKeys)
Non-symmetric matrix constructor.
Definition KeyedMatrix.hpp:916
decltype(auto) col(const ColKeyType &colKey)
Gets the values for the col key.
Definition KeyedMatrix.hpp:1307
KeyedMatrixBase & operator=(KeyedMatrixBase &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:985
KeyedMatrixBase< Scalar, RowKeyType, ColKeyType, Rows, Cols > inverse() const
Calculates the inverse matrix.
Definition KeyedMatrix.hpp:1419
KeyedMatrixBase(const KeyedMatrixBase< Scalar, RowKeyType, ColKeyType, oRows, oCols > &other)
Copy constructor.
Definition KeyedMatrix.hpp:1007
const Eigen::Matrix< Scalar, Rows, Cols > & operator()(all_t, all_t) const
Requests the full matrix.
Definition KeyedMatrix.hpp:1183
Base class for Keyed matrices with multiple columns.
Definition KeyedMatrix.hpp:219
void replaceColKey(const ColKeyType &oldKey, const ColKeyType &newKey)
Replace the old with the new key.
Definition KeyedMatrix.hpp:248
bool hasCols(std::span< const ColKeyType > keys) const
Checks if the matrix has multiple keys.
Definition KeyedMatrix.hpp:233
std::vector< ColKeyType > colKeysVector
Col Keys.
Definition KeyedMatrix.hpp:262
std::vector< Eigen::Index > colSlice
Col Slice used for accessing.
Definition KeyedMatrix.hpp:265
const std::vector< ColKeyType > & colKeys() const
Returns the col keys.
Definition KeyedMatrix.hpp:225
unordered_map< ColKeyType, Eigen::Index > colIndices
ColKey to Col Index mapping.
Definition KeyedMatrix.hpp:260
decltype(auto) cols() const
Return the cols of the underlying Eigen matrix.
Definition KeyedMatrix.hpp:222
bool hasCol(const ColKeyType &key) const
Checks if the matrix has the key.
Definition KeyedMatrix.hpp:229
bool hasAnyCols(std::span< const ColKeyType > keys) const
Checks if the matrix has any keys.
Definition KeyedMatrix.hpp:240
void removeCol(const ColKeyType &colKey)
Removes the col from the matrix.
Definition KeyedMatrix.hpp:319
void removeCols(std::span< const ColKeyType > colKeys)
Removes the cols from the matrix.
Definition KeyedMatrix.hpp:323
void addCols(std::span< const ColKeyType > colKeys)
Adds new cols to the matrix.
Definition KeyedMatrix.hpp:297
void addCol(const ColKeyType &colKey)
Adds a new col to the matrix.
Definition KeyedMatrix.hpp:293
Base class for Keyed matrices with multiple columns of static size.
Definition KeyedMatrix.hpp:281
Base class for Keyed matrices with multiple rows.
Definition KeyedMatrix.hpp:74
bool hasRows(std::span< const RowKeyType > keys) const
Checks if the matrix has multiple keys.
Definition KeyedMatrix.hpp:88
std::vector< Eigen::Index > rowSlice
Row Slice used for accessing.
Definition KeyedMatrix.hpp:120
unordered_map< RowKeyType, Eigen::Index > rowIndices
RowKey to Row Index mapping.
Definition KeyedMatrix.hpp:115
decltype(auto) rows() const
Return the rows of the underlying Eigen matrix.
Definition KeyedMatrix.hpp:77
bool hasRow(const RowKeyType &key) const
Checks if the matrix has the key.
Definition KeyedMatrix.hpp:84
const std::vector< RowKeyType > & rowKeys() const
Returns the row keys.
Definition KeyedMatrix.hpp:80
bool hasAnyRows(std::span< const RowKeyType > keys) const
Checks if the matrix has any key.
Definition KeyedMatrix.hpp:95
std::vector< RowKeyType > rowKeysVector
Row Keys.
Definition KeyedMatrix.hpp:117
void replaceRowKey(const RowKeyType &oldKey, const RowKeyType &newKey)
Replace the old with the new key.
Definition KeyedMatrix.hpp:103
void removeRows(std::span< const RowKeyType > rowKeys)
Removes the rows from the matrix.
Definition KeyedMatrix.hpp:178
void addRow(const RowKeyType &rowKey)
Adds a new row to the matrix.
Definition KeyedMatrix.hpp:148
void addRows(std::span< const RowKeyType > rowKeys)
Adds new rows to the matrix.
Definition KeyedMatrix.hpp:152
void removeRow(const RowKeyType &rowKey)
Removes the row from the matrix.
Definition KeyedMatrix.hpp:174
Base class for Keyed matrices with multiple rows of static size.
Definition KeyedMatrix.hpp:136
KeyedMatrix storage class.
Definition KeyedMatrix.hpp:51
Eigen::Matrix< Scalar, Rows, Cols > matrix
Data storage of the type.
Definition KeyedMatrix.hpp:53
std::mutex _sliceMutex
Mutex for accessing the slices.
Definition KeyedMatrix.hpp:54
Class to inherit common methods for static and dynamic sized row vectors.
Definition KeyedMatrix.hpp:633
decltype(auto) segment(std::span< const ColKeyType > colKeys) const
Gets the values for the col keys.
Definition KeyedMatrix.hpp:849
KeyedRowVectorBase(const Eigen::MatrixBase< Derived > &vector)
Constructor.
Definition KeyedMatrix.hpp:638
Eigen::Matrix< Scalar, 1, Cols > & operator()(all_t)
Requests the full vector.
Definition KeyedMatrix.hpp:818
const Scalar & operator()(const ColKeyType &colKey) const
Gets the value for the col key.
Definition KeyedMatrix.hpp:780
decltype(auto) segment(std::span< const ColKeyType > colKeys)
Gets the values for the col keys.
Definition KeyedMatrix.hpp:858
decltype(auto) segment(std::span< const ColKeyType > colKeys) const
Gets the values for the col keys.
Definition KeyedMatrix.hpp:830
const Eigen::Matrix< Scalar, 1, Cols > & operator()(all_t) const
Requests the full vector.
Definition KeyedMatrix.hpp:816
KeyedRowVectorBase(KeyedRowVectorBase &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:691
KeyedRowVectorBase(const KeyedRowVectorBase< Scalar, ColKeyType, oCols > &other)
Copy constructor.
Definition KeyedMatrix.hpp:719
KeyedRowVectorBase & operator=(KeyedRowVectorBase< Scalar, ColKeyType, oCols > &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:759
KeyedRowVectorBase & operator=(const KeyedRowVectorBase &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:678
void checkContinuousSegment(std::span< const ColKeyType > colKeys, size_t Q) const
Checks if the col keys are describing a continuous block.
Definition KeyedMatrix.hpp:879
KeyedRowVectorBase & operator=(const KeyedRowVectorBase< Scalar, ColKeyType, oCols > &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:731
~KeyedRowVectorBase()=default
Destructor.
Scalar & operator()(const ColKeyType &colKey)
Gets the value for the col key.
Definition KeyedMatrix.hpp:787
decltype(auto) segment(std::span< const ColKeyType > colKeys)
Gets the values for the col keys.
Definition KeyedMatrix.hpp:840
KeyedRowVectorBase(const Eigen::MatrixBase< Derived > &vector, std::span< const ColKeyType > colKeys)
Constructor.
Definition KeyedMatrix.hpp:647
KeyedRowVectorBase & operator=(KeyedRowVectorBase &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:700
KeyedRowVectorBase(const KeyedRowVectorBase &other)
Copy constructor.
Definition KeyedMatrix.hpp:669
KeyedRowVectorBase(KeyedRowVectorBase< Scalar, ColKeyType, oCols > &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:747
KeyedVectorBase< Scalar, ColKeyType, Cols > transposed() const
Calculates the transposed vector.
Definition KeyedMatrix.hpp:870
Class to inherit common methods for static and dynamic sized vectors.
Definition KeyedMatrix.hpp:366
decltype(auto) segment(std::span< const RowKeyType > rowKeys) const
Gets the values for the row keys.
Definition KeyedMatrix.hpp:563
decltype(auto) segment(std::span< const RowKeyType > rowKeys) const
Gets the values for the row keys.
Definition KeyedMatrix.hpp:582
void checkContinuousSegment(std::span< const RowKeyType > rowKeys, size_t P) const
Checks if the row keys are describing a continuous block.
Definition KeyedMatrix.hpp:612
KeyedVectorBase & operator=(KeyedVectorBase &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:433
decltype(auto) segment(std::span< const RowKeyType > rowKeys)
Gets the values for the row keys.
Definition KeyedMatrix.hpp:591
decltype(auto) segment(std::span< const RowKeyType > rowKeys)
Gets the values for the row keys.
Definition KeyedMatrix.hpp:573
~KeyedVectorBase()=default
Destructor.
Scalar & operator()(const RowKeyType &rowKey)
Gets the value for the row key.
Definition KeyedMatrix.hpp:520
Eigen::Matrix< Scalar, Rows, 1 > & operator()(all_t)
Requests the full vector.
Definition KeyedMatrix.hpp:551
KeyedVectorBase & operator=(const KeyedVectorBase< Scalar, RowKeyType, oRows > &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:464
KeyedVectorBase & operator=(KeyedVectorBase< Scalar, RowKeyType, oRows > &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:492
KeyedVectorBase(const Eigen::MatrixBase< Derived > &vector)
Constructor.
Definition KeyedMatrix.hpp:371
KeyedVectorBase(KeyedVectorBase &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:424
const Eigen::Matrix< Scalar, Rows, 1 > & operator()(all_t) const
Requests the full vector.
Definition KeyedMatrix.hpp:549
KeyedVectorBase(const Eigen::MatrixBase< Derived > &vector, std::span< const RowKeyType > rowKeys)
Constructor.
Definition KeyedMatrix.hpp:380
const Scalar & operator()(const RowKeyType &rowKey) const
Gets the value for the row key.
Definition KeyedMatrix.hpp:513
KeyedVectorBase(KeyedVectorBase< Scalar, RowKeyType, oRows > &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:480
KeyedVectorBase & operator=(const KeyedVectorBase &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:411
KeyedVectorBase(const KeyedVectorBase< Scalar, RowKeyType, oRows > &other)
Copy constructor.
Definition KeyedMatrix.hpp:452
KeyedVectorBase(const KeyedVectorBase &other)
Copy constructor.
Definition KeyedMatrix.hpp:402
KeyedRowVectorBase< Scalar, RowKeyType, Rows > transposed() const
Calculates the transposed vector.
Definition KeyedMatrix.hpp:603
EGM96 coefficients.
Definition GMFCoeffs.hpp:21
All type to request all rows or columns in KeyedMatrices.
Definition KeyedMatrix.hpp:40
all_t()=default
Default Constructor.
KeyedVector< double, RowKeyType, 2 > KeyedVector2d
Static 2 row KeyedVector with double types.
Definition KeyedMatrix.hpp:2352
KeyedRowVectorX< double, ColKeyType > KeyedRowVectorXd
Dynamic size KeyedRowVector with double types.
Definition KeyedMatrix.hpp:2377
KeyedRowVector< double, ColKeyType, 6 > KeyedRowVector6d
Static 6 col KeyedRowVector with double types.
Definition KeyedMatrix.hpp:2397
KeyedRowVector< double, ColKeyType, 2 > KeyedRowVector2d
Static 2 col KeyedRowVector with double types.
Definition KeyedMatrix.hpp:2381
KeyedMatrix< double, RowKeyType, ColKeyType, 3, 3 > KeyedMatrix3d
Static 3x3 squared size KeyedMatrix with double types.
Definition KeyedMatrix.hpp:2323
KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > KeyedMatrixX
Dynamic size KeyedMatrix.
Definition KeyedMatrix.hpp:2308
KeyedVectorX< double, RowKeyType > KeyedVectorXd
Dynamic size KeyedVector with double types.
Definition KeyedMatrix.hpp:2348
KeyedMatrix< double, RowKeyType, ColKeyType, 4, 4 > KeyedMatrix4d
Static 4x4 squared size KeyedMatrix with double types.
Definition KeyedMatrix.hpp:2328
KeyedMatrix< double, RowKeyType, ColKeyType, 5, 5 > KeyedMatrix5d
Static 5x5 squared size KeyedMatrix with double types.
Definition KeyedMatrix.hpp:2333
KeyedVector< double, RowKeyType, 6 > KeyedVector6d
Static 6 row KeyedVector with double types.
Definition KeyedMatrix.hpp:2368
KeyedVector< double, RowKeyType, 5 > KeyedVector5d
Static 5 row KeyedVector with double types.
Definition KeyedMatrix.hpp:2364
KeyedRowVector< Scalar, ColKeyType, Eigen::Dynamic > KeyedRowVectorX
Dynamic size KeyedRowVector.
Definition KeyedMatrix.hpp:2373
KeyedVector< double, RowKeyType, 4 > KeyedVector4d
Static 4 row KeyedVector with double types.
Definition KeyedMatrix.hpp:2360
KeyedMatrix< double, RowKeyType, ColKeyType, 2, 2 > KeyedMatrix2d
Static 2x2 squared size KeyedMatrix with double types.
Definition KeyedMatrix.hpp:2318
KeyedVector< Scalar, RowKeyType, Eigen::Dynamic > KeyedVectorX
Dynamic size KeyedVector.
Definition KeyedMatrix.hpp:2344
KeyedRowVector< double, ColKeyType, 3 > KeyedRowVector3d
Static 3 col KeyedRowVector with double types.
Definition KeyedMatrix.hpp:2385
std::ostream & operator<<(std::ostream &os, const NAV::KeyedMatrix< Scalar, RowKeyType, ColKeyType, Rows, Cols > &obj)
Stream insertion operator overload.
Definition KeyedMatrix.hpp:2614
static const internal::all_t all
Used to request all rows or columns in KeyedMatrices.
Definition KeyedMatrix.hpp:1457
KeyedVector< double, RowKeyType, 3 > KeyedVector3d
Static 3 row KeyedVector with double types.
Definition KeyedMatrix.hpp:2356
KeyedRowVector< double, ColKeyType, 4 > KeyedRowVector4d
Static 4 col KeyedRowVector with double types.
Definition KeyedMatrix.hpp:2389
KeyedMatrixX< double, RowKeyType, ColKeyType > KeyedMatrixXd
Dynamic size KeyedMatrix with double types.
Definition KeyedMatrix.hpp:2313
KeyedRowVector< double, ColKeyType, 5 > KeyedRowVector5d
Static 5 col KeyedRowVector with double types.
Definition KeyedMatrix.hpp:2393
KeyedMatrix< double, RowKeyType, ColKeyType, 6, 6 > KeyedMatrix6d
Static 6x6 squared size KeyedMatrix with double types.
Definition KeyedMatrix.hpp:2338