0.2.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 <algorithm>
21#include <ranges>
22#include <type_traits>
23#include "util/Assert.h"
24#include "util/Eigen.hpp"
26
27#pragma GCC diagnostic push
28#if !defined(__clang__) && defined(__GNUC__)
29 #pragma GCC diagnostic ignored "-Wvirtual-move-assign" // NOLINT(clang-diagnostic-unknown-warning-option)
30#endif
31
32namespace NAV
33{
34namespace internal
35{
37struct all_t
38{
40 all_t() = default;
41};
42
47template<typename Scalar, int Rows, int Cols>
49{
50 protected:
51 Eigen::Matrix<Scalar, Rows, Cols> matrix;
52
53 private:
54 template<typename Scalar_, typename RowKeyType_, typename ColKeyType_, int Rows_, int Cols_>
55 friend class KeyedMatrixBase;
56 template<typename Scalar_, typename RowKeyType_, int Rows_>
57 friend class KeyedVectorBase;
58 template<typename Scalar_, typename ColKeyType_, int Cols_>
59 friend class KeyedRowVectorBase;
60};
61
62// ###########################################################################################################
63
69template<typename Scalar, typename RowKeyType, int Rows, int Cols>
70class KeyedMatrixRowsBase : virtual public KeyedMatrixStorage<Scalar, Rows, Cols>
71{
72 public:
74 [[nodiscard]] decltype(auto) rows() const { return this->matrix.rows(); }
75
77 const std::vector<RowKeyType>& rowKeys() const { return rowKeysVector; }
78
81 bool hasRow(const RowKeyType& key) const { return rowIndices.contains(key); }
82
85 bool hasRows(const std::vector<RowKeyType>& keys) const
86 {
87 return std::all_of(keys.begin(), keys.end(), [&](const RowKeyType& key) { return hasRow(key); });
88 }
89
92 bool hasAnyRows(const std::vector<RowKeyType>& keys) const
93 {
94 return std::any_of(keys.begin(), keys.end(), [&](const RowKeyType& key) { return hasRow(key); });
95 }
96
100 void replaceRowKey(const RowKeyType& oldKey, const RowKeyType& newKey)
101 {
102 auto iter = std::find(rowKeysVector.begin(), rowKeysVector.end(), oldKey);
103 INS_ASSERT_USER_ERROR(iter != rowKeysVector.end(), "You cannot replace keys, which are not in the vector/matrix.");
104
105 *iter = newKey;
106 rowIndices[newKey] = rowIndices.at(oldKey);
107 rowIndices.erase(oldKey);
108 }
109
110 protected:
114 std::vector<RowKeyType> rowKeysVector;
115
117 mutable std::vector<Eigen::Index> rowSlice;
118
119 private:
120 template<typename Scalar_, typename RowKeyType_, typename ColKeyType_, int Rows_, int Cols_>
121 friend class KeyedMatrixBase;
122 template<typename Scalar_, typename RowKeyType_, int Rows_>
123 friend class KeyedVectorBase;
124};
125
131template<typename Scalar, typename RowKeyType, int Rows, int Cols>
132class KeyedMatrixRows : public KeyedMatrixRowsBase<Scalar, RowKeyType, Rows, Cols>
133{};
134
139template<typename Scalar, typename RowKeyType, int Cols>
140class KeyedMatrixRows<Scalar, RowKeyType, Eigen::Dynamic, Cols> : public KeyedMatrixRowsBase<Scalar, RowKeyType, Eigen::Dynamic, Cols>
141{
142 public:
145 void addRow(const RowKeyType& rowKey) { addRows({ rowKey }); }
146
149 void addRows(const std::vector<RowKeyType>& rowKeys)
150 {
151 INS_ASSERT_USER_ERROR(!this->hasAnyRows(rowKeys), "You cannot add a row key which is already in the matrix.");
152 INS_ASSERT_USER_ERROR(std::unordered_set<RowKeyType>(rowKeys.begin(), rowKeys.end()).size() == rowKeys.size(), "Each row key must be unique");
153
154 auto initialSize = static_cast<Eigen::Index>(this->rowIndices.size());
155 for (const auto& rowKey : rowKeys) { this->rowIndices.insert({ rowKey, static_cast<Eigen::Index>(this->rowIndices.size()) }); }
156 this->rowKeysVector.reserve(this->rowKeysVector.size() + rowKeys.size());
157 std::copy(rowKeys.begin(), rowKeys.end(), std::back_inserter(this->rowKeysVector));
158 auto finalSize = static_cast<Eigen::Index>(this->rowIndices.size());
159
160 if (finalSize > initialSize)
161 {
162 this->matrix.conservativeResize(finalSize, Eigen::NoChange);
163 this->matrix.block(initialSize, 0, finalSize - initialSize, this->matrix.cols()) = Eigen::MatrixX<Scalar>::Zero(finalSize - initialSize, this->matrix.cols());
164 }
165 this->rowSlice.reserve(this->rowKeysVector.size());
166 }
167
170 void removeRow(const RowKeyType& rowKey) { removeRows({ rowKey }); }
171
174 void removeRows(const std::vector<RowKeyType>& rowKeys)
175 {
176 std::vector<int> indices;
177 for (const auto& rowKey : rowKeys)
178 {
179 auto iter = std::find_if(this->rowIndices.begin(), this->rowIndices.end(), [&](const auto& item) { return item.first == rowKey; });
180 INS_ASSERT_USER_ERROR(iter != this->rowIndices.end(), "You tried removing a row key, which did not exist.");
181 if (iter != this->rowIndices.end())
182 {
183 indices.push_back(static_cast<int>(iter->second));
184 }
185 }
186 NAV::removeRows(this->matrix, indices);
187
188 for (const auto& rowKey : rowKeys)
189 {
190 auto iter = std::find_if(this->rowIndices.begin(), this->rowIndices.end(), [&](const auto& item) { return item.first == rowKey; });
191 if (iter != this->rowIndices.end())
192 {
193 std::erase_if(this->rowKeysVector, [&](const auto& item) { return item == rowKey; });
194
195 auto idx = iter->second;
196 for (auto& rowIndex : this->rowIndices)
197 {
198 if (rowIndex.second > idx) { rowIndex.second--; }
199 }
200 this->rowIndices.erase(iter);
201 }
202 }
203 }
204};
205
206// ###########################################################################################################
207
213template<typename Scalar, typename ColKeyType, int Rows, int Cols>
214class KeyedMatrixColsBase : virtual public KeyedMatrixStorage<Scalar, Rows, Cols>
215{
216 public:
218 [[nodiscard]] decltype(auto) cols() const { return this->matrix.cols(); }
219
221 const std::vector<ColKeyType>& colKeys() const { return colKeysVector; }
222
225 bool hasCol(const ColKeyType& key) const { return colIndices.contains(key); }
226
229 bool hasCols(const std::vector<ColKeyType>& keys) const
230 {
231 return std::all_of(keys.begin(), keys.end(), [&](const ColKeyType& key) { return hasCol(key); });
232 }
233
236 bool hasAnyCols(const std::vector<ColKeyType>& keys) const
237 {
238 return std::any_of(keys.begin(), keys.end(), [&](const ColKeyType& key) { return hasCol(key); });
239 }
240
244 void replaceColKey(const ColKeyType& oldKey, const ColKeyType& newKey)
245 {
246 auto iter = std::find(colKeysVector.begin(), colKeysVector.end(), oldKey);
247 INS_ASSERT_USER_ERROR(iter != colKeysVector.end(), "You cannot replace keys, which are not in the vector/matrix.");
248
249 *iter = newKey;
250 colIndices[newKey] = colIndices.at(oldKey);
251 colIndices.erase(oldKey);
252 }
253
254 protected:
258 std::vector<ColKeyType> colKeysVector;
259
261 mutable std::vector<Eigen::Index> colSlice;
262
263 private:
264 template<typename Scalar_, typename RowKeyType_, typename ColKeyType_, int Rows_, int Cols_>
265 friend class KeyedMatrixBase;
266 template<typename Scalar_, typename ColKeyType_, int Cols_>
267 friend class KeyedRowVectorBase;
268};
269
275template<typename Scalar, typename ColKeyType, int Rows, int Cols>
276class KeyedMatrixCols : public KeyedMatrixColsBase<Scalar, ColKeyType, Rows, Cols>
277{};
278
283template<typename Scalar, typename ColKeyType, int Rows>
284class KeyedMatrixCols<Scalar, ColKeyType, Rows, Eigen::Dynamic> : public KeyedMatrixColsBase<Scalar, ColKeyType, Rows, Eigen::Dynamic>
285{
286 public:
289 void addCol(const ColKeyType& colKey) { addCols({ colKey }); }
290
293 void addCols(const std::vector<ColKeyType>& colKeys)
294 {
295 INS_ASSERT_USER_ERROR(!this->hasAnyCols(colKeys), "You cannot add a col key which is already in the matrix.");
296 INS_ASSERT_USER_ERROR(std::unordered_set<ColKeyType>(colKeys.begin(), colKeys.end()).size() == colKeys.size(), "Each col key must be unique");
297
298 auto initialSize = static_cast<Eigen::Index>(this->colIndices.size());
299 for (const auto& colKey : colKeys) { this->colIndices.insert({ colKey, static_cast<Eigen::Index>(this->colIndices.size()) }); }
300 this->colKeysVector.reserve(this->colKeysVector.size() + colKeys.size());
301 std::copy(colKeys.begin(), colKeys.end(), std::back_inserter(this->colKeysVector));
302 auto finalSize = static_cast<Eigen::Index>(this->colIndices.size());
303
304 if (finalSize > initialSize)
305 {
306 this->matrix.conservativeResize(Eigen::NoChange, finalSize);
307 this->matrix.block(0, initialSize, this->matrix.rows(), finalSize - initialSize) = Eigen::MatrixX<Scalar>::Zero(this->matrix.rows(), finalSize - initialSize);
308 }
309 this->colSlice.reserve(this->colKeysVector.size());
310 }
311
314 void removeCol(const ColKeyType& colKey) { removeCols({ colKey }); }
315
318 void removeCols(const std::vector<ColKeyType>& colKeys)
319 {
320 std::vector<int> indices;
321 for (const auto& colKey : colKeys)
322 {
323 auto iter = std::find_if(this->colIndices.begin(), this->colIndices.end(), [&](const auto& item) { return item.first == colKey; });
324 INS_ASSERT_USER_ERROR(iter != this->colIndices.end(), "You tried removing a col key, which did not exist.");
325 if (iter != this->colIndices.end())
326 {
327 indices.push_back(static_cast<int>(iter->second));
328 }
329 }
330 NAV::removeCols(this->matrix, indices);
331
332 for (const auto& colKey : colKeys)
333 {
334 auto iter = std::find_if(this->colIndices.begin(), this->colIndices.end(), [&](const auto& item) { return item.first == colKey; });
335 if (iter != this->colIndices.end())
336 {
337 std::erase_if(this->colKeysVector, [&](const auto& item) { return item == colKey; });
338
339 auto idx = iter->second;
340 for (auto& colIndex : this->colIndices)
341 {
342 if (colIndex.second > idx) { colIndex.second--; }
343 }
344 this->colIndices.erase(iter);
345 }
346 }
347 }
348};
349
350// ###########################################################################################################
351
352template<typename Scalar, typename ColKeyType, int Cols>
353class KeyedRowVectorBase;
354
359template<typename Scalar, typename RowKeyType, int Rows>
360class KeyedVectorBase : public KeyedMatrixRows<Scalar, RowKeyType, Rows, 1>
361{
362 public:
365 template<typename Derived>
366 explicit KeyedVectorBase(const Eigen::MatrixBase<Derived>& vector)
367 {
368 this->matrix = vector;
369 }
370
374 template<typename Derived>
375 KeyedVectorBase(const Eigen::MatrixBase<Derived>& vector, const std::vector<RowKeyType>& rowKeys)
376 {
377 INS_ASSERT_USER_ERROR(std::unordered_set<RowKeyType>(rowKeys.begin(), rowKeys.end()).size() == rowKeys.size(), "Each row key must be unique");
378
379 INS_ASSERT_USER_ERROR(vector.cols() == 1, "Only vectors with 1 column are allowed.");
380 INS_ASSERT_USER_ERROR(Rows == Eigen::Dynamic || vector.rows() == static_cast<int>(rowKeys.size()), "Number of vector rows doesn't correspond to the amount of row keys");
381
382 for (size_t i = 0; i < rowKeys.size(); i++) { this->rowIndices.insert({ rowKeys.at(i), static_cast<Eigen::Index>(i) }); }
383
384 this->matrix = vector;
385 this->rowKeysVector = rowKeys;
386 this->rowSlice.reserve(this->rowKeysVector.size());
387 }
388
389 // #######################################################################################################
390 // Special member functions
391 // #######################################################################################################
392
394 ~KeyedVectorBase() = default;
398 {
399 this->matrix = other.matrix;
400 this->rowIndices = other.rowIndices;
401 this->rowKeysVector = other.rowKeysVector;
402 this->rowSlice.reserve(this->rowKeysVector.size());
403 }
407 {
408 if (this == &other) { return *this; } // Guard self assignment
409
410 this->matrix = other.matrix;
411 this->rowIndices = other.rowIndices;
412 this->rowKeysVector = other.rowKeysVector;
413 this->rowSlice.reserve(this->rowKeysVector.size());
414
415 return *this;
416 }
420 {
421 this->matrix = std::move(other.matrix);
422 this->rowIndices = std::move(other.rowIndices);
423 this->rowKeysVector = std::move(other.rowKeysVector);
424 this->rowSlice.reserve(this->rowKeysVector.size());
425 }
429 {
430 if (this == &other) { return *this; } // Guard self assignment
431
432 this->matrix = std::move(other.matrix);
433 this->rowIndices = std::move(other.rowIndices);
434 this->rowKeysVector = std::move(other.rowKeysVector);
435 this->rowSlice.reserve(this->rowKeysVector.size());
436
437 return *this;
438 }
439
440 // ###########################################################################################################
441 // Special member functions with different Rows/Cols
442 // ###########################################################################################################
443
446 template<int oRows>
447 KeyedVectorBase(const KeyedVectorBase<Scalar, RowKeyType, oRows>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
448 {
449 INS_ASSERT_USER_ERROR(Rows == Eigen::Dynamic || other.rows() == Rows, "Can only copy construct dynamic<=>static matrices if the rows match");
450
451 this->matrix = other.matrix;
452 this->rowIndices = other.rowIndices;
453 this->rowKeysVector = other.rowKeysVector;
454 this->rowSlice.reserve(this->rowKeysVector.size());
455 }
458 template<int oRows>
460 {
461 // No need to guard self assignment, as the types are different, so it cannot be the same object
462
463 INS_ASSERT_USER_ERROR(other.rowKeys() == this->rowKeys(), "Can only copy assign matrices if the row keys match");
464
465 this->matrix = other.matrix;
466 this->rowIndices = other.rowIndices;
467 this->rowKeysVector = other.rowKeysVector;
468 this->rowSlice.reserve(this->rowKeysVector.size());
469
470 return *this;
471 }
474 template<int oRows>
475 KeyedVectorBase(KeyedVectorBase<Scalar, RowKeyType, oRows>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
476 {
477 INS_ASSERT_USER_ERROR(Rows == Eigen::Dynamic || other.rows() == Rows, "Can only copy construct dynamic<=>static matrices if the rows match");
478
479 this->matrix = std::move(other.matrix);
480 this->rowIndices = std::move(other.rowIndices);
481 this->rowKeysVector = std::move(other.rowKeysVector);
482 this->rowSlice.reserve(this->rowKeysVector.size());
483 }
486 template<int oRows>
488 {
489 // No need to guard self assignment, as the types are different, so it cannot be the same object
490
491 INS_ASSERT_USER_ERROR(other.rowKeys() == this->rowKeys(), "Can only copy assign matrices if the row keys match");
492
493 this->matrix = std::move(other.matrix);
494 this->rowIndices = std::move(other.rowIndices);
495 this->rowKeysVector = std::move(other.rowKeysVector);
496 this->rowSlice.reserve(this->rowKeysVector.size());
497
498 return *this;
499 }
500
501 // #######################################################################################################
502 // Access
503 // #######################################################################################################
504
508 const Scalar& operator()(const RowKeyType& rowKey) const
509 {
510 return this->matrix(this->rowIndices.at(rowKey), 0);
511 }
515 Scalar& operator()(const RowKeyType& rowKey)
516 {
517 return this->matrix(this->rowIndices.at(rowKey), 0);
518 }
519
523 decltype(auto) operator()(const std::vector<RowKeyType>& rowKeys) const
524 {
525 this->rowSlice.clear();
526 for (const auto& rowKey : rowKeys) { this->rowSlice.push_back(this->rowIndices.at(rowKey)); }
527
528 return this->matrix(this->rowSlice, 0);
529 }
533 decltype(auto) operator()(const std::vector<RowKeyType>& rowKeys)
534 {
535 this->rowSlice.clear();
536 for (const auto& rowKey : rowKeys) { this->rowSlice.push_back(this->rowIndices.at(rowKey)); }
537
538 return this->matrix(this->rowSlice, 0);
539 }
540
542 const Eigen::Matrix<Scalar, Rows, 1>& operator()(all_t /* all */) const { return this->matrix; }
544 Eigen::Matrix<Scalar, Rows, 1>& operator()(all_t /* all */) { return this->matrix; }
546 explicit operator Eigen::Vector<Scalar, Rows>() { return this->matrix; }
547
548 // #######################################################################################################
549 // Block operations
550 // #######################################################################################################
551
555 template<size_t P>
556 decltype(auto) segment(const std::vector<RowKeyType>& rowKeys) const // NOLINT(readability-const-return-type)
557 {
558 checkContinuousSegment(rowKeys, P);
559
560 return this->matrix.template middleRows<P>(this->rowIndices.at(rowKeys.at(0)));
561 }
565 template<size_t P>
566 decltype(auto) segment(const std::vector<RowKeyType>& rowKeys)
567 {
568 checkContinuousSegment(rowKeys, P);
569
570 return this->matrix.template middleRows<P>(this->rowIndices.at(rowKeys.at(0)));
571 }
575 decltype(auto) segment(const std::vector<RowKeyType>& rowKeys) const // NOLINT(readability-const-return-type)
576 {
577 checkContinuousSegment(rowKeys, rowKeys.size());
578
579 return this->matrix.middleRows(this->rowIndices.at(rowKeys.at(0)), rowKeys.size());
580 }
584 decltype(auto) segment(const std::vector<RowKeyType>& rowKeys)
585 {
586 checkContinuousSegment(rowKeys, rowKeys.size());
587
588 return this->matrix.middleRows(this->rowIndices.at(rowKeys.at(0)), rowKeys.size());
589 }
590
591 // #######################################################################################################
592 // Methods
593 // #######################################################################################################
594
597 {
598 return { this->matrix.transpose(), this->rowKeys() };
599 }
600
601 private:
605 void checkContinuousSegment([[maybe_unused]] const std::vector<RowKeyType>& rowKeys, [[maybe_unused]] size_t P) const
606 {
607#ifndef NDEBUG
608 INS_ASSERT_USER_ERROR(P == rowKeys.size(), "The block size must be equivalent to the amount of row keys.");
609
610 std::vector<Eigen::Index> consecutiveRows(rowKeys.size());
611 std::iota(std::begin(consecutiveRows), std::end(consecutiveRows), this->rowIndices.at(rowKeys.at(0)));
612 std::vector<Eigen::Index> rowIndices;
613 rowIndices.reserve(rowKeys.size());
614 for (const auto& rowKey : rowKeys) { rowIndices.push_back(this->rowIndices.at(rowKey)); }
615 INS_ASSERT_USER_ERROR(rowIndices == consecutiveRows, "The given rowKeys must describe a consecutive part in the matrix.");
616#endif
617 }
618};
619
624template<typename Scalar, typename ColKeyType, int Cols>
625class KeyedRowVectorBase : public KeyedMatrixCols<Scalar, ColKeyType, 1, Cols>
626{
627 public:
630 template<typename Derived>
631 explicit KeyedRowVectorBase(const Eigen::MatrixBase<Derived>& vector)
632 {
633 this->matrix = vector;
634 }
635
639 template<typename Derived>
640 KeyedRowVectorBase(const Eigen::MatrixBase<Derived>& vector, const std::vector<ColKeyType>& colKeys)
641 {
642 INS_ASSERT_USER_ERROR(std::unordered_set<ColKeyType>(colKeys.begin(), colKeys.end()).size() == colKeys.size(), "Each col key must be unique");
643
644 INS_ASSERT_USER_ERROR(vector.rows() == 1, "Only vectors with 1 row are allowed.");
645 INS_ASSERT_USER_ERROR(Cols == Eigen::Dynamic || vector.cols() == static_cast<Eigen::Index>(colKeys.size()), "Number of vector cols doesn't correspond to the amount of col keys");
646
647 for (size_t i = 0; i < colKeys.size(); i++) { this->colIndices.insert({ colKeys.at(i), static_cast<Eigen::Index>(i) }); }
648
649 this->matrix = vector;
650 this->colKeysVector = colKeys;
651 this->colSlice.reserve(this->colKeysVector.size());
652 }
653
654 // #######################################################################################################
655 // Special member functions
656 // #######################################################################################################
657
663 {
664 this->matrix = other.matrix;
665 this->colIndices = other.colIndices;
666 this->colKeysVector = other.colKeysVector;
667 this->colSlice.reserve(this->colKeysVector.size());
668 }
672 {
673 if (this == &other) { return *this; } // Guard self assignment
674
675 this->matrix = other.matrix;
676 this->colIndices = other.colIndices;
677 this->colKeysVector = other.colKeysVector;
678 this->colSlice.reserve(this->colKeysVector.size());
679
680 return *this;
681 }
685 {
686 this->matrix = std::move(other.matrix);
687 this->colIndices = std::move(other.colIndices);
688 this->colKeysVector = std::move(other.colKeysVector);
689 this->colSlice.reserve(this->colKeysVector.size());
690 }
694 {
695 if (this == &other) { return *this; } // Guard self assignment
696
697 this->matrix = std::move(other.matrix);
698 this->colIndices = std::move(other.colIndices);
699 this->colKeysVector = std::move(other.colKeysVector);
700 this->colSlice.reserve(this->colKeysVector.size());
701
702 return *this;
703 }
704
705 // ###########################################################################################################
706 // Special member functions with different Rows/Cols
707 // ###########################################################################################################
708
711 template<int oCols>
712 KeyedRowVectorBase(const KeyedRowVectorBase<Scalar, ColKeyType, oCols>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
713 {
714 INS_ASSERT_USER_ERROR(Cols == Eigen::Dynamic || other.cols() == Cols, "Can only copy construct dynamic<=>static matrices if the cols match");
715
716 this->matrix = other.matrix;
717 this->colIndices = other.colIndices;
718 this->colKeysVector = other.colKeysVector;
719 this->colSlice.reserve(this->colKeysVector.size());
720 }
723 template<int oCols>
725 {
726 // No need to guard self assignment, as the types are different, so it cannot be the same object
727
728 INS_ASSERT_USER_ERROR(other.colKeys() == this->colKeys(), "Can only copy assign matrices if the col keys match");
729
730 this->matrix = other.matrix;
731 this->colIndices = other.colIndices;
732 this->colKeysVector = other.colKeysVector;
733 this->colSlice.reserve(this->colKeysVector.size());
734
735 return *this;
736 }
739 template<int oCols>
740 KeyedRowVectorBase(KeyedRowVectorBase<Scalar, ColKeyType, oCols>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
741 {
742 INS_ASSERT_USER_ERROR(Cols == Eigen::Dynamic || other.cols() == Cols, "Can only copy construct dynamic<=>static matrices if the cols match");
743
744 this->matrix = std::move(other.matrix);
745 this->colIndices = std::move(other.colIndices);
746 this->colKeysVector = std::move(other.colKeysVector);
747 this->colSlice.reserve(this->colKeysVector.size());
748 }
751 template<int oCols>
753 {
754 // No need to guard self assignment, as the types are different, so it cannot be the same object
755
756 INS_ASSERT_USER_ERROR(other.colKeys() == this->colKeys(), "Can only copy assign matrices if the col keys match");
757
758 this->matrix = std::move(other.matrix);
759 this->colIndices = std::move(other.colIndices);
760 this->colKeysVector = std::move(other.colKeysVector);
761 this->colSlice.reserve(this->colKeysVector.size());
762
763 return *this;
764 }
765
766 // #######################################################################################################
767 // Access
768 // #######################################################################################################
769
773 const Scalar& operator()(const ColKeyType& colKey) const
774 {
775 return this->matrix(0, this->colIndices.at(colKey));
776 }
780 Scalar& operator()(const ColKeyType& colKey)
781 {
782 return this->matrix(0, this->colIndices.at(colKey));
783 }
784
788 decltype(auto) operator()(const std::vector<ColKeyType>& colKeys) const
789 {
790 this->colSlice.clear();
791 for (const auto& colKey : colKeys) { this->colSlice.push_back(this->colIndices.at(colKey)); }
792
793 return this->matrix(0, this->colSlice);
794 }
798 decltype(auto) operator()(const std::vector<ColKeyType>& colKeys)
799 {
800 this->colSlice.clear();
801 for (const auto& colKey : colKeys) { this->colSlice.push_back(this->colIndices.at(colKey)); }
802
803 return this->matrix(0, this->colSlice);
804 }
805
807 const Eigen::Matrix<Scalar, 1, Cols>& operator()(all_t /* all */) const { return this->matrix; }
809 Eigen::Matrix<Scalar, 1, Cols>& operator()(all_t /* all */) { return this->matrix; }
811 explicit operator Eigen::RowVector<Scalar, Cols>() { return this->matrix; }
812
813 // #######################################################################################################
814 // Block operations
815 // #######################################################################################################
816
820 template<size_t Q>
821 decltype(auto) segment(const std::vector<ColKeyType>& colKeys) const
822 {
823 checkContinuousSegment(colKeys, Q);
824
825 return this->matrix.template middleCols<Q>(this->colIndices.at(colKeys.at(0)));
826 }
830 template<size_t Q>
831 decltype(auto) segment(const std::vector<ColKeyType>& colKeys)
832 {
833 checkContinuousSegment(colKeys, Q);
834
835 return this->matrix.template middleCols<Q>(this->colIndices.at(colKeys.at(0)));
836 }
840 decltype(auto) segment(const std::vector<ColKeyType>& colKeys) const
841 {
842 checkContinuousSegment(colKeys, colKeys.size());
843
844 return this->matrix.middleCols(this->colIndices.at(colKeys.at(0)), colKeys.size());
845 }
849 decltype(auto) segment(const std::vector<ColKeyType>& colKeys)
850 {
851 checkContinuousSegment(colKeys, colKeys.size());
852
853 return this->matrix.middleCols(this->colIndices.at(colKeys.at(0)), colKeys.size());
854 }
855
856 // #######################################################################################################
857 // Methods
858 // #######################################################################################################
859
862 {
863 return { this->matrix.transpose(), this->colKeys() };
864 }
865
866 private:
870 void checkContinuousSegment([[maybe_unused]] const std::vector<ColKeyType>& colKeys, [[maybe_unused]] size_t Q) const
871 {
872#ifndef NDEBUG
873 INS_ASSERT_USER_ERROR(Q == colKeys.size(), "The block size must be equivalent to the amount of col keys.");
874
875 std::vector<Eigen::Index> consecutiveCols(colKeys.size());
876 std::iota(std::begin(consecutiveCols), std::end(consecutiveCols), this->colIndices.at(colKeys.at(0)));
877 std::vector<Eigen::Index> colIndices;
878 colIndices.reserve(colKeys.size());
879 for (const auto& colKey : colKeys) { colIndices.push_back(this->colIndices.at(colKey)); }
880 INS_ASSERT_USER_ERROR(colIndices == consecutiveCols, "The given colKeys must describe a consecutive part in the matrix.");
881#endif
882 }
883};
884
891template<typename Scalar, typename RowKeyType, typename ColKeyType, int Rows, int Cols>
892class KeyedMatrixBase : public KeyedMatrixRows<Scalar, RowKeyType, Rows, Cols>, public KeyedMatrixCols<Scalar, ColKeyType, Rows, Cols>
893{
894 public:
897 template<typename Derived>
898 explicit KeyedMatrixBase(const Eigen::MatrixBase<Derived>& matrix)
899 {
900 this->matrix = matrix;
901 }
906 template<typename Derived>
907 KeyedMatrixBase(const Eigen::MatrixBase<Derived>& matrix, const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys)
908 {
909 INS_ASSERT_USER_ERROR(std::unordered_set<RowKeyType>(rowKeys.begin(), rowKeys.end()).size() == rowKeys.size(), "Each row key must be unique");
910 INS_ASSERT_USER_ERROR(std::unordered_set<ColKeyType>(colKeys.begin(), colKeys.end()).size() == colKeys.size(), "Each col key must be unique");
911
912 INS_ASSERT_USER_ERROR(matrix.rows() == static_cast<Eigen::Index>(rowKeys.size()), "Number of matrix rows doesn't correspond to the amount of row keys");
913 INS_ASSERT_USER_ERROR(matrix.cols() == static_cast<Eigen::Index>(colKeys.size()), "Number of matrix cols doesn't correspond to the amount of col keys");
914
915 INS_ASSERT_USER_ERROR(Rows == Eigen::Dynamic || Rows == static_cast<int>(rowKeys.size()), "Number of matrix rows doesn't correspond to the static amount of row keys");
916 INS_ASSERT_USER_ERROR(Cols == Eigen::Dynamic || Cols == static_cast<int>(colKeys.size()), "Number of matrix cols doesn't correspond to the static amount of col keys");
917
918 for (size_t i = 0; i < rowKeys.size(); i++) { this->rowIndices.insert({ rowKeys.at(i), static_cast<Eigen::Index>(i) }); }
919 for (size_t i = 0; i < colKeys.size(); i++) { this->colIndices.insert({ colKeys.at(i), static_cast<Eigen::Index>(i) }); }
920
921 this->matrix = matrix;
922 this->rowKeysVector = rowKeys;
923 this->colKeysVector = colKeys;
924 this->colSlice.reserve(this->colKeysVector.size());
925 this->rowSlice.reserve(this->rowKeysVector.size());
926 }
927
928 // #######################################################################################################
929 // Special member functions
930 // #######################################################################################################
931
933 ~KeyedMatrixBase() = default;
937 {
938 this->matrix = other.matrix;
939 this->rowIndices = other.rowIndices;
940 this->rowKeysVector = other.rowKeysVector;
941 this->colIndices = other.colIndices;
942 this->colKeysVector = other.colKeysVector;
943 this->colSlice.reserve(this->colKeysVector.size());
944 this->rowSlice.reserve(this->rowKeysVector.size());
945 }
949 {
950 if (this == &other) { return *this; } // Guard self assignment
951
952 this->matrix = other.matrix;
953 this->rowIndices = other.rowIndices;
954 this->rowKeysVector = other.rowKeysVector;
955 this->colIndices = other.colIndices;
956 this->colKeysVector = other.colKeysVector;
957 this->colSlice.reserve(this->colKeysVector.size());
958 this->rowSlice.reserve(this->rowKeysVector.size());
959
960 return *this;
961 }
965 {
966 this->matrix = std::move(other.matrix);
967 this->rowIndices = std::move(other.rowIndices);
968 this->rowKeysVector = std::move(other.rowKeysVector);
969 this->colIndices = std::move(other.colIndices);
970 this->colKeysVector = std::move(other.colKeysVector);
971 this->colSlice.reserve(this->colKeysVector.size());
972 this->rowSlice.reserve(this->rowKeysVector.size());
973 }
977 {
978 if (this == &other) { return *this; } // Guard self assignment
979
980 this->matrix = std::move(other.matrix);
981 this->rowIndices = std::move(other.rowIndices);
982 this->rowKeysVector = std::move(other.rowKeysVector);
983 this->colIndices = std::move(other.colIndices);
984 this->colKeysVector = std::move(other.colKeysVector);
985 this->colSlice.reserve(this->colKeysVector.size());
986 this->rowSlice.reserve(this->rowKeysVector.size());
987
988 return *this;
989 }
990
991 // ###########################################################################################################
992 // Special member functions with different Rows/Cols
993 // ###########################################################################################################
994
997 template<int oRows, int oCols>
998 KeyedMatrixBase(const KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, oRows, oCols>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
999 {
1000 INS_ASSERT_USER_ERROR(Rows == Eigen::Dynamic || other.rows() == Rows, "Can only copy construct dynamic<=>static matrices if the rows match");
1001 INS_ASSERT_USER_ERROR(Cols == Eigen::Dynamic || other.cols() == Cols, "Can only copy construct dynamic<=>static matrices if the cols match");
1002
1003 this->matrix = other.matrix;
1004 this->rowIndices = other.rowIndices;
1005 this->rowKeysVector = other.rowKeysVector;
1006 this->colIndices = other.colIndices;
1007 this->colKeysVector = other.colKeysVector;
1008 this->colSlice.reserve(this->colKeysVector.size());
1009 this->rowSlice.reserve(this->rowKeysVector.size());
1010 }
1013 template<int oRows, int oCols>
1015 {
1016 // No need to guard self assignment, as the types are different, so it cannot be the same object
1017
1018 INS_ASSERT_USER_ERROR(other.rowKeys() == this->rowKeys(), "Can only copy assign matrices if the row keys match");
1019 INS_ASSERT_USER_ERROR(other.colKeys() == this->colKeys(), "Can only copy assign matrices if the col keys match");
1020
1021 this->matrix = other.matrix;
1022 this->rowIndices = other.rowIndices;
1023 this->rowKeysVector = other.rowKeysVector;
1024 this->colIndices = other.colIndices;
1025 this->colKeysVector = other.colKeysVector;
1026 this->colSlice.reserve(this->colKeysVector.size());
1027 this->rowSlice.reserve(this->rowKeysVector.size());
1028
1029 return *this;
1030 }
1033 template<int oRows, int oCols>
1034 KeyedMatrixBase(KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, oRows, oCols>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1035 {
1036 INS_ASSERT_USER_ERROR(Rows == Eigen::Dynamic || other.rows() == Rows, "Can only copy construct dynamic<=>static matrices if the rows match");
1037 INS_ASSERT_USER_ERROR(Cols == Eigen::Dynamic || other.cols() == Cols, "Can only copy construct dynamic<=>static matrices if the cols match");
1038
1039 this->matrix = std::move(other.matrix);
1040 this->rowIndices = std::move(other.rowIndices);
1041 this->rowKeysVector = std::move(other.rowKeysVector);
1042 this->colIndices = std::move(other.colIndices);
1043 this->colKeysVector = std::move(other.colKeysVector);
1044 this->colSlice.reserve(this->colKeysVector.size());
1045 this->rowSlice.reserve(this->rowKeysVector.size());
1046 }
1049 template<int oRows, int oCols>
1051 {
1052 // No need to guard self assignment, as the types are different, so it cannot be the same object
1053
1054 INS_ASSERT_USER_ERROR(other.rowKeys() == this->rowKeys(), "Can only copy assign matrices if the row keys match");
1055 INS_ASSERT_USER_ERROR(other.colKeys() == this->colKeys(), "Can only copy assign matrices if the col keys match");
1056
1057 this->matrix = std::move(other.matrix);
1058 this->rowIndices = std::move(other.rowIndices);
1059 this->rowKeysVector = std::move(other.rowKeysVector);
1060 this->colIndices = std::move(other.colIndices);
1061 this->colKeysVector = std::move(other.colKeysVector);
1062 this->colSlice.reserve(this->colKeysVector.size());
1063 this->rowSlice.reserve(this->rowKeysVector.size());
1064
1065 return *this;
1066 }
1067
1068 // #######################################################################################################
1069 // Access
1070 // #######################################################################################################
1071
1076 const Scalar& operator()(const RowKeyType& rowKey, const ColKeyType& colKey) const
1077 {
1078 return this->matrix(this->rowIndices.at(rowKey), this->colIndices.at(colKey));
1079 }
1084 Scalar& operator()(const RowKeyType& rowKey, const ColKeyType& colKey)
1085 {
1086 return this->matrix(this->rowIndices.at(rowKey), this->colIndices.at(colKey));
1087 }
1088
1093 decltype(auto) operator()(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) const
1094 {
1095 this->rowSlice.clear();
1096 for (const auto& rowKey : rowKeys) { this->rowSlice.push_back(this->rowIndices.at(rowKey)); }
1097
1098 this->colSlice.clear();
1099 for (const auto& colKey : colKeys) { this->colSlice.push_back(this->colIndices.at(colKey)); }
1100
1101 return this->matrix(this->rowSlice, this->colSlice);
1102 }
1107 decltype(auto) operator()(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys)
1108 {
1109 this->rowSlice.clear();
1110 for (const auto& rowKey : rowKeys) { this->rowSlice.push_back(this->rowIndices.at(rowKey)); }
1111
1112 this->colSlice.clear();
1113 for (const auto& colKey : colKeys) { this->colSlice.push_back(this->colIndices.at(colKey)); }
1114
1115 return this->matrix(this->rowSlice, this->colSlice);
1116 }
1121 decltype(auto) operator()(const std::vector<RowKeyType>& rowKeys, const ColKeyType& colKey) const { return (*this)(rowKeys, std::vector{ colKey }); }
1126 decltype(auto) operator()(const std::vector<RowKeyType>& rowKeys, const ColKeyType& colKey) { return (*this)(rowKeys, std::vector{ colKey }); }
1131 decltype(auto) operator()(const RowKeyType& rowKey, const std::vector<ColKeyType>& colKeys) const { return (*this)(std::vector{ rowKey }, colKeys); }
1136 decltype(auto) operator()(const RowKeyType& rowKey, const std::vector<ColKeyType>& colKeys) { return (*this)(std::vector{ rowKey }, colKeys); }
1137
1141 decltype(auto) operator()(const RowKeyType& rowKey, all_t /* all */) const { return (*this)(std::vector{ rowKey }, this->colKeys()); }
1145 decltype(auto) operator()(const RowKeyType& rowKey, all_t /* all */) { return (*this)(std::vector{ rowKey }, this->colKeys()); }
1149 decltype(auto) operator()(all_t /* all */, const ColKeyType& colKey) const { return *this(this->rowKeys(), std::vector{ colKey }); }
1153 decltype(auto) operator()(all_t /* all */, const ColKeyType& colKey) { return (*this)(this->rowKeys(), std::vector{ colKey }); }
1157 decltype(auto) operator()(const std::vector<RowKeyType>& rowKeys, all_t /* all */) const { return (*this)(rowKeys, this->colKeys()); }
1161 decltype(auto) operator()(const std::vector<RowKeyType>& rowKeys, all_t /* all */) { return (*this)(rowKeys, this->colKeys()); }
1165 decltype(auto) operator()(all_t /* all */, const std::vector<ColKeyType>& colKeys) const { return (*this)(this->rowKeys(), colKeys); }
1169 decltype(auto) operator()(all_t /* all */, const std::vector<ColKeyType>& colKeys) { return (*this)(this->rowKeys(), colKeys); }
1170
1172 const Eigen::Matrix<Scalar, Rows, Cols>& operator()(all_t /* all */, all_t /* all */) const { return this->matrix; }
1174 Eigen::Matrix<Scalar, Rows, Cols>& operator()(all_t /* all */, all_t /* all */) { return this->matrix; }
1176 explicit operator Eigen::Matrix<Scalar, Rows, Cols>() { return this->matrix; }
1177
1178 // ###########################################################################################################
1179 // Static Block operations
1180 // ###########################################################################################################
1181
1186 template<size_t P, size_t Q = P>
1187 decltype(auto) block(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) const // NOLINT(readability-const-return-type)
1188 {
1189 checkContinuousBlock(rowKeys, colKeys, P, Q);
1190
1191 return this->matrix.template block<P, Q>(this->rowIndices.at(rowKeys.at(0)), this->colIndices.at(colKeys.at(0)));
1192 }
1197 template<size_t P, size_t Q = P>
1198 decltype(auto) block(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys)
1199 {
1200 checkContinuousBlock(rowKeys, colKeys, P, Q);
1201
1202 return this->matrix.template block<P, Q>(this->rowIndices.at(rowKeys.at(0)), this->colIndices.at(colKeys.at(0)));
1203 }
1208 template<size_t P>
1209 decltype(auto) block(const std::vector<RowKeyType>& rowKeys, const ColKeyType& colKey) const // NOLINT(readability-const-return-type)
1210 {
1211 return this->block<P, 1>(rowKeys, std::vector{ colKey });
1212 }
1217 template<size_t P>
1218 decltype(auto) block(const std::vector<RowKeyType>& rowKeys, const ColKeyType& colKey)
1219 {
1220 return this->block<P, 1>(rowKeys, std::vector{ colKey });
1221 }
1226 template<size_t Q>
1227 decltype(auto) block(const RowKeyType& rowKey, const std::vector<ColKeyType>& colKeys) const // NOLINT(readability-const-return-type)
1228 {
1229 return this->block<1, Q>(std::vector{ rowKey }, colKeys);
1230 }
1235 template<size_t Q>
1236 decltype(auto) block(const RowKeyType& rowKey, const std::vector<ColKeyType>& colKeys)
1237 {
1238 return this->block<1, Q>(std::vector{ rowKey }, colKeys);
1239 }
1240
1244 template<size_t P>
1245 decltype(auto) middleRows(const std::vector<RowKeyType>& rowKeys) const // NOLINT(readability-const-return-type)
1246 {
1247 checkContinuousBlock(rowKeys, this->colKeys(), P, this->colKeys().size());
1248
1249 return this->matrix.template middleRows<P>(this->rowIndices.at(rowKeys.at(0)));
1250 }
1254 template<size_t P>
1255 decltype(auto) middleRows(const std::vector<RowKeyType>& rowKeys)
1256 {
1257 checkContinuousBlock(rowKeys, this->colKeys(), P, this->colKeys().size());
1258
1259 return this->matrix.template middleRows<P>(this->rowIndices.at(rowKeys.at(0)));
1260 }
1264 template<size_t Q>
1265 decltype(auto) middleCols(const std::vector<ColKeyType>& colKeys) const // NOLINT(readability-const-return-type)
1266 {
1267 checkContinuousBlock(this->rowKeys(), colKeys, this->rowKeys().size(), Q);
1268
1269 return this->matrix.template middleCols<Q>(this->colIndices.at(colKeys.at(0)));
1270 }
1274 template<size_t Q>
1275 decltype(auto) middleCols(const std::vector<ColKeyType>& colKeys)
1276 {
1277 checkContinuousBlock(this->rowKeys(), colKeys, this->rowKeys().size(), Q);
1278
1279 return this->matrix.template middleCols<Q>(this->colIndices.at(colKeys.at(0)));
1280 }
1284 decltype(auto) row(const RowKeyType& rowKey) const { return this->matrix.row(this->rowIndices.at(rowKey)); }
1288 decltype(auto) row(const RowKeyType& rowKey) { return this->matrix.row(this->rowIndices.at(rowKey)); }
1292 decltype(auto) col(const ColKeyType& colKey) const { return this->matrix.col(this->colIndices.at(colKey)); }
1296 decltype(auto) col(const ColKeyType& colKey) { return this->matrix.col(this->colIndices.at(colKey)); }
1297
1299 const Eigen::Matrix<Scalar, Rows, Cols>& block(all_t /* all */, all_t /* all */) const { return this->matrix; }
1301 Eigen::Matrix<Scalar, Rows, Cols>& block(all_t /* all */, all_t /* all */) { return this->matrix; }
1302
1303 // ###########################################################################################################
1304 // Dynamic block operations
1305 // ###########################################################################################################
1306
1311 decltype(auto) block(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) const
1312 {
1313 checkContinuousBlock(rowKeys, colKeys, rowKeys.size(), colKeys.size());
1314
1315 return this->matrix.block(this->rowIndices.at(rowKeys.at(0)), this->colIndices.at(colKeys.at(0)), rowKeys.size(), colKeys.size());
1316 }
1321 decltype(auto) block(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys)
1322 {
1323 checkContinuousBlock(rowKeys, colKeys, rowKeys.size(), colKeys.size());
1324
1325 return this->matrix.block(this->rowIndices.at(rowKeys.at(0)), this->colIndices.at(colKeys.at(0)), rowKeys.size(), colKeys.size());
1326 }
1331 decltype(auto) block(const std::vector<RowKeyType>& rowKeys, const ColKeyType& colKey) const
1332 {
1333 return this->block(rowKeys, std::vector{ colKey });
1334 }
1339 decltype(auto) block(const std::vector<RowKeyType>& rowKeys, const ColKeyType& colKey)
1340 {
1341 return this->block(rowKeys, std::vector{ colKey });
1342 }
1347 decltype(auto) block(const RowKeyType& rowKey, const std::vector<ColKeyType>& colKeys) const
1348 {
1349 return this->block(std::vector{ rowKey }, colKeys);
1350 }
1355 decltype(auto) block(const RowKeyType& rowKey, const std::vector<ColKeyType>& colKeys)
1356 {
1357 return this->block(std::vector{ rowKey }, colKeys);
1358 }
1359
1363 decltype(auto) middleRows(const std::vector<RowKeyType>& rowKeys) const
1364 {
1365 checkContinuousBlock(rowKeys, this->colKeys(), rowKeys.size(), this->colKeys().size());
1366
1367 return this->matrix.middleRows(this->rowIndices.at(rowKeys.at(0)), rowKeys.size());
1368 }
1372 decltype(auto) middleRows(const std::vector<RowKeyType>& rowKeys)
1373 {
1374 checkContinuousBlock(rowKeys, this->colKeys(), rowKeys.size(), this->colKeys().size());
1375
1376 return this->matrix.middleRows(this->rowIndices.at(rowKeys.at(0)), rowKeys.size());
1377 }
1381 decltype(auto) middleCols(const std::vector<ColKeyType>& colKeys) const
1382 {
1383 checkContinuousBlock(this->rowKeys(), colKeys, this->rowKeys().size(), colKeys.size());
1384
1385 return this->matrix.middleCols(this->colIndices.at(colKeys.at(0)), colKeys.size());
1386 }
1390 decltype(auto) middleCols(const std::vector<ColKeyType>& colKeys)
1391 {
1392 checkContinuousBlock(this->rowKeys(), colKeys, this->rowKeys().size(), colKeys.size());
1393
1394 return this->matrix.middleCols(this->colIndices.at(colKeys.at(0)), colKeys.size());
1395 }
1396
1397 // #######################################################################################################
1398 // Methods
1399 // #######################################################################################################
1400
1403 {
1404 return { this->matrix.transpose(), this->colKeys(), this->rowKeys() };
1405 }
1406
1409 {
1410 return { this->matrix.inverse(), this->rowKeys(), this->colKeys() };
1411 }
1412
1413 private:
1419 void checkContinuousBlock([[maybe_unused]] const std::vector<RowKeyType>& rowKeys, [[maybe_unused]] const std::vector<ColKeyType>& colKeys,
1420 [[maybe_unused]] size_t P, [[maybe_unused]] size_t Q) const
1421 {
1422#ifndef NDEBUG
1423 INS_ASSERT_USER_ERROR(P == rowKeys.size(), "The block size must be equivalent to the amount of row keys.");
1424 INS_ASSERT_USER_ERROR(Q == colKeys.size(), "The block size must be equivalent to the amount of col keys.");
1425
1426 std::vector<Eigen::Index> consecutiveRows(rowKeys.size());
1427 std::iota(std::begin(consecutiveRows), std::end(consecutiveRows), this->rowIndices.at(rowKeys.at(0)));
1428 std::vector<Eigen::Index> rowIndices;
1429 rowIndices.reserve(rowKeys.size());
1430 for (const auto& rowKey : rowKeys) { rowIndices.push_back(this->rowIndices.at(rowKey)); }
1431 INS_ASSERT_USER_ERROR(rowIndices == consecutiveRows, "The given rowKeys must describe a consecutive part in the matrix.");
1432
1433 std::vector<Eigen::Index> consecutiveCols(colKeys.size());
1434 std::iota(std::begin(consecutiveCols), std::end(consecutiveCols), this->colIndices.at(colKeys.at(0)));
1435 std::vector<Eigen::Index> colIndices;
1436 colIndices.reserve(colKeys.size());
1437 for (const auto& colKey : colKeys) { colIndices.push_back(this->colIndices.at(colKey)); }
1438 INS_ASSERT_USER_ERROR(colIndices == consecutiveCols, "The given colKeys must describe a consecutive part in the matrix.");
1439#endif
1440 }
1441};
1442
1443} // namespace internal
1444
1447
1448template<typename Scalar, typename ColKeyType, int Cols>
1449class KeyedRowVector;
1450
1455template<typename Scalar, typename RowKeyType, int Rows>
1456class KeyedVector : public internal::KeyedVectorBase<Scalar, RowKeyType, Rows>
1457{
1458 public:
1463 template<typename Derived>
1464 KeyedVector(const Eigen::MatrixBase<Derived>& vector, const std::vector<RowKeyType>& rowKeys)
1465 : internal::KeyedVectorBase<Scalar, RowKeyType, Rows>(vector, rowKeys)
1466 {}
1467
1468 // #######################################################################################################
1469 // Special member functions
1470 // #######################################################################################################
1471
1473 ~KeyedVector() = default;
1477 : internal::KeyedVectorBase<Scalar, RowKeyType, Rows>(other)
1478 {}
1482 {
1483 if (this == &other) { return *this; } // Guard self assignment
1484
1486 static_cast<const internal::KeyedVectorBase<Scalar, RowKeyType, Rows>&>(other);
1487
1488 return *this;
1489 }
1492 KeyedVector(KeyedVector&& other) noexcept
1494 {}
1498 {
1499 if (this == &other) { return *this; } // Guard self assignment
1500
1502 std::move(static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, Rows>&>(other));
1503
1504 return *this;
1505 }
1506
1507 // ###########################################################################################################
1508 // Special member functions with different Rows/Cols
1509 // ###########################################################################################################
1510
1513 KeyedVector(const KeyedVector<Scalar, RowKeyType, Eigen::Dynamic>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1514 : internal::KeyedVectorBase<Scalar, RowKeyType, Rows>(other)
1515 {
1516 INS_ASSERT_USER_ERROR(other.rows() == Rows, "Can only copy assign dynamic matrices from static ones if the size matches");
1517 }
1521 {
1522 // No need to guard self assignment, as the types are different, so it cannot be the same object
1523
1524 INS_ASSERT_USER_ERROR(other.rows() == Rows, "Can only copy assign dynamic matrices from static ones if the size matches");
1525
1528
1529 return *this;
1530 }
1533 KeyedVector(KeyedVector<Scalar, RowKeyType, Eigen::Dynamic>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1535 {
1536 INS_ASSERT_USER_ERROR(this->rows() == Rows, "Can only move construct dynamic matrices from static ones if the size matches");
1537 }
1541 {
1542 // No need to guard self assignment, as the types are different, so it cannot be the same object
1543
1544 INS_ASSERT_USER_ERROR(other.rows() == Rows, "Can only move assign dynamic matrices from static ones if the size matches");
1545
1548
1549 return *this;
1550 }
1551
1552 // #######################################################################################################
1553 // Methods
1554 // #######################################################################################################
1555
1558 {
1559 auto transpose = static_cast<const internal::KeyedVectorBase<Scalar, RowKeyType, Rows>&>(*this).transposed();
1560 return { transpose(all), transpose.colKeys() };
1561 }
1562};
1563
1567template<typename Scalar, typename RowKeyType>
1568class KeyedVector<Scalar, RowKeyType, Eigen::Dynamic> : public internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>
1569{
1570 public:
1573 : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(Eigen::VectorX<Scalar>()) {}
1574
1579 template<typename Derived>
1580 KeyedVector(const Eigen::MatrixBase<Derived>& vector, const std::vector<RowKeyType>& rowKeys)
1581 : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(vector, rowKeys)
1582 {}
1583
1584 // #######################################################################################################
1585 // Special member functions
1586 // #######################################################################################################
1587
1589 ~KeyedVector() = default;
1593 : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(other)
1594 {}
1598 {
1599 if (this == &other) { return *this; } // Guard self assignment
1600
1603
1604 return *this;
1605 }
1614 {
1615 if (this == &other) { return *this; } // Guard self assignment
1616
1619
1620 return *this;
1621 }
1622
1623 // ###########################################################################################################
1624 // Special member functions with different Rows/Cols
1625 // ###########################################################################################################
1626
1629 template<int oRows>
1630 KeyedVector(const KeyedVector<Scalar, RowKeyType, oRows>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1631 : internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>(other)
1632 {}
1635 template<int oRows>
1637 {
1638 // No need to guard self assignment, as the types are different, so it cannot be the same object
1639
1642
1643 return *this;
1644 }
1647 template<int oRows>
1648 KeyedVector(KeyedVector<Scalar, RowKeyType, oRows>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1650 {}
1653 template<int oRows>
1655 {
1656 // No need to guard self assignment, as the types are different, so it cannot be the same object
1657
1659 std::move(static_cast<internal::KeyedVectorBase<Scalar, RowKeyType, oRows>&>(other));
1660
1661 return *this;
1662 }
1663
1664 // #######################################################################################################
1665 // Methods
1666 // #######################################################################################################
1667
1670 {
1671 auto transpose = static_cast<const internal::KeyedVectorBase<Scalar, RowKeyType, Eigen::Dynamic>&>(*this).transposed();
1672 return { transpose(all), transpose.colKeys() };
1673 }
1674};
1675
1680template<typename Scalar, typename ColKeyType, int Cols>
1681class KeyedRowVector : public internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>
1682{
1683 public:
1688 template<typename Derived>
1689 KeyedRowVector(const Eigen::MatrixBase<Derived>& vector, const std::vector<ColKeyType>& colKeys)
1690 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>(vector, colKeys)
1691 {}
1692
1693 // #######################################################################################################
1694 // Special member functions
1695 // #######################################################################################################
1696
1698 ~KeyedRowVector() = default;
1702 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>(other)
1703 {}
1707 {
1708 if (this == &other) { return *this; } // Guard self assignment
1709
1712
1713 return *this;
1714 }
1723 {
1724 if (this == &other) { return *this; } // Guard self assignment
1725
1727 std::move(static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>&>(other));
1728
1729 return *this;
1730 }
1731
1732 // ###########################################################################################################
1733 // Special member functions with different Cols
1734 // ###########################################################################################################
1735
1738 KeyedRowVector(const KeyedRowVector<Scalar, ColKeyType, Eigen::Dynamic>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1739 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>(other)
1740 {
1741 INS_ASSERT_USER_ERROR(other.cols() == Cols, "Can only copy assign dynamic matrices from static ones if the size matches");
1742 }
1746 {
1747 // No need to guard self assignment, as the types are different, so it cannot be the same object
1748
1749 INS_ASSERT_USER_ERROR(other.cols() == Cols, "Can only copy assign dynamic matrices from static ones if the size matches");
1750
1753
1754 return *this;
1755 }
1758 KeyedRowVector(KeyedRowVector<Scalar, ColKeyType, Eigen::Dynamic>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1760 {
1761 INS_ASSERT_USER_ERROR(this->cols() == Cols, "Can only move construct dynamic matrices from static ones if the size matches");
1762 }
1766 {
1767 // No need to guard self assignment, as the types are different, so it cannot be the same object
1768
1769 INS_ASSERT_USER_ERROR(other.cols() == Cols, "Can only move assign dynamic matrices from static ones if the size matches");
1770
1773
1774 return *this;
1775 }
1776
1777 // #######################################################################################################
1778 // Methods
1779 // #######################################################################################################
1780
1783 {
1784 auto transpose = static_cast<const internal::KeyedRowVectorBase<Scalar, ColKeyType, Cols>&>(*this).transposed();
1785 return { transpose(all), transpose.rowKeys() };
1786 }
1787};
1788
1792template<typename Scalar, typename ColKeyType>
1793class KeyedRowVector<Scalar, ColKeyType, Eigen::Dynamic>
1794 : public internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>
1795{
1796 public:
1799 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(Eigen::RowVectorX<Scalar>()) {}
1800
1805 template<typename Derived>
1806 KeyedRowVector(const Eigen::MatrixBase<Derived>& vector, const std::vector<ColKeyType>& colKeys)
1807 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(vector, colKeys)
1808 {}
1809
1810 // #######################################################################################################
1811 // Special member functions
1812 // #######################################################################################################
1813
1815 ~KeyedRowVector() = default;
1819 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(other)
1820 {}
1824 {
1825 if (this == &other) { return *this; } // Guard self assignment
1826
1829
1830 return *this;
1831 }
1840 {
1841 if (this == &other) { return *this; } // Guard self assignment
1842
1845
1846 return *this;
1847 }
1848
1849 // ###########################################################################################################
1850 // Special member functions with different Cols
1851 // ###########################################################################################################
1852
1855 template<int oCols>
1856 KeyedRowVector(const KeyedRowVector<Scalar, ColKeyType, oCols>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1857 : internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>(other)
1858 {}
1861 template<int oCols>
1863 {
1864 // No need to guard self assignment, as the types are different, so it cannot be the same object
1865
1868
1869 return *this;
1870 }
1873 template<int oCols>
1874 KeyedRowVector(KeyedRowVector<Scalar, ColKeyType, oCols>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1876 {}
1879 template<int oCols>
1881 {
1882 // No need to guard self assignment, as the types are different, so it cannot be the same object
1883
1885 std::move(static_cast<internal::KeyedRowVectorBase<Scalar, ColKeyType, oCols>&>(other));
1886
1887 return *this;
1888 }
1889
1890 // #######################################################################################################
1891 // Methods
1892 // #######################################################################################################
1893
1896 {
1897 auto transpose = static_cast<const internal::KeyedRowVectorBase<Scalar, ColKeyType, Eigen::Dynamic>&>(*this).transposed();
1898 return { transpose(all), transpose.rowKeys() };
1899 }
1900};
1901
1908template<typename Scalar, typename RowKeyType, typename ColKeyType, int Rows, int Cols>
1909class KeyedMatrix : public internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>
1910{
1911 public:
1917 template<typename Derived>
1918 KeyedMatrix(const Eigen::MatrixBase<Derived>& matrix, const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys)
1919 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>(matrix, rowKeys, colKeys)
1920 {}
1921
1926 template<typename Derived>
1927 KeyedMatrix(const Eigen::MatrixBase<Derived>& matrix, const std::vector<RowKeyType>& keys)
1928 : KeyedMatrix<Scalar, RowKeyType, ColKeyType, Rows, Cols>(matrix, keys, keys)
1929 {}
1930
1931 // #######################################################################################################
1932 // Special member functions
1933 // #######################################################################################################
1934
1936 ~KeyedMatrix() = default;
1940 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>(other)
1941 {}
1945 {
1946 if (this == &other) { return *this; } // Guard self assignment
1947
1950
1951 return *this;
1952 }
1961 {
1962 if (this == &other) { return *this; } // Guard self assignment
1963
1966
1967 return *this;
1968 }
1969
1970 // ###########################################################################################################
1971 // Special member functions with different Rows/Cols
1972 // ###########################################################################################################
1973
1976 KeyedMatrix(const KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1977 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>(other)
1978 {
1979 INS_ASSERT_USER_ERROR(other.rows() == Rows && other.cols() == Cols, "Can only copy assign dynamic matrices from static ones if the size matches");
1980 }
1984 {
1985 // No need to guard self assignment, as the types are different, so it cannot be the same object
1986
1987 INS_ASSERT_USER_ERROR(other.rows() == Rows && other.cols() == Cols, "Can only copy assign dynamic matrices from static ones if the size matches");
1988
1991
1992 return *this;
1993 }
1996 KeyedMatrix(KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
1998 {
1999 INS_ASSERT_USER_ERROR(this->rows() == Rows && this->cols() == Cols, "Can only move construct dynamic matrices from static ones if the size matches");
2000 }
2004 {
2005 // No need to guard self assignment, as the types are different, so it cannot be the same object
2006
2007 INS_ASSERT_USER_ERROR(other.rows() == Rows && other.cols() == Cols, "Can only move assign dynamic matrices from static ones if the size matches");
2008
2011
2012 return *this;
2013 }
2014
2015 // #######################################################################################################
2016 // Methods
2017 // #######################################################################################################
2018
2023 getSubMatrix(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) const
2024 {
2025 if (rowKeys == this->rowKeysVector && colKeys == this->colKeysVector)
2026 {
2027 return *this;
2028 }
2029
2030 return { (*this)(rowKeys, colKeys), rowKeys, colKeys };
2031 }
2032
2035 {
2036 auto transpose = static_cast<const internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Rows, Cols>&>(*this).transposed();
2037 return { transpose(all, all), transpose.rowKeys(), transpose.colKeys() };
2038 }
2039
2042 {
2044 return { inv(all, all), inv.rowKeys(), inv.colKeys() };
2045 }
2046};
2047
2052template<typename Scalar, typename RowKeyType, typename ColKeyType>
2053class KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>
2054 : public internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>
2055{
2056 public:
2059 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(Eigen::MatrixX<Scalar>()) {}
2060
2066 template<typename Derived>
2067 KeyedMatrix(const Eigen::MatrixBase<Derived>& matrix, const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys)
2068 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(matrix, rowKeys, colKeys)
2069 {}
2070
2075 template<typename Derived>
2076 KeyedMatrix(const Eigen::MatrixBase<Derived>& matrix, const std::vector<RowKeyType>& keys)
2077 : KeyedMatrix<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(matrix, keys, keys)
2078 {}
2079
2080 // #######################################################################################################
2081 // Special member functions
2082 // #######################################################################################################
2083
2085 ~KeyedMatrix() = default;
2089 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(other)
2090 {}
2094 {
2095 if (this == &other) { return *this; } // Guard self assignment
2096
2099
2100 return *this;
2101 }
2110 {
2111 if (this == &other) { return *this; } // Guard self assignment
2112
2115
2116 return *this;
2117 }
2118
2119 // ###########################################################################################################
2120 // Special member functions with different Rows/Cols
2121 // ###########################################################################################################
2122
2125 template<int oRows, int oCols>
2126 KeyedMatrix(const KeyedMatrix<Scalar, RowKeyType, ColKeyType, oRows, oCols>& other) // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
2127 : internal::KeyedMatrixBase<Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic>(other)
2128 {}
2131 template<int oRows, int oCols>
2133 {
2134 // No need to guard self assignment, as the types are different, so it cannot be the same object
2135
2138
2139 return *this;
2140 }
2143 template<int oRows, int oCols>
2144 KeyedMatrix(KeyedMatrix<Scalar, RowKeyType, ColKeyType, oRows, oCols>&& other) noexcept // NOLINT(google-explicit-constructor,hicpp-explicit-conversions)
2146 {}
2149 template<int oRows, int oCols>
2151 {
2152 // No need to guard self assignment, as the types are different, so it cannot be the same object
2153
2156
2157 return *this;
2158 }
2159
2160 // #######################################################################################################
2161 // Modifying methods
2162 // #######################################################################################################
2163
2167 void addRowsCols(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys)
2168 {
2169 INS_ASSERT_USER_ERROR(!this->hasAnyRows(rowKeys), "You cannot add a row key which is already in the matrix.");
2170 INS_ASSERT_USER_ERROR(!this->hasAnyCols(colKeys), "You cannot add a col key which is already in the matrix.");
2171 INS_ASSERT_USER_ERROR(std::unordered_set<RowKeyType>(rowKeys.begin(), rowKeys.end()).size() == rowKeys.size(), "Each row key must be unique");
2172 INS_ASSERT_USER_ERROR(std::unordered_set<ColKeyType>(colKeys.begin(), colKeys.end()).size() == colKeys.size(), "Each col key must be unique");
2173
2174 auto initialRowSize = static_cast<Eigen::Index>(this->rowIndices.size());
2175 for (const auto& rowKey : rowKeys) { this->rowIndices.insert({ rowKey, static_cast<Eigen::Index>(this->rowIndices.size()) }); }
2176 this->rowKeysVector.reserve(this->rowKeysVector.size() + rowKeys.size());
2177 std::copy(rowKeys.begin(), rowKeys.end(), std::back_inserter(this->rowKeysVector));
2178 auto finalRowSize = static_cast<Eigen::Index>(this->rowIndices.size());
2179
2180 auto initialColSize = static_cast<Eigen::Index>(this->colIndices.size());
2181 for (const auto& colKey : colKeys) { this->colIndices.insert({ colKey, static_cast<Eigen::Index>(this->colIndices.size()) }); }
2182 this->colKeysVector.reserve(this->colKeysVector.size() + colKeys.size());
2183 std::copy(colKeys.begin(), colKeys.end(), std::back_inserter(this->colKeysVector));
2184 auto finalColSize = static_cast<Eigen::Index>(this->colIndices.size());
2185
2186 auto rows = finalRowSize - initialRowSize;
2187 auto cols = finalColSize - initialColSize;
2188 if (rows > 0 || cols > 0)
2189 {
2190 this->matrix.conservativeResize(finalRowSize, finalColSize);
2191 this->matrix.block(initialRowSize, 0, rows, this->matrix.cols()) = Eigen::MatrixX<Scalar>::Zero(rows, this->matrix.cols());
2192 this->matrix.block(0, initialColSize, this->matrix.rows(), cols) = Eigen::MatrixX<Scalar>::Zero(this->matrix.rows(), cols);
2193 }
2194 this->colSlice.reserve(this->colKeysVector.size());
2195 this->rowSlice.reserve(this->rowKeysVector.size());
2196 }
2197
2201 void removeRowsCols(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys)
2202 {
2203 std::vector<int> rowIndices;
2204 for (const auto& rowKey : rowKeys)
2205 {
2206 auto iter = std::find_if(this->rowIndices.begin(), this->rowIndices.end(), [&](const auto& item) { return item.first == rowKey; });
2207 INS_ASSERT_USER_ERROR(iter != this->rowIndices.end(), "You tried removing a row key, which did not exist.");
2208 if (iter != this->rowIndices.end())
2209 {
2210 rowIndices.push_back(static_cast<int>(iter->second));
2211 }
2212 }
2213 std::vector<int> colIndices;
2214 for (const auto& colKey : colKeys)
2215 {
2216 auto iter = std::find_if(this->colIndices.begin(), this->colIndices.end(), [&](const auto& item) { return item.first == colKey; });
2217 INS_ASSERT_USER_ERROR(iter != this->colIndices.end(), "You tried removing a col key, which did not exist.");
2218 if (iter != this->colIndices.end())
2219 {
2220 colIndices.push_back(static_cast<int>(iter->second));
2221 }
2222 }
2223
2224 NAV::removeRowsAndCols(this->matrix, rowIndices, colIndices);
2225
2226 for (const auto& rowKey : rowKeys)
2227 {
2228 auto iter = std::find_if(this->rowIndices.begin(), this->rowIndices.end(), [&](const auto& item) { return item.first == rowKey; });
2229 if (iter != this->rowIndices.end())
2230 {
2231 std::erase_if(this->rowKeysVector, [&](const auto& item) { return item == rowKey; });
2232
2233 auto idx = iter->second;
2234 for (auto& rowIndex : this->rowIndices)
2235 {
2236 if (rowIndex.second > idx) { rowIndex.second--; }
2237 }
2238 this->rowIndices.erase(iter);
2239 }
2240 }
2241 for (const auto& colKey : colKeys)
2242 {
2243 auto iter = std::find_if(this->colIndices.begin(), this->colIndices.end(), [&](const auto& item) { return item.first == colKey; });
2244 if (iter != this->colIndices.end())
2245 {
2246 std::erase_if(this->colKeysVector, [&](const auto& item) { return item == colKey; });
2247
2248 auto idx = iter->second;
2249 for (auto& colIndex : this->colIndices)
2250 {
2251 if (colIndex.second > idx) { colIndex.second--; }
2252 }
2253 this->colIndices.erase(iter);
2254 }
2255 }
2256 }
2257
2258 // #######################################################################################################
2259 // Methods
2260 // #######################################################################################################
2261
2266 getSubMatrix(const std::vector<RowKeyType>& rowKeys, const std::vector<ColKeyType>& colKeys) const
2267 {
2268 if (rowKeys == this->rowKeysVector && colKeys == this->colKeysVector)
2269 {
2270 return *this;
2271 }
2272
2273 return { (*this)(rowKeys, colKeys), rowKeys, colKeys };
2274 }
2275
2278 {
2280 return { transpose(all, all), transpose.rowKeys(), transpose.colKeys() };
2281 }
2282
2285 {
2287 return { inv(all, all), inv.rowKeys(), inv.colKeys() };
2288 }
2289};
2290
2295template<typename Scalar, typename RowKeyType, typename ColKeyType = RowKeyType>
2300template<typename RowKeyType, typename ColKeyType = RowKeyType>
2305template<typename RowKeyType, typename ColKeyType = RowKeyType>
2310template<typename RowKeyType, typename ColKeyType = RowKeyType>
2315template<typename RowKeyType, typename ColKeyType = RowKeyType>
2317
2321template<typename Scalar, typename RowKeyType>
2325template<typename RowKeyType>
2329template<typename RowKeyType>
2333template<typename RowKeyType>
2337template<typename RowKeyType>
2339
2342template<typename Scalar, typename ColKeyType>
2346template<typename ColKeyType>
2350template<typename ColKeyType>
2354template<typename ColKeyType>
2358template<typename ColKeyType>
2360
2361} // namespace NAV
2362
2363#pragma GCC diagnostic pop
2364
2365#ifndef DOXYGEN_IGNORE
2366
2368template<typename Scalar, typename RowKeyType, typename ColKeyType, int Rows, int Cols>
2369struct fmt::formatter<NAV::KeyedMatrix<Scalar, RowKeyType, ColKeyType, Rows, Cols>> : fmt::formatter<std::string>
2370{
2375 auto format(const NAV::KeyedMatrix<Scalar, RowKeyType, ColKeyType, Rows, Cols>& mat, format_context& ctx)
2376 {
2377 std::string result;
2378 auto rows = static_cast<size_t>(mat.rows());
2379 auto cols = static_cast<size_t>(mat.cols());
2380
2381 if (rows > 0 && cols > 0)
2382 {
2383 std::vector<std::string> rowKeysStr;
2384 std::vector<size_t> rowKeysLength;
2385 rowKeysStr.reserve(rows);
2386 rowKeysLength.reserve(rows);
2387 size_t rowKeysColSpace = 0;
2388 for (const auto& rowKey : mat.rowKeys())
2389 {
2390 rowKeysStr.push_back(fmt::format("{}", rowKey));
2391 auto rowKeyLength = rowKeysStr.back().length();
2392 rowKeysColSpace = std::max(rowKeysColSpace, rowKeyLength);
2393 rowKeysLength.push_back(rowKeyLength);
2394 }
2395
2396 constexpr size_t colMinLength = 9UL;
2397
2398 std::vector<std::string> colKeysStr;
2399 std::vector<size_t> colKeysLength;
2400 size_t rowLineLength = rowKeysColSpace + 1; // '\n' at the end of line
2401 colKeysStr.reserve(cols);
2402 colKeysLength.reserve(cols);
2403 for (const auto& colKey : mat.colKeys())
2404 {
2405 colKeysStr.push_back(fmt::format("{}", colKey));
2406 auto colKeyLength = colKeysStr.back().length();
2407 colKeysLength.push_back(colKeyLength);
2408 rowLineLength += 2 + std::max(colKeysStr.back().length(), colMinLength); // 2 spaces before each column
2409 }
2410
2411 result.reserve((rows + 1) * rowLineLength);
2412 // ---------------------------------------- Column keys ------------------------------------------
2413 result += " " + std::string(rowKeysColSpace, ' ');
2414 for (size_t c = 0; c < cols; c++)
2415 {
2416 result += " ";
2417 if (colMinLength > colKeysLength.at(c))
2418 {
2419 result += std::string(colMinLength - colKeysLength.at(c), ' '); // Spaces in front of column name (if too short)
2420 }
2421 result += colKeysStr.at(c);
2422 }
2423 result += '\n';
2424 // ------------------------------------------- Rows ----------------------------------------------
2425 for (size_t r = 0; r < rows; r++)
2426 {
2427 if (rowKeysColSpace > rowKeysLength.at(r))
2428 {
2429 result += std::string(rowKeysColSpace - rowKeysLength.at(r), ' '); // Spaces in front of row name (if too short)
2430 }
2431 result += rowKeysStr.at(r) + " ";
2432 for (size_t c = 0; c < cols; c++)
2433 {
2434 auto colLength = std::max(colKeysStr.at(c).length(), colMinLength);
2435
2436 std::string tmp = fmt::format(" {:> {}.{}g}", mat(NAV::all, NAV::all)(static_cast<int>(r), static_cast<int>(c)), colLength, colLength - 2);
2437 if (tmp.length() > colLength)
2438 {
2439 tmp = fmt::format(" {:> {}.{}g}", mat(NAV::all, NAV::all)(static_cast<int>(r), static_cast<int>(c)), colLength, colLength - 6);
2440 }
2441 result += tmp;
2442 }
2443 if (r != rows - 1) { result += '\n'; }
2444 }
2445 }
2446
2447 return fmt::formatter<std::string>::format(result, ctx);
2448 }
2449};
2450
2452template<typename Scalar, typename RowKeyType, int Rows>
2453struct fmt::formatter<NAV::KeyedVector<Scalar, RowKeyType, Rows>> : fmt::formatter<std::string>
2454{
2459 auto format(const NAV::KeyedVector<Scalar, RowKeyType, Rows>& vec, format_context& ctx)
2460 {
2461 std::string result;
2462 auto rows = static_cast<size_t>(vec.rows());
2463
2464 if (rows > 0)
2465 {
2466 std::vector<std::string> rowKeysStr;
2467 std::vector<size_t> rowKeysLength;
2468 rowKeysStr.reserve(rows);
2469 rowKeysLength.reserve(rows);
2470 size_t rowKeysColSpace = 0;
2471 for (const auto& rowKey : vec.rowKeys())
2472 {
2473 rowKeysStr.push_back(fmt::format("{}", rowKey));
2474 auto rowKeyLength = rowKeysStr.back().length();
2475 rowKeysColSpace = std::max(rowKeysColSpace, rowKeyLength);
2476 rowKeysLength.push_back(rowKeyLength);
2477 }
2478
2479 size_t colLength = 9UL;
2480
2481 result.reserve(rows * (rowKeysColSpace + 2 + colLength));
2482 // ------------------------------------------- Rows ----------------------------------------------
2483 for (size_t r = 0; r < rows; r++)
2484 {
2485 if (rowKeysColSpace > rowKeysLength.at(r))
2486 {
2487 result += std::string(rowKeysColSpace - rowKeysLength.at(r), ' '); // Spaces in front of row name (if too short)
2488 }
2489 result += rowKeysStr.at(r);
2490
2491 std::string tmp = fmt::format(" {:> {}.{}g}", vec(NAV::all)(static_cast<int>(r)), colLength, colLength - 2);
2492 if (tmp.length() > colLength)
2493 {
2494 tmp = fmt::format(" {:> {}.{}g}", vec(NAV::all)(static_cast<int>(r)), colLength, colLength - 6);
2495 }
2496 result += tmp;
2497
2498 if (r != rows - 1) { result += '\n'; }
2499 }
2500 }
2501
2502 return fmt::formatter<std::string>::format(result, ctx);
2503 }
2504};
2505
2507template<typename Scalar, typename ColKeyType, int Cols>
2508struct fmt::formatter<NAV::KeyedRowVector<Scalar, ColKeyType, Cols>> : fmt::formatter<std::string>
2509{
2514 auto format(const NAV::KeyedRowVector<Scalar, ColKeyType, Cols>& vec, format_context& ctx)
2515 {
2516 std::string result;
2517 auto cols = static_cast<size_t>(vec.cols());
2518
2519 if (cols > 0)
2520 {
2521 size_t colMinLength = 9UL;
2522
2523 std::vector<std::string> colKeysStr;
2524 std::vector<size_t> colKeysLength;
2525 size_t rowLineLength = 1; // '\n' at the end of line
2526 colKeysStr.reserve(cols);
2527 colKeysLength.reserve(cols);
2528 for (const auto& colKey : vec.colKeys())
2529 {
2530 colKeysStr.push_back(fmt::format("{}", colKey));
2531 auto colKeyLength = colKeysStr.back().length();
2532 colKeysLength.push_back(colKeyLength);
2533 rowLineLength += 2 + std::max(colKeysStr.back().length(), colMinLength); // 2 spaces before each column
2534 }
2535
2536 result.reserve(2 * rowLineLength);
2537 // ---------------------------------------- Column keys ------------------------------------------
2538 for (size_t c = 0; c < cols; c++)
2539 {
2540 if (c != 0) { result += " "; }
2541 if (colMinLength > colKeysLength.at(c))
2542 {
2543 result += std::string(colMinLength - colKeysLength.at(c), ' '); // Spaces in front of column name (if too short)
2544 }
2545 result += colKeysStr.at(c);
2546 }
2547 result += '\n';
2548 // ------------------------------------------ Values ---------------------------------------------
2549
2550 for (size_t c = 0; c < cols; c++)
2551 {
2552 auto colLength = std::max(colKeysStr.at(c).length(), colMinLength);
2553 if (c != 0) { result += " "; }
2554 std::string tmp = fmt::format("{:> {}.{}g}", vec(NAV::all)(static_cast<int>(c)), colLength, colLength - 2);
2555 if (tmp.length() > colLength)
2556 {
2557 tmp = fmt::format("{:> {}.{}g}", vec(NAV::all)(static_cast<int>(c)), colLength, colLength - 6);
2558 }
2559 result += tmp;
2560 }
2561 }
2562
2563 return fmt::formatter<std::string>::format(result, ctx);
2564 }
2565};
2566
2567#endif
2568
2573template<typename Scalar, typename RowKeyType, typename ColKeyType, int Rows, int Cols>
2575{
2576 return os << fmt::format("{}", obj);
2577}
2582template<typename Scalar, typename RowKeyType, int Rows>
2583std::ostream& operator<<(std::ostream& os, const NAV::KeyedVector<Scalar, RowKeyType, Rows>& obj)
2584{
2585 return os << fmt::format("{}", obj);
2586}
2591template<typename Scalar, typename ColKeyType, int Cols>
2592std::ostream& operator<<(std::ostream& os, const NAV::KeyedRowVector<Scalar, ColKeyType, Cols>& obj)
2593{
2594 return os << fmt::format("{}", obj);
2595}
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:116
void removeCols(Eigen::DenseBase< Derived > &matrix, size_t index, size_t length)
Removes columns from a matrix or vector.
Definition Eigen.hpp:152
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:190
Unordered map wrapper.
ankerl::unordered_dense::map< Key, T > unordered_map
Unordered map type.
Definition Unordered_map.hpp:34
Dynamic sized KeyedMatrix.
Definition KeyedMatrix.hpp:2055
KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > transposed() const
Calculates the transposed matrix.
Definition KeyedMatrix.hpp:2277
KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > getSubMatrix(const std::vector< RowKeyType > &rowKeys, const std::vector< ColKeyType > &colKeys) const
Returns a submatrix specified by the row and col keys.
Definition KeyedMatrix.hpp:2266
KeyedMatrix(const Eigen::MatrixBase< Derived > &matrix, const std::vector< RowKeyType > &rowKeys, const std::vector< ColKeyType > &colKeys)
Non-symmetric matrix constructor.
Definition KeyedMatrix.hpp:2067
KeyedMatrix & operator=(KeyedMatrix &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:2109
KeyedMatrix(KeyedMatrix< Scalar, RowKeyType, ColKeyType, oRows, oCols > &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:2144
KeyedMatrix(const KeyedMatrix &other)
Copy constructor.
Definition KeyedMatrix.hpp:2088
KeyedMatrix(KeyedMatrix &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:2104
KeyedMatrix & operator=(const KeyedMatrix< Scalar, RowKeyType, ColKeyType, oRows, oCols > &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:2132
void addRowsCols(const std::vector< RowKeyType > &rowKeys, const std::vector< ColKeyType > &colKeys)
Adds new rows and cols to the matrix.
Definition KeyedMatrix.hpp:2167
KeyedMatrix(const Eigen::MatrixBase< Derived > &matrix, const std::vector< RowKeyType > &keys)
Symmetric matrix constructor.
Definition KeyedMatrix.hpp:2076
KeyedMatrix & operator=(const KeyedMatrix &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:2093
KeyedMatrix & operator=(KeyedMatrix< Scalar, RowKeyType, ColKeyType, oRows, oCols > &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:2150
KeyedMatrix(const KeyedMatrix< Scalar, RowKeyType, ColKeyType, oRows, oCols > &other)
Copy constructor.
Definition KeyedMatrix.hpp:2126
void removeRowsCols(const std::vector< RowKeyType > &rowKeys, const std::vector< ColKeyType > &colKeys)
Removes the rows and cols from the matrix.
Definition KeyedMatrix.hpp:2201
KeyedMatrix()
Default Constructor.
Definition KeyedMatrix.hpp:2058
KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > inverse() const
Calculates the inverse matrix.
Definition KeyedMatrix.hpp:2284
Static sized KeyedMatrix.
Definition KeyedMatrix.hpp:1910
KeyedMatrix(const KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > &other)
Copy constructor.
Definition KeyedMatrix.hpp:1976
KeyedMatrix(const KeyedMatrix &other)
Copy constructor.
Definition KeyedMatrix.hpp:1939
KeyedMatrix & operator=(const KeyedMatrix &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1944
~KeyedMatrix()=default
Destructor.
KeyedMatrix(const Eigen::MatrixBase< Derived > &matrix, const std::vector< RowKeyType > &rowKeys, const std::vector< ColKeyType > &colKeys)
Non-symmetric matrix constructor.
Definition KeyedMatrix.hpp:1918
KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > getSubMatrix(const std::vector< RowKeyType > &rowKeys, const std::vector< ColKeyType > &colKeys) const
Returns a submatrix specified by the row and col keys.
Definition KeyedMatrix.hpp:2023
KeyedMatrix< Scalar, RowKeyType, ColKeyType, Rows, Cols > transposed() const
Calculates the transposed matrix.
Definition KeyedMatrix.hpp:2034
KeyedMatrix & operator=(const KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1983
KeyedMatrix & operator=(KeyedMatrix &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:1960
KeyedMatrix(const Eigen::MatrixBase< Derived > &matrix, const std::vector< RowKeyType > &keys)
Symmetric matrix constructor.
Definition KeyedMatrix.hpp:1927
KeyedMatrix< Scalar, RowKeyType, ColKeyType, Rows, Cols > inverse() const
Calculates the inverse matrix.
Definition KeyedMatrix.hpp:2041
KeyedMatrix(KeyedMatrix &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:1955
KeyedMatrix & operator=(KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:2003
KeyedMatrix(KeyedMatrix< Scalar, RowKeyType, ColKeyType, Eigen::Dynamic, Eigen::Dynamic > &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:1996
Dynamic sized KeyedRowVector.
Definition KeyedMatrix.hpp:1795
KeyedRowVector(KeyedRowVector &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:1834
KeyedRowVector & operator=(KeyedRowVector &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:1839
KeyedRowVector(KeyedRowVector< Scalar, ColKeyType, oCols > &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:1874
KeyedRowVector & operator=(const KeyedRowVector &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1823
KeyedRowVector()
Default Constructor.
Definition KeyedMatrix.hpp:1798
KeyedRowVector & operator=(KeyedRowVector< Scalar, ColKeyType, oCols > &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:1880
KeyedRowVector(const Eigen::MatrixBase< Derived > &vector, const std::vector< ColKeyType > &colKeys)
RowVector constructor.
Definition KeyedMatrix.hpp:1806
KeyedVector< Scalar, ColKeyType, Eigen::Dynamic > transposed() const
Calculates the transposed vector.
Definition KeyedMatrix.hpp:1895
KeyedRowVector & operator=(const KeyedRowVector< Scalar, ColKeyType, oCols > &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1862
KeyedRowVector(const KeyedRowVector< Scalar, ColKeyType, oCols > &other)
Copy constructor.
Definition KeyedMatrix.hpp:1856
KeyedRowVector(const KeyedRowVector &other)
Copy constructor.
Definition KeyedMatrix.hpp:1818
Static sized KeyedRowVector.
Definition KeyedMatrix.hpp:1682
KeyedRowVector(KeyedRowVector &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:1717
~KeyedRowVector()=default
Destructor.
KeyedRowVector & operator=(KeyedRowVector &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:1722
KeyedRowVector(KeyedRowVector< Scalar, ColKeyType, Eigen::Dynamic > &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:1758
KeyedRowVector(const KeyedRowVector &other)
Copy constructor.
Definition KeyedMatrix.hpp:1701
KeyedVector< Scalar, ColKeyType, Cols > transposed() const
Calculates the transposed vector.
Definition KeyedMatrix.hpp:1782
KeyedRowVector(const Eigen::MatrixBase< Derived > &vector, const std::vector< ColKeyType > &colKeys)
RowVector constructor.
Definition KeyedMatrix.hpp:1689
KeyedRowVector(const KeyedRowVector< Scalar, ColKeyType, Eigen::Dynamic > &other)
Copy constructor.
Definition KeyedMatrix.hpp:1738
KeyedRowVector & operator=(const KeyedRowVector< Scalar, ColKeyType, Eigen::Dynamic > &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1745
KeyedRowVector & operator=(const KeyedRowVector &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1706
KeyedRowVector & operator=(KeyedRowVector< Scalar, ColKeyType, Eigen::Dynamic > &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:1765
Dynamic sized KeyedVector.
Definition KeyedMatrix.hpp:1569
KeyedVector(KeyedVector< Scalar, RowKeyType, oRows > &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:1648
KeyedVector(const KeyedVector< Scalar, RowKeyType, oRows > &other)
Copy constructor.
Definition KeyedMatrix.hpp:1630
KeyedVector(const Eigen::MatrixBase< Derived > &vector, const std::vector< RowKeyType > &rowKeys)
Vector constructor.
Definition KeyedMatrix.hpp:1580
KeyedVector(KeyedVector &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:1608
KeyedVector()
Default Constructor.
Definition KeyedMatrix.hpp:1572
KeyedRowVector< Scalar, RowKeyType, Eigen::Dynamic > transposed() const
Calculates the transposed vector.
Definition KeyedMatrix.hpp:1669
KeyedVector & operator=(const KeyedVector &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1597
KeyedVector(const KeyedVector &other)
Copy constructor.
Definition KeyedMatrix.hpp:1592
KeyedVector & operator=(KeyedVector &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:1613
KeyedVector & operator=(const KeyedVector< Scalar, RowKeyType, oRows > &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1636
KeyedVector & operator=(KeyedVector< Scalar, RowKeyType, oRows > &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:1654
Static sized KeyedVector.
Definition KeyedMatrix.hpp:1457
KeyedVector(KeyedVector< Scalar, RowKeyType, Eigen::Dynamic > &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:1533
KeyedVector(const KeyedVector &other)
Copy constructor.
Definition KeyedMatrix.hpp:1476
KeyedVector(const Eigen::MatrixBase< Derived > &vector, const std::vector< RowKeyType > &rowKeys)
Vector constructor.
Definition KeyedMatrix.hpp:1464
KeyedVector & operator=(KeyedVector &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:1497
KeyedVector(KeyedVector &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:1492
KeyedVector & operator=(KeyedVector< Scalar, RowKeyType, Eigen::Dynamic > &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:1540
KeyedVector(const KeyedVector< Scalar, RowKeyType, Eigen::Dynamic > &other)
Copy constructor.
Definition KeyedMatrix.hpp:1513
KeyedVector & operator=(const KeyedVector &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1481
KeyedRowVector< Scalar, RowKeyType, Rows > transposed() const
Calculates the transposed vector.
Definition KeyedMatrix.hpp:1557
KeyedVector & operator=(const KeyedVector< Scalar, RowKeyType, Eigen::Dynamic > &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1520
~KeyedVector()=default
Destructor.
Class to inherit common methods for static and dynamic sized matrices.
Definition KeyedMatrix.hpp:893
decltype(auto) row(const RowKeyType &rowKey) const
Gets the values for the row key.
Definition KeyedMatrix.hpp:1284
decltype(auto) middleRows(const std::vector< RowKeyType > &rowKeys)
Gets the values for the row keys.
Definition KeyedMatrix.hpp:1255
KeyedMatrixBase< Scalar, ColKeyType, RowKeyType, Cols, Rows > transposed() const
Calculates the transposed matrix.
Definition KeyedMatrix.hpp:1402
KeyedMatrixBase(const Eigen::MatrixBase< Derived > &matrix, const std::vector< RowKeyType > &rowKeys, const std::vector< ColKeyType > &colKeys)
Non-symmetric matrix constructor.
Definition KeyedMatrix.hpp:907
decltype(auto) block(const RowKeyType &rowKey, const std::vector< ColKeyType > &colKeys)
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1355
KeyedMatrixBase(KeyedMatrixBase &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:964
Scalar & operator()(const RowKeyType &rowKey, const ColKeyType &colKey)
Gets the value for the row and col key.
Definition KeyedMatrix.hpp:1084
decltype(auto) block(const std::vector< RowKeyType > &rowKeys, const ColKeyType &colKey)
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1218
KeyedMatrixBase(const Eigen::MatrixBase< Derived > &matrix)
Constructor.
Definition KeyedMatrix.hpp:898
const Eigen::Matrix< Scalar, Rows, Cols > & block(all_t, all_t) const
Requests the full matrix.
Definition KeyedMatrix.hpp:1299
decltype(auto) middleRows(const std::vector< RowKeyType > &rowKeys)
Gets the values for the row keys.
Definition KeyedMatrix.hpp:1372
decltype(auto) row(const RowKeyType &rowKey)
Gets the values for the row key.
Definition KeyedMatrix.hpp:1288
decltype(auto) block(const RowKeyType &rowKey, const std::vector< ColKeyType > &colKeys) const
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1347
KeyedMatrixBase(const KeyedMatrixBase &other)
Copy constructor.
Definition KeyedMatrix.hpp:936
decltype(auto) middleCols(const std::vector< ColKeyType > &colKeys) const
Gets the values for the col keys.
Definition KeyedMatrix.hpp:1265
Eigen::Matrix< Scalar, Rows, Cols > & operator()(all_t, all_t)
Requests the full matrix.
Definition KeyedMatrix.hpp:1174
KeyedMatrixBase(KeyedMatrixBase< Scalar, RowKeyType, ColKeyType, oRows, oCols > &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:1034
decltype(auto) middleCols(const std::vector< ColKeyType > &colKeys)
Gets the values for the col keys.
Definition KeyedMatrix.hpp:1390
decltype(auto) block(const std::vector< RowKeyType > &rowKeys, const ColKeyType &colKey) const
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1209
decltype(auto) middleCols(const std::vector< ColKeyType > &colKeys) const
Gets the values for the col keys.
Definition KeyedMatrix.hpp:1381
KeyedMatrixBase & operator=(const KeyedMatrixBase &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:948
decltype(auto) block(const std::vector< RowKeyType > &rowKeys, const ColKeyType &colKey)
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1339
decltype(auto) block(const std::vector< RowKeyType > &rowKeys, const std::vector< ColKeyType > &colKeys) const
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1187
decltype(auto) block(const std::vector< RowKeyType > &rowKeys, const std::vector< ColKeyType > &colKeys) const
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1311
~KeyedMatrixBase()=default
Destructor.
decltype(auto) block(const std::vector< RowKeyType > &rowKeys, const ColKeyType &colKey) const
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1331
KeyedMatrixBase & operator=(KeyedMatrixBase< Scalar, RowKeyType, ColKeyType, oRows, oCols > &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:1050
const Scalar & operator()(const RowKeyType &rowKey, const ColKeyType &colKey) const
Gets the value for the row and col key.
Definition KeyedMatrix.hpp:1076
decltype(auto) middleCols(const std::vector< ColKeyType > &colKeys)
Gets the values for the col keys.
Definition KeyedMatrix.hpp:1275
decltype(auto) block(const std::vector< RowKeyType > &rowKeys, const std::vector< ColKeyType > &colKeys)
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1198
Eigen::Matrix< Scalar, Rows, Cols > & block(all_t, all_t)
Requests the full matrix.
Definition KeyedMatrix.hpp:1301
decltype(auto) col(const ColKeyType &colKey) const
Gets the values for the col key.
Definition KeyedMatrix.hpp:1292
KeyedMatrixBase & operator=(const KeyedMatrixBase< Scalar, RowKeyType, ColKeyType, oRows, oCols > &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:1014
decltype(auto) middleRows(const std::vector< RowKeyType > &rowKeys) const
Gets the values for the row keys.
Definition KeyedMatrix.hpp:1363
decltype(auto) block(const RowKeyType &rowKey, const std::vector< ColKeyType > &colKeys) const
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1227
decltype(auto) block(const RowKeyType &rowKey, const std::vector< ColKeyType > &colKeys)
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1236
decltype(auto) block(const std::vector< RowKeyType > &rowKeys, const std::vector< ColKeyType > &colKeys)
Gets the values for the row and col keys.
Definition KeyedMatrix.hpp:1321
decltype(auto) middleRows(const std::vector< RowKeyType > &rowKeys) const
Gets the values for the row keys.
Definition KeyedMatrix.hpp:1245
decltype(auto) col(const ColKeyType &colKey)
Gets the values for the col key.
Definition KeyedMatrix.hpp:1296
KeyedMatrixBase & operator=(KeyedMatrixBase &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:976
KeyedMatrixBase< Scalar, RowKeyType, ColKeyType, Rows, Cols > inverse() const
Calculates the inverse matrix.
Definition KeyedMatrix.hpp:1408
KeyedMatrixBase(const KeyedMatrixBase< Scalar, RowKeyType, ColKeyType, oRows, oCols > &other)
Copy constructor.
Definition KeyedMatrix.hpp:998
const Eigen::Matrix< Scalar, Rows, Cols > & operator()(all_t, all_t) const
Requests the full matrix.
Definition KeyedMatrix.hpp:1172
Base class for Keyed matrices with multiple columns.
Definition KeyedMatrix.hpp:215
void replaceColKey(const ColKeyType &oldKey, const ColKeyType &newKey)
Replace the old with the new key.
Definition KeyedMatrix.hpp:244
std::vector< ColKeyType > colKeysVector
Col Keys.
Definition KeyedMatrix.hpp:258
bool hasCols(const std::vector< ColKeyType > &keys) const
Checks if the matrix has multiple keys.
Definition KeyedMatrix.hpp:229
std::vector< Eigen::Index > colSlice
Col Slice used for accessing.
Definition KeyedMatrix.hpp:261
bool hasAnyCols(const std::vector< ColKeyType > &keys) const
Checks if the matrix has any keys.
Definition KeyedMatrix.hpp:236
const std::vector< ColKeyType > & colKeys() const
Returns the col keys.
Definition KeyedMatrix.hpp:221
unordered_map< ColKeyType, Eigen::Index > colIndices
ColKey to Col Index mapping.
Definition KeyedMatrix.hpp:256
decltype(auto) cols() const
Return the cols of the underlying Eigen matrix.
Definition KeyedMatrix.hpp:218
bool hasCol(const ColKeyType &key) const
Checks if the matrix has the key.
Definition KeyedMatrix.hpp:225
void addCols(const std::vector< ColKeyType > &colKeys)
Adds new cols to the matrix.
Definition KeyedMatrix.hpp:293
void removeCols(const std::vector< ColKeyType > &colKeys)
Removes the cols from the matrix.
Definition KeyedMatrix.hpp:318
void removeCol(const ColKeyType &colKey)
Removes the col from the matrix.
Definition KeyedMatrix.hpp:314
void addCol(const ColKeyType &colKey)
Adds a new col to the matrix.
Definition KeyedMatrix.hpp:289
Base class for Keyed matrices with multiple columns of static size.
Definition KeyedMatrix.hpp:277
Base class for Keyed matrices with multiple rows.
Definition KeyedMatrix.hpp:71
std::vector< Eigen::Index > rowSlice
Row Slice used for accessing.
Definition KeyedMatrix.hpp:117
unordered_map< RowKeyType, Eigen::Index > rowIndices
RowKey to Row Index mapping.
Definition KeyedMatrix.hpp:112
decltype(auto) rows() const
Return the rows of the underlying Eigen matrix.
Definition KeyedMatrix.hpp:74
bool hasRow(const RowKeyType &key) const
Checks if the matrix has the key.
Definition KeyedMatrix.hpp:81
bool hasRows(const std::vector< RowKeyType > &keys) const
Checks if the matrix has multiple keys.
Definition KeyedMatrix.hpp:85
bool hasAnyRows(const std::vector< RowKeyType > &keys) const
Checks if the matrix has any key.
Definition KeyedMatrix.hpp:92
const std::vector< RowKeyType > & rowKeys() const
Returns the row keys.
Definition KeyedMatrix.hpp:77
std::vector< RowKeyType > rowKeysVector
Row Keys.
Definition KeyedMatrix.hpp:114
void replaceRowKey(const RowKeyType &oldKey, const RowKeyType &newKey)
Replace the old with the new key.
Definition KeyedMatrix.hpp:100
void addRow(const RowKeyType &rowKey)
Adds a new row to the matrix.
Definition KeyedMatrix.hpp:145
void removeRows(const std::vector< RowKeyType > &rowKeys)
Removes the rows from the matrix.
Definition KeyedMatrix.hpp:174
void addRows(const std::vector< RowKeyType > &rowKeys)
Adds new rows to the matrix.
Definition KeyedMatrix.hpp:149
void removeRow(const RowKeyType &rowKey)
Removes the row from the matrix.
Definition KeyedMatrix.hpp:170
Base class for Keyed matrices with multiple rows of static size.
Definition KeyedMatrix.hpp:133
KeyedMatrix storage class.
Definition KeyedMatrix.hpp:49
Eigen::Matrix< Scalar, Rows, Cols > matrix
Data storage of the type.
Definition KeyedMatrix.hpp:51
Class to inherit common methods for static and dynamic sized row vectors.
Definition KeyedMatrix.hpp:626
KeyedRowVectorBase(const Eigen::MatrixBase< Derived > &vector)
Constructor.
Definition KeyedMatrix.hpp:631
Eigen::Matrix< Scalar, 1, Cols > & operator()(all_t)
Requests the full vector.
Definition KeyedMatrix.hpp:809
const Scalar & operator()(const ColKeyType &colKey) const
Gets the value for the col key.
Definition KeyedMatrix.hpp:773
decltype(auto) segment(const std::vector< ColKeyType > &colKeys)
Gets the values for the col keys.
Definition KeyedMatrix.hpp:831
decltype(auto) segment(const std::vector< ColKeyType > &colKeys) const
Gets the values for the col keys.
Definition KeyedMatrix.hpp:821
const Eigen::Matrix< Scalar, 1, Cols > & operator()(all_t) const
Requests the full vector.
Definition KeyedMatrix.hpp:807
KeyedRowVectorBase(KeyedRowVectorBase &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:684
KeyedRowVectorBase(const KeyedRowVectorBase< Scalar, ColKeyType, oCols > &other)
Copy constructor.
Definition KeyedMatrix.hpp:712
KeyedRowVectorBase & operator=(KeyedRowVectorBase< Scalar, ColKeyType, oCols > &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:752
KeyedRowVectorBase & operator=(const KeyedRowVectorBase &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:671
KeyedRowVectorBase & operator=(const KeyedRowVectorBase< Scalar, ColKeyType, oCols > &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:724
~KeyedRowVectorBase()=default
Destructor.
decltype(auto) segment(const std::vector< ColKeyType > &colKeys) const
Gets the values for the col keys.
Definition KeyedMatrix.hpp:840
Scalar & operator()(const ColKeyType &colKey)
Gets the value for the col key.
Definition KeyedMatrix.hpp:780
KeyedRowVectorBase & operator=(KeyedRowVectorBase &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:693
KeyedRowVectorBase(const KeyedRowVectorBase &other)
Copy constructor.
Definition KeyedMatrix.hpp:662
KeyedRowVectorBase(KeyedRowVectorBase< Scalar, ColKeyType, oCols > &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:740
KeyedRowVectorBase(const Eigen::MatrixBase< Derived > &vector, const std::vector< ColKeyType > &colKeys)
Constructor.
Definition KeyedMatrix.hpp:640
KeyedVectorBase< Scalar, ColKeyType, Cols > transposed() const
Calculates the transposed vector.
Definition KeyedMatrix.hpp:861
decltype(auto) segment(const std::vector< ColKeyType > &colKeys)
Gets the values for the col keys.
Definition KeyedMatrix.hpp:849
Class to inherit common methods for static and dynamic sized vectors.
Definition KeyedMatrix.hpp:361
decltype(auto) segment(const std::vector< RowKeyType > &rowKeys)
Gets the values for the row keys.
Definition KeyedMatrix.hpp:566
KeyedVectorBase(const Eigen::MatrixBase< Derived > &vector, const std::vector< RowKeyType > &rowKeys)
Constructor.
Definition KeyedMatrix.hpp:375
KeyedVectorBase & operator=(KeyedVectorBase &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:428
~KeyedVectorBase()=default
Destructor.
Scalar & operator()(const RowKeyType &rowKey)
Gets the value for the row key.
Definition KeyedMatrix.hpp:515
Eigen::Matrix< Scalar, Rows, 1 > & operator()(all_t)
Requests the full vector.
Definition KeyedMatrix.hpp:544
KeyedVectorBase & operator=(const KeyedVectorBase< Scalar, RowKeyType, oRows > &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:459
KeyedVectorBase & operator=(KeyedVectorBase< Scalar, RowKeyType, oRows > &&other) noexcept
Move assignment operator.
Definition KeyedMatrix.hpp:487
KeyedVectorBase(const Eigen::MatrixBase< Derived > &vector)
Constructor.
Definition KeyedMatrix.hpp:366
decltype(auto) segment(const std::vector< RowKeyType > &rowKeys)
Gets the values for the row keys.
Definition KeyedMatrix.hpp:584
KeyedVectorBase(KeyedVectorBase &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:419
decltype(auto) segment(const std::vector< RowKeyType > &rowKeys) const
Gets the values for the row keys.
Definition KeyedMatrix.hpp:575
const Eigen::Matrix< Scalar, Rows, 1 > & operator()(all_t) const
Requests the full vector.
Definition KeyedMatrix.hpp:542
const Scalar & operator()(const RowKeyType &rowKey) const
Gets the value for the row key.
Definition KeyedMatrix.hpp:508
KeyedVectorBase(KeyedVectorBase< Scalar, RowKeyType, oRows > &&other) noexcept
Move constructor.
Definition KeyedMatrix.hpp:475
KeyedVectorBase & operator=(const KeyedVectorBase &other)
Copy assignment operator.
Definition KeyedMatrix.hpp:406
KeyedVectorBase(const KeyedVectorBase< Scalar, RowKeyType, oRows > &other)
Copy constructor.
Definition KeyedMatrix.hpp:447
KeyedVectorBase(const KeyedVectorBase &other)
Copy constructor.
Definition KeyedMatrix.hpp:397
decltype(auto) segment(const std::vector< RowKeyType > &rowKeys) const
Gets the values for the row keys.
Definition KeyedMatrix.hpp:556
KeyedRowVectorBase< Scalar, RowKeyType, Rows > transposed() const
Calculates the transposed vector.
Definition KeyedMatrix.hpp:596
All type to request all rows or columns in KeyedMatrices.
Definition KeyedMatrix.hpp:38
all_t()=default
Default Constructor.
std::ostream & operator<<(std::ostream &os, const NAV::KeyedMatrix< Scalar, RowKeyType, ColKeyType, Rows, Cols > &obj)
Stream insertion operator overload.
Definition KeyedMatrix.hpp:2574
static const internal::all_t all
Used to request all rows or columns in KeyedMatrices.
Definition KeyedMatrix.hpp:1446