37 static bool IsCofactorNegated(
int row,
int col) {
39 return ((row + col) & 1) != 0;
43 static T CofactorElement3(
const Matrix<3, T>& m,
int row,
int col) {
44 static const int index[3][2] = { {1, 2}, {0, 2}, {0, 1} };
45 const int i0 = index[row][0];
46 const int i1 = index[row][1];
47 const int j0 = index[col][0];
48 const int j1 = index[col][1];
49 const T cofactor = m(i0, j0) * m(i1, j1) - m(i0, j1) * m(i1, j0);
50 return IsCofactorNegated(row, col) ? -cofactor : cofactor;
54 static T CofactorElement4(
const Matrix<4, T>& m,
int row,
int col) {
57 static const int index[4][3] = { {1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 1, 2} };
58 const int i0 = index[row][0];
59 const int i1 = index[row][1];
60 const int i2 = index[row][2];
61 const int j0 = index[col][0];
62 const int j1 = index[col][1];
63 const int j2 = index[col][2];
64 const T c0 = m(i0, j0) * (m(i1, j1) * m(i2, j2) - m(i1, j2) * m(i2, j1));
65 const T c1 = -m(i0, j1) * (m(i1, j0) * m(i2, j2) - m(i1, j2) * m(i2, j0));
66 const T c2 = m(i0, j2) * (m(i1, j0) * m(i2, j1) - m(i1, j1) * m(i2, j0));
67 const T cofactor = c0 + c1 + c2;
68 return IsCofactorNegated(row, col) ? -cofactor : cofactor;
79 static T Determinant2(
const Matrix<2, T>& m) {
80 return m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0);
84 static T Determinant3(
const Matrix<3, T>& m) {
85 return (m(0, 0) * CofactorElement3(m, 0, 0) +
86 m(0, 1) * CofactorElement3(m, 0, 1) +
87 m(0, 2) * CofactorElement3(m, 0, 2));
91 static T Determinant4(
const Matrix<4, T>& m) {
92 return (m(0, 0) * CofactorElement4(m, 0, 0) +
93 m(0, 1) * CofactorElement4(m, 0, 1) +
94 m(0, 2) * CofactorElement4(m, 0, 2) +
95 m(0, 3) * CofactorElement4(m, 0, 3));
105 template <
typename T>
106 Matrix<2, T> CofactorMatrix2(
const Matrix<2, T>& m) {
107 return Matrix<2, T>(m(1, 1), -m(1, 0),
111 template <
typename T>
112 Matrix<3, T> CofactorMatrix3(
const Matrix<3, T>& m) {
114 for (
int row = 0; row < 3; ++row) {
115 for (
int col = 0; col < 3; ++col)
116 result(row, col) = CofactorElement3(m, row, col);
121 template <
typename T>
122 Matrix<4, T> CofactorMatrix4(
const Matrix<4, T>& m) {
124 for (
int row = 0; row < 4; ++row) {
125 for (
int col = 0; col < 4; ++col)
126 result(row, col) = CofactorElement4(m, row, col);
138 template <
typename T>
139 Matrix<2, T> Adjugate2(
const Matrix<2, T>& m,
T* determinant) {
140 const T m00 = m(0, 0);
141 const T m01 = m(0, 1);
142 const T m10 = m(1, 0);
143 const T m11 = m(1, 1);
145 *determinant = m00 * m11 - m01 * m10;
146 return Matrix<2, T>(m11, -m01, -m10, m00);
149 template <
typename T>
150 Matrix<3, T> Adjugate3(
const Matrix<3, T>& m,
T* determinant) {
151 const Matrix<3, T> cofactor_matrix = CofactorMatrix3(m);
153 *determinant = m(0, 0) * cofactor_matrix(0, 0) +
154 m(0, 1) * cofactor_matrix(0, 1) +
155 m(0, 2) * cofactor_matrix(0, 2);
160 template <
typename T>
161 Matrix<4, T> Adjugate4(
const Matrix<4, T>& m,
T* determinant) {
169 const T s0 = m(0, 0) * m(1, 1) - m(1, 0) * m(0, 1);
170 const T s1 = m(0, 0) * m(1, 2) - m(1, 0) * m(0, 2);
171 const T s2 = m(0, 0) * m(1, 3) - m(1, 0) * m(0, 3);
173 const T s3 = m(0, 1) * m(1, 2) - m(1, 1) * m(0, 2);
174 const T s4 = m(0, 1) * m(1, 3) - m(1, 1) * m(0, 3);
175 const T s5 = m(0, 2) * m(1, 3) - m(1, 2) * m(0, 3);
177 const T c0 = m(2, 0) * m(3, 1) - m(3, 0) * m(2, 1);
178 const T c1 = m(2, 0) * m(3, 2) - m(3, 0) * m(2, 2);
179 const T c2 = m(2, 0) * m(3, 3) - m(3, 0) * m(2, 3);
181 const T c3 = m(2, 1) * m(3, 2) - m(3, 1) * m(2, 2);
182 const T c4 = m(2, 1) * m(3, 3) - m(3, 1) * m(2, 3);
183 const T c5 = m(2, 2) * m(3, 3) - m(3, 2) * m(2, 3);
186 *determinant = s0 * c5 - s1 * c4 + s2 * c3 + s3 * c2 - s4 * c1 + s5 * c0;
189 m(1, 1) * c5 - m(1, 2) * c4 + m(1, 3) * c3,
190 -m(0, 1) * c5 + m(0, 2) * c4 - m(0, 3) * c3,
191 m(3, 1) * s5 - m(3, 2) * s4 + m(3, 3) * s3,
192 -m(2, 1) * s5 + m(2, 2) * s4 - m(2, 3) * s3,
194 -m(1, 0) * c5 + m(1, 2) * c2 - m(1, 3) * c1,
195 m(0, 0) * c5 - m(0, 2) * c2 + m(0, 3) * c1,
196 -m(3, 0) * s5 + m(3, 2) * s2 - m(3, 3) * s1,
197 m(2, 0) * s5 - m(2, 2) * s2 + m(2, 3) * s1,
199 m(1, 0) * c4 - m(1, 1) * c2 + m(1, 3) * c0,
200 -m(0, 0) * c4 + m(0, 1) * c2 - m(0, 3) * c0,
201 m(3, 0) * s4 - m(3, 1) * s2 + m(3, 3) * s0,
202 -m(2, 0) * s4 + m(2, 1) * s2 - m(2, 3) * s0,
204 -m(1, 0) * c3 + m(1, 1) * c1 - m(1, 2) * c0,
205 m(0, 0) * c3 - m(0, 1) * c1 + m(0, 2) * c0,
206 -m(3, 0) * s3 + m(3, 1) * s1 - m(3, 2) * s0,
207 m(2, 0) * s3 - m(2, 1) * s1 + m(2, 2) * s0);
226 template <
int Dimension,
typename T>
228 DCHECK(
false) <<
"Unspecialized Matrix Determinant function used.";
231 template <
int Dimension,
typename T>
233 DCHECK(
false) <<
"Unspecialized Matrix Cofactor function used.";
236 template <
int Dimension,
typename T>
239 DCHECK(
false) <<
"Unspecialized Matrix Adjugate function used.";
242 template <
int Dimension,
typename T>
250 if (det == static_cast<T>(0))
253 return adjugate * (
static_cast<T>(1) / det);
256 template <
int Dimension,
typename T>
258 for (
int col1 = 0; col1 < Dimension; ++col1) {
261 for (
int col2 = col1 + 1; col2 < Dimension; ++col2)
262 if (
Dot(column,
Column(m, col2)) > tolerance)
275 #define ION_SPECIALIZE_MATRIX_FUNCS(dim, scalar) \
276 template <> scalar ION_API Determinant(const Matrix<dim, scalar>& m) { \
277 return Determinant ## dim(m); \
279 template <> Matrix<dim, scalar> ION_API CofactorMatrix( \
280 const Matrix<dim, scalar>& m) { \
281 return CofactorMatrix ## dim(m); \
283 template <> Matrix<dim, scalar> ION_API AdjugateWithDeterminant( \
284 const Matrix<dim, scalar>& m, scalar* determinant) { \
285 return Adjugate ## dim(m, determinant); \
289 template Matrix<dim, scalar> ION_API InverseWithDeterminant( \
290 const Matrix<dim, scalar>& m, scalar* determinant); \
291 template bool ION_API MatrixAlmostOrthogonal( \
292 const Matrix<dim, scalar>& m, scalar tolerance)
301 #undef ION_SPECIALIZE_MATRIX_FUNCS
Matrix< Dimension, T > AdjugateWithDeterminant(const Matrix< Dimension, T > &m, T *determinant)
Returns the adjugate of the matrix, which is defined as the transpose of the cofactor matrix...
T Dot(const Vector< Dimension, T > &v0, const Vector< Dimension, T > &v1)
Returns the dot (inner) product of two Vectors.
bool MatrixAlmostOrthogonal(const Matrix< Dimension, T > &m, T tolerance)
Returns true if the dot product of all column vector pairs in the matrix is less than a provided tole...
Vector< Dimension, T > Column(const Matrix< Dimension, T > &m, int col)
Returns a particular column of a matrix as a vector.
The Matrix class defines a square N-dimensional matrix.
T Determinant(const Matrix< Dimension, T > &m)
Public functions.
Matrix< Dimension, T > CofactorMatrix(const Matrix< Dimension, T > &m)
Returns the signed cofactor matrix (adjunct) of the matrix.
Copyright 2016 Google Inc.
Matrix< Dimension, T > InverseWithDeterminant(const Matrix< Dimension, T > &m, T *determinant)
Returns the inverse of the matrix.
static Matrix Zero()
Returns a Matrix containing all zeroes.
const T Abs(const T &val)
Returns the absolute value of a number in a type-safe way.
Matrix< Dimension, T > Transpose(const Matrix< Dimension, T > &m)
Public functions.
ION_SPECIALIZE_MATRIX_FUNCS(2, float)
T LengthSquared(const Vector< Dimension, T > &v)
Returns the square of the length of a Vector.