29template<
int M,
int N,
typename T>
class matMxN
39 c[i][j] = (i == j) ? T(1) : T(0);
45 constexpr explicit matMxN(
const vecN<(M < N ? M : N), T>& d)
49 c[i][j] = (i == j) ? d[i] : T(0);
57 static_assert(((M2 > M) && (N2 >= N)) || ((M2 >= M) && (N2 > N)),
58 "matrix must have strictly larger dimensions");
65 static_assert(N == 2,
"wrong #constructor arguments");
72 static_assert(N == 3,
"wrong #constructor arguments");
73 c[0] = x; c[1] = y; c[2] = z;
80 static_assert(N == 4,
"wrong #constructor arguments");
81 c[0] = x; c[1] = y; c[2] = z; c[3] = w;
100 [[nodiscard]]
constexpr const T*
data()
const {
return c[0].data(); }
101 [[nodiscard]]
constexpr T*
data() {
return c[0].data(); }
115 for (
auto i :
xrange(N))
if (x[i] != y[i])
return false;
120 std::array<vecN<M, T>, N> c;
133template<
int M,
int N,
typename T>
137 for (
auto i :
xrange(N)) R[i] = A[i] + B[i];
142template<
int M,
int N,
typename T>
146 for (
auto i :
xrange(N)) R[i] = A[i] - B[i];
151template<
int M,
int N,
typename T>
158template<
int M,
int N,
typename T>
162 for (
auto i :
xrange(N)) R[i] = x * A[i];
167template<
int M,
int N,
typename T>
171 for (
auto i :
xrange(N)) R[i] = A[i] * x;
176template<
int M,
int N,
typename T>
180 for (
auto i :
xrange(N)) r += A[i] * x[i];
185template<
int M,
int N,
int O,
typename T>
189 for (
auto i :
xrange(O)) R[i] = A * B[i];
194template<
int M,
int N,
typename T>
198 for (
auto i :
xrange(N)) {
199 for (
auto j :
xrange(M)) {
210 return A[0][0] * A[1][1] - A[0][1] * A[1][0];
217 return A[0][0] * (A[1][1] * A[2][2] - A[1][2] * A[2][1])
218 - A[1][0] * (A[0][1] * A[2][2] - A[0][2] * A[2][1])
219 + A[2][0] * (A[0][1] * A[1][2] - A[0][2] * A[1][1]);
227 T f0 = A[2][2] * A[3][3] - A[3][2] * A[2][3];
228 T f1 = A[2][1] * A[3][3] - A[3][1] * A[2][3];
229 T f2 = A[2][1] * A[3][2] - A[3][1] * A[2][2];
230 T f3 = A[2][0] * A[3][3] - A[3][0] * A[2][3];
231 T f4 = A[2][0] * A[3][2] - A[3][0] * A[2][2];
232 T f5 = A[2][0] * A[3][1] - A[3][0] * A[2][1];
233 vecN<4, T> c((A[1][1] * f0 - A[1][2] * f1 + A[1][3] * f2),
234 (A[1][2] * f3 - A[1][3] * f4 - A[1][0] * f0),
235 (A[1][0] * f1 - A[1][1] * f3 + A[1][3] * f5),
236 (A[1][1] * f4 - A[1][2] * f5 - A[1][0] * f2));
255 vecN<3, T>(A[1][1] * A[2][2] - A[1][2] * A[2][1],
256 A[0][2] * A[2][1] - A[0][1] * A[2][2],
257 A[0][1] * A[1][2] - A[0][2] * A[1][1]),
258 vecN<3, T>(A[1][2] * A[2][0] - A[1][0] * A[2][2],
259 A[0][0] * A[2][2] - A[0][2] * A[2][0],
260 A[0][2] * A[1][0] - A[0][0] * A[1][2]),
261 vecN<3, T>(A[1][0] * A[2][1] - A[1][1] * A[2][0],
262 A[0][1] * A[2][0] - A[0][0] * A[2][1],
263 A[0][0] * A[1][1] - A[0][1] * A[1][0]));
272 T c00 = A[2][2] * A[3][3] - A[3][2] * A[2][3];
273 T c02 = A[1][2] * A[3][3] - A[3][2] * A[1][3];
274 T c03 = A[1][2] * A[2][3] - A[2][2] * A[1][3];
276 T c04 = A[2][1] * A[3][3] - A[3][1] * A[2][3];
277 T c06 = A[1][1] * A[3][3] - A[3][1] * A[1][3];
278 T c07 = A[1][1] * A[2][3] - A[2][1] * A[1][3];
280 T c08 = A[2][1] * A[3][2] - A[3][1] * A[2][2];
281 T c10 = A[1][1] * A[3][2] - A[3][1] * A[1][2];
282 T c11 = A[1][1] * A[2][2] - A[2][1] * A[1][2];
284 T c12 = A[2][0] * A[3][3] - A[3][0] * A[2][3];
285 T c14 = A[1][0] * A[3][3] - A[3][0] * A[1][3];
286 T c15 = A[1][0] * A[2][3] - A[2][0] * A[1][3];
288 T c16 = A[2][0] * A[3][2] - A[3][0] * A[2][2];
289 T c18 = A[1][0] * A[3][2] - A[3][0] * A[1][2];
290 T c19 = A[1][0] * A[2][2] - A[2][0] * A[1][2];
292 T c20 = A[2][0] * A[3][1] - A[3][0] * A[2][1];
293 T c22 = A[1][0] * A[3][1] - A[3][0] * A[1][1];
294 T c23 = A[1][0] * A[2][1] - A[2][0] * A[1][1];
303 vecN<4, T> v0(A[1][0], A[0][0], A[0][0], A[0][0]);
304 vecN<4, T> v1(A[1][1], A[0][1], A[0][1], A[0][1]);
305 vecN<4, T> v2(A[1][2], A[0][2], A[0][2], A[0][2]);
306 vecN<4, T> v3(A[1][3], A[0][3], A[0][3], A[0][3]);
318 T OneOverDeterminant =
static_cast<T
>(1) /
dot(A[0], row0);
320 return inverse * OneOverDeterminant;
324template<
int M,
int N,
typename T>
328 for (
auto i :
xrange(N))
t += A[i] * A[i];
333template<
int M,
int N,
typename T>
336 for (
auto j :
xrange(M)) {
337 for (
auto i :
xrange(N)) {
338 os << A[i][j] <<
' ';
constexpr matMxN(const vecN< M, T > &x, const vecN< M, T > &y, const vecN< M, T > &z, const vecN< M, T > &w)
constexpr vecN< M, T > & operator[](unsigned i)
friend constexpr bool operator==(const matMxN &x, const matMxN &y)
constexpr const T * data() const
constexpr matMxN(const vecN<(M< N ? M :N), T > &d)
constexpr matMxN & operator*=(T x)
constexpr const vecN< M, T > & operator[](unsigned i) const
constexpr matMxN(const matMxN< M2, N2, T > &x)
constexpr matMxN & operator*=(const matMxN< N, N, T > &x)
constexpr matMxN & operator-=(const matMxN &x)
constexpr matMxN & operator+=(const matMxN &x)
constexpr matMxN(const vecN< M, T > &x, const vecN< M, T > &y, const vecN< M, T > &z)
constexpr matMxN(const vecN< M, T > &x, const vecN< M, T > &y)
imat3 i3(ivec3(1, 2, 3), ivec3(4, 5, 6), ivec3(7, 8, 9))
constexpr T norm2_2(const matMxN< M, N, T > &A)
constexpr T dot(const vecN< N, T > &x, const vecN< N, T > &y)
constexpr matMxN< M, N, T > operator*(T x, const matMxN< M, N, T > &A)
constexpr matMxN< N, M, T > transpose(const matMxN< M, N, T > &A)
constexpr T sum(const vecN< N, T > &x)
std::ostream & operator<<(std::ostream &os, const matMxN< M, N, T > &A)
constexpr matMxN< 2, 2, T > inverse(const matMxN< 2, 2, T > &A)
constexpr matMxN< M, N, T > operator-(const matMxN< M, N, T > &A, const matMxN< M, N, T > &B)
constexpr T determinant(const matMxN< 2, 2, T > &A)
constexpr matMxN< M, N, T > operator+(const matMxN< M, N, T > &A, const matMxN< M, N, T > &B)
constexpr auto xrange(T e)