pbpt
Loading...
Searching...
No Matches
matrix.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <concepts>
5#include <stdexcept>
6#include <type_traits>
7#include <utility>
8#include <functional>
9
10#include "vector.hpp"
11
16
17namespace pbpt::math {
18//Forward declarations
19template<typename T, int R, int C>
20requires std::is_floating_point_v<T> && (R > 0) && (C > 0)
21class Matrix;
22
28template<typename T, int N>
30 protected:
32 const T* m_start_ptr;
35
36public:
42 constexpr VectorView(const T* start, int stride) : m_start_ptr(start), m_stride(stride) {}
43
49 constexpr const T& operator[](int i) const { return m_start_ptr[i * m_stride]; }
50
56 constexpr const T& at(int i) const { return m_start_ptr[i * m_stride]; }
57
59 constexpr int dims() const noexcept { return N; }
60
66 constexpr T dot(const Vector<T, N>& rhs) const {
67 T result = 0;
68 for (int i = 0; i < N; ++i) result += (*this)[i] * rhs[i];
69 return result;
70 }
71
77
78 constexpr T dot(const VectorView<T, N>& rhs) const {
79 T result = 0;
80 for (int i = 0; i < N; ++i) result += (*this)[i] * rhs[i];
81 return result;
82 }
83
88 constexpr Vector<T, N> to_vector() const {
89 Vector<T, N> result;
90 for (int i = 0; i < N; ++i) result[i] = (*this)[i];
91 return result;
92 }
93
99 constexpr T& operator[](int i) { return const_cast<T&>(this->m_start_ptr[i * this->m_stride]); }
100
106 constexpr T& at(int i) { return const_cast<T&>(this->m_start_ptr[i * this->m_stride]); }
107
113 constexpr VectorView& operator=(const Vector<T, N>& other) {
114 for (int i = 0; i < N; ++i) (*this)[i] = other[i];
115 return *this;
116 }
117
123 constexpr VectorView& operator=(const VectorView<T, N>& other) {
124 for (int i = 0; i < N; ++i) (*this)[i] = other[i];
125 return *this;
126 }
127
132 void apply(const std::function<void(T&, int)>& func) {
133 for (int i = 0; i < N; ++i) func((*this)[i], i);
134 }
135};
136
141template<typename T, int R, int C, int ViewR, int ViewC>
143protected:
150
151public:
152 /*** @brief Provides a view into a sub-region of the matrix.*/
153 using RowView = VectorView<T, ViewC>;
154 /*** @brief Provides a view into a sub-region of the matrix.*/
155 using ColView = VectorView<T, ViewR>;
156
163 constexpr MatrixView(const Matrix<T, R, C>& original, int row_start, int col_start)
164 : m_original(original), m_row_start(row_start), m_col_start(col_start) {}
165
172 constexpr const T& at(int r, int c) const {
173 return m_original.at(m_row_start + r, m_col_start + c);
174 }
175
179 constexpr const RowView operator[](int r) const {
180 return RowView(&(*this).at(r, 0), 1);
181 }
182
186 constexpr RowView operator[](int r) {
187 return RowView(&(*this).at(r, 0), 1);
188 }
189
193 constexpr const RowView row(int r) const {
194 return RowView(&(*this).at(r, 0), 1);
195 }
196
200 constexpr ColView col(int c) {
201 return ColView(&(*this).at(0, c), ViewC);
202 }
203
210 for (int i = 0; i < ViewR; ++i) {
211 for (int j = 0; j < ViewC; ++j) {
212 result[i][j] = (*this)[i][j];
213 }
214 }
215 return result;
216 }
217
224 constexpr T& at(int r, int c) {
225 return const_cast<T&>(this->m_original.at(this->m_row_start + r, this->m_col_start + c));
226 }
227
234 for (int i = 0; i < ViewR; ++i) {
235 for (int j = 0; j < ViewC; ++j) {
236 (*this).at(i, j) = other.at(i, j);
237 }
238 }
239 return *this;
240 }
241
246 void apply(const std::function<void(T&, int, int)>& func) {
247 for (int i = 0; i < ViewR; ++i) {
248 for (int j = 0; j < ViewC; ++j) {
249 func((*this).at(i, j), i, j);
250 }
251 }
252 }
253};
254
265template<typename T, int R, int C>
266requires std::is_floating_point_v<T> && (R > 0) && (C > 0)
267class Matrix {
268
269private:
270 // Row-major storage for cache efficiency and intuitive C++ access.
271 std::array<T, R * C> m_data{};
272
273public:
282 template<int ViewR, int ViewC>
284
285 /*** @brief Provides a view into a sub-region of the matrix.*/
286 using RowView = VectorView<T, C>;
287
288 /*** @brief Provides a view into a sub-region of the matrix.*/
289 using ColView = VectorView<T, R>;
290
291 // --- 静态工厂函数 (Static Factory Functions) ---
292
296 static constexpr Matrix zeros() noexcept { return Matrix(); }
297
302 static constexpr Matrix identity() noexcept requires(R == C) {
303 Matrix result{};
304 for (int i = 0; i < R; ++i) {
305 result[i][i] = 1.0;
306 }
307 return result;
308 }
309
310 // --- 构造函数 (Constructors) ---
311
315 constexpr Matrix() noexcept = default;
316
324 template<typename... Vecs>
325 // 将类型检查 (std::is_same_v<...>) 加入 requires 子句
326 requires(sizeof...(Vecs) == C && (std::is_same_v<Vector<T, R>, std::remove_cvref_t<Vecs>> && ...))
327 constexpr explicit Matrix(Vecs&&... col_vecs) noexcept {
328
329 int col_index = 0;
330 (([&] {
331 for(int row_index = 0; row_index < R; ++row_index) {
332 (*this)[row_index][col_index] = col_vecs[row_index];
333 }
334 ++col_index;
335 })(), ...);
336 }
337
343
344 template<std::convertible_to<T>... Vals>
345 // 使用折叠表达式 (&& ...) 来展开参数包
346 requires(sizeof...(Vals) == R * C && (std::is_arithmetic_v<std::remove_cvref_t<Vals>> && ...))
347 constexpr Matrix(Vals&&... vals) noexcept : m_data{static_cast<T>(std::forward<Vals>(vals))...} {}
348
349 // --- 访问器 (Accessors) ---
350
358 constexpr const T& at(int r, int c) const {
359 if (r < 0 || r >= R || c < 0 || c >= C) {
360 if (std::is_constant_evaluated()) {
361 throw "Compile-time error: Matrix index out of range";
362 } else {
363 throw std::out_of_range("Matrix index out of range");
364 }
365 }
366 return m_data[r * C + c];
367 }
368
372 constexpr RowView operator[](int r) {
373 return RowView(&(*this).at(r, 0), 1);
374 }
375
379 constexpr const RowView operator[](int r) const {
380 return RowView(&(*this).at(r, 0), 1);
381 }
382
386 constexpr RowView row(int r) {
387 return RowView(&(*this).at(r, 0), 1);
388 }
389
393 constexpr const RowView row(int r) const {
394 return RowView(&(*this).at(r, 0), 1);
395 }
396
400 constexpr ColView col(int c) {
401 return ColView(&(*this).at(0, c), C);
402 }
403
407 constexpr const ColView col(int c) const {
408 return ColView(&(*this).at(0, c), C);
409 }
410
412 constexpr int row_dims() const noexcept { return R; }
413
415 constexpr int col_dims() const noexcept { return C; }
416
422 const T* data() const noexcept { return m_data.data(); }
423
429 T* data() noexcept { return m_data.data(); }
430
431 // 比较运算符
432
438 constexpr bool operator==(const Matrix& rhs) const noexcept {
439 for (int i = 0; i < R * C; ++i) {
440 if (!math::is_equal(m_data[i], rhs.m_data[i])) return false;
441 }
442 return true;
443 }
444
450 constexpr bool operator!=(const Matrix& rhs) const noexcept {
451 return !(*this == rhs);
452 }
453
454 // --- 复合赋值运算符 (Compound Assignment Operators) ---
455
461 constexpr Matrix& operator+=(const Matrix& rhs) noexcept {
462 for (int i = 0; i < R * C; ++i) m_data[i] += rhs.m_data[i];
463 return *this;
464 }
465
471 constexpr Matrix& operator-=(const Matrix& rhs) noexcept {
472 for (int i = 0; i < R * C; ++i) m_data[i] -= rhs.m_data[i];
473 return *this;
474 }
475
481 constexpr Matrix& operator*=(T scalar) noexcept {
482 for (int i = 0; i < R * C; ++i) m_data[i] *= scalar;
483 return *this;
484 }
485
486 // --- 矩阵数学运算 (Matrix Math Operations) ---
487
492 constexpr Matrix<T, C, R> transposed() const noexcept {
493 Matrix<T, C, R> result{};
494 for (int i = 0; i < R; ++i) {
495 for (int j = 0; j < C; ++j) {
496 result[j][i] = (*this)[i][j];
497 }
498 }
499 return result;
500 }
501
506 constexpr Matrix<T, C, R>& transpose() noexcept requires(R == C) {
507 Matrix<T, C, R> result{};
508 for (int i = 0; i < R; ++i) {
509 for (int j = 0; j < C; ++j) {
510 result[j][i] = (*this)[i][j];
511 }
512 }
513 *this = result;
514 return *this;
515 }
516
521 constexpr T determinant() const requires(R == C) {
522 if constexpr (R == 1) {
523 return (*this).at(0, 0);
524 } else if constexpr (R == 2) {
525 return (*this).at(0, 0) * (*this).at(1, 1) - (*this).at(0, 1) * (*this).at(1, 0);
526 } else if constexpr (R == 3) {
527 return (*this).at(0, 0) * ((*this).at(1, 1) * (*this).at(2, 2) - (*this).at(1, 2) * (*this).at(2, 1)) -
528 (*this).at(0, 1) * ((*this).at(1, 0) * (*this).at(2, 2) - (*this).at(1, 2) * (*this).at(2, 0)) +
529 (*this).at(0, 2) * ((*this).at(1, 0) * (*this).at(2, 1) - (*this).at(1, 1) * (*this).at(2, 0));
530 } else {
531 // General case: Laplace expansion (less efficient, but works for any size)
532 T det = 0;
533 for (int c = 0; c < C; ++c) {
534 T sign = (c % 2 == 0) ? 1 : -1;
535 det += sign * (*this).at(0, c) * submatrix(0, c).determinant();
536 }
537 return det;
538 }
539 }
540
546 constexpr Matrix inversed() const requires(R == C) {
547 T det = determinant();
548 if (det == 0) {
549 if (std::is_constant_evaluated()) {
550 throw "Compile-time error: Cannot invert a singular matrix";
551 } else {
552 throw std::runtime_error("Cannot invert a singular matrix");
553 }
554 }
555
556 Matrix cofactor_matrix{};
557 for (int r = 0; r < R; ++r) {
558 for (int c = 0; c < C; ++c) {
559 T sign = ((r + c) % 2 == 0) ? 1 : -1;
560 cofactor_matrix[r][c] = sign * submatrix(r, c).determinant();
561 }
562 }
563
564 Matrix adjugate_matrix = cofactor_matrix.transposed();
565 return adjugate_matrix * (static_cast<T>(1.0) / det);
566 }
567
573 constexpr Matrix& inverse() requires(R == C) {
574 T det = determinant();
575 if (det == 0) {
576 if (std::is_constant_evaluated()) {
577 throw "Compile-time error: Cannot invert a singular matrix";
578 } else {
579 throw std::runtime_error("Cannot invert a singular matrix");
580 }
581 }
582
583 Matrix cofactor_matrix{};
584 for (int r = 0; r < R; ++r) {
585 for (int c = 0; c < C; ++c) {
586 T sign = ((r + c) % 2 == 0) ? 1 : -1;
587 cofactor_matrix[r][c] = sign * submatrix(r, c).determinant();
588 }
589 }
590
591 Matrix adjugate_matrix = cofactor_matrix.transposed();
592 *this = adjugate_matrix * (static_cast<T>(1.0) / det);
593 return *this;
594 }
595
604 template <int ViewR, int ViewC>
605 constexpr Matrix::MatView<ViewR, ViewC> view(int row_start, int col_start) {
606 // Basic bounds check to ensure the view doesn't immediately go out of bounds
607 if (std::is_constant_evaluated()) {
608 if (row_start + ViewR > R || col_start + ViewC > C) {
609 throw "Compile-time error: View dimensions exceed original matrix bounds";
610 }
611 }
612 return Matrix::MatView<ViewR, ViewC>(*this, row_start, col_start);
613 }
614
623 template <int ViewR, int ViewC>
624 constexpr const Matrix::MatView<ViewR, ViewC> view(int row_start, int col_start) const {
625 // Basic bounds check to ensure the view doesn't immediately go out of bounds
626 if (std::is_constant_evaluated()) {
627 if (row_start + ViewR > R || col_start + ViewC > C) {
628 throw "Compile-time error: View dimensions exceed original matrix bounds";
629 }
630 }
631 return Matrix::MatView<ViewR, ViewC>(*this, row_start, col_start);
632 }
633
638 constexpr auto submatrix(int row_to_remove, int col_to_remove) const requires(R == C) {
639 Matrix<T, R - 1, C - 1> sub{};
640 int sub_r = 0;
641 for (int r = 0; r < R; ++r) {
642 if (r == row_to_remove) continue;
643 int sub_c = 0;
644 for (int c = 0; c < C; ++c) {
645 if (c == col_to_remove) continue;
646 sub[sub_r][sub_c] = (*this)[r][c];
647 sub_c++;
648 }
649 sub_r++;
650 }
651 return sub;
652 }
653
654 // Matrix-Matrix Addition
660 constexpr Matrix operator+(const Matrix& rhs) const noexcept {
661 auto result = *this;
662 return result += rhs;
663 }
664
665 // Matrix-Matrix Subtraction
671 constexpr Matrix operator-(const Matrix& rhs) const noexcept {
672 auto result = *this;
673 return result -= rhs;
674 }
675
676 // Matrix-Scalar Multiplication
682 template<std::convertible_to<T> U>
683 constexpr Matrix operator*(U scalar) const noexcept {
684 Matrix result{};
685 for (int r = 0; r < R; ++r) {
686 for (int c = 0; c < C; ++c) {
687 result[r][c] = (*this)[r][c] * scalar;
688 }
689 }
690 return result;
691 }
692
693 // Scalar-Matrix Multiplication
699 template<std::convertible_to<T> U>
700 friend constexpr Matrix operator*(U scalar, const Matrix<T, R, C>& mat) noexcept {
701 auto result = mat;
702 return result *= static_cast<T>(scalar);
703 }
704
705 // --- 核心乘法运算 (Core Multiplication) ---
706
710 constexpr Vector<T, R> operator*(const Vector<T, R>& rhs) const noexcept {
711 Vector<T, R> result{};
712 for (int r = 0; r < R; ++r) {
713 result[r] = row(r).dot(rhs);
714 }
715 return result;
716 }
717
724 template<int M>
725 constexpr Matrix<T, R, M> operator*(const Matrix<T, C, M>& rhs) const noexcept {
726 Matrix<T, R, M> result{};
727 for (int r = 0; r < R; ++r) {
728 for (int c = 0; c < M; ++c) {
729 result[r][c] = row(r).dot(rhs.col(c));
730 }
731 }
732 return result;
733 }
734
745 friend std::ostream& operator<<(std::ostream& os, const Matrix<T, R, C>& mat) {
746 os << "Matrix " << R << "x" << C << "[\n";
747 for (int i = 0; i < R; ++i) {
748 os << " ";
749 for (int j = 0; j < C; ++j) {
750 os << mat.at(i, j) << (j == C - 1 ? "" : ",\t");
751 }
752 os << "\n";
753 }
754 os << "]";
755 return os;
756 }
757
763 constexpr bool is_zero() const {
764 for (int r = 0; r < R; ++r) {
765 for (int c = 0; c < C; ++c) {
766 if ((*this)[r][c] != 0) return false;
767 }
768 }
769 return true;
770 }
771
777 constexpr bool is_identity() const {
778 for (int r = 0; r < R; ++r) {
779 for (int c = 0; c < C; ++c) {
780 if (r == c && (*this)[r][c] != 1) return false;
781 if (r != c && (*this)[r][c] != 0) return false;
782 }
783 }
784 return true;
785 }
786
792 constexpr bool has_nan() const {
793 for (int r = 0; r < R; ++r) {
794 for (int c = 0; c < C; ++c) {
795 if (std::isnan((*this)[r][c])) return true;
796 }
797 }
798 return false;
799 }
800};
801
802// --- 类型别名 (Type Aliases) ---
803/*@breif
804*/
805// --- 类型别名 (Type Aliases) ---
816
817} // namespace math
A template class for RxC dimensional mathematical matrices.
Definition matrix.hpp:267
constexpr const Matrix::MatView< ViewR, ViewC > view(int row_start, int col_start) const
Creates a non-owning, read-only view into a sub-region of this const matrix.
Definition matrix.hpp:624
MatrixView< T, R, C, ViewR, ViewC > MatView
Provides a view into a sub-region of the matrix.
Definition matrix.hpp:283
constexpr Matrix::MatView< ViewR, ViewC > view(int row_start, int col_start)
Creates a mutable, non-owning view into a sub-region of this matrix.
Definition matrix.hpp:605
constexpr Matrix operator-(const Matrix &rhs) const noexcept
Matrix subtraction.
Definition matrix.hpp:671
constexpr bool operator==(const Matrix &rhs) const noexcept
Compares two matrices for equality.
Definition matrix.hpp:438
friend std::ostream & operator<<(std::ostream &os, const Matrix< T, R, C > &mat)
Matrix stream output.
Definition matrix.hpp:745
static constexpr Matrix zeros() noexcept
Creates a matrix with all components set to zero.
Definition matrix.hpp:296
constexpr Matrix(Vals &&... vals) noexcept
Constructs a matrix from a list of values.
Definition matrix.hpp:347
constexpr const RowView row(int r) const
Returns a non-owning, read-only view of a row.
Definition matrix.hpp:393
constexpr int row_dims() const noexcept
Returns the number of rows.
Definition matrix.hpp:412
constexpr RowView row(int r)
Returns a non-owning, mutable view of a row.
Definition matrix.hpp:386
constexpr const T & at(int r, int c) const
Provides const access to matrix components by row and column.
Definition matrix.hpp:358
constexpr Matrix & operator+=(const Matrix &rhs) noexcept
Adds the elements of another matrix to this matrix.
Definition matrix.hpp:461
constexpr T determinant() const
Computes the determinant of the matrix.
Definition matrix.hpp:521
friend constexpr Matrix operator*(U scalar, const Matrix< T, R, C > &mat) noexcept
Matrix multiplication by a scalar.
Definition matrix.hpp:700
constexpr Matrix inversed() const
Computes the inverse of the matrix.
Definition matrix.hpp:546
const T * data() const noexcept
Returns a pointer to the underlying contiguous data array.
Definition matrix.hpp:422
constexpr bool is_zero() const
Checks if the matrix is zero.
Definition matrix.hpp:763
constexpr Matrix() noexcept=default
Default constructor. Initializes a zero matrix.
constexpr const RowView operator[](int r) const
Returns a non-owning, read-only view of a row.
Definition matrix.hpp:379
constexpr const ColView col(int c) const
Returns a non-owning, read-only view of a column.
Definition matrix.hpp:407
constexpr ColView col(int c)
Returns a non-owning, mutable view of a column.
Definition matrix.hpp:400
constexpr int col_dims() const noexcept
Returns the number of columns.
Definition matrix.hpp:415
constexpr Matrix< T, R, M > operator*(const Matrix< T, C, M > &rhs) const noexcept
Matrix-Matrix multiplication.
Definition matrix.hpp:725
constexpr auto submatrix(int row_to_remove, int col_to_remove) const
Definition matrix.hpp:638
constexpr Vector< T, R > operator*(const Vector< T, R > &rhs) const noexcept
Matrix-Vector multiplication.
Definition matrix.hpp:710
constexpr Matrix & operator*=(T scalar) noexcept
Multiplies this matrix by a scalar.
Definition matrix.hpp:481
constexpr Matrix< T, C, R > & transpose() noexcept
Computes the transpose of this matrix.
Definition matrix.hpp:506
constexpr Matrix & inverse()
Computes the inverse of the matrix.
Definition matrix.hpp:573
T * data() noexcept
Returns a pointer to the underlying contiguous data array.
Definition matrix.hpp:429
constexpr bool has_nan() const
Checks if the matrix has NaN values.
Definition matrix.hpp:792
static constexpr Matrix identity() noexcept
Creates an identity matrix.
Definition matrix.hpp:302
constexpr Matrix & operator-=(const Matrix &rhs) noexcept
Subtracts the elements of another matrix from this matrix.
Definition matrix.hpp:471
constexpr Matrix operator*(U scalar) const noexcept
Matrix multiplication by a scalar.
Definition matrix.hpp:683
constexpr bool operator!=(const Matrix &rhs) const noexcept
Compares two matrices for inequality.
Definition matrix.hpp:450
constexpr Matrix operator+(const Matrix &rhs) const noexcept
Matrix addition.
Definition matrix.hpp:660
constexpr bool is_identity() const
Checks if the matrix is identity.
Definition matrix.hpp:777
constexpr Matrix< T, C, R > transposed() const noexcept
Computes the transpose of this matrix.
Definition matrix.hpp:492
constexpr RowView operator[](int r)
Returns a non-owning, mutable view of a row.
Definition matrix.hpp:372
A non-owning, mutable view/proxy into a sub-region of another Matrix.
Definition matrix.hpp:142
int m_col_start
The starting column of the view in the original matrix's coordinate system.
Definition matrix.hpp:149
constexpr T & at(int r, int c)
Provides mutable access to an element of the view.
Definition matrix.hpp:224
constexpr const T & at(int r, int c) const
Provides read-only access to an element of the view.
Definition matrix.hpp:172
constexpr const RowView row(int r) const
Returns a non-owning, read-only view of a row.
Definition matrix.hpp:193
constexpr ColView col(int c)
Returns a non-owning, mutable view of a column.
Definition matrix.hpp:200
constexpr RowView operator[](int r)
Returns a non-owning, read-only view of a row.
Definition matrix.hpp:186
constexpr MatrixView(const Matrix< T, R, C > &original, int row_start, int col_start)
Constructs a view from a Matrix instance.
Definition matrix.hpp:163
constexpr const RowView operator[](int r) const
Returns a non-owning, read-only view of a row.
Definition matrix.hpp:179
int m_row_start
The starting row of the view in the original matrix's coordinate system.
Definition matrix.hpp:147
const Matrix< T, R, C > & m_original
A const reference to the original matrix.
Definition matrix.hpp:145
constexpr Matrix< T, ViewR, ViewC > to_matrix() const
Converts the view into a new, owning Matrix instance.
Definition matrix.hpp:208
void apply(const std::function< void(T &, int, int)> &func)
Applies a function to each element of the matrix.
Definition matrix.hpp:246
constexpr MatrixView & operator=(const Matrix< T, ViewR, ViewC > &other)
Assigns another matrix's content to the region represented by this view.
Definition matrix.hpp:233
A template class for N-dimensional mathematical vectors.
Definition vector.hpp:35
A non-owning, mutable view/proxy of vector-like data.
Definition matrix.hpp:29
constexpr VectorView & operator=(const Vector< T, N > &other)
Assigns an owning vector's content to the region represented by this view.
Definition matrix.hpp:113
int m_stride
Definition matrix.hpp:34
const T * m_start_ptr
Definition matrix.hpp:32
constexpr Vector< T, N > to_vector() const
Converts the view into a new, owning Vec instance.
Definition matrix.hpp:88
constexpr VectorView(const T *start, int stride)
Constructs a read-only vector view.
Definition matrix.hpp:42
constexpr T dot(const Vector< T, N > &rhs) const
Calculates the dot product with an owning vector.
Definition matrix.hpp:66
constexpr VectorView & operator=(const VectorView< T, N > &other)
Assigns another vector view's content to the region represented by this view.
Definition matrix.hpp:123
constexpr T dot(const VectorView< T, N > &rhs) const
Calculates the dot product with another vector view.
Definition matrix.hpp:78
constexpr int dims() const noexcept
Returns the number of dimensions of the view.
Definition matrix.hpp:59
constexpr T & at(int i)
Provides mutable access to an element of the view.
Definition matrix.hpp:106
constexpr T & operator[](int i)
Provides mutable access to an element of the view.
Definition matrix.hpp:99
void apply(const std::function< void(T &, int)> &func)
Applies a function to each element of the view.
Definition matrix.hpp:132
constexpr const T & operator[](int i) const
Provides read-only access to an element of the view.
Definition matrix.hpp:49
constexpr const T & at(int i) const
Provides read-only access to an element of the view.
Definition matrix.hpp:56
The namespace for math library implementation.
Definition bounding_box.hpp:9
constexpr bool is_equal(T a, T b)
Compares two floating-point values for equality.
Definition function.hpp:287
Matrix< Float, 4, 4 > Mat4
A 4x4 matrix of type Float.
Definition matrix.hpp:811
Matrix< Float, 2, 2 > Mat2
A 2x2 matrix of type Float.
Definition matrix.hpp:807
Matrix< Float, 4, 3 > Mat4x3
A 4x3 matrix of type Float.
Definition matrix.hpp:815
Matrix< Float, 3, 3 > Mat3
A 3x3 matrix of type Float.
Definition matrix.hpp:809
Matrix< Float, 3, 4 > Mat3x4
A 3x4 matrix of type Float.
Definition matrix.hpp:813
Defines a generic, N-dimensional, constexpr-friendly vector class.