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)) R[i] = A[i] + B[i];
122 for (
auto i :
xrange(N)) R[i] = A[i] - B[i];
129 for (
auto i :
xrange(N)) R[i] = x * A[i];
136 for (
auto i :
xrange(N)) R[i] = A[i] * x;
143 for (
auto i :
xrange(N)) r += A[i] * x[i];
151 for (
auto i :
xrange(O)) R[i] = A * B[i];
157 for (
auto j :
xrange(M)) {
158 for (
auto i :
xrange(N)) {
159 os << A[i][j] <<
' ';
167 std::array<vecN<M, T>, N> c;
180template<
int M,
int N,
typename T>
187template<
int M,
int N,
typename T>
191 for (
auto i :
xrange(N)) {
192 for (
auto j :
xrange(M)) {
203 return A[0][0] * A[1][1] - A[0][1] * A[1][0];
210 return A[0][0] * (A[1][1] * A[2][2] - A[1][2] * A[2][1])
211 - A[1][0] * (A[0][1] * A[2][2] - A[0][2] * A[2][1])
212 + A[2][0] * (A[0][1] * A[1][2] - A[0][2] * A[1][1]);
220 T f0 = A[2][2] * A[3][3] - A[3][2] * A[2][3];
221 T f1 = A[2][1] * A[3][3] - A[3][1] * A[2][3];
222 T f2 = A[2][1] * A[3][2] - A[3][1] * A[2][2];
223 T f3 = A[2][0] * A[3][3] - A[3][0] * A[2][3];
224 T f4 = A[2][0] * A[3][2] - A[3][0] * A[2][2];
225 T f5 = A[2][0] * A[3][1] - A[3][0] * A[2][1];
226 vecN<4, T> c((A[1][1] * f0 - A[1][2] * f1 + A[1][3] * f2),
227 (A[1][2] * f3 - A[1][3] * f4 - A[1][0] * f0),
228 (A[1][0] * f1 - A[1][1] * f3 + A[1][3] * f5),
229 (A[1][1] * f4 - A[1][2] * f5 - A[1][0] * f2));
248 vecN<3, T>(A[1][1] * A[2][2] - A[1][2] * A[2][1],
249 A[0][2] * A[2][1] - A[0][1] * A[2][2],
250 A[0][1] * A[1][2] - A[0][2] * A[1][1]),
251 vecN<3, T>(A[1][2] * A[2][0] - A[1][0] * A[2][2],
252 A[0][0] * A[2][2] - A[0][2] * A[2][0],
253 A[0][2] * A[1][0] - A[0][0] * A[1][2]),
254 vecN<3, T>(A[1][0] * A[2][1] - A[1][1] * A[2][0],
255 A[0][1] * A[2][0] - A[0][0] * A[2][1],
256 A[0][0] * A[1][1] - A[0][1] * A[1][0]));
265 T c00 = A[2][2] * A[3][3] - A[3][2] * A[2][3];
266 T c02 = A[1][2] * A[3][3] - A[3][2] * A[1][3];
267 T c03 = A[1][2] * A[2][3] - A[2][2] * A[1][3];
269 T c04 = A[2][1] * A[3][3] - A[3][1] * A[2][3];
270 T c06 = A[1][1] * A[3][3] - A[3][1] * A[1][3];
271 T c07 = A[1][1] * A[2][3] - A[2][1] * A[1][3];
273 T c08 = A[2][1] * A[3][2] - A[3][1] * A[2][2];
274 T c10 = A[1][1] * A[3][2] - A[3][1] * A[1][2];
275 T c11 = A[1][1] * A[2][2] - A[2][1] * A[1][2];
277 T c12 = A[2][0] * A[3][3] - A[3][0] * A[2][3];
278 T c14 = A[1][0] * A[3][3] - A[3][0] * A[1][3];
279 T c15 = A[1][0] * A[2][3] - A[2][0] * A[1][3];
281 T c16 = A[2][0] * A[3][2] - A[3][0] * A[2][2];
282 T c18 = A[1][0] * A[3][2] - A[3][0] * A[1][2];
283 T c19 = A[1][0] * A[2][2] - A[2][0] * A[1][2];
285 T c20 = A[2][0] * A[3][1] - A[3][0] * A[2][1];
286 T c22 = A[1][0] * A[3][1] - A[3][0] * A[1][1];
287 T c23 = A[1][0] * A[2][1] - A[2][0] * A[1][1];
296 vecN<4, T> v0(A[1][0], A[0][0], A[0][0], A[0][0]);
297 vecN<4, T> v1(A[1][1], A[0][1], A[0][1], A[0][1]);
298 vecN<4, T> v2(A[1][2], A[0][2], A[0][2], A[0][2]);
299 vecN<4, T> v3(A[1][3], A[0][3], A[0][3], A[0][3]);
311 T OneOverDeterminant =
static_cast<T
>(1) /
dot(A[0], row0);
313 return inverse * OneOverDeterminant;
317template<
int M,
int N,
typename T>
321 for (
auto i :
xrange(N))
t += A[i] * A[i];
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)
constexpr friend matMxN operator+(const matMxN &A, const matMxN &B)
constexpr friend matMxN operator*(const matMxN &A, T x)
constexpr const T * data() const
constexpr matMxN(const vecN<(M< N ? M :N), T > &d)
constexpr friend vecN< M, T > operator*(const matMxN &A, const vecN< N, T > &x)
constexpr friend matMxN operator-(const matMxN &A, const matMxN &B)
constexpr matMxN & operator*=(T x)
constexpr const vecN< M, T > & operator[](unsigned i) const
friend std::ostream & operator<<(std::ostream &os, const matMxN &A)
constexpr matMxN(const matMxN< M2, N2, T > &x)
constexpr matMxN & operator*=(const matMxN< N, N, T > &x)
constexpr matMxN & operator-=(const matMxN &x)
constexpr friend matMxN< M, O, T > operator*(const matMxN &A, const matMxN< N, O, T > &B)
constexpr bool operator==(const matMxN &) const =default
constexpr matMxN & operator+=(const matMxN &x)
constexpr friend matMxN operator*(T x, const matMxN &A)
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-(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)
constexpr matMxN< 2, 2, T > inverse(const matMxN< 2, 2, T > &A)
constexpr T determinant(const matMxN< 2, 2, T > &A)
constexpr auto xrange(T e)