31#ifndef FENNEC_MATH_MATRIX_H
32#define FENNEC_MATH_MATRIX_H
46#include <fennec/math/detail/_fwd.h>
47#include <fennec/math/detail/_matrix.h>
63template<
typename scalar,
size_t rows,
size_t...cols>
64constexpr vec<scalar, rows> column(
const matrix<scalar, rows, cols...>& m,
size_t i)
noexcept {
74template<
typename scalar,
size_t rows,
size_t...cols>
75constexpr vec<scalar,
sizeof...(cols)> row(
const matrix<scalar, rows, cols...>& m,
size_t i)
noexcept {
76 return vec<scalar,
sizeof...(cols)>(m[cols][i]...);
80template<
typename ScalarT>
81using tmat2x2 = mat<ScalarT, 2, 2>;
82template<
typename ScalarT>
using tmat2x3 = mat<ScalarT, 2, 3>;
83template<
typename ScalarT>
using tmat2x4 = mat<ScalarT, 2, 4>;
84template<
typename ScalarT>
using tmat3x2 = mat<ScalarT, 3, 2>;
85template<
typename ScalarT>
using tmat3x3 = mat<ScalarT, 3, 3>;
86template<
typename ScalarT>
using tmat3x4 = mat<ScalarT, 3, 4>;
87template<
typename ScalarT>
using tmat4x2 = mat<ScalarT, 4, 2>;
88template<
typename ScalarT>
using tmat4x3 = mat<ScalarT, 4, 3>;
89template<
typename ScalarT>
using tmat4x4 = mat<ScalarT, 4, 4>;
91using mat2 = tmat2x2<float_t>;
92using mat3 = tmat3x3<float_t>;
93using mat4 = tmat4x4<float_t>;
95using mat2x2 = tmat2x2<float_t>;
96using mat2x3 = tmat2x3<float_t>;
97using mat2x4 = tmat2x4<float_t>;
98using mat3x2 = tmat3x2<float_t>;
99using mat3x3 = tmat3x3<float_t>;
100using mat3x4 = tmat3x4<float_t>;
101using mat4x2 = tmat4x2<float_t>;
102using mat4x3 = tmat4x3<float_t>;
103using mat4x4 = tmat4x4<float_t>;
105using dmat2 = tmat2x2<double_t>;
106using dmat3 = tmat3x3<double_t>;
107using dmat4 = tmat3x3<double_t>;
109using dmat2x2 = tmat2x2<double_t>;
110using dmat2x3 = tmat2x3<double_t>;
111using dmat2x4 = tmat2x4<double_t>;
112using dmat3x2 = tmat3x2<double_t>;
113using dmat3x3 = tmat3x3<double_t>;
114using dmat3x4 = tmat3x4<double_t>;
115using dmat4x2 = tmat4x2<double_t>;
116using dmat4x3 = tmat4x3<double_t>;
117using dmat4x4 = tmat4x4<double_t>;
128template<
typename scalar,
size_t rows,
size_t...cols>
129constexpr matrix<scalar, rows, cols...> matrixCompMult(
const matrix<scalar, rows, cols...>& x,
const matrix<scalar, rows, cols...>& y)
noexcept {
130 return matrix<scalar, rows, cols...>(x[cols] *
y[cols] ...);
145template<
typename scalar,
size_t...s0,
size_t...s1>
146constexpr matrix<scalar,
sizeof...(s0), s1...> outerProduct(
const vector<scalar, s0...>& c,
const vector<scalar, s1...>& r)
noexcept {
147 return matrix<scalar,
sizeof...(s0), s1...>(
157template<
typename scalar,
size_t rows,
size_t...cols>
158constexpr mat<scalar, rows,
sizeof...(cols)> transpose(
const matrix<scalar, rows, cols...>& m)
noexcept {
159 return mat<scalar, rows,
sizeof...(cols)>::transpose(m);
166template<
typename scalar,
size_t rows,
size_t...cols>
167constexpr scalar determinant(
const matrix<scalar, rows, cols...>&)
noexcept {
169 static_assert(
false,
"implementation undefined");
173template<
typename scalar,
size_t rows,
size_t...cols>
174constexpr matrix<scalar, rows, cols...> inverse(
const matrix<scalar, rows, cols...>&)
noexcept {
176 static_assert(
false,
"implementation undefined");
185template<
typename ScalarT,
size_t RowsV,
size_t...ColIndicesV>
requires(is_scalar_v<ScalarT>)
190 static_assert(is_arithmetic_v<ScalarT> or is_bool_v<ScalarT>);
197 static constexpr size_t rows = RowsV;
201 static constexpr size_t columns =
sizeof...(ColIndicesV);
205 static constexpr size_t num_components = rows * columns;
209 using row_t = vec<ScalarT, columns>;
213 using column_t = vec<ScalarT, rows>;
217 using scalar_t = ScalarT;
221 using matrix_t = matrix;
225 using transpose_t = mat<ScalarT, rows, columns>;
230 array<column_t, columns> data;
244 constexpr matrix() =
default;
252 constexpr matrix(
const matrix_t& mat)
261 constexpr matrix(matrix_t&& mat) noexcept
265 template<
typename OScalarT>
266 constexpr matrix(
const matrix<OScalarT, RowsV, ColIndicesV...>& mat)
268 for (
size_t i = 0; i < columns; ++i) {
269 for (
size_t j = 0; j < rows; ++j) {
270 data[i][j] = scalar_t(mat[i][j]);
275 template<
typename OScalarT>
276 constexpr matrix(matrix<OScalarT, RowsV, ColIndicesV...>&& mat) noexcept
278 for (
size_t i = 0; i < columns; ++i) {
279 for (
size_t j = 0; j < rows; ++j) {
280 data[i][j] = scalar_t(mat[i][j]);
300 constexpr matrix(scalar_t s) {
301 (((ColIndicesV < rows) ? data[ColIndicesV][ColIndicesV] = s : 0), ...);
312 constexpr matrix(ArgsT&&...args) {
313 matrix::_construct(fennec::forward<ArgsT>(args)...);
329 constexpr matrix_t& operator=(
const matrix_t& rhs) {
330 data = rhs.data;
return *
this;
339 constexpr matrix_t& operator=(matrix_t&& rhs)
noexcept {
340 data = rhs.data;
return *
this;
353 constexpr column_t& operator[](
size_t i) {
363 constexpr const column_t& operator[](
size_t i)
const {
369 constexpr scalar_t& operator[](
size_t i,
size_t j) {
378 constexpr scalar_t operator[](
size_t i,
size_t j)
const {
394 constexpr friend matrix_t operator+(
const matrix_t& lhs, scalar_t rhs) {
395 return matrix_t(lhs[ColIndicesV] + rhs ...);
403 constexpr friend matrix_t operator+(scalar_t lhs,
const matrix_t& rhs) {
404 return matrix_t(lhs + rhs[ColIndicesV] ...);
412 constexpr friend matrix_t operator-(
const matrix_t& lhs, scalar_t rhs) {
413 return matrix_t(lhs[ColIndicesV] - rhs ...);
421 constexpr friend matrix_t operator-(scalar_t lhs,
const matrix_t& rhs) {
422 return matrix_t(lhs - rhs[ColIndicesV] ...);
430 constexpr friend matrix_t operator*(
const matrix_t& lhs, scalar_t rhs) {
431 return matrix_t(lhs[ColIndicesV] * rhs ...);
439 constexpr friend matrix_t operator*(scalar_t lhs,
const matrix_t& rhs) {
440 return matrix_t(lhs * rhs[ColIndicesV] ...);
448 constexpr friend matrix_t operator/(
const matrix_t& lhs, scalar_t rhs) {
449 return matrix_t(lhs[ColIndicesV] / rhs ...);
457 constexpr friend matrix_t operator/(scalar_t lhs,
const matrix_t& rhs) {
458 return matrix_t(lhs / rhs[ColIndicesV] ...);
468 constexpr friend matrix_t& operator+=(matrix_t& lhs, scalar_t rhs) {
469 ((lhs[ColIndicesV] += rhs), ...);
478 constexpr friend matrix_t& operator+=(scalar_t lhs, matrix_t& rhs) {
479 ((rhs[ColIndicesV] += lhs), ...);
488 constexpr friend matrix_t& operator-=(matrix_t& lhs, scalar_t rhs) {
489 ((lhs[ColIndicesV] -= rhs), ...);
498 constexpr friend matrix_t& operator-=(scalar_t lhs, matrix_t& rhs) {
499 ((rhs[ColIndicesV] -= lhs), ...);
508 constexpr friend matrix_t& operator*=(matrix_t& lhs, scalar_t rhs) {
509 ((lhs[ColIndicesV] *= rhs), ...);
518 constexpr friend matrix_t& operator*=(scalar_t lhs, matrix_t& rhs) {
519 ((rhs[ColIndicesV] *= lhs), ...);
528 constexpr friend matrix_t& operator/=(matrix_t& lhs, scalar_t rhs) {
529 ((lhs[ColIndicesV] /= rhs), ...);
538 constexpr friend matrix_t& operator/=(scalar_t lhs, matrix_t& rhs) {
539 ((rhs[ColIndicesV] /= lhs), ...);
550 constexpr friend matrix_t operator%(
const matrix_t& lhs, scalar_t rhs)
requires is_integral_v<scalar_t> {
551 matrix_t retval = lhs;
552 ((retval[ColIndicesV] %= rhs), ...);
561 constexpr friend matrix_t operator%(scalar_t lhs,
const matrix_t& rhs)
requires is_integral_v<scalar_t> {
562 matrix_t retval = rhs;
563 ((retval[ColIndicesV] %= lhs), ...);
572 constexpr friend matrix_t& operator%=(matrix_t& lhs, scalar_t rhs)
requires is_integral_v<scalar_t> {
573 ((lhs[ColIndicesV] %= rhs), ...);
582 constexpr friend matrix_t& operator%=(scalar_t lhs, matrix_t& rhs)
requires is_integral_v<scalar_t> {
583 ((rhs[ColIndicesV] %= lhs), ...);
599 constexpr friend column_t operator*(
const matrix_t& lhs,
const row_t& rhs) {
600 return _mul(lhs, rhs);
608 constexpr friend row_t operator*(
const column_t& lhs,
const matrix_t& rhs) {
609 return row_t(fennec::dot(fennec::column(rhs, ColIndicesV), lhs) ...);
626 constexpr friend bool operator==(
const matrix_t& lhs,
const matrix_t& rhs) {
627 return lhs.data == rhs.data;
635 constexpr friend bool operator!=(
const matrix_t& lhs,
const matrix_t& rhs) {
636 return lhs.data != rhs.data;
643 template<
size_t ORowsV,
size_t...OColIndicesV>
requires(columns == ORowsV)
644 constexpr friend matrix<scalar_t, RowsV, OColIndicesV...>
operator*(
const matrix_t& lhs,
const matrix<scalar_t, ORowsV, OColIndicesV...>& rhs) {
645 return matrix<scalar_t, RowsV, OColIndicesV...>(
646 matrix::_mul(lhs, rhs[OColIndicesV])...
650 template<
size_t ORowsV,
size_t...OColIndicesV>
requires(columns == ORowsV)
651 constexpr matrix<scalar_t, RowsV, OColIndicesV...>&
operator*=(
const matrix<scalar_t, ORowsV, OColIndicesV...>& rhs) {
652 return *
this = *
this * rhs;
663 static constexpr matrix_t transpose(
const transpose_t& mat) {
664 return matrix_t(fennec::row(mat, ColIndicesV)...);
670 template<
size_t i0 = 0>
671 constexpr void _construct() {
676 template<
size_t i0 = 0,
typename HeadT,
typename...RestT>
677 constexpr void _construct(HeadT&& head, RestT&&...rest) {
678 matrix::_insert<i0>(head);
679 matrix::_construct<i0 + component_count_v<HeadT>>(std::forward<RestT>(rest)...);
683 template<
size_t i0 = 0>
684 constexpr void _insert(scalar_t s) {
685 data[i0 / rows][i0 % rows] = s;
689 template<
size_t i0 = 0,
typename OScalarT>
requires(is_arithmetic_v<OScalarT>)
690 constexpr void _insert(OScalarT s) {
691 data[i0 / rows][i0 % rows] = scalar_t(s);
695 template<
size_t i0 = 0,
size_t...i>
696 constexpr void _insert(
const vector<scalar_t, i...>& v) {
697 (matrix::_insert<i0 + i>(v[i]), ...);
701 template<
size_t i0 = 0,
typename OScalarT,
size_t...i>
702 constexpr void _insert(
const vector<OScalarT, i...>& v) {
703 (matrix::_insert<i0 + i>(v[i]), ...);
707 static constexpr column_t _mul(
const matrix_t& lhs,
const row_t& rhs) {
711 return ((lhs[ColIndicesV] * rhs[ColIndicesV]) + ...);
A header containing the definition for a static/stack allocated array.
constexpr genType y()
Definition constants.h:672
decltype(detail::_gen_vector< vector, ScalarT >(make_index_metasequence< SizeV >{})) vec
Main vector template.
Definition vector.h:124
constexpr size_t total_component_count_v
shorthand for component_count<T>::value
Definition vector_traits.h:102