Go to the documentation of this file. 1 #ifndef EAGINE_MATH_MATRIX_HPP
9 #define EAGINE_MATH_MATRIX_HPP
11 #include "../assert.hpp"
12 #include "../maybe_unused.hpp"
23 template <
typename T,
int C,
int R,
bool RM,
bool V>
31 using _iseq = std::integer_sequence<int, U...>;
34 using _make_iseq = std::make_integer_sequence<int, N>;
36 vect::data_t<T, RM ? C : R, V> _v[RM ? R : C];
38 template <
typename P,
int... I>
39 static auto _from_hlp(
const P* dt,
span_size_t sz, _iseq<I...>) noexcept
42 {vect::from_array < T,
44 V > ::apply(dt + I * (RM ? C : R), sz - I * (RM ? C : R))...}};
50 return _from_hlp(dt, sz, _make_iseq < RM ? R : C > ());
53 template <
typename P,
int M,
int N,
bool W,
int... I>
57 {vect::cast<P, (RM ? M : N), W, T, (RM ? C : R), V>::apply(
62 template <
typename P,
int M,
int N,
bool W>
64 -> std::enable_if_t<(C <= M) && (R <= N),
matrix> {
65 return _from_hlp(m, _make_iseq < RM ? R : C > ());
76 template <
typename T,
int C,
int R,
bool RM,
bool V>
86 template <
typename T,
int C,
int R,
bool RM,
bool V>
93 template <
typename T,
int C,
int R,
bool RM,
bool V>
100 template <
typename T,
int C,
int R,
bool RM,
bool V>
107 template <
typename T,
int N,
bool RM,
bool V>
114 template <
int CI,
int RI,
typename T,
int C,
int R,
bool V>
116 -> std::enable_if_t<(CI < C && RI < R), T> {
122 template <
int CI,
int RI,
typename T,
int C,
int R,
bool V>
124 -> std::enable_if_t<(CI < C && RI < R), T> {
130 template <
typename T,
int C,
int R,
bool V>
131 static constexpr
auto
133 EAGINE_ASSERT(ci < C && ri < R);
139 template <
typename T,
int C,
int R,
bool V>
140 static constexpr
auto
142 EAGINE_ASSERT(ci < C && ri < R);
148 template <
int RI,
int CI,
typename T,
int C,
int R,
bool V>
150 -> std::enable_if_t<(CI < C && RI < R), T> {
156 template <
int RI,
int CI,
typename T,
int C,
int R,
bool V>
158 -> std::enable_if_t<(CI < C && RI < R), T> {
164 template <
typename T,
int C,
int R,
bool V>
165 static constexpr
auto
167 EAGINE_ASSERT(ci < C && ri < R);
173 template <
typename T,
int C,
int R,
bool V>
174 static constexpr
auto
176 EAGINE_ASSERT(ci < C && ri < R);
182 template <
int CI,
int RI,
typename T,
int C,
int R,
bool V>
184 -> std::enable_if_t<(CI < C && RI < R)> {
190 template <
int CI,
int RI,
typename T,
int C,
int R,
bool V>
192 -> std::enable_if_t<(CI < C && RI < R)> {
198 template <
typename T,
int C,
int R,
bool V>
201 EAGINE_ASSERT(ci < C && ri < R);
207 template <
typename T,
int C,
int R,
bool V>
210 EAGINE_ASSERT(ci < C && ri < R);
216 template <
int RI,
int CI,
typename T,
int C,
int R,
bool V>
218 -> std::enable_if_t<(CI < C && RI < R)> {
224 template <
int RI,
int CI,
typename T,
int C,
int R,
bool V>
226 -> std::enable_if_t<(CI < C && RI < R)> {
232 template <
typename T,
int C,
int R,
bool V>
235 EAGINE_ASSERT(ci < C && ri < R);
241 template <
typename T,
int C,
int R,
bool V>
244 EAGINE_ASSERT(ci < C && ri < R);
249 template <
bool DstRM,
typename T,
bool V>
250 static inline auto transpose_tpl_hlp(
251 const vect::data_t<T, 4, V>& q0,
252 const vect::data_t<T, 4, V>& q1,
253 const vect::data_t<T, 4, V>& q2,
254 const vect::data_t<T, 4, V>& q3) noexcept {
256 {vect::shuffle2<T, 4, V>::template apply<0, 2, 4, 6>(q0, q2),
257 vect::shuffle2<T, 4, V>::template apply<1, 3, 5, 7>(q0, q2),
258 vect::shuffle2<T, 4, V>::template apply<0, 2, 4, 6>(q1, q3),
259 vect::shuffle2<T, 4, V>::template apply<1, 3, 5, 7>(q1, q3)}};
263 template <
bool DstRM,
bool SrcRM,
typename T,
bool V>
264 static inline auto transpose_tpl(
const matrix<T, 4, 4, SrcRM, V>& m) noexcept
265 -> matrix<T, 4, 4, DstRM, V> {
266 return transpose_tpl_hlp<DstRM, T, V>(
267 vect::shuffle2<T, 4, V>::template apply<0, 1, 4, 5>(m._v[0], m._v[1]),
268 vect::shuffle2<T, 4, V>::template apply<2, 3, 6, 7>(m._v[0], m._v[1]),
269 vect::shuffle2<T, 4, V>::template apply<0, 1, 4, 5>(m._v[2], m._v[3]),
270 vect::shuffle2<T, 4, V>::template apply<2, 3, 6, 7>(m._v[2], m._v[3]));
274 template <
bool DstRM,
bool SrcRM,
typename T,
int C,
int R,
bool V>
275 static inline auto transpose_tpl(
const matrix<T, C, R, SrcRM, V>& m) noexcept
276 -> matrix<T, (DstRM == SrcRM ? R : C), (DstRM == SrcRM ? C : R), DstRM, V> {
277 static const bool S = (DstRM != SrcRM);
278 matrix<T, (S ? C : R), (S ? R : C), DstRM, V> r;
280 for(
int i = 0; i < R; ++i) {
281 for(
int j = 0; j < C; ++j) {
291 template <
typename T,
int C,
int R,
bool RM,
bool V>
294 return transpose_tpl<RM, RM, T>(m);
298 template <
typename X>
299 struct reordered_matrix;
303 template <
typename X>
308 template <
typename T,
int C,
int R,
bool RM,
bool V>
309 struct reordered_matrix<
matrix<T, C, R, RM, V>> :
matrix<T, R, C, !RM, V> {};
313 template <
typename T,
int C,
int R,
bool RM,
bool V>
316 return transpose_tpl<!RM, RM, T>(m);
321 template <
typename T,
int C,
int R,
bool V>
329 template <
typename T,
int C,
int R,
bool V>
337 template <
typename T,
int C,
int R,
bool V>
345 template <
typename T,
int C,
int R,
bool V>
353 template <
int I,
typename T,
int C,
int R,
bool RM,
bool V>
355 -> std::enable_if_t<(I < (RM ? R : C)),
vector<T, (RM ? C : R), V>> {
361 template <
int I,
typename T,
int C,
int R,
bool RM,
bool V>
363 -> std::enable_if_t<(I < (RM ? C : R)),
vector<T, (RM ? R : C), V>> {
364 return major_vector<I>(
reorder(m));
368 template <
int I,
typename T,
bool RM,
bool V>
370 -> std::enable_if_t<(I < 4), vector<T, 4, V>> {
371 return {vect::shuffle2<T, 4, V>::template apply<0, 1, 4, 5>(
372 vect::shuffle2<T, 4, V>::template apply<0 + I, 4 + I, -1, -1>(
374 vect::shuffle2<T, 4, V>::template apply<0 + I, 4 + I, -1, -1>(
380 template <
int I,
typename T,
int C,
int R,
bool V>
383 static_assert(I < R);
384 return major_vector<I>(m);
389 template <
int I,
typename T,
int C,
int R,
bool V>
392 static_assert(I < R);
393 return minor_vector<I>(m);
397 template <
typename T,
int C,
int R,
bool RM,
bool V>
401 EAGINE_ASSERT(i == 0U);
402 EAGINE_MAYBE_UNUSED(i);
407 template <
typename T,
int R,
int C,
bool RM,
bool V,
int I>
409 _row_hlp(
const matrix<T, C, R, RM, V>& m, int_constant<I>,
int i) noexcept
414 return _row_hlp(m, int_constant<I - 1>(), i);
419 template <
typename T,
int R,
int C,
bool RM,
bool V>
427 template <
int I,
typename T,
int C,
int R,
bool V>
430 return major_vector<I>(m);
435 template <
int I,
typename T,
int C,
int R,
bool V>
438 return minor_vector<I>(m);
442 template <
typename T,
int C,
int R,
bool RM,
bool V>
446 EAGINE_ASSERT(i == 0);
447 EAGINE_MAYBE_UNUSED(i);
452 template <
typename T,
int C,
int R,
bool RM,
bool V,
int I>
454 _col_hlp(
const matrix<T, C, R, RM, V>& m, int_constant<I>,
int i) noexcept
459 return _col_hlp(m, int_constant<I - 1>(), i);
464 template <
typename T,
int R,
int C,
bool RM,
bool V>
473 template <
typename X>
481 template <
typename X>
484 template <
bool RM,
typename T,
int C,
int R,
bool V>
490 template <
typename X>
495 template <
typename X>
499 template <
typename T,
int C,
int R,
bool RM,
bool V>
503 template <
bool RM,
typename T,
int C,
int R,
bool V>
510 template <
bool RM,
typename T,
int C,
int R,
bool V>
511 static constexpr
auto construct_matrix(
const matrix<T, C, R, !RM, V>& m) noexcept
512 -> matrix<T, C, R, RM, V> {
517 template <
typename T,
int M,
int N,
int K,
bool RM1,
bool RM2,
bool V>
518 struct are_multiplicable<matrix<T, M, K, RM1, V>, matrix<T, K, N, RM2, V>>
522 template <
typename T,
int M,
int N,
int K,
bool RM1,
bool RM2,
bool V>
523 struct multiplication_result<matrix<T, K, M, RM1, V>, matrix<T, N, K, RM2, V>>
524 : matrix<T, N, M, RM1, V> {};
528 template <
typename T,
int M,
int N,
int K,
bool RM1,
bool RM2,
bool V>
534 for(
int i = 0; i < M; ++i) {
535 for(
int j = 0; j < N; ++j) {
538 for(
int k = 0; k < K; ++k) {
549 template <
typename T,
int C,
int R,
bool RM,
bool V>
550 struct are_multiplicable<
matrix<T, C, R, RM, V>,
vector<T, C, V>>
554 template <
typename T,
int C,
int R,
bool RM,
bool V>
555 struct multiplication_result<matrix<T, C, R, RM, V>, vector<T, C, V>>
556 : vector<T, R, V> {};
560 template <
typename T,
int C,
int R,
bool RM,
bool V>
566 for(
int i = 0; i < R; ++i) {
568 for(
int j = 0; j < C; ++j) {
569 s +=
get_rm(m, i, j) * v._v[j];
585 typename = std::enable_if_t<
586 is_matrix_constructor<MC1>::value && is_matrix_constructor<MC2>::value &&
587 are_multiplicable<constructed_matrix_t<MC1>, constructed_matrix_t<MC2>>::value>>
588 static inline auto operator*(
const MC1& mc1,
const MC2& mc2) noexcept {
594 template <
typename T,
int C,
int R,
bool RM,
bool V>
595 struct is_known_matrix_type<math::matrix<T, C, R, RM, V>>
596 : std::is_scalar<T> {};
598 template <
typename T,
int C,
int R,
bool RM,
bool V>
599 struct canonical_compound_type<math::matrix<T, C, R, RM, V>>
600 : type_identity<std::remove_cv_t<T[C][R]>> {};
602 template <
typename T,
int C,
int R,
bool RM,
bool V>
603 struct compound_view_maker<math::matrix<T, C, R, RM, V>> {
604 auto operator()(
const math::matrix<T, C, R, RM, V>& m)
const noexcept {
605 return vect::view < T, RM ? C : R, V > ::apply(m._v);
609 template <
typename T,
int C,
int R,
bool RM,
bool V>
610 struct is_row_major<math::matrix<T, C, R, RM, V>> :
bool_constant<RM> {};
614 #endif // EAGINE_MATH_MATRIX_HPP
std::ptrdiff_t span_size_t
Signed span size type used by eagine.
Definition: types.hpp:36
Common code is placed in this namespace.
Definition: eagine.hpp:21
auto operator[](int i) const noexcept -> const vector< T, RM ? C :R, V >
Subscript operator.
Definition: matrix.hpp:69
static constexpr auto make_column_major(matrix< T, C, R, false, V > m) noexcept -> matrix< T, C, R, false, V >
Returns a matrix ordered as column-major.
Definition: matrix.hpp:338
static constexpr auto columns(const matrix< T, C, R, RM, V > &) noexcept
Returns then number of matrix columns.
Definition: matrix.hpp:94
static auto from(const matrix< P, M, N, RM, W > &m) noexcept -> std::enable_if_t<(C<=M) &&(R<=N), matrix >
Creates a matrix from another matrix type.
Definition: matrix.hpp:63
T element_type
Element type.
Definition: matrix.hpp:28
Basic N-dimensional vector implementation template.
Definition: fwd.hpp:19
static constexpr auto row_major(const matrix< T, C, R, RM, V > &) noexcept
Indicates if a matrix is row-major.
Definition: matrix.hpp:101
static constexpr auto rows(const matrix< T, C, R, RM, V > &) noexcept
Returns then number of matrix rows.
Definition: matrix.hpp:87
static constexpr auto dimension(const matrix< T, N, N, RM, V > &) noexcept
Returns the dimension of a square matrix.
Definition: matrix.hpp:108
constexpr auto is_matrix_constructor_v
Trait indicating if a type X is a matrix constructor.
Definition: matrix.hpp:482
typename constructed_matrix< X >::type constructed_matrix_t
Trait returning the matrix type constructed by constructor type X.
Definition: matrix.hpp:496
Indicates if the specified type X is a matrix constructor.
Definition: matrix.hpp:474
static auto reorder(const matrix< T, C, R, RM, V > &m) noexcept -> matrix< T, C, R, !RM, V >
Returns a matrix reordered (switches row/column major).
Definition: matrix.hpp:314
static auto set_cm(matrix< T, C, R, false, V > &m, T v) noexcept -> std::enable_if_t<(CI< C &&RI< R)>
Sets the matrix element at [CI, RI]. Column-major implementation.
Definition: matrix.hpp:183
Gets the constructed matrix type for a matrix constructor type.
Definition: matrix.hpp:491
std::integral_constant< bool, B > bool_constant
Alias for boolean constant type.
Definition: int_constant.hpp:20
static constexpr auto make_row_major(matrix< T, C, R, true, V > m) noexcept -> matrix< T, C, R, true, V >
Returns a matrix ordered as row-major.
Definition: matrix.hpp:322
typename reordered_matrix< X >::type reordered_matrix_t
Trait returns a reordered (switch row/column-major) type for a matrix type.
Definition: matrix.hpp:304
static constexpr auto get_rm(const matrix< T, C, R, false, V > &m) noexcept -> std::enable_if_t<(CI< C &&RI< R), T >
Returns the matrix element at [RI, CI]. Column-major implementation.
Definition: matrix.hpp:149
static constexpr auto major_vector(const matrix< T, C, R, RM, V > &m) noexcept -> std::enable_if_t<(I<(RM ? R :C)), vector< T,(RM ? C :R), V >>
Returns the I-th major vector of a matrix.
Definition: matrix.hpp:354
static auto operator*(const MC1 &mc1, const MC2 &mc2) noexcept
Multiplication operator for matrix constructors.
Definition: matrix.hpp:588
static constexpr auto column(const matrix< T, C, R, false, V > &m) noexcept -> vector< T, R, V >
Returns the I-th column vector of a matrix. Column-major implementation.
Definition: matrix.hpp:428
const auto is_row_major_v
Trait indicating if a matrix type is row-major.
Definition: matrix.hpp:82
static constexpr auto row(const matrix< T, C, R, true, V > &m) noexcept -> vector< T, C, V >
Returns the I-th row vector of a matrix. Row-major implementation.
Definition: matrix.hpp:381
static auto set_rm(matrix< T, C, R, false, V > &m, T v) noexcept -> std::enable_if_t<(CI< C &&RI< R)>
Sets the matrix element at [RI, CI]. Column-major implementation.
Definition: matrix.hpp:217
static auto from(const P *dt, span_size_t sz) noexcept -> matrix
Creates a matrix from data pointer and size.
Definition: matrix.hpp:49
static auto multiply(const matrix< T, K, M, RM1, V > &m1, const matrix< T, N, K, RM2, V > &m2) noexcept -> matrix< T, N, M, RM1, V >
Matrix multiplication function.
Definition: matrix.hpp:529
static constexpr auto get_cm(const matrix< T, C, R, false, V > &m) noexcept -> std::enable_if_t<(CI< C &&RI< R), T >
Returns the matrix element at [CI, RI]. Column-major implementation.
Definition: matrix.hpp:115
std::integral_constant< int, I > int_constant
Alias for signed int constant type.
Definition: int_constant.hpp:25
static auto minor_vector(const matrix< T, C, R, RM, V > &m) noexcept -> std::enable_if_t<(I<(RM ? C :R)), vector< T,(RM ? R :C), V >>
Returns the I-th minor vector of a matrix.
Definition: matrix.hpp:362
static auto transpose(const matrix< T, C, R, RM, V > &m) noexcept -> matrix< T, R, C, RM, V >
Transposes a matrix.
Definition: matrix.hpp:292
Basic RxC matrix implementation template.
Definition: fwd.hpp:25