Eule::Matrix4x4 Class Reference

A matrix 4x4 class representing a 3d transformation. More...

`#include <Matrix4x4.h>`

## Public Member Functions

| Matrix4x4 ()
| Matrix4x4 (const Matrix4x4 &other)
| Matrix4x4 (Matrix4x4 &&other) noexcept
Matrix4x4 | operator* (const Matrix4x4 &other) const
void | operator*= (const Matrix4x4 &other)
Matrix4x4 | operator/ (const Matrix4x4 &other) const
void | operator/= (const Matrix4x4 &other)
Matrix4x4 | operator* (const double scalar) const
| Cellwise scaling. More...
void | operator*= (const double scalar)
| Cellwise scaling. More...
Matrix4x4 | operator/ (const double denominator) const
| Cellwise division. More...
void | operator/= (const double denominator)
| Cellwise division. More...
Matrix4x4 | operator+ (const Matrix4x4 &other) const
| Cellwise addition. More...
void | operator+= (const Matrix4x4 &other)
| Cellwise addition. More...
Matrix4x4 | operator- (const Matrix4x4 &other) const
| Cellwise subtraction. More...
void | operator-= (const Matrix4x4 &other)
| Cellwise subtraction. More...
std::array< double, 4 > & | operator[] (std::size_t y)
const std::array< double, 4 > & | operator[] (std::size_t y) const
void | operator= (const Matrix4x4 &other)
void | operator= (Matrix4x4 &&other) noexcept
bool | operator== (const Matrix4x4 &other)
bool | operator!= (const Matrix4x4 &other)
const Vector3d | GetTranslationComponent () const
| Will return d,h,l as a Vector3d(x,y,z) More...
void | SetTranslationComponent (const Vector3d &trans)
| Will set d,h,l from a Vector3d(x,y,z) More...
Matrix4x4 | DropTranslationComponents () const
| Will return this Matrix4x4 with d,h,l being set to 0. More...
Matrix4x4 | Transpose3x3 () const
| Will return the 3x3 transpose of this matrix. More...
Matrix4x4 | Transpose4x4 () const
| Will return the 4x4 transpose of this matrix. More...
Matrix4x4 | Multiply4x4 (const Matrix4x4 &o) const
| Will return the Matrix4x4 of an actual 4x4 multiplication. operator* only does a 3x3. More...
Matrix4x4 | GetCofactors (std::size_t p, std::size_t q, std::size_t n) const
| Will return the cofactors of this matrix, by dimension n. More...
double | Determinant (std::size_t n) const
| Will return the determinant, by dimension n. More...
Matrix4x4 | Adjoint (std::size_t n) const
| Will return the adjoint of this matrix, by dimension n. More...
Matrix4x4 | Inverse3x3 () const
| Will return the 3x3-inverse of this matrix. More...
Matrix4x4 | Inverse4x4 () const
| Will return the full 4x4-inverse of this matrix. More...
bool | IsInversible3x3 () const
| Will check if the 3x3-component is inversible. More...
bool | IsInversible4x4 () const
| Will check if the entire matrix is inversible. More...
bool | Similar (const Matrix4x4 &other, double epsilon=0.00001) const
| Will compare if two matrices are similar to a certain epsilon value. More...

## Public Attributes

std::array< std::array< double, 4 >, 4 > | v
| Array holding the matrices values. More...
double & | a = v[0][0]
double & | b = v[0][1]
double & | c = v[0][2]
double & | d = v[0][3]
double & | e = v[1][0]
double & | f = v[1][1]
double & | g = v[1][2]
double & | h = v[1][3]
double & | i = v[2][0]
double & | j = v[2][1]
double & | k = v[2][2]
double & | l = v[2][3]
double & | m = v[3][0]
double & | n = v[3][1]
double & | o = v[3][2]
double & | p = v[3][3]

## Friends

std::ostream & | operator<< (std::ostream &os, const Matrix4x4 &m)
std::wostream & | operator<< (std::wostream &os, const Matrix4x4 &m)

## Detailed Description

A matrix 4x4 class representing a 3d transformation.

This matrix consists of a 3x3 matrix containing scaling and rotation information, and a vector (d,h,l) representing the translation.

myMatrix[y][x] = 3
X ==============>
Y
| # # # # # # # # # # #
| # a b c d #
| # #
| # e f g h #
| # #
V # i j k l #
# #
# m n o p #
# # # # # # # # # # #

Note: This class can also be used to compute regular 4x4 multiplications. Use Multiply4x4() for that.

Definition at line 36 of file Matrix4x4.h.

## Constructor & Destructor Documentation

## Matrix4x4() [1/3]

Matrix4x4::Matrix4x4 | ( |  | ) |

