19template<
typename T,
int R,
int C>
20requires std::is_floating_point_v<T> && (R > 0) && (C > 0)
28template<typename T,
int N>
59 constexpr int dims() const noexcept {
return N; }
68 for (
int i = 0; i < N; ++i) result += (*
this)[i] * rhs[i];
80 for (
int i = 0; i < N; ++i) result += (*
this)[i] * rhs[i];
90 for (
int i = 0; i < N; ++i) result[i] = (*
this)[i];
99 constexpr T&
operator[](
int i) {
return const_cast<T&
>(this->m_start_ptr[i * this->m_stride]); }
106 constexpr T&
at(
int i) {
return const_cast<T&
>(this->m_start_ptr[i * this->m_stride]); }
114 for (
int i = 0; i < N; ++i) (*
this)[i] = other[i];
124 for (
int i = 0; i < N; ++i) (*
this)[i] = other[i];
132 void apply(
const std::function<
void(T&,
int)>& func) {
133 for (
int i = 0; i < N; ++i) func((*
this)[i], i);
141template<
typename T,
int R,
int C,
int ViewR,
int ViewC>
172 constexpr const T&
at(
int r,
int c)
const {
180 return RowView(&(*this).at(r, 0), 1);
187 return RowView(&(*this).at(r, 0), 1);
193 constexpr const RowView
row(
int r)
const {
194 return RowView(&(*this).at(r, 0), 1);
200 constexpr ColView
col(
int c) {
201 return ColView(&(*this).at(0, c), ViewC);
210 for (
int i = 0; i < ViewR; ++i) {
211 for (
int j = 0; j < ViewC; ++j) {
212 result[i][j] = (*this)[i][j];
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));
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);
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);
265template<
typename T,
int R,
int C>
266requires std::is_floating_point_v<T> && (R > 0) && (C > 0)
271 std::array<T, R * C> m_data{};
282 template<
int ViewR,
int ViewC>
304 for (
int i = 0; i < R; ++i) {
324 template<typename... Vecs>
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 {
331 for(
int row_index = 0; row_index < R; ++row_index) {
332 (*this)[row_index][col_index] = col_vecs[row_index];
344 template<std::convertible_to<T>... Vals>
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))...} {}
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";
363 throw std::out_of_range(
"Matrix index out of range");
366 return m_data[r * C + c];
373 return RowView(&(*this).at(r, 0), 1);
380 return RowView(&(*this).at(r, 0), 1);
386 constexpr RowView
row(
int r) {
387 return RowView(&(*this).at(r, 0), 1);
393 constexpr const RowView
row(
int r)
const {
394 return RowView(&(*this).at(r, 0), 1);
400 constexpr ColView
col(
int c) {
401 return ColView(&(*this).at(0, c), C);
407 constexpr const ColView
col(
int c)
const {
408 return ColView(&(*this).at(0, c), C);
412 constexpr int row_dims() const noexcept {
return R; }
415 constexpr int col_dims() const noexcept {
return C; }
422 const T*
data() const noexcept {
return m_data.data(); }
429 T*
data() noexcept {
return m_data.data(); }
439 for (
int i = 0; i < R * C; ++i) {
451 return !(*
this == rhs);
462 for (
int i = 0; i < R * C; ++i) m_data[i] += rhs.m_data[i];
472 for (
int i = 0; i < R * C; ++i) m_data[i] -= rhs.m_data[i];
482 for (
int i = 0; i < R * C; ++i) m_data[i] *= scalar;
494 for (
int i = 0; i < R; ++i) {
495 for (
int j = 0; j < C; ++j) {
496 result[j][i] = (*this)[i][j];
508 for (
int i = 0; i < R; ++i) {
509 for (
int j = 0; j < C; ++j) {
510 result[j][i] = (*this)[i][j];
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));
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();
549 if (std::is_constant_evaluated()) {
550 throw "Compile-time error: Cannot invert a singular matrix";
552 throw std::runtime_error(
"Cannot invert a singular 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();
565 return adjugate_matrix * (
static_cast<T
>(1.0) / det);
576 if (std::is_constant_evaluated()) {
577 throw "Compile-time error: Cannot invert a singular matrix";
579 throw std::runtime_error(
"Cannot invert a singular 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();
592 *
this = adjugate_matrix * (
static_cast<T
>(1.0) / det);
604 template <
int ViewR,
int ViewC>
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";
623 template <
int ViewR,
int ViewC>
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";
638 constexpr auto submatrix(
int row_to_remove,
int col_to_remove)
const requires(R == C) {
639 Matrix<T, R - 1, C - 1> sub{};
641 for (
int r = 0; r < R; ++r) {
642 if (r == row_to_remove)
continue;
644 for (
int c = 0; c < C; ++c) {
645 if (c == col_to_remove)
continue;
646 sub[sub_r][sub_c] = (*this)[r][c];
662 return result += rhs;
673 return result -= rhs;
682 template<std::convertible_to<T> U>
685 for (
int r = 0; r < R; ++r) {
686 for (
int c = 0; c < C; ++c) {
687 result[r][c] = (*this)[r][c] * scalar;
699 template<std::convertible_to<T> U>
702 return result *=
static_cast<T
>(scalar);
712 for (
int r = 0; r < R; ++r) {
713 result[r] =
row(r).dot(rhs);
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));
746 os <<
"Matrix " << R <<
"x" << C <<
"[\n";
747 for (
int i = 0; i < R; ++i) {
749 for (
int j = 0; j < C; ++j) {
750 os << mat.
at(i, j) << (j == C - 1 ?
"" :
",\t");
764 for (
int r = 0; r < R; ++r) {
765 for (
int c = 0; c < C; ++c) {
766 if ((*
this)[r][c] != 0)
return false;
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;
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;
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.