20 #if !defined(__MITSUBA_CORE_MATRIX_H_)
21 #define __MITSUBA_CORE_MATRIX_H_
23 #include <mitsuba/mitsuba.h>
24 #include <boost/static_assert.hpp>
33 template <
int M,
int N,
typename T>
struct Matrix {
47 #if !defined(MTS_DEBUG_UNINITIALIZED)
51 for (
int i=0; i<M; ++i)
52 for (
int j=0; j<N; ++j)
53 m[i][j] = std::numeric_limits<double>::quiet_NaN();
59 for (
int i=0; i<M; ++i)
60 for (
int j=0; j<N; ++j)
65 explicit inline Matrix(
const T _m[M][N]) {
66 memcpy(m, _m,
sizeof(T) * M * N);
70 explicit inline Matrix(
const T _m[M*N]) {
71 memcpy(m, _m,
sizeof(T) * M * N);
81 memcpy(m, mtx.
m,
sizeof(T) * M * N);
86 for (
int i=0; i<M; ++i)
87 for (
int j=0; j<N; ++j)
88 m[i][j] = (i == j) ? 1.0f : 0.0f;
93 memset(m, 0,
sizeof(T) * M * N);
101 inline const T &
operator()(
int i,
int j)
const {
return m[i][j]; }
105 for (
int i=0; i<M; ++i)
106 for (
int j=0; j<N; ++j)
107 if (m[i][j] != mat.
m[i][j])
114 for (
int i=0; i<M; ++i)
115 for (
int j=0; j<N; ++j)
116 if (m[i][j] != mat.
m[i][j])
123 for (
int i=0; i<M; ++i)
124 for (
int j=0; j<N; ++j)
125 m[i][j] = mat.
m[i][j];
132 for (
int i=0; i<M; ++i)
133 for (
int j=0; j<N; ++j)
134 result.
m[i][j] = m[i][j] + mat.
m[i][j];
141 for (
int i=0; i<M; ++i)
142 for (
int j=0; j<N; ++j)
143 result.
m[i][j] = m[i][j] + value;
149 for (
int i=0; i<M; ++i)
150 for (
int j=0; j<N; ++j)
151 m[i][j] += mat.
m[i][j];
157 for (
int i=0; i<M; ++i)
158 for (
int j=0; j<N; ++j)
166 for (
int i=0; i<M; ++i)
167 for (
int j=0; j<N; ++j)
168 result.
m[i][j] = m[i][j] - mat.
m[i][j];
175 for (
int i=0; i<M; ++i)
176 for (
int j=0; j<N; ++j)
177 result.
m[i][j] = m[i][j] - value;
183 for (
int i=0; i<M; ++i)
184 for (
int j=0; j<N; ++j)
185 m[i][j] -= mat.
m[i][j];
191 for (
int i=0; i<M; ++i)
192 for (
int j=0; j<N; ++j)
199 for (
int i=0; i<M; ++i)
200 for (
int j=0; j<N; ++j)
208 for (
int i=0; i<M; ++i)
209 for (
int j=0; j<N; ++j)
210 result.
m[i][j] = -m[i][j];
217 for (
int i=0; i<M; ++i)
218 for (
int j=0; j<N; ++j)
219 result.
m[i][j] = m[i][j]*value;
225 for (
int i=0; i<M; ++i)
226 for (
int j=0; j<N; ++j)
236 SLog(
EWarn,
"Matrix: Division by zero!");
238 Float recip = 1/value;
239 for (
int i=0; i<M; ++i)
240 for (
int j=0; j<N; ++j)
241 result.
m[i][j] = m[i][j]*recip;
249 SLog(
EWarn,
"Matrix: Division by zero!");
251 Float recip = 1/value;
252 for (
int i=0; i<M; ++i)
253 for (
int j=0; j<N; ++j)
260 BOOST_STATIC_ASSERT(M == N);
261 Matrix temp = *
this * mat;
268 BOOST_STATIC_ASSERT(M == N);
270 for (
int i=0; i<M; ++i)
278 for (
int i=0; i<M; ++i)
279 for (
int j=0; j<N; ++j)
280 val += m[i][j] * m[i][j];
281 return std::sqrt(val);
309 bool lu(
Matrix &LU,
int piv[M],
int &pivsign)
const;
321 bool chol(
Matrix &L)
const;
355 T luDet(
int pivsign)
const;
366 for (
int i=0; i<M; ++i)
367 for (
int j=0; j<N; ++j)
375 for (
int i=0; i<M; ++i) {
376 for (
int j=0; j<N; ++j) {
377 if (m[i][j] != ((i==j) ? 1 : 0))
391 if (!lu(LU, piv, pivsign))
393 return LU.
luDet(pivsign);
397 bool invert(
Matrix &target)
const;
406 BOOST_STATIC_ASSERT(M == N);
415 for (
int i=0; i<M; ++i)
416 for (
int j=0; j<N; ++j)
417 target.
m[i][j] = m[j][i];
427 std::ostringstream oss;
428 oss <<
"Matrix" << M <<
"x" << N <<
"["<< std::endl;
429 for (
int i=0; i<M; ++i) {
431 for (
int j=0; j<N; ++j) {
445 static void tred2(T V[M][N], T d[N], T e[N]);
448 static void tql2(T V[M][N], T d[N], T e[N]);
470 m[0][0] = v1.x; m[0][1] = v2.x;
471 m[1][0] = v1.y; m[1][1] = v2.y;
482 m[0][0] = a00; m[0][1] = a01;
483 m[1][0] = a10; m[1][1] = a11;
488 return m[0][0]*m[1][1] - m[0][1]*m[1][0];
493 Float det = m[0][0]*m[1][1] - m[0][1]*m[1][0];
497 target.
m[0][0] = m[1][1] * invDet;
498 target.
m[0][1] = -m[0][1] * invDet;
499 target.
m[1][1] = m[0][0] * invDet;
500 target.
m[1][0] = -m[1][0] * invDet;
504 return invert2x2(target);
509 det = m[0][0]*m[1][1] - m[0][1]*m[1][0];
513 target.
m[0][0] = m[1][1] * invDet;
514 target.
m[0][1] = -m[0][1] * invDet;
515 target.
m[1][1] = m[0][0] * invDet;
516 target.
m[1][0] = -m[1][0] * invDet;
523 m[0][0] * v.x + m[0][1] * v.y,
524 m[1][0] * v.x + m[1][1] * v.y
531 for (
int i=0; i<2; ++i)
532 for (
int j=0; j<2; ++j)
533 result.
m[i][j] = m[i][j]*value;
539 for (
int i=0; i<2; ++i)
540 for (
int j=0; j<2; ++j)
541 m[i][j] = mat.
m[i][j];
547 return Vector2(m[i][0], m[i][1]);
552 return Vector2(m[0][i], m[1][i]);
575 m[0][0] = v1.x; m[0][1] = v2.x; m[0][2] = v3.x;
576 m[1][0] = v1.y; m[1][1] = v2.y; m[1][2] = v3.y;
577 m[2][0] = v1.z; m[2][1] = v2.z; m[2][2] = v3.z;
590 m[0][0] = a00; m[0][1] = a01; m[0][2] = a02;
591 m[1][0] = a10; m[1][1] = a11; m[1][2] = a12;
592 m[2][0] = a20; m[2][1] = a21; m[2][2] = a22;
597 return ((m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]))
598 - (m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0]))
599 + (m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0])));
605 m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z,
606 m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z,
607 m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z);
612 return Vector(v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0],
613 v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1],
614 v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2]);
620 for (
int i=0; i<3; ++i)
621 for (
int j=0; j<3; ++j)
622 result.
m[i][j] = m[i][j]*value;
629 for (
int i=0; i<3; ++i)
630 for (
int j=0; j<3; ++j)
631 m[i][j] = mat.
m[i][j];
638 m[i][0], m[i][1], m[i][2]
645 m[0][i], m[1][i], m[2][i]
670 m[0][0] = v1.x; m[0][1] = v2.x; m[0][2] = v3.x; m[0][3] = v4.x;
671 m[1][0] = v1.y; m[1][1] = v2.y; m[1][2] = v3.y; m[1][3] = v4.y;
672 m[2][0] = v1.z; m[2][1] = v2.z; m[2][2] = v3.z; m[2][3] = v4.z;
673 m[3][0] = v1.w; m[3][1] = v2.w; m[3][2] = v3.w; m[3][3] = v4.w;
688 m[0][0] = a00; m[0][1] = a01; m[0][2] = a02; m[0][3] = a03;
689 m[1][0] = a10; m[1][1] = a11; m[1][2] = a12; m[1][3] = a13;
690 m[2][0] = a20; m[2][1] = a21; m[2][2] = a22; m[2][3] = a23;
691 m[3][0] = a30; m[3][1] = a31; m[3][2] = a32; m[3][3] = a33;
696 return ((m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]))
697 - (m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0]))
698 + (m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0])));
704 m[0][0] * v.x + m[0][1] * v.y + m[0][2] * v.z + m[0][3] * v.w,
705 m[1][0] * v.x + m[1][1] * v.y + m[1][2] * v.z + m[1][3] * v.w,
706 m[2][0] * v.x + m[2][1] * v.y + m[2][2] * v.z + m[2][3] * v.w,
707 m[3][0] * v.x + m[3][1] * v.y + m[3][2] * v.z + m[3][3] * v.w
714 for (
int i=0; i<4; ++i)
715 for (
int j=0; j<4; ++j)
716 result.
m[i][j] = m[i][j]*value;
722 for (
int i=0; i<4; ++i)
723 for (
int j=0; j<4; ++j)
724 m[i][j] = mat.
m[i][j];
731 m[i][0], m[i][1], m[i][2], m[i][3]
738 m[0][i], m[1][i], m[2][i], m[3][i]
746 BOOST_STATIC_ASSERT(N1 == M2);
748 for (
int i=0; i<M1; ++i) {
749 for (
int j=0; j<N2; ++j) {
751 for (
int k=0; k<N1; ++k)
752 sum += mat1.
m[i][k] * mat2.
m[k][j];
753 result.
m[i][j] = sum;
void serialize(Stream *stream) const
Serialize the matrix to a stream.
Definition: matrix.h:421
Vector operator*(const Vector &v) const
Matrix-vector multiplication.
Definition: matrix.h:603
std::string toString() const
Return a string representation.
Definition: matrix.h:426
Matrix< M, N, T > operator*(T f, const Matrix< M, N, T > &m)
Definition: matrix.h:759
Float trace() const
Compute the trace of a square matrix.
Definition: matrix.h:267
Matrix operator+(const Matrix &mat) const
Matrix addition (returns a temporary)
Definition: matrix.h:130
bool operator!=(const Matrix &mat) const
Inequality operator.
Definition: matrix.h:113
Matrix3x3(const Float _m[3][3])
Initialize the matrix from a given 3x3 array.
Definition: matrix.h:568
Vector3 row(int i) const
Return a row by index.
Definition: matrix.h:636
Matrix3x3 operator*(Float value) const
Scalar multiplication (creates a temporary)
Definition: matrix.h:618
Matrix2x2(const Matrix< 2, 2, Float > &mtx)
Copy constructor.
Definition: matrix.h:478
Matrix operator*(T value) const
Scalar multiplication (creates a temporary)
Definition: matrix.h:215
FINLINE bool invert(Matrix2x2 &target) const
Definition: matrix.h:503
FINLINE bool invert2x2(Matrix2x2 &target) const
Compute the inverse (Faster than Matrix::invert)
Definition: matrix.h:492
Vector4 row(int i) const
Return a row by index.
Definition: matrix.h:729
Matrix2x2(Float value)
Initialize the matrix with constant entries.
Definition: matrix.h:460
Matrix4x4(Float value)
Initialize the matrix with constant entries.
Definition: matrix.h:660
Generic fixed-size dense matrix class using a row-major storage format.
Definition: matrix.h:33
Matrix4x4 operator*(Float value) const
Scalar multiplication (creates a temporary)
Definition: matrix.h:712
Matrix4x4(Stream *stream)
Unserialize a matrix from a stream.
Definition: matrix.h:677
Matrix4x4(const Vector4 &v1, const Vector4 &v2, const Vector4 &v3, const Vector4 &v4)
Initialize the matrix from four 4D column vectors.
Definition: matrix.h:669
Matrix4x4(Float a00, Float a01, Float a02, Float a03, Float a10, Float a11, Float a12, Float a13, Float a20, Float a21, Float a22, Float a23, Float a30, Float a31, Float a32, Float a33)
Initialize with the given values.
Definition: matrix.h:683
Matrix(T value)
Initialize the matrix with constant entries.
Definition: matrix.h:58
Vector3 col(int i) const
Return a column by index.
Definition: matrix.h:643
T & operator()(int i, int j)
Indexing operator.
Definition: matrix.h:98
Matrix3x3 & operator=(const Matrix< 3, 3, Float > &mat)
Assignment operator.
Definition: matrix.h:628
TVector3< Float > Vector
Definition: fwd.h:113
void eig3_noniter(Matrix3x3 &m, Float lambda[3])
Fast non-iterative 3x3 eigenvalue decomposition.
Matrix3x3(Stream *stream)
Unserialize a matrix from a stream.
Definition: matrix.h:581
Vector preMult(const Vector &v) const
multiply the matrix by transpose of v, returns the transpose of the line vector.
Definition: matrix.h:611
Matrix3x3(Float a00, Float a01, Float a02, Float a10, Float a11, Float a12, Float a20, Float a21, Float a22)
Initialize with the given values.
Definition: matrix.h:587
Basic 2x2 matrix data type.
Definition: matrix.h:455
Matrix operator-(const Matrix &mat) const
Matrix subtraction (returns a temporary)
Definition: matrix.h:164
#define MTS_EXPORT_CORE
Definition: getopt.h:29
Matrix2x2(const Float _m[4])
Initialize the matrix from a given (float) 2x2 array in row-major order.
Definition: matrix.h:466
#define SLog(level, fmt,...)
Write a Log message to the console (static version - to be used outside of classes that derive from O...
Definition: logger.h:49
bool operator==(const Matrix &mat) const
Equality operator.
Definition: matrix.h:104
Vector2 operator*(const Vector2 &v) const
Matrix-vector multiplication.
Definition: matrix.h:521
const T & operator()(int i, int j) const
Indexing operator (const verions)
Definition: matrix.h:101
Matrix2x2(Stream *stream)
Unserialize a matrix from a stream.
Definition: matrix.h:475
T det(const TVector2< T > &v1, const TVector2< T > &v2)
Definition: vector.h:411
Vector4 col(int i) const
Return a column by index.
Definition: matrix.h:736
Float det() const
Return the determinant (Faster than Matrix::det)
Definition: matrix.h:487
void writeArray(const T *array, size_t count)
Write an array to the stream (uses partial template specialization to select a method appropriate to ...
Definition: stream.h:520
bool isZero() const
Check if the matrix is identically zero.
Definition: matrix.h:365
Matrix3x3(const Float _m[9])
Initialize the matrix from a given (float) 3x3 array in row-major order.
Definition: matrix.h:571
Matrix(const T _m[M *N])
Initialize the matrix from a given (flat) MxN array in row-major order.
Definition: matrix.h:70
Matrix4x4()
Definition: matrix.h:657
Matrix3x3(const Matrix< 3, 3, Float > &mtx)
Copy constructor.
Definition: matrix.h:584
Matrix4x4 & operator=(const Matrix< 4, 4, Float > &mat)
Assignment operator.
Definition: matrix.h:721
Matrix4x4(const Float _m[16])
Initialize the matrix from a given (float) 4x4 array in row-major order.
Definition: matrix.h:666
Matrix3x3(const Vector &v1, const Vector &v2, const Vector &v3)
Initialize the matrix from three 3D column vectors.
Definition: matrix.h:574
Vector4 operator*(const Vector4 &v) const
Matrix-vector multiplication.
Definition: matrix.h:702
Matrix()
Construct a new MxN matrix without initializing it.
Definition: matrix.h:48
Vector2 row(int i) const
Return a row by index.
Definition: matrix.h:546
Matrix(const T _m[M][N])
Initialize the matrix from a given MxN array.
Definition: matrix.h:65
void transpose(Matrix< N, M, T > &target) const
Compute the transpose of this matrix.
Definition: matrix.h:414
Matrix(Stream *stream)
Unserialize a matrix from a stream.
Definition: matrix.h:75
Matrix2x2 operator*(Float value) const
Scalar multiplication (creates a temporary)
Definition: matrix.h:529
Matrix4x4(const Float _m[4][4])
Initialize the matrix from a given 4x4 array.
Definition: matrix.h:663
TVector2< Float > Vector2
Definition: fwd.h:106
const Matrix & operator-=(const Matrix &mat)
Matrix subtraction.
Definition: matrix.h:182
TVector4< Float > Vector4
Definition: fwd.h:122
T det() const
Compute the determinant of a square matrix (internally creates a LU decomposition) ...
Definition: matrix.h:388
Abstract seekable stream class.
Definition: stream.h:58
Matrix3x3()
Definition: matrix.h:562
T m[M][N]
Definition: matrix.h:35
Warning message.
Definition: formatter.h:32
const Matrix & operator*=(const Matrix &mat)
Matrix multiplication (for square matrices)
Definition: matrix.h:259
const Matrix & operator-=(T value)
Matrix-scalar addition.
Definition: matrix.h:198
Matrix2x2()
Definition: matrix.h:457
TVector3< Float > Vector3
Definition: fwd.h:115
const Matrix & operator+=(T value)
Matrix-scalar addition.
Definition: matrix.h:156
const Matrix & operator/=(T value)
Scalar division.
Definition: matrix.h:246
Basic 4x4 matrix data type.
Definition: matrix.h:656
Matrix2x2(Float a00, Float a01, Float a10, Float a11)
Initialize with the given values.
Definition: matrix.h:481
Matrix2x2(const Vector2 &v1, const Vector2 &v2)
Initialize the matrix from two 2D column vectors.
Definition: matrix.h:469
Matrix operator-() const
Component-wise negation.
Definition: matrix.h:206
const Matrix & operator*=(T value)
Scalar multiplication.
Definition: matrix.h:224
Matrix2x2(const Float _m[2][2])
Initialize the matrix from a given 2x2 array.
Definition: matrix.h:463
Float det3x3() const
Return the determinant of the upper left 3x3 sub-matrix.
Definition: matrix.h:695
Matrix operator/(T value) const
Scalar division (creates a temporary)
Definition: matrix.h:232
void readArray(T *array, size_t count)
Read an array from the stream (uses partial template specialization to select a method appropriate to...
Definition: stream.h:516
Matrix operator+(T value) const
Matrix-scalar addition (returns a temporary)
Definition: matrix.h:139
Matrix3x3(Float value)
Initialize the matrix with constant entries.
Definition: matrix.h:565
const Matrix & operator-(T value)
Matrix-scalar subtraction.
Definition: matrix.h:190
Matrix operator-(T value) const
Matrix-scalar subtraction (returns a temporary)
Definition: matrix.h:173
FINLINE bool invert2x2(Matrix2x2 &target, Float &det) const
Compute the inverse with det (Faster than Matrix::invert)
Definition: matrix.h:508
Matrix & operator=(const Matrix &mat)
Assignment operator.
Definition: matrix.h:122
#define RCPOVERFLOW
Definition: constants.h:97
Matrix(const Matrix &mtx)
Copy constructor.
Definition: matrix.h:80
Float det() const
Return the determinant (Faster than Matrix::det())
Definition: matrix.h:596
const Matrix & operator+=(const Matrix &mat)
Matrix addition.
Definition: matrix.h:148
void setIdentity()
Initialize with the identity matrix.
Definition: matrix.h:85
Float frob() const
Compute the Frobenius norm.
Definition: matrix.h:276
bool isIdentity() const
Test if this is the identity matrix.
Definition: matrix.h:374
Matrix4x4(const Matrix< 4, 4, Float > &mtx)
Copy constructor.
Definition: matrix.h:680
Basic 3x3 matrix data type.
Definition: matrix.h:560
Matrix2x2 & operator=(const Matrix< 2, 2, Float > &mat)
Assignment operator.
Definition: matrix.h:538
T luDet(int pivsign) const
Compute the determinant of a decomposed matrix created by lu()
Definition: matrix.inl:122
void symEig(Matrix &Q, T d[M]) const
Perform a symmetric eigendecomposition of a square matrix into Q and D.
Definition: matrix.h:405
Vector2 col(int i) const
Return a column by index.
Definition: matrix.h:551
bool eig3(Matrix3x3 &m, Float lambda[3])
Fast 3x3 eigenvalue decomposition.
void setZero()
Initialize with zeroes.
Definition: matrix.h:92