Definition at line 12 of file Matrix4x4.cpp.

{
// Create identity matrix
for (std::size_t i = 0; i < 4; i++)
for (std::size_t j = 0; j < 4; j++)
v[i][j] = double(i == j);
return;
}

## Matrix4x4() [2/3]

Matrix4x4::Matrix4x4 | ( | const Matrix4x4 & | other | ) |

Definition at line 22 of file Matrix4x4.cpp.

{
v = other.v;
return;
}

## Matrix4x4() [3/3]

Matrix4x4::Matrix4x4 | ( | Matrix4x4 && | other | ) |

noexcept

Definition at line 28 of file Matrix4x4.cpp.

{
v = std::move(other.v);
return;
}

## Member Function Documentation

## Adjoint()

Matrix4x4 Matrix4x4::Adjoint | ( | std::size_t | n | ) | const

Will return the adjoint of this matrix, by dimension n.

Definition at line 533 of file Matrix4x4.cpp.

{
if (n > 4)
throw std::runtime_error("Dimension out of range! 0 <= n <= 4");
Matrix4x4 adj;
double sign = 1;
for (std::size_t i = 0; i < n; i++)
for (std::size_t j = 0; j < n; j++)
{
Matrix4x4 cofs = GetCofactors(i, j, n);
// sign of adj[j][i] positive if sum of row
// and column indexes is even.
sign = ((i + j) % 2 == 0) ? 1 : -1;
// Interchanging rows and columns to get the
// transpose of the cofactor matrix
adj[j][i] = sign * (cofs.Determinant(n - 1));
}
return adj;
}

## Determinant()

double Matrix4x4::Determinant | ( | std::size_t | n | ) | const

Will return the determinant, by dimension n.

Definition at line 511 of file Matrix4x4.cpp.

{
if (n > 4)
throw std::runtime_error("Dimension out of range! 0 <= n <= 4");
double d = 0;
double sign = 1;
if (n == 1)
return v[0][0];
for (std::size_t x = 0; x < n; x++)
{
Matrix4x4 cofs = GetCofactors(0, x, n);
d += sign * v[0][x] * cofs.Determinant(n - 1);
sign = -sign;
}
return d;
}

## DropTranslationComponents()

Matrix4x4 Matrix4x4::DropTranslationComponents | ( |  | ) | const

Will return this Matrix4x4 with d,h,l being set to 0.

Definition at line 420 of file Matrix4x4.cpp.

{
Matrix4x4 m(*this);
m.d = 0;
m.h = 0;
m.l = 0;
return m;
}

## GetCofactors()

Matrix4x4 Matrix4x4::GetCofactors | ( | std::size_t | p,
|  | std::size_t | q,
|  | std::size_t | n
| ) |  | const

Will return the cofactors of this matrix, by dimension n.

Definition at line 478 of file Matrix4x4.cpp.

{
if (n > 4)
throw std::runtime_error("Dimension out of range! 0 <= n <= 4");
Matrix4x4 cofs;
std::size_t i = 0;
std::size_t j = 0;
for (std::size_t y = 0; y < n; y++)
for (std::size_t x = 0; x < n; x++)
{
if ((y != p) && (x != q))
{
cofs[i][j] = v[y][x];
j++;
}
if (j == n - 1)
{
j = 0;
i++;
}
}
return cofs;
}

## GetTranslationComponent()

const Vector3d Matrix4x4::GetTranslationComponent | ( |  | ) | const

Will return d,h,l as a Vector3d(x,y,z)

Definition at line 407 of file Matrix4x4.cpp.

{
return Vector3d(d, h, l);
}

## Inverse3x3()

Matrix4x4 Matrix4x4::Inverse3x3 | ( |  | ) | const

Will return the 3x3-inverse of this matrix.

Meaning, the 3x3 component will be inverted, and the translation component will be negated

Definition at line 558 of file Matrix4x4.cpp.

{
Matrix4x4 inv;
double det = Determinant(3);
if (det == 0.0)
throw std::runtime_error("Matrix3x3 not inversible!");
Matrix4x4 adj = Adjoint(3);
for (std::size_t i = 0; i < 3; i++)
for (std::size_t j = 0; j < 3; j++)
inv[i][j] = adj[i][j] / det;
inv.SetTranslationComponent(-GetTranslationComponent());
return inv;
}

## Inverse4x4()

Matrix4x4 Matrix4x4::Inverse4x4 | ( |  | ) | const

Will return the full 4x4-inverse of this matrix.

Definition at line 577 of file Matrix4x4.cpp.

