0.3.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 Array5d = Array<double, 5, 1>;
30using Array6d = Array<double, 6, 1>;
31using Vector5d = Matrix<double, 5, 1>;
32using Vector6d = Matrix<double, 6, 1>;
33using Vector7d = Matrix<double, 7, 1>;
34using Vector8d = Matrix<double, 8, 1>;
35using Vector9d = Matrix<double, 9, 1>;
36using Matrix5d = Matrix<double, 5, 5>;
37using Matrix6d = Matrix<double, 6, 6>;
38using Matrix7d = Matrix<double, 7, 7>;
39using Matrix8d = Matrix<double, 8, 8>;
40using Matrix9d = Matrix<double, 9, 9>;
41
42using Array3ld = Array<long double, 3, 1>;
43
44using Vector3ld = Matrix<long double, 3, 1>;
45using Vector4ld = Matrix<long double, 4, 1>;
46
47using Matrix3ld = Matrix<long double, 3, 3>;
48using Matrix4ld = Matrix<long double, 4, 4>;
49
50using Quaternionld = Quaternion<long double>;
51
52using AngleAxisld = AngleAxis<long double>;
53
60template<typename _Scalar, int _Rows, int _Cols>
61void to_json(json& j, const Matrix<_Scalar, _Rows, _Cols>& matrix)
62{
63 for (int r = 0; r < matrix.rows(); r++)
64 {
65 for (int c = 0; c < matrix.cols(); c++)
66 {
67 if (std::isnan(matrix(r, c))) { j[std::to_string(r)][std::to_string(c)] = "NaN"; }
68 else { j[std::to_string(r)][std::to_string(c)] = matrix(r, c); }
69 }
70 }
71}
72
79template<typename _Scalar, int _Rows, int _Cols>
80void from_json(const json& j, Matrix<_Scalar, _Rows, _Cols>& matrix)
81{
82 if constexpr (_Rows == -1 || _Cols == -1)
83 {
84 int rows = -1;
85 int cols = -1;
86 for (int r = 0; j.contains(std::to_string(r)); r++)
87 {
88 rows = std::max(r, rows);
89 for (int c = 0; j.at(std::to_string(r)).contains(std::to_string(c)); c++)
90 {
91 cols = std::max(c, cols);
92 }
93 }
94 matrix = Eigen::Matrix<_Scalar, _Rows, _Cols>::Zero(rows + 1, cols + 1);
95 }
96
97 for (int r = 0; j.contains(std::to_string(r)); r++) // NOLINT(readability-misleading-indentation)
98 {
99 for (int c = 0; j.at(std::to_string(r)).contains(std::to_string(c)); c++)
100 {
101 if (j.at(std::to_string(r)).at(std::to_string(c)).is_string())
102 {
103 auto str = j.at(std::to_string(r)).at(std::to_string(c)).get<std::string>();
104 if (str == "NaN") { matrix(r, c) = std::nan(""); }
105 else { LOG_WARN("Reading matrix value failed at position ({}, {}). Value is an unknown string '{}'.", r, c, str); }
106 }
107 else if (j.at(std::to_string(r)).at(std::to_string(c)).is_number())
108 {
109 j.at(std::to_string(r)).at(std::to_string(c)).get_to(matrix(r, c));
110 }
111 else
112 {
113 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());
114 }
115 }
116 }
117}
118
123template<typename _Scalar>
124void to_json(json& j, const Quaternion<_Scalar>& quat)
125{
126 to_json(j, quat.coeffs());
127}
128
133template<typename _Scalar>
134void from_json(const json& j, Quaternion<_Scalar>& quat)
135{
136 from_json(j, quat.coeffs());
137}
138
139} // namespace Eigen
140
141namespace NAV
142{
143
148template<typename Derived>
149void removeRows(Eigen::DenseBase<Derived>& matrix, size_t index, size_t length)
150{
151 INS_ASSERT_USER_ERROR(static_cast<size_t>(matrix.rows()) >= index + length, "Tried to remove rows which do not exist");
152
153 std::vector<int> indicesToKeep;
154 indicesToKeep.reserve(static_cast<size_t>(matrix.rows()) - length);
155 for (int i = 0; i < static_cast<int>(index); i++) { indicesToKeep.push_back(i); }
156 for (int i = static_cast<int>(index + length); i < matrix.rows(); i++) { indicesToKeep.push_back(i); }
157
158 matrix = matrix(indicesToKeep, Eigen::all).eval();
159}
160
164template<typename Derived>
165void removeRows(Eigen::DenseBase<Derived>& matrix, const std::vector<int>& rowIndices)
166{
167 std::vector<int> rowIndicesToKeep;
168 rowIndicesToKeep.reserve(static_cast<size_t>(matrix.rows()) - rowIndices.size());
169 for (int i = 0; i < matrix.rows(); i++)
170 {
171 if (std::ranges::find(rowIndices, i) == rowIndices.end())
172 {
173 rowIndicesToKeep.push_back(i);
174 }
175 }
176
177 matrix = matrix(rowIndicesToKeep, Eigen::all).eval();
178}
179
184template<typename Derived>
185void removeCols(Eigen::DenseBase<Derived>& matrix, size_t index, size_t length)
186{
187 INS_ASSERT_USER_ERROR(static_cast<size_t>(matrix.cols()) >= index + length, "Tried to remove cols which do not exist");
188
189 std::vector<int> indicesToKeep;
190 indicesToKeep.reserve(static_cast<size_t>(matrix.cols()) - length);
191 for (int i = 0; i < static_cast<int>(index); i++) { indicesToKeep.push_back(i); }
192 for (int i = static_cast<int>(index + length); i < matrix.cols(); i++) { indicesToKeep.push_back(i); }
193
194 matrix = matrix(Eigen::all, indicesToKeep).eval();
195}
196
200template<typename Derived>
201void removeCols(Eigen::DenseBase<Derived>& matrix, const std::vector<int>& colIndices)
202{
203 std::vector<int> colIndicesToKeep;
204 colIndicesToKeep.reserve(static_cast<size_t>(matrix.cols()) - colIndices.size());
205 for (int i = 0; i < matrix.cols(); i++)
206 {
207 if (std::ranges::find(colIndices, i) == colIndices.end())
208 {
209 colIndicesToKeep.push_back(i);
210 }
211 }
212
213 matrix = matrix(Eigen::all, colIndicesToKeep).eval();
214}
215
222template<typename Derived>
223void removeRowsAndCols(Eigen::DenseBase<Derived>& matrix, size_t row, size_t rows, size_t col, size_t cols)
224{
225 INS_ASSERT_USER_ERROR(static_cast<size_t>(matrix.rows()) >= row + rows, "Tried to remove rows which do not exist");
226 INS_ASSERT_USER_ERROR(static_cast<size_t>(matrix.cols()) >= col + cols, "Tried to remove cols which do not exist");
227
228 std::vector<int> rowsToKeep;
229 rowsToKeep.reserve(static_cast<size_t>(matrix.rows()) - rows);
230 for (int i = 0; i < static_cast<int>(row); i++) { rowsToKeep.push_back(i); }
231 for (int i = static_cast<int>(row + rows); i < matrix.rows(); i++) { rowsToKeep.push_back(i); }
232
233 std::vector<int> colsToKeep;
234 colsToKeep.reserve(static_cast<size_t>(matrix.cols()) - cols);
235 for (int i = 0; i < static_cast<int>(col); i++) { colsToKeep.push_back(i); }
236 for (int i = static_cast<int>(col + cols); i < matrix.cols(); i++) { colsToKeep.push_back(i); }
237
238 matrix = matrix(rowsToKeep, colsToKeep).eval();
239}
240
245template<typename Derived>
246void removeRowsAndCols(Eigen::DenseBase<Derived>& matrix, const std::vector<int>& rowIndices, const std::vector<int>& colIndices)
247{
248 std::vector<int> rowIndicesToKeep;
249 rowIndicesToKeep.reserve(static_cast<size_t>(matrix.rows()) - rowIndices.size());
250 for (int i = 0; i < matrix.rows(); i++)
251 {
252 if (std::ranges::find(rowIndices, i) == rowIndices.end())
253 {
254 rowIndicesToKeep.push_back(i);
255 }
256 }
257
258 std::vector<int> colIndicesToKeep;
259 colIndicesToKeep.reserve(static_cast<size_t>(matrix.cols()) - colIndices.size());
260 for (int i = 0; i < matrix.cols(); i++)
261 {
262 if (std::ranges::find(colIndices, i) == colIndices.end())
263 {
264 colIndicesToKeep.push_back(i);
265 }
266 }
267
268 matrix = matrix(rowIndicesToKeep, colIndicesToKeep).eval();
269}
270
271} // namespace NAV
272
273#ifndef DOXYGEN_IGNORE
274
275// clang-format off
276
277template<typename T>
278 requires std::is_base_of_v<Eigen::DenseBase<T>, T>
279struct fmt::formatter<T> : ostream_formatter
280{};
281
282template<typename T>
283struct fmt::formatter<Eigen::MatrixBase<T>> : ostream_formatter
284{};
285
286
287template<typename T>
288requires std::is_base_of_v<Eigen::QuaternionBase<T>, T>
289struct fmt::formatter<T> : ostream_formatter
290{};
291
292template<typename T>
293struct fmt::formatter<Eigen::QuaternionBase<T>> : ostream_formatter
294{};
295
296// clang-format on
297
298#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:50
Array< double, 5, 1 > Array5d
Double 5x1 Eigen::Array.
Definition Eigen.hpp:29
Array< double, 6, 1 > Array6d
Double 6x1 Eigen::Array.
Definition Eigen.hpp:30
Matrix< double, 6, 6 > Matrix6d
Double 6x6 Eigen::Matrix.
Definition Eigen.hpp:37
Matrix< double, 5, 5 > Matrix5d
Double 5x5 Eigen::Matrix.
Definition Eigen.hpp:36
Matrix< long double, 3, 3 > Matrix3ld
Long double 3x3 Eigen::Matrix.
Definition Eigen.hpp:47
void removeRows(Eigen::DenseBase< Derived > &matrix, size_t index, size_t length)
Removes rows from a matrix or vector.
Definition Eigen.hpp:149
Matrix< double, 7, 1 > Vector7d
Double 7x1 Eigen::Vector.
Definition Eigen.hpp:33
Matrix< long double, 3, 1 > Vector3ld
Long double 3x1 Eigen::Vector.
Definition Eigen.hpp:44
Matrix< double, 9, 1 > Vector9d
Double 9x1 Eigen::Vector.
Definition Eigen.hpp:35
Matrix< double, 8, 1 > Vector8d
Double 8x1 Eigen::Vector.
Definition Eigen.hpp:34
Matrix< double, 5, 1 > Vector5d
Double 5x1 Eigen::Vector.
Definition Eigen.hpp:31
Matrix< double, 6, 1 > Vector6d
Double 6x1 Eigen::Vector.
Definition Eigen.hpp:32
Matrix< long double, 4, 4 > Matrix4ld
Long double 4x4 Eigen::Matrix.
Definition Eigen.hpp:48
Array< long double, 3, 1 > Array3ld
Long double 3x1 Eigen::Array.
Definition Eigen.hpp:42
void to_json(json &j, const Matrix< _Scalar, _Rows, _Cols > &matrix)
Converts the provided matrix into a json object.
Definition Eigen.hpp:61
Matrix< double, 8, 8 > Matrix8d
Double 8x8 Eigen::Matrix.
Definition Eigen.hpp:39
Matrix< double, 7, 7 > Matrix7d
Double 7x7 Eigen::Matrix.
Definition Eigen.hpp:38
void removeCols(Eigen::DenseBase< Derived > &matrix, size_t index, size_t length)
Removes columns from a matrix or vector.
Definition Eigen.hpp:185
Matrix< long double, 4, 1 > Vector4ld
Long double 3x1 Eigen::Vector.
Definition Eigen.hpp:45
AngleAxis< long double > AngleAxisld
Long double Eigen::AngleAxis.
Definition Eigen.hpp:52
void removeRowsAndCols(Eigen::DenseBase< Derived > &matrix, size_t row, size_t rows, size_t col, size_t cols)
Removes rows and columns from a matrix or vector.
Definition Eigen.hpp:223
Matrix< double, 9, 9 > Matrix9d
Double 9x9 Eigen::Matrix.
Definition Eigen.hpp:40
void from_json(const json &j, Matrix< _Scalar, _Rows, _Cols > &matrix)
Converts the provided json object into a matrix.
Definition Eigen.hpp:80
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