WPILibC++ 2025.1.1
Loading...
Searching...
No Matches
ct_matrix.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <concepts>
8#include <initializer_list>
9#include <type_traits>
10
11#include <Eigen/Core>
12#include <gcem.hpp>
13
14namespace frc {
15
16template <typename T>
17concept EigenMatrixLike = std::derived_from<T, Eigen::MatrixBase<T>>;
18
19/**
20 * Compile-time wrapper for Eigen::Matrix.
21 *
22 * @tparam Rows Rows of matrix.
23 * @tparam Cols Columns of matrix.
24 */
25template <typename Scalar, int Rows, int Cols>
26class ct_matrix {
27 public:
28 constexpr ct_matrix() = default;
29
30 /**
31 * Constructs a scalar VariableMatrix from a nested list of Variables.
32 *
33 * @param list The nested list of Variables.
34 */
35 constexpr ct_matrix( // NOLINT (runtime/explicit)
36 std::initializer_list<std::initializer_list<Scalar>> list)
37 : m_storage{list} {}
38
39 template <typename Derived>
40 requires std::derived_from<Derived, Eigen::MatrixBase<Derived>>
41 // NOLINTNEXTLINE (runtime/explicit)
42 constexpr ct_matrix(const Derived& mat) : m_storage{mat} {}
43
44 /**
45 * Returns number of rows.
46 *
47 * @return Number of rows.
48 */
49 constexpr int rows() const { return m_storage.rows(); }
50
51 /**
52 * Returns number of columns.
53 *
54 * @return Number of columns.
55 */
56 constexpr int cols() const { return m_storage.cols(); }
57
58 /**
59 * Returns reference to matrix element.
60 *
61 * @param row Row index.
62 * @param col Column index.
63 */
64 constexpr const Scalar& operator()(int row, int col) const {
65 return m_storage(row, col);
66 }
67
68 /**
69 * Returns reference to matrix element.
70 *
71 * @param row Row index.
72 * @param col Column index.
73 */
74 constexpr Scalar& operator()(int row, int col) { return m_storage(row, col); }
75
76 /**
77 * Returns reference to matrix element.
78 *
79 * @param index Index.
80 */
81 constexpr const Scalar& operator()(int index) const
82 requires(Rows == 1 || Cols == 1)
83 {
84 return m_storage(index);
85 }
86
87 /**
88 * Returns reference to matrix element.
89 *
90 * @param index Index.
91 */
92 constexpr Scalar& operator()(int index)
93 requires(Rows == 1 || Cols == 1)
94 {
95 return m_storage(index);
96 }
97
98 /**
99 * Constexpr version of Eigen's scalar multiplication operator.
100 *
101 * @param lhs LHS scalar.
102 * @param rhs RHS matrix.
103 * @return Result of multiplication.
104 */
106 Scalar lhs, const ct_matrix<Scalar, Rows, Cols>& rhs) {
107 if (std::is_constant_evaluated()) {
109
110 for (int i = 0; i < rhs.rows(); ++i) {
111 for (int j = 0; j < rhs.cols(); ++j) {
112 result(i, j) = lhs * rhs(i, j);
113 }
114 }
115
116 return result;
117 } else {
118 return lhs * rhs.m_storage;
119 }
120 }
121
122 /**
123 * Constexpr version of Eigen's matrix multiplication operator.
124 *
125 * @tparam Cols2 Columns of RHS matrix.
126 * @param lhs LHS matrix.
127 * @param rhs RHS matrix.
128 * @return Result of multiplication.
129 */
130 template <int Cols2>
134 if (std::is_constant_evaluated()) {
136
137 for (int i = 0; i < lhs.rows(); ++i) {
138 for (int j = 0; j < rhs.cols(); ++j) {
139 Scalar sum = 0.0;
140 for (int k = 0; k < lhs.cols(); ++k) {
141 sum += lhs(i, k) * rhs(k, j);
142 }
143 result(i, j) = sum;
144 }
145 }
146
147 return result;
148 } else {
149 return lhs.m_storage * rhs.storage();
150 }
151 }
152
153 /**
154 * Constexpr version of Eigen's matrix addition operator.
155 *
156 * @param lhs LHS matrix.
157 * @param rhs RHS matrix.
158 * @return Result of addition.
159 */
163 if (std::is_constant_evaluated()) {
165
166 for (int row = 0; row < 3; ++row) {
167 for (int col = 0; col < 3; ++col) {
168 result(row, col) = lhs(row, col) + rhs(row, col);
169 }
170 }
171
172 return result;
173 } else {
174 return lhs.m_storage + rhs.m_storage;
175 }
176 }
177
178 /**
179 * Constexpr version of Eigen's matrix subtraction operator.
180 *
181 * @param lhs LHS matrix.
182 * @param rhs RHS matrix.
183 * @return Result of subtraction.
184 */
188 if (std::is_constant_evaluated()) {
190
191 for (int row = 0; row < 3; ++row) {
192 for (int col = 0; col < 3; ++col) {
193 result(row, col) = lhs(row, col) - rhs(row, col);
194 }
195 }
196
197 return result;
198 } else {
199 return lhs.m_storage - rhs.m_storage;
200 }
201 }
202
203 /**
204 * Constexpr version of Eigen's transpose member function.
205 *
206 * @return Transpose of matrix.
207 */
209 if (std::is_constant_evaluated()) {
211
212 for (int row = 0; row < rows(); ++row) {
213 for (int col = 0; col < cols(); ++col) {
214 result(col, row) = (*this)(row, col);
215 }
216 }
217
218 return result;
219 } else {
220 return m_storage.transpose().eval();
221 }
222 }
223
224 /**
225 * Constexpr version of Eigen's identity function.
226 *
227 * @return Identity matrix of the specified size.
228 */
230 requires(Rows != Eigen::Dynamic && Cols != Eigen::Dynamic)
231 {
232 if (std::is_constant_evaluated()) {
234
235 for (int row = 0; row < Rows; ++row) {
236 for (int col = 0; col < Cols; ++col) {
237 if (row == col) {
238 result(row, row) = 1.0;
239 } else {
240 result(row, col) = 0.0;
241 }
242 }
243 }
244
245 return result;
246 } else {
247 return Eigen::Matrix<Scalar, Rows, Cols>::Identity();
248 }
249 }
250
251 /**
252 * Constexpr version of Eigen's vector dot member function.
253 *
254 * @tparam RhsRows Rows of RHS vector.
255 * @tparam RhsCols Columns of RHS vector.
256 * @param rhs RHS vector.
257 * @return Dot product of two vectors.
258 */
259 template <int RhsRows, int RhsCols>
260 requires(Rows == 1 || Cols == 1) && (RhsRows == 1 || RhsCols == 1) &&
261 (Rows * Cols == RhsRows * RhsCols)
262 constexpr Scalar dot(const ct_matrix<Scalar, RhsRows, RhsCols>& rhs) const {
263 if (std::is_constant_evaluated()) {
264 Scalar sum = 0.0;
265
266 for (int index = 0; index < rows() * rhs.cols(); ++index) {
267 sum += (*this)(index)*rhs(index);
268 }
269
270 return sum;
271 } else {
272 return m_storage.dot(rhs.storage());
273 }
274 }
275
276 /**
277 * Constexpr version of Eigen's norm member function.
278 *
279 * @return Norm of matrix.
280 */
281 constexpr Scalar norm() const {
282 if (std::is_constant_evaluated()) {
283 Scalar sum = 0.0;
284
285 for (int row = 0; row < Rows; ++row) {
286 for (int col = 0; col < Cols; ++col) {
287 sum += (*this)(row, col) * (*this)(row, col);
288 }
289 }
290
291 return gcem::sqrt(sum);
292 } else {
293 return m_storage.norm();
294 }
295 }
296
297 /**
298 * Constexpr version of Eigen's 3D vector cross member function.
299 *
300 * @param rhs RHS vector.
301 * @return Cross product of two vectors.
302 */
304 requires(Rows == 3 && Cols == 1)
305 {
306 return Eigen::Vector3d{{(*this)(1) * rhs(2) - rhs(1) * (*this)(2),
307 rhs(0) * (*this)(2) - (*this)(0) * rhs(2),
308 (*this)(0) * rhs(1) - rhs(0) * (*this)(1)}};
309 }
310
311 /**
312 * Constexpr version of Eigen's 2x2 matrix determinant member function.
313 *
314 * @return Determinant of matrix.
315 */
316 constexpr Scalar determinant() const
317 requires(Rows == 2 && Cols == 2)
318 {
319 // |a b|
320 // |c d| = ad - bc
321 Scalar a = (*this)(0, 0);
322 Scalar b = (*this)(0, 1);
323 Scalar c = (*this)(1, 0);
324 Scalar d = (*this)(1, 1);
325 return a * d - b * c;
326 }
327
328 /**
329 * Constexpr version of Eigen's 3x3 matrix determinant member function.
330 *
331 * @return Determinant of matrix.
332 */
333 constexpr Scalar determinant() const
334 requires(Rows == 3 && Cols == 3)
335 {
336 // |a b c|
337 // |d e f| = aei + bfg + cdh - ceg - bdi - afh
338 // |g h i|
339 Scalar a = (*this)(0, 0);
340 Scalar b = (*this)(0, 1);
341 Scalar c = (*this)(0, 2);
342 Scalar d = (*this)(1, 0);
343 Scalar e = (*this)(1, 1);
344 Scalar f = (*this)(1, 2);
345 Scalar g = (*this)(2, 0);
346 Scalar h = (*this)(2, 1);
347 Scalar i = (*this)(2, 2);
348 return a * e * i + b * f * g + c * d * h - c * e * g - b * d * i -
349 a * f * h;
350 }
351
352 /**
353 * Returns the internal Eigen matrix.
354 *
355 * @return The internal Eigen matrix.
356 */
357 constexpr const Eigen::Matrix<Scalar, Rows, Cols>& storage() const {
358 return m_storage;
359 }
360
361 /**
362 * Implicit cast to an Eigen matrix.
363 */
364 constexpr operator Eigen::Matrix<Scalar, Rows, Cols>() const { // NOLINT
365 return m_storage;
366 }
367
368 private:
369 Eigen::Matrix<Scalar, Rows, Cols> m_storage;
370};
371
372template <typename Derived>
373 requires std::derived_from<Derived, Eigen::MatrixBase<Derived>>
374ct_matrix(const Derived&)
375 -> ct_matrix<typename Derived::Scalar, Derived::RowsAtCompileTime,
376 Derived::ColsAtCompileTime>;
377
378template <typename Scalar, int Rows>
380
381template <typename Scalar, int Cols>
383
388
389} // namespace frc
Compile-time wrapper for Eigen::Matrix.
Definition ct_matrix.h:26
constexpr ct_matrix(std::initializer_list< std::initializer_list< Scalar > > list)
Constructs a scalar VariableMatrix from a nested list of Variables.
Definition ct_matrix.h:35
constexpr Scalar dot(const ct_matrix< Scalar, RhsRows, RhsCols > &rhs) const
Constexpr version of Eigen's vector dot member function.
Definition ct_matrix.h:262
friend constexpr ct_matrix< Scalar, Rows, Cols > operator*(Scalar lhs, const ct_matrix< Scalar, Rows, Cols > &rhs)
Constexpr version of Eigen's scalar multiplication operator.
Definition ct_matrix.h:105
friend constexpr ct_matrix< Scalar, Rows, Cols > operator+(const ct_matrix< Scalar, Rows, Cols > &lhs, const ct_matrix< Scalar, Rows, Cols > &rhs)
Constexpr version of Eigen's matrix addition operator.
Definition ct_matrix.h:160
static constexpr ct_matrix< Scalar, Rows, Cols > Identity()
Constexpr version of Eigen's identity function.
Definition ct_matrix.h:229
friend constexpr ct_matrix< Scalar, Rows, Cols2 > operator*(const ct_matrix< Scalar, Rows, Cols > &lhs, const ct_matrix< Scalar, Rows, Cols2 > &rhs)
Constexpr version of Eigen's matrix multiplication operator.
Definition ct_matrix.h:131
constexpr Scalar determinant() const
Constexpr version of Eigen's 2x2 matrix determinant member function.
Definition ct_matrix.h:316
constexpr Scalar & operator()(int index)
Returns reference to matrix element.
Definition ct_matrix.h:92
constexpr Scalar & operator()(int row, int col)
Returns reference to matrix element.
Definition ct_matrix.h:74
constexpr ct_matrix()=default
constexpr const Scalar & operator()(int row, int col) const
Returns reference to matrix element.
Definition ct_matrix.h:64
friend constexpr ct_matrix< Scalar, Rows, Cols > operator-(const ct_matrix< Scalar, Rows, Cols > &lhs, const ct_matrix< Scalar, Rows, Cols > &rhs)
Constexpr version of Eigen's matrix subtraction operator.
Definition ct_matrix.h:185
constexpr int cols() const
Returns number of columns.
Definition ct_matrix.h:56
constexpr const Scalar & operator()(int index) const
Returns reference to matrix element.
Definition ct_matrix.h:81
constexpr Scalar norm() const
Constexpr version of Eigen's norm member function.
Definition ct_matrix.h:281
constexpr int rows() const
Returns number of rows.
Definition ct_matrix.h:49
constexpr ct_matrix< Scalar, 3, 1 > cross(const ct_matrix< Scalar, 3, 1 > &rhs)
Constexpr version of Eigen's 3D vector cross member function.
Definition ct_matrix.h:303
constexpr ct_matrix< Scalar, Cols, Rows > transpose() const
Constexpr version of Eigen's transpose member function.
Definition ct_matrix.h:208
constexpr ct_matrix(const Derived &mat)
Definition ct_matrix.h:42
constexpr Scalar determinant() const
Constexpr version of Eigen's 3x3 matrix determinant member function.
Definition ct_matrix.h:333
constexpr const Eigen::Matrix< Scalar, Rows, Cols > & storage() const
Returns the internal Eigen matrix.
Definition ct_matrix.h:357
Definition ct_matrix.h:17
Definition CAN.h:11
ct_matrix(const Derived &) -> ct_matrix< typename Derived::Scalar, Derived::RowsAtCompileTime, Derived::ColsAtCompileTime >
constexpr return_t< T > sqrt(const T x) noexcept
Compile-time square-root function.
Definition sqrt.hpp:109