{
Matrix4x4 inv;
double det = Determinant(4);
if (det == 0.0)
throw std::runtime_error("Matrix4x4 not inversible!");
Matrix4x4 adj = Adjoint(4);
for (std::size_t i = 0; i < 4; i++)
for (std::size_t j = 0; j < 4; j++)
inv[i][j] = adj[i][j] / det;
return inv;
}

## IsInversible3x3()

bool Matrix4x4::IsInversible3x3 | ( |  | ) | const

Will check if the 3x3-component is inversible.

Definition at line 598 of file Matrix4x4.cpp.

{
return (Determinant(3) != 0);
}

## IsInversible4x4()

bool Matrix4x4::IsInversible4x4 | ( |  | ) | const

Will check if the entire matrix is inversible.

Definition at line 603 of file Matrix4x4.cpp.

{
return (Determinant(4) != 0);
}

## Multiply4x4()

Matrix4x4 Matrix4x4::Multiply4x4 | ( | const Matrix4x4 & | o | ) | const

Will return the Matrix4x4 of an actual 4x4 multiplication. operator* only does a 3x3.

Definition at line 451 of file Matrix4x4.cpp.

{
Matrix4x4 m;
m[0][0] = (v[0][0]*o[0][0]) + (v[0][1]*o[1][0]) + (v[0][2]*o[2][0]) + (v[0][3]*o[3][0]);
m[0][1] = (v[0][0]*o[0][1]) + (v[0][1]*o[1][1]) + (v[0][2]*o[2][1]) + (v[0][3]*o[3][1]);
m[0][2] = (v[0][0]*o[0][2]) + (v[0][1]*o[1][2]) + (v[0][2]*o[2][2]) + (v[0][3]*o[3][2]);
m[0][3] = (v[0][0]*o[0][3]) + (v[0][1]*o[1][3]) + (v[0][2]*o[2][3]) + (v[0][3]*o[3][3]);
m[1][0] = (v[1][0]*o[0][0]) + (v[1][1]*o[1][0]) + (v[1][2]*o[2][0]) + (v[1][3]*o[3][0]);
m[1][1] = (v[1][0]*o[0][1]) + (v[1][1]*o[1][1]) + (v[1][2]*o[2][1]) + (v[1][3]*o[3][1]);
m[1][2] = (v[1][0]*o[0][2]) + (v[1][1]*o[1][2]) + (v[1][2]*o[2][2]) + (v[1][3]*o[3][2]);
m[1][3] = (v[1][0]*o[0][3]) + (v[1][1]*o[1][3]) + (v[1][2]*o[2][3]) + (v[1][3]*o[3][3]);
m[2][0] = (v[2][0]*o[0][0]) + (v[2][1]*o[1][0]) + (v[2][2]*o[2][0]) + (v[2][3]*o[3][0]);
m[2][1] = (v[2][0]*o[0][1]) + (v[2][1]*o[1][1]) + (v[2][2]*o[2][1]) + (v[2][3]*o[3][1]);
m[2][2] = (v[2][0]*o[0][2]) + (v[2][1]*o[1][2]) + (v[2][2]*o[2][2]) + (v[2][3]*o[3][2]);
m[2][3] = (v[2][0]*o[0][3]) + (v[2][1]*o[1][3]) + (v[2][2]*o[2][3]) + (v[2][3]*o[3][3]);
m[3][0] = (v[3][0]*o[0][0]) + (v[3][1]*o[1][0]) + (v[3][2]*o[2][0]) + (v[3][3]*o[3][0]);
m[3][1] = (v[3][0]*o[0][1]) + (v[3][1]*o[1][1]) + (v[3][2]*o[2][1]) + (v[3][3]*o[3][1]);
m[3][2] = (v[3][0]*o[0][2]) + (v[3][1]*o[1][2]) + (v[3][2]*o[2][2]) + (v[3][3]*o[3][2]);
m[3][3] = (v[3][0]*o[0][3]) + (v[3][1]*o[1][3]) + (v[3][2]*o[2][3]) + (v[3][3]*o[3][3]);
return m;
}

## operator!=()

bool Matrix4x4::operator!= | ( | const Matrix4x4 & | other | ) |

Definition at line 402 of file Matrix4x4.cpp.

{
return !operator==(other);
}

## operator*() [1/2]

Matrix4x4 Matrix4x4::operator* | ( | const double | scalar | ) | const

Cellwise scaling.

Definition at line 164 of file Matrix4x4.cpp.

