M5Unit-IMU 0.0.2 git rev:e5b00aa
Loading...
Searching...
No Matches
matrix.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
21#ifndef M5_UNIT_IMU_MATH_MATRIX_HPP
22#define M5_UNIT_IMU_MATH_MATRIX_HPP
23
24#include <array>
25#include <cmath>
26#include <cstddef>
27
28namespace m5 {
29namespace math {
30
32constexpr float MATRIX_ZERO_EPSILON{1e-9f};
33
38template <std::size_t R, std::size_t C>
39class Matrix {
40public:
41 Matrix() = default;
42
44 static constexpr std::size_t rows()
45 {
46 return R;
47 }
49 static constexpr std::size_t cols()
50 {
51 return C;
52 }
53
55 inline float& at(const std::size_t row, const std::size_t col)
56 {
57 return _data[row][col];
58 }
60 inline float at(const std::size_t row, const std::size_t col) const
61 {
62 return _data[row][col];
63 }
65 inline float& operator()(const std::size_t row, const std::size_t col)
66 {
67 return at(row, col);
68 }
70 inline float operator()(const std::size_t row, const std::size_t col) const
71 {
72 return at(row, col);
73 }
74
76 inline Matrix<R, C> operator+(const Matrix<R, C>& rhs) const
77 {
78 Matrix<R, C> result;
79 for (std::size_t r = 0; r < R; ++r) {
80 for (std::size_t c = 0; c < C; ++c) {
81 result._data[r][c] = _data[r][c] + rhs._data[r][c];
82 }
83 }
84 return result;
85 }
87 inline Matrix<R, C> operator-(const Matrix<R, C>& rhs) const
88 {
89 Matrix<R, C> result;
90 for (std::size_t r = 0; r < R; ++r) {
91 for (std::size_t c = 0; c < C; ++c) {
92 result._data[r][c] = _data[r][c] - rhs._data[r][c];
93 }
94 }
95 return result;
96 }
98 inline Matrix<R, C> operator*(const float scalar) const
99 {
100 Matrix<R, C> result;
101 for (std::size_t r = 0; r < R; ++r) {
102 for (std::size_t c = 0; c < C; ++c) {
103 result._data[r][c] = _data[r][c] * scalar;
104 }
105 }
106 return result;
107 }
108
110 template <std::size_t K>
111 inline Matrix<R, K> operator*(const Matrix<C, K>& rhs) const
112 {
113 Matrix<R, K> result;
114 for (std::size_t r = 0; r < R; ++r) {
115 for (std::size_t k = 0; k < K; ++k) {
116 float sum{};
117 for (std::size_t c = 0; c < C; ++c) {
118 sum += _data[r][c] * rhs(c, k);
119 }
120 result(r, k) = sum;
121 }
122 }
123 return result;
124 }
125
128 {
129 Matrix<C, R> result;
130 for (std::size_t r = 0; r < R; ++r) {
131 for (std::size_t c = 0; c < C; ++c) {
132 result(c, r) = _data[r][c];
133 }
134 }
135 return result;
136 }
137
139 static inline Matrix<R, C> identity()
140 {
141 static_assert(R == C, "Matrix::identity() requires a square matrix");
142 Matrix<R, C> result;
143 for (std::size_t i = 0; i < R; ++i) {
144 result._data[i][i] = 1.0f;
145 }
146 return result;
147 }
148
149private:
150 std::array<std::array<float, C>, R> _data{};
151};
152
165inline bool invert3x3(const Matrix<3, 3>& m, Matrix<3, 3>& out)
166{
167 const float a = m(0, 0);
168 const float b = m(0, 1);
169 const float c = m(0, 2);
170 const float d = m(1, 0);
171 const float e = m(1, 1);
172 const float f = m(1, 2);
173 const float g = m(2, 0);
174 const float h = m(2, 1);
175 const float i = m(2, 2);
176
177 const float cof00 = e * i - f * h;
178 const float cof01 = -(d * i - f * g);
179 const float cof02 = d * h - e * g;
180 const float cof10 = -(b * i - c * h);
181 const float cof11 = a * i - c * g;
182 const float cof12 = -(a * h - b * g);
183 const float cof20 = b * f - c * e;
184 const float cof21 = -(a * f - c * d);
185 const float cof22 = a * e - b * d;
186
187 const float det = a * cof00 + b * cof01 + c * cof02;
188 if (std::fabs(det) < MATRIX_ZERO_EPSILON) {
189 return false;
190 }
191 const float inv_det = 1.0f / det;
192
193 // Adjugate (transpose of the cofactor matrix) scaled by 1/det.
194 out(0, 0) = cof00 * inv_det;
195 out(0, 1) = cof10 * inv_det;
196 out(0, 2) = cof20 * inv_det;
197 out(1, 0) = cof01 * inv_det;
198 out(1, 1) = cof11 * inv_det;
199 out(1, 2) = cof21 * inv_det;
200 out(2, 0) = cof02 * inv_det;
201 out(2, 1) = cof12 * inv_det;
202 out(2, 2) = cof22 * inv_det;
203 return true;
204}
205
213template <std::size_t N>
214inline bool cholesky_solve(const Matrix<N, N>& a, const Matrix<N, 1>& b, Matrix<N, 1>& x)
215{
216 std::array<std::array<float, N>, N> l{};
217
218 for (std::size_t row = 0; row < N; ++row) {
219 for (std::size_t col = 0; col <= row; ++col) {
220 float sum = a(row, col);
221 for (std::size_t k = 0; k < col; ++k) {
222 sum -= l[row][k] * l[col][k];
223 }
224 if (row == col) {
225 if (sum < MATRIX_ZERO_EPSILON) {
226 return false;
227 }
228 l[row][col] = std::sqrt(sum);
229 } else {
230 l[row][col] = sum / l[col][col];
231 }
232 }
233 }
234
235 // Forward substitution: L * y = b
236 std::array<float, N> y{};
237 for (std::size_t row = 0; row < N; ++row) {
238 float sum = b(row, 0);
239 for (std::size_t k = 0; k < row; ++k) {
240 sum -= l[row][k] * y[k];
241 }
242 y[row] = sum / l[row][row];
243 }
244
245 // Back substitution: L^T * x = y
246 for (std::size_t ridx = N; ridx-- > 0;) {
247 float sum = y[ridx];
248 for (std::size_t k = ridx + 1; k < N; ++k) {
249 sum -= l[k][ridx] * x(k, 0);
250 }
251 x(ridx, 0) = sum / l[ridx][ridx];
252 }
253 return true;
254}
255
256} // namespace math
257} // namespace m5
258#endif
Fixed-size (R rows x C columns) float matrix, std::array backed (no heap allocation)
Definition matrix.hpp:39
Matrix< R, C > operator+(const Matrix< R, C > &rhs) const
Component-wise addition.
Definition matrix.hpp:76
static Matrix< R, C > identity()
Identity matrix (square matrices only)
Definition matrix.hpp:139
static constexpr std::size_t rows()
Number of rows.
Definition matrix.hpp:44
float at(const std::size_t row, const std::size_t col) const
Element access (read-only)
Definition matrix.hpp:60
Matrix< R, C > operator*(const float scalar) const
Scalar multiplication.
Definition matrix.hpp:98
float & at(const std::size_t row, const std::size_t col)
Element access (mutable)
Definition matrix.hpp:55
float operator()(const std::size_t row, const std::size_t col) const
Element access via operator() (read-only)
Definition matrix.hpp:70
Matrix< R, K > operator*(const Matrix< C, K > &rhs) const
Matrix product (this [R x C] times rhs [C x K] -> [R x K])
Definition matrix.hpp:111
static constexpr std::size_t cols()
Number of columns.
Definition matrix.hpp:49
float & operator()(const std::size_t row, const std::size_t col)
Element access via operator() (mutable)
Definition matrix.hpp:65
Matrix< R, C > operator-(const Matrix< R, C > &rhs) const
Component-wise subtraction.
Definition matrix.hpp:87
Matrix< C, R > transposed() const
Transpose (C x R)
Definition matrix.hpp:127
constexpr float MATRIX_ZERO_EPSILON
Magnitudes below this are treated as singular/non-positive-definite (matrix safety)
Definition matrix.hpp:32
bool invert3x3(const Matrix< 3, 3 > &m, Matrix< 3, 3 > &out)
Closed-form inverse of a 3x3 matrix.
Definition matrix.hpp:165
bool cholesky_solve(const Matrix< N, N > &a, const Matrix< N, 1 > &b, Matrix< N, 1 > &x)
Solve A*x = b for a symmetric positive-definite A via Cholesky decomposition.
Definition matrix.hpp:214
Top level namespace of M5Stack.
Definition ahrs_controller.cpp:26