0.2.0
Loading...
Searching...
No Matches
Eigen.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
13
14#pragma once
15
16#include <util/Logger.hpp>
17#include <Eigen/Core>
18#include <Eigen/Dense>
19
20#include <nlohmann/json.hpp>
21using json = nlohmann::json;
22
23#include <fmt/ostream.h>
24
25#include "Assert.h"
26
27namespace Eigen
28{
29using Array3ld = Array<long double, 3, 1>;
30
31using Vector3ld = Matrix<long double, 3, 1>;
32using Vector4ld = Matrix<long double, 4, 1>;
33
34using Matrix3ld = Matrix<long double, 3, 3>;
35using Matrix4ld = Matrix<long double, 4, 4>;
36
37using Quaternionld = Quaternion<long double>;
38
39using AngleAxisld = AngleAxis<long double>;
40
47template<typename _Scalar, int _Rows, int _Cols>
48void to_json(json& j, const Matrix<_Scalar, _Rows, _Cols>& matrix)
49{
50 for (int r = 0; r < matrix.rows(); r++)
51 {
52 for (int c = 0; c < matrix.cols(); c++)
53 {
54 if (std::isnan(matrix(r, c))) { j[std::to_string(r)][std::to_string(c)] = "NaN"; }
55 else { j[std::to_string(r)][std::to_string(c)] = matrix(r, c); }
56 }
57 }
58}
59
66template<typename _Scalar, int _Rows, int _Cols>
67void from_json(const json& j, Matrix<_Scalar, _Rows, _Cols>& matrix)
68{
69 if constexpr (_Rows == -1 || _Cols == -1)
70 {
71 int rows = -1;
72 int cols = -1;
73 for (int r = 0; j.contains(std::to_string(r)); r++)
74 {
75 rows = std::max(r, rows);
76 for (int c = 0; j.at(std::to_string(r)).contains(std::to_string(c)); c++)
77 {
78 cols = std::max(c, cols);
79 }
80 }
81 matrix = Eigen::Matrix<_Scalar, _Rows, _Cols>::Zero(rows + 1, cols + 1);
82 }
83
84 for (int r = 0; j.contains(std::to_string(r)); r++) // NOLINT(readability-misleading-indentation)
85 {
86 for (int c = 0; j.at(std::to_string(r)).contains(std::to_string(c)); c++)
87 {
88 if (j.at(std::to_string(r)).at(std::to_string(c)).is_string())
89 {
90 auto str = j.at(std::to_string(r)).at(std::to_string(c)).get<std::string>();
91 if (str == "NaN") { matrix(r, c) = std::nan(""); }
92 else { LOG_WARN("Reading matrix value failed at position ({}, {}). Value is an unknown string '{}'.", r, c, str); }
93 }
94 else if (j.at(std::to_string(r)).at(std::to_string(c)).is_number())
95 {
96 j.at(std::to_string(r)).at(std::to_string(c)).get_to(matrix(r, c));
97 }
98 else
99 {
100 LOG_WARN("Reading matrix value failed at position ({}, {}). Value has the type '{}' which cannot be converted into a floating point number.", r, c, j.at(std::to_string(r)).at(std::to_string(c)).type_name());
101 }
102 }
103 }
104}
105
106} // namespace Eigen
107
108namespace NAV
109{
110
115template<typename Derived>
116void removeRows(Eigen::DenseBase<Derived>& matrix, size_t index, size_t length)
117{
118 INS_ASSERT_USER_ERROR(static_cast<size_t>(matrix.rows()) >= index + length, "Tried to remove rows which do not exist");
119
120 std::vector<int> indicesToKeep;
121 indicesToKeep.reserve(static_cast<size_t>(matrix.rows()) - length);
122 for (int i = 0; i < static_cast<int>(index); i++) { indicesToKeep.push_back(i); }
123 for (int i = static_cast<int>(index + length); i < matrix.rows(); i++) { indicesToKeep.push_back(i); }
124
125 matrix = matrix(indicesToKeep, Eigen::all).eval();
126}
127
131template<typename Derived>
132void removeRows(Eigen::DenseBase<Derived>& matrix, const std::vector<int>& rowIndices)
133{
134 std::vector<int> rowIndicesToKeep;
135 rowIndicesToKeep.reserve(static_cast<size_t>(matrix.rows()) - rowIndices.size());
136 for (int i = 0; i < matrix.rows(); i++)
137 {
138 if (std::find(rowIndices.begin(), rowIndices.end(), i) == rowIndices.end())
139 {
140 rowIndicesToKeep.push_back(i);
141 }
142 }
143
144 matrix = matrix(rowIndicesToKeep, Eigen::all).eval();
145}
146
151template<typename Derived>
152void removeCols(Eigen::DenseBase<Derived>& matrix, size_t index, size_t length)
153{
154 INS_ASSERT_USER_ERROR(static_cast<size_t>(matrix.cols()) >= index + length, "Tried to remove cols which do not exist");
155
156 std::vector<int> indicesToKeep;
157 indicesToKeep.reserve(static_cast<size_t>(matrix.cols()) - length);
158 for (int i = 0; i < static_cast<int>(index); i++) { indicesToKeep.push_back(i); }
159 for (int i = static_cast<int>(index + length); i < matrix.cols(); i++) { indicesToKeep.push_back(i); }
160
161 matrix = matrix(Eigen::all, indicesToKeep).eval();
162}
163
167template<typename Derived>
168void removeCols(Eigen::DenseBase<Derived>& matrix, const std::vector<int>& colIndices)
169{
170 std::vector<int> colIndicesToKeep;
171 colIndicesToKeep.reserve(static_cast<size_t>(matrix.cols()) - colIndices.size());
172 for (int i = 0; i < matrix.cols(); i++)
173 {
174 if (std::find(colIndices.begin(), colIndices.end(), i) == colIndices.end())
175 {
176 colIndicesToKeep.push_back(i);
177 }
178 }
179
180 matrix = matrix(Eigen::all, colIndicesToKeep).eval();
181}
182
189template<typename Derived>
190void removeRowsAndCols(Eigen::DenseBase<Derived>& matrix, size_t row, size_t rows, size_t col, size_t cols)
191{
192 INS_ASSERT_USER_ERROR(static_cast<size_t>(matrix.rows()) >= row + rows, "Tried to remove rows which do not exist");
193 INS_ASSERT_USER_ERROR(static_cast<size_t>(matrix.cols()) >= col + cols, "Tried to remove cols which do not exist");
194
195 std::vector<int> rowsToKeep;
196 rowsToKeep.reserve(static_cast<size_t>(matrix.rows()) - rows);
197 for (int i = 0; i < static_cast<int>(row); i++) { rowsToKeep.push_back(i); }
198 for (int i = static_cast<int>(row + rows); i < matrix.rows(); i++) { rowsToKeep.push_back(i); }
199
200 std::vector<int> colsToKeep;
201 colsToKeep.reserve(static_cast<size_t>(matrix.cols()) - cols);
202 for (int i = 0; i < static_cast<int>(col); i++) { colsToKeep.push_back(i); }
203 for (int i = static_cast<int>(col + cols); i < matrix.cols(); i++) { colsToKeep.push_back(i); }
204
205 matrix = matrix(rowsToKeep, colsToKeep).eval();
206}
207
212template<typename Derived>
213void removeRowsAndCols(Eigen::DenseBase<Derived>& matrix, const std::vector<int>& rowIndices, const std::vector<int>& colIndices)
214{
215 std::vector<int> rowIndicesToKeep;
216 rowIndicesToKeep.reserve(static_cast<size_t>(matrix.rows()) - rowIndices.size());
217 for (int i = 0; i < matrix.rows(); i++)
218 {
219 if (std::find(rowIndices.begin(), rowIndices.end(), i) == rowIndices.end())
220 {
221 rowIndicesToKeep.push_back(i);
222 }
223 }
224
225 std::vector<int> colIndicesToKeep;
226 colIndicesToKeep.reserve(static_cast<size_t>(matrix.cols()) - colIndices.size());
227 for (int i = 0; i < matrix.cols(); i++)
228 {
229 if (std::find(colIndices.begin(), colIndices.end(), i) == colIndices.end())
230 {
231 colIndicesToKeep.push_back(i);
232 }
233 }
234
235 matrix = matrix(rowIndicesToKeep, colIndicesToKeep).eval();
236}
237
238} // namespace NAV
239
240#ifndef DOXYGEN_IGNORE
241
242// clang-format off
243
244template<typename T>
245 requires std::is_base_of_v<Eigen::DenseBase<T>, T>
246struct fmt::formatter<T> : ostream_formatter
247{};
248
249// FIXME: This is not compiling with gcc 11.3 but with >12.1.
250// template<typename T>
251// requires std::is_base_of_v<Eigen::QuaternionBase<T>, T>
252// struct fmt::formatter<T> : ostream_formatter
253// {};
254template<>
255struct fmt::formatter<Eigen::Quaternionf> : ostream_formatter
256{};
257template<>
258struct fmt::formatter<Eigen::Quaterniond> : ostream_formatter
259{};
260template<>
261struct fmt::formatter<Eigen::Quaternionld> : ostream_formatter
262{};
263
264// clang-format on
265
266#endif
Assertion helpers.
#define INS_ASSERT_USER_ERROR(_EXP, _MSG)
Assert function with message.
Definition Assert.h:21
Quaternion< long double > Quaternionld
Long double Eigen::Quaternion.
Definition Eigen.hpp:37
Matrix< long double, 3, 3 > Matrix3ld
Long double 3x3 Eigen::Matrix.
Definition Eigen.hpp:34
void removeRows(Eigen::DenseBase< Derived > &matrix, size_t index, size_t length)
Removes rows from a matrix or vector.
Definition Eigen.hpp:116
Matrix< long double, 3, 1 > Vector3ld
Long double 3x1 Eigen::Vector.
Definition Eigen.hpp:31
Matrix< long double, 4, 4 > Matrix4ld
Long double 4x4 Eigen::Matrix.
Definition Eigen.hpp:35
Array< long double, 3, 1 > Array3ld
Long double 3x1 Eigen::Array.
Definition Eigen.hpp:29
void removeCols(Eigen::DenseBase< Derived > &matrix, size_t index, size_t length)
Removes columns from a matrix or vector.
Definition Eigen.hpp:152
Matrix< long double, 4, 1 > Vector4ld
Long double 3x1 Eigen::Vector.
Definition Eigen.hpp:32
AngleAxis< long double > AngleAxisld
Long double Eigen::AngleAxis.
Definition Eigen.hpp:39
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
nlohmann::json json
json namespace
Definition FlowManager.hpp:21
Utility class for logging to console and file.
#define LOG_WARN
Error occurred, but a fallback option exists and program continues to work normally.
Definition Logger.hpp:71