{
Matrix4x4 m;
#ifndef _EULE_NO_INTRINSICS_
// Load matrix rows
__m256d __row0 = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]);
__m256d __row1 = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]);
__m256d __row2 = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]);
__m256d __row3 = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]);
// Load scalar
__m256d __scalar = _mm256_set1_pd(scalar);
// Scale values
__m256d __sr0 = _mm256_mul_pd(__row0, __scalar);
__m256d __sr1 = _mm256_mul_pd(__row1, __scalar);
__m256d __sr2 = _mm256_mul_pd(__row2, __scalar);
__m256d __sr3 = _mm256_mul_pd(__row3, __scalar);
// Extract results
_mm256_storeu_pd(m.v[0].data(), __sr0);
_mm256_storeu_pd(m.v[1].data(), __sr1);
_mm256_storeu_pd(m.v[2].data(), __sr2);
_mm256_storeu_pd(m.v[3].data(), __sr3);
#else
for (std::size_t x = 0; x < 4; x++)
for (std::size_t y = 0; y < 4; y++)
m[x][y] = v[x][y] * scalar;
#endif
return m;
}

## operator*() [2/2]

Matrix4x4 Matrix4x4::operator* | ( | const Matrix4x4 & | other | ) | const

Definition at line 34 of file Matrix4x4.cpp.

{
Matrix4x4 newMatrix;
newMatrix.p = 1;
#ifndef _EULE_NO_INTRINSICS_
/* <= Matrix3x3 multiplication => */
// Load matrix components
__m256d __va1 = _mm256_set_pd(v[0][0], v[0][0], v[0][0], v[1][0]);
__m256d __va2 = _mm256_set_pd(v[1][0], v[1][0], v[2][0], v[2][0]);
__m256d __oa1 = _mm256_set_pd(other[0][0], other[0][1], other[0][2], other[0][0]);
__m256d __oa2 = _mm256_set_pd(other[0][1], other[0][2], other[0][0], other[0][1]);
__m256d __vb1 = _mm256_set_pd(v[0][1], v[0][1], v[0][1], v[1][1]);
__m256d __vb2 = _mm256_set_pd(v[1][1], v[1][1], v[2][1], v[2][1]);
__m256d __ob1 = _mm256_set_pd(other[1][0], other[1][1], other[1][2], other[1][0]);
__m256d __ob2 = _mm256_set_pd(other[1][1], other[1][2], other[1][0], other[1][1]);
__m256d __vc1 = _mm256_set_pd(v[0][2], v[0][2], v[0][2], v[1][2]);
__m256d __vc2 = _mm256_set_pd(v[1][2], v[1][2], v[2][2], v[2][2]);
__m256d __oc1 = _mm256_set_pd(other[2][0], other[2][1], other[2][2], other[2][0]);
__m256d __oc2 = _mm256_set_pd(other[2][1], other[2][2], other[2][0], other[2][1]);
// Initialize sums
__m256d __sum1 = _mm256_set1_pd(0);
__m256d __sum2 = _mm256_set1_pd(0);
// Let's multiply-add them together
// First, the first block
__sum1 = _mm256_fmadd_pd(__va1, __oa1, __sum1);
__sum1 = _mm256_fmadd_pd(__vb1, __ob1, __sum1);
__sum1 = _mm256_fmadd_pd(__vc1, __oc1, __sum1);
// Then the second block
__sum2 = _mm256_fmadd_pd(__va2, __oa2, __sum2);
__sum2 = _mm256_fmadd_pd(__vb2, __ob2, __sum2);
__sum2 = _mm256_fmadd_pd(__vc2, __oc2, __sum2);
// Retrieve results
double sum1[4];
double sum2[4];
_mm256_storeu_pd(sum1, __sum1);
_mm256_storeu_pd(sum2, __sum2);
// Apply results
// Block 1
newMatrix[0][0] = sum1[3];
newMatrix[0][1] = sum1[2];
newMatrix[0][2] = sum1[1];
newMatrix[1][0] = sum1[0];
// Block 2
newMatrix[1][1] = sum2[3];
newMatrix[1][2] = sum2[2];
newMatrix[2][0] = sum2[1];
newMatrix[2][1] = sum2[0];
// Does not fit in the intrinsic calculation. Might just calculate 'by hand'.
newMatrix[2][2] = (v[2][0] * other[0][2]) + (v[2][1] * other[1][2]) + (v[2][2] * other[2][2]);
/* <= Translation component => */
// Load translation components into registers
__m256d __transSelf = _mm256_set_pd(0, l, h, d);
__m256d __transOther = _mm256_set_pd(0, other.l, other.h, other.d);
// Let's add them
__m256d __sum = _mm256_add_pd(__transSelf, __transOther);
// Retrieve results
double sum[4];
_mm256_storeu_pd(sum, __sum);
// Apply them
newMatrix.d = sum[0];
newMatrix.h = sum[1];
newMatrix.l = sum[2];
#else
// Rotation, Scaling
newMatrix[0][0] = (v[0][0] * other[0][0]) + (v[0][1] * other[1][0]) + (v[0][2] * other[2][0]);
newMatrix[0][1] = (v[0][0] * other[0][1]) + (v[0][1] * other[1][1]) + (v[0][2] * other[2][1]);
newMatrix[0][2] = (v[0][0] * other[0][2]) + (v[0][1] * other[1][2]) + (v[0][2] * other[2][2]);
newMatrix[1][0] = (v[1][0] * other[0][0]) + (v[1][1] * other[1][0]) + (v[1][2] * other[2][0]);
newMatrix[1][1] = (v[1][0] * other[0][1]) + (v[1][1] * other[1][1]) + (v[1][2] * other[2][1]);
newMatrix[1][2] = (v[1][0] * other[0][2]) + (v[1][1] * other[1][2]) + (v[1][2] * other[2][2]);
newMatrix[2][0] = (v[2][0] * other[0][0]) + (v[2][1] * other[1][0]) + (v[2][2] * other[2][0]);
newMatrix[2][1] = (v[2][0] * other[0][1]) + (v[2][1] * other[1][1]) + (v[2][2] * other[2][1]);
newMatrix[2][2] = (v[2][0] * other[0][2]) + (v[2][1] * other[1][2]) + (v[2][2] * other[2][2]);
// Translation
newMatrix[0][3] = v[0][3] + other[0][3];
newMatrix[1][3] = v[1][3] + other[1][3];
newMatrix[2][3] = v[2][3] + other[2][3];
#endif
return newMatrix;
}

## operator*=() [1/2]

void Matrix4x4::operator*= | ( | const double | scalar | ) |

Cellwise scaling.

Definition at line 202 of file Matrix4x4.cpp.

{
*this = *this * scalar;
return;
}

## operator*=() [2/2]

void Matrix4x4::operator*= | ( | const Matrix4x4 & | other | ) |

Definition at line 147 of file Matrix4x4.cpp.

{
*this = *this * other;
return;
}

## operator+()

Matrix4x4 Matrix4x4::operator+ | ( | const Matrix4x4 & | other | ) | const

Cellwise addition.

Definition at line 221 of file Matrix4x4.cpp.

{
Matrix4x4 m;
#ifndef _EULE_NO_INTRINSICS_
// Load matrix rows
__m256d __row0a = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]);
__m256d __row1a = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]);
__m256d __row2a = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]);
__m256d __row3a = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]);
__m256d __row0b = _mm256_set_pd(other[0][3], other[0][2], other[0][1], other[0][0]);
__m256d __row1b = _mm256_set_pd(other[1][3], other[1][2], other[1][1], other[1][0]);
__m256d __row2b = _mm256_set_pd(other[2][3], other[2][2], other[2][1], other[2][0]);
__m256d __row3b = _mm256_set_pd(other[3][3], other[3][2], other[3][1], other[3][0]);
// Add rows
__m256d __sr0 = _mm256_add_pd(__row0a, __row0b);
__m256d __sr1 = _mm256_add_pd(__row1a, __row1b);
__m256d __sr2 = _mm256_add_pd(__row2a, __row2b);
__m256d __sr3 = _mm256_add_pd(__row3a, __row3b);
// Extract results
_mm256_storeu_pd(m.v[0].data(), __sr0);
_mm256_storeu_pd(m.v[1].data(), __sr1);
_mm256_storeu_pd(m.v[2].data(), __sr2);
_mm256_storeu_pd(m.v[3].data(), __sr3);
#else
for (std::size_t x = 0; x < 4; x++)
for (std::size_t y = 0; y < 4; y++)
m[x][y] = v[x][y] + other[x][y];
#endif
return m;
}

## operator+=()

void Matrix4x4::operator+= | ( | const Matrix4x4 & | other | ) |

Cellwise addition.

Definition at line 261 of file Matrix4x4.cpp.

{
#ifndef _EULE_NO_INTRINSICS_
// Doing it again is a tad directer, and thus faster. We avoid an intermittent Matrix4x4 instance
// Load matrix rows
__m256d __row0a = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]);
__m256d __row1a = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]);
__m256d __row2a = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]);
__m256d __row3a = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]);
__m256d __row0b = _mm256_set_pd(other[0][3], other[0][2], other[0][1], other[0][0]);
__m256d __row1b = _mm256_set_pd(other[1][3], other[1][2], other[1][1], other[1][0]);
__m256d __row2b = _mm256_set_pd(other[2][3], other[2][2], other[2][1], other[2][0]);
__m256d __row3b = _mm256_set_pd(other[3][3], other[3][2], other[3][1], other[3][0]);
// Add rows
__m256d __sr0 = _mm256_add_pd(__row0a, __row0b);
__m256d __sr1 = _mm256_add_pd(__row1a, __row1b);
__m256d __sr2 = _mm256_add_pd(__row2a, __row2b);
__m256d __sr3 = _mm256_add_pd(__row3a, __row3b);
// Extract results
_mm256_storeu_pd(v[0].data(), __sr0);
_mm256_storeu_pd(v[1].data(), __sr1);
_mm256_storeu_pd(v[2].data(), __sr2);
_mm256_storeu_pd(v[3].data(), __sr3);
#else
*this = *this + other;
#endif
return;
}

## operator-()

Matrix4x4 Matrix4x4::operator- | ( | const Matrix4x4 & | other | ) | const

Cellwise subtraction.

Definition at line 298 of file Matrix4x4.cpp.

{
Matrix4x4 m;
#ifndef _EULE_NO_INTRINSICS_
// Load matrix rows
__m256d __row0a = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]);
__m256d __row1a = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]);
__m256d __row2a = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]);
__m256d __row3a = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]);
__m256d __row0b = _mm256_set_pd(other[0][3], other[0][2], other[0][1], other[0][0]);
__m256d __row1b = _mm256_set_pd(other[1][3], other[1][2], other[1][1], other[1][0]);
__m256d __row2b = _mm256_set_pd(other[2][3], other[2][2], other[2][1], other[2][0]);
__m256d __row3b = _mm256_set_pd(other[3][3], other[3][2], other[3][1], other[3][0]);
// Subtract rows
__m256d __sr0 = _mm256_sub_pd(__row0a, __row0b);
__m256d __sr1 = _mm256_sub_pd(__row1a, __row1b);
__m256d __sr2 = _mm256_sub_pd(__row2a, __row2b);
__m256d __sr3 = _mm256_sub_pd(__row3a, __row3b);
// Extract results
_mm256_storeu_pd(m.v[0].data(), __sr0);
_mm256_storeu_pd(m.v[1].data(), __sr1);
_mm256_storeu_pd(m.v[2].data(), __sr2);
_mm256_storeu_pd(m.v[3].data(), __sr3);
#else
for (std::size_t x = 0; x < 4; x++)
for (std::size_t y = 0; y < 4; y++)
m[x][y] = v[x][y] - other[x][y];
#endif
return m;
}

## operator-=()

void Matrix4x4::operator-= | ( | const Matrix4x4 & | other | ) |

Cellwise subtraction.

Definition at line 338 of file Matrix4x4.cpp.

{
#ifndef _EULE_NO_INTRINSICS_
// Doing it again is a tad directer, and thus faster. We avoid an intermittent Matrix4x4 instance
// Load matrix rows
__m256d __row0a = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]);
__m256d __row1a = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]);
__m256d __row2a = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]);
__m256d __row3a = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]);
__m256d __row0b = _mm256_set_pd(other[0][3], other[0][2], other[0][1], other[0][0]);
__m256d __row1b = _mm256_set_pd(other[1][3], other[1][2], other[1][1], other[1][0]);
__m256d __row2b = _mm256_set_pd(other[2][3], other[2][2], other[2][1], other[2][0]);
__m256d __row3b = _mm256_set_pd(other[3][3], other[3][2], other[3][1], other[3][0]);
// Subtract rows
__m256d __sr0 = _mm256_sub_pd(__row0a, __row0b);
__m256d __sr1 = _mm256_sub_pd(__row1a, __row1b);
__m256d __sr2 = _mm256_sub_pd(__row2a, __row2b);
__m256d __sr3 = _mm256_sub_pd(__row3a, __row3b);
// Extract results
_mm256_storeu_pd(v[0].data(), __sr0);
_mm256_storeu_pd(v[1].data(), __sr1);
_mm256_storeu_pd(v[2].data(), __sr2);
_mm256_storeu_pd(v[3].data(), __sr3);
#else
* this = *this - other;
#endif
return;
}

## operator/() [1/2]

Matrix4x4 Matrix4x4::operator/ | ( | const double | denominator | ) | const

Cellwise division.

Definition at line 208 of file Matrix4x4.cpp.

{
const double precomputeDivision = 1.0 / denominator;
return *this * precomputeDivision;
}

## operator/() [2/2]

Matrix4x4 Matrix4x4::operator/ | ( | const Matrix4x4 & | other | ) | const

Definition at line 153 of file Matrix4x4.cpp.

{
return *this * other.Inverse3x3();
}

## operator/=() [1/2]

void Matrix4x4::operator/= | ( | const double | denominator | ) |

Cellwise division.

Definition at line 215 of file Matrix4x4.cpp.

{
*this = *this / denominator;
return;
}

## operator/=() [2/2]

void Matrix4x4::operator/= | ( | const Matrix4x4 & | other | ) |

Definition at line 158 of file Matrix4x4.cpp.

{
*this = *this * other.Inverse3x3();
return;
}

## operator=() [1/2]

void Matrix4x4::operator= | ( | const Matrix4x4 & | other | ) |

Definition at line 385 of file Matrix4x4.cpp.

{
v = other.v;
return;
}

## operator=() [2/2]

void Matrix4x4::operator= | ( | Matrix4x4 && | other | ) |

noexcept

Definition at line 391 of file Matrix4x4.cpp.

{
v = std::move(other.v);
return;
}

## operator==()

bool Matrix4x4::operator== | ( | const Matrix4x4 & | other | ) |

Definition at line 397 of file Matrix4x4.cpp.

{
return v == other.v;
}

## operator[]() [1/2]

std::array< double, 4 > & Matrix4x4::operator[] | ( | std::size_t | y | ) |

Definition at line 375 of file Matrix4x4.cpp.

{
return v[y];
}

## operator[]() [2/2]

const std::array< double, 4 > & Matrix4x4::operator[] | ( | std::size_t | y | ) | const

Definition at line 380 of file Matrix4x4.cpp.

{
return v[y];
}

## SetTranslationComponent()

void Matrix4x4::SetTranslationComponent | ( | const Vector3d & | trans | ) |

Will set d,h,l from a Vector3d(x,y,z)

Definition at line 412 of file Matrix4x4.cpp.

{
d = trans.x;
h = trans.y;
l = trans.z;
return;
}

## Similar()

bool Matrix4x4::Similar | ( | const Matrix4x4 & | other,
|  | double | epsilon = `0.00001`
| ) |  | const

Will compare if two matrices are similar to a certain epsilon value.

Definition at line 608 of file Matrix4x4.cpp.

{
for (std::size_t i = 0; i < 4; i++)
for (std::size_t j = 0; j < 4; j++)
if (!Math::Similar(v[i][j], other[i][j], epsilon))
return false;
return true;
}

## Transpose3x3()

Matrix4x4 Matrix4x4::Transpose3x3 | ( |  | ) | const

Will return the 3x3 transpose of this matrix.

Definition at line 429 of file Matrix4x4.cpp.

{
Matrix4x4 trans(*this); // Keep other cells
for (std::size_t i = 0; i < 3; i++)
for (std::size_t j = 0; j < 3; j++)
trans[j][i] = v[i][j];
return trans;
}

## Transpose4x4()

Matrix4x4 Matrix4x4::Transpose4x4 | ( |  | ) | const

Will return the 4x4 transpose of this matrix.

Definition at line 440 of file Matrix4x4.cpp.

{
Matrix4x4 trans;
for (std::size_t i = 0; i < 4; i++)
for (std::size_t j = 0; j < 4; j++)
trans[j][i] = v[i][j];
return trans;
}

## Friends And Related Function Documentation

## operator<< [1/2]

std::ostream& operator<< | ( | std::ostream & | os,
|  | const Matrix4x4 & | m
| ) |  |

friend

Definition at line 620 of file Matrix4x4.cpp.

{
os << std::endl;
for (std::size_t y = 0; y < 4; y++)
{
for (std::size_t x = 0; x < 4; x++)
os << " | " << m[y][x];
os << " |" << std::endl;
}
return os;
}

## operator<< [2/2]

std::wostream& operator<< | ( | std::wostream & | os,
|  | const Matrix4x4 & | m
| ) |  |

friend

Definition at line 635 of file Matrix4x4.cpp.

{
os << std::endl;
for (std::size_t y = 0; y < 4; y++)
{
for (std::size_t x = 0; x < 4; x++)
os << L" | " << m[y][x];
os << L" |" << std::endl;
}
return os;
}

## Member Data Documentation

## a

double& Eule::Matrix4x4::a = v[0][0]

Definition at line 128 of file Matrix4x4.h.

## b

double& Eule::Matrix4x4::b = v[0][1]

Definition at line 129 of file Matrix4x4.h.

## c

double& Eule::Matrix4x4::c = v[0][2]

Definition at line 130 of file Matrix4x4.h.

## d

double& Eule::Matrix4x4::d = v[0][3]

Definition at line 131 of file Matrix4x4.h.

## e

double& Eule::Matrix4x4::e = v[1][0]

Definition at line 132 of file Matrix4x4.h.

## f

double& Eule::Matrix4x4::f = v[1][1]

Definition at line 133 of file Matrix4x4.h.

## g

double& Eule::Matrix4x4::g = v[1][2]

Definition at line 134 of file Matrix4x4.h.

## h

double& Eule::Matrix4x4::h = v[1][3]

Definition at line 135 of file Matrix4x4.h.

## i

double& Eule::Matrix4x4::i = v[2][0]

Definition at line 136 of file Matrix4x4.h.

## j

double& Eule::Matrix4x4::j = v[2][1]

Definition at line 137 of file Matrix4x4.h.

## k

double& Eule::Matrix4x4::k = v[2][2]

Definition at line 138 of file Matrix4x4.h.

## l

double& Eule::Matrix4x4::l = v[2][3]

Definition at line 139 of file Matrix4x4.h.

## m

double& Eule::Matrix4x4::m = v[3][0]

Definition at line 140 of file Matrix4x4.h.

## n

double& Eule::Matrix4x4::n = v[3][1]

Definition at line 141 of file Matrix4x4.h.

## o

double& Eule::Matrix4x4::o = v[3][2]

Definition at line 142 of file Matrix4x4.h.

## p

double& Eule::Matrix4x4::p = v[3][3]

Definition at line 143 of file Matrix4x4.h.

## v

std::array<std::array<double, 4>, 4> Eule::Matrix4x4::v

Array holding the matrices values.

Definition at line 44 of file Matrix4x4.h.

The documentation for this class was generated from the following files:

- Eule/Matrix4x4.h
- Eule/Matrix4x4.cpp

Eule::Matrix4x4::j
double & j
Definition: Matrix4x4.h:137
Eule::Matrix4x4::Adjoint
Matrix4x4 Adjoint(std::size_t n) const
Will return the adjoint of this matrix, by dimension n.
Definition: Matrix4x4.cpp:533
Eule::Matrix4x4::operator==
bool operator==(const Matrix4x4 &other)
Definition: Matrix4x4.cpp:397
Eule::Matrix4x4::i
double & i
Definition: Matrix4x4.h:136
Eule::Matrix4x4::e
double & e
Definition: Matrix4x4.h:132
Eule::Matrix4x4::f
double & f
Definition: Matrix4x4.h:133
Eule::Matrix4x4::Inverse3x3
Matrix4x4 Inverse3x3() const
Will return the 3x3-inverse of this matrix.
Definition: Matrix4x4.cpp:558
Eule::Matrix4x4::k
double & k
Definition: Matrix4x4.h:138
Eule::Matrix4x4::v
std::array< std::array< double, 4 >, 4 > v
Array holding the matrices values.
Definition: Matrix4x4.h:44
Eule::Vector3d
Vector3< double > Vector3d
Definition: Matrix4x4.h:9
Eule::Vector3::z
T z
Definition: Vector3.h:96
Eule::Matrix4x4
A matrix 4x4 class representing a 3d transformation.
Definition: Matrix4x4.h:36
Eule::Matrix4x4::b
double & b
Definition: Matrix4x4.h:129
Eule::Matrix4x4::g
double & g
Definition: Matrix4x4.h:134
Eule::Vector3::x
T x
Definition: Vector3.h:94
Eule::Matrix4x4::p
double & p
Definition: Matrix4x4.h:143
Eule::Matrix4x4::l
double & l
Definition: Matrix4x4.h:139
Eule::Matrix4x4::Determinant
double Determinant(std::size_t n) const
Will return the determinant, by dimension n.
Definition: Matrix4x4.cpp:511
Eule::Math::Similar
static constexpr bool Similar(const double a, const double b, const double epsilon=0.00001)
Compares two double values with a given accuracy.
Eule::Matrix4x4::SetTranslationComponent
void SetTranslationComponent(const Vector3d &trans)
Will set d,h,l from a Vector3d(x,y,z)
Definition: Matrix4x4.cpp:412
Eule::Matrix4x4::c
double & c
Definition: Matrix4x4.h:130
Eule::Matrix4x4::o
double & o
Definition: Matrix4x4.h:142
Eule::Matrix4x4::a
double & a
Definition: Matrix4x4.h:128
Eule::Matrix4x4::m
double & m
Definition: Matrix4x4.h:140
Eule::Matrix4x4::GetCofactors
Matrix4x4 GetCofactors(std::size_t p, std::size_t q, std::size_t n) const
Will return the cofactors of this matrix, by dimension n.
Definition: Matrix4x4.cpp:478
Eule::Matrix4x4::GetTranslationComponent
const Vector3d GetTranslationComponent() const
Will return d,h,l as a Vector3d(x,y,z)
Definition: Matrix4x4.cpp:407
Eule::Matrix4x4::n
double & n
Definition: Matrix4x4.h:141
Eule::Matrix4x4::h
double & h
Definition: Matrix4x4.h:135
Eule::Matrix4x4::d
double & d
Definition: Matrix4x4.h:131
Eule::Vector3::y
T y
Definition: Vector3.h:95