Leonetienne/Eule
Homemade math library, mainly targetted towards computer graphics
Public Member Functions | Public Attributes | Friends | List of all members
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.

13 {
14  // Create identity matrix
15  for (std::size_t i = 0; i < 4; i++)
16  for (std::size_t j = 0; j < 4; j++)
17  v[i][j] = double(i == j);
18 
19  return;
20 }

◆ Matrix4x4() [2/3]

Matrix4x4::Matrix4x4 ( const Matrix4x4 other)

Definition at line 22 of file Matrix4x4.cpp.

23 {
24  v = other.v;
25  return;
26 }

◆ Matrix4x4() [3/3]

Matrix4x4::Matrix4x4 ( Matrix4x4 &&  other)
noexcept

Definition at line 28 of file Matrix4x4.cpp.

29 {
30  v = std::move(other.v);
31  return;
32 }

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.

534 {
535  if (n > 4)
536  throw std::runtime_error("Dimension out of range! 0 <= n <= 4");
537 
538  Matrix4x4 adj;
539  double sign = 1;
540 
541  for (std::size_t i = 0; i < n; i++)
542  for (std::size_t j = 0; j < n; j++)
543  {
544  Matrix4x4 cofs = GetCofactors(i, j, n);
545 
546  // sign of adj[j][i] positive if sum of row
547  // and column indexes is even.
548  sign = ((i + j) % 2 == 0) ? 1 : -1;
549 
550  // Interchanging rows and columns to get the
551  // transpose of the cofactor matrix
552  adj[j][i] = sign * (cofs.Determinant(n - 1));
553  }
554 
555  return adj;
556 }

◆ Determinant()

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

Will return the determinant, by dimension n.

Definition at line 511 of file Matrix4x4.cpp.

512 {
513  if (n > 4)
514  throw std::runtime_error("Dimension out of range! 0 <= n <= 4");
515 
516  double d = 0;
517  double sign = 1;
518 
519  if (n == 1)
520  return v[0][0];
521 
522  for (std::size_t x = 0; x < n; x++)
523  {
524  Matrix4x4 cofs = GetCofactors(0, x, n);
525 
526  d += sign * v[0][x] * cofs.Determinant(n - 1);
527  sign = -sign;
528  }
529 
530  return d;
531 }

◆ 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.

421 {
422  Matrix4x4 m(*this);
423  m.d = 0;
424  m.h = 0;
425  m.l = 0;
426  return m;
427 }

◆ 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.

479 {
480  if (n > 4)
481  throw std::runtime_error("Dimension out of range! 0 <= n <= 4");
482 
483  Matrix4x4 cofs;
484 
485  std::size_t i = 0;
486  std::size_t j = 0;
487 
488  for (std::size_t y = 0; y < n; y++)
489  for (std::size_t x = 0; x < n; x++)
490  {
491  if ((y != p) && (x != q))
492  {
493  cofs[i][j] = v[y][x];
494  j++;
495  }
496 
497  if (j == n - 1)
498  {
499  j = 0;
500  i++;
501  }
502  }
503 
504  return cofs;
505 }

◆ 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.

408 {
409  return Vector3d(d, h, l);
410 }

◆ 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.

559 {
560  Matrix4x4 inv;
561 
562  double det = Determinant(3);
563  if (det == 0.0)
564  throw std::runtime_error("Matrix3x3 not inversible!");
565 
566  Matrix4x4 adj = Adjoint(3);
567 
568  for (std::size_t i = 0; i < 3; i++)
569  for (std::size_t j = 0; j < 3; j++)
570  inv[i][j] = adj[i][j] / det;
571 
573 
574  return inv;
575 }

◆ Inverse4x4()

Matrix4x4 Matrix4x4::Inverse4x4 ( ) const

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

Definition at line 577 of file Matrix4x4.cpp.

578 {
579  Matrix4x4 inv;
580 
581  double det = Determinant(4);
582  if (det == 0.0)
583  throw std::runtime_error("Matrix4x4 not inversible!");
584 
585  Matrix4x4 adj = Adjoint(4);
586 
587  for (std::size_t i = 0; i < 4; i++)
588  for (std::size_t j = 0; j < 4; j++)
589  inv[i][j] = adj[i][j] / det;
590 
591  return inv;
592 }

◆ IsInversible3x3()

bool Matrix4x4::IsInversible3x3 ( ) const

Will check if the 3x3-component is inversible.

Definition at line 598 of file Matrix4x4.cpp.

599 {
600  return (Determinant(3) != 0);
601 }

◆ IsInversible4x4()

bool Matrix4x4::IsInversible4x4 ( ) const

Will check if the entire matrix is inversible.

Definition at line 603 of file Matrix4x4.cpp.

604 {
605  return (Determinant(4) != 0);
606 }

◆ 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.

452 {
453  Matrix4x4 m;
454 
455  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]);
456  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]);
457  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]);
458  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]);
459 
460  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]);
461  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]);
462  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]);
463  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]);
464 
465  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]);
466  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]);
467  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]);
468  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]);
469 
470  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]);
471  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]);
472  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]);
473  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]);
474 
475  return m;
476 }

◆ operator!=()

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

Definition at line 402 of file Matrix4x4.cpp.

403 {
404  return !operator==(other);
405 }

◆ operator*() [1/2]

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

Cellwise scaling.

Definition at line 164 of file Matrix4x4.cpp.

165 {
166  Matrix4x4 m;
167 
168  #ifndef _EULE_NO_INTRINSICS_
169 
170  // Load matrix rows
171  __m256d __row0 = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]);
172  __m256d __row1 = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]);
173  __m256d __row2 = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]);
174  __m256d __row3 = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]);
175 
176  // Load scalar
177  __m256d __scalar = _mm256_set1_pd(scalar);
178 
179  // Scale values
180  __m256d __sr0 = _mm256_mul_pd(__row0, __scalar);
181  __m256d __sr1 = _mm256_mul_pd(__row1, __scalar);
182  __m256d __sr2 = _mm256_mul_pd(__row2, __scalar);
183  __m256d __sr3 = _mm256_mul_pd(__row3, __scalar);
184 
185  // Extract results
186  _mm256_storeu_pd(m.v[0].data(), __sr0);
187  _mm256_storeu_pd(m.v[1].data(), __sr1);
188  _mm256_storeu_pd(m.v[2].data(), __sr2);
189  _mm256_storeu_pd(m.v[3].data(), __sr3);
190 
191  #else
192 
193  for (std::size_t x = 0; x < 4; x++)
194  for (std::size_t y = 0; y < 4; y++)
195  m[x][y] = v[x][y] * scalar;
196 
197  #endif
198 
199  return m;
200 }

◆ operator*() [2/2]

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

Definition at line 34 of file Matrix4x4.cpp.

35 {
36  Matrix4x4 newMatrix;
37  newMatrix.p = 1;
38 
39  #ifndef _EULE_NO_INTRINSICS_
40 
41 
42  /* <= Matrix3x3 multiplication => */
43 
44  // Load matrix components
45  __m256d __va1 = _mm256_set_pd(v[0][0], v[0][0], v[0][0], v[1][0]);
46  __m256d __va2 = _mm256_set_pd(v[1][0], v[1][0], v[2][0], v[2][0]);
47 
48  __m256d __oa1 = _mm256_set_pd(other[0][0], other[0][1], other[0][2], other[0][0]);
49  __m256d __oa2 = _mm256_set_pd(other[0][1], other[0][2], other[0][0], other[0][1]);
50 
51  __m256d __vb1 = _mm256_set_pd(v[0][1], v[0][1], v[0][1], v[1][1]);
52  __m256d __vb2 = _mm256_set_pd(v[1][1], v[1][1], v[2][1], v[2][1]);
53 
54  __m256d __ob1 = _mm256_set_pd(other[1][0], other[1][1], other[1][2], other[1][0]);
55  __m256d __ob2 = _mm256_set_pd(other[1][1], other[1][2], other[1][0], other[1][1]);
56 
57  __m256d __vc1 = _mm256_set_pd(v[0][2], v[0][2], v[0][2], v[1][2]);
58  __m256d __vc2 = _mm256_set_pd(v[1][2], v[1][2], v[2][2], v[2][2]);
59 
60  __m256d __oc1 = _mm256_set_pd(other[2][0], other[2][1], other[2][2], other[2][0]);
61  __m256d __oc2 = _mm256_set_pd(other[2][1], other[2][2], other[2][0], other[2][1]);
62 
63  // Initialize sums
64  __m256d __sum1 = _mm256_set1_pd(0);
65  __m256d __sum2 = _mm256_set1_pd(0);
66 
67  // Let's multiply-add them together
68  // First, the first block
69  __sum1 = _mm256_fmadd_pd(__va1, __oa1, __sum1);
70  __sum1 = _mm256_fmadd_pd(__vb1, __ob1, __sum1);
71  __sum1 = _mm256_fmadd_pd(__vc1, __oc1, __sum1);
72 
73  // Then the second block
74  __sum2 = _mm256_fmadd_pd(__va2, __oa2, __sum2);
75  __sum2 = _mm256_fmadd_pd(__vb2, __ob2, __sum2);
76  __sum2 = _mm256_fmadd_pd(__vc2, __oc2, __sum2);
77 
78  // Retrieve results
79  double sum1[4];
80  double sum2[4];
81 
82  _mm256_storeu_pd(sum1, __sum1);
83  _mm256_storeu_pd(sum2, __sum2);
84 
85  // Apply results
86  // Block 1
87  newMatrix[0][0] = sum1[3];
88  newMatrix[0][1] = sum1[2];
89  newMatrix[0][2] = sum1[1];
90  newMatrix[1][0] = sum1[0];
91 
92  // Block 2
93  newMatrix[1][1] = sum2[3];
94  newMatrix[1][2] = sum2[2];
95  newMatrix[2][0] = sum2[1];
96  newMatrix[2][1] = sum2[0];
97 
98  // Does not fit in the intrinsic calculation. Might just calculate 'by hand'.
99  newMatrix[2][2] = (v[2][0] * other[0][2]) + (v[2][1] * other[1][2]) + (v[2][2] * other[2][2]);
100 
101 
102  /* <= Translation component => */
103 
104  // Load translation components into registers
105  __m256d __transSelf = _mm256_set_pd(0, l, h, d);
106  __m256d __transOther = _mm256_set_pd(0, other.l, other.h, other.d);
107 
108  // Let's add them
109  __m256d __sum = _mm256_add_pd(__transSelf, __transOther);
110 
111  // Retrieve results
112  double sum[4];
113  _mm256_storeu_pd(sum, __sum);
114 
115  // Apply them
116  newMatrix.d = sum[0];
117  newMatrix.h = sum[1];
118  newMatrix.l = sum[2];
119 
120  #else
121 
122 
123  // Rotation, Scaling
124  newMatrix[0][0] = (v[0][0] * other[0][0]) + (v[0][1] * other[1][0]) + (v[0][2] * other[2][0]);
125  newMatrix[0][1] = (v[0][0] * other[0][1]) + (v[0][1] * other[1][1]) + (v[0][2] * other[2][1]);
126  newMatrix[0][2] = (v[0][0] * other[0][2]) + (v[0][1] * other[1][2]) + (v[0][2] * other[2][2]);
127 
128  newMatrix[1][0] = (v[1][0] * other[0][0]) + (v[1][1] * other[1][0]) + (v[1][2] * other[2][0]);
129  newMatrix[1][1] = (v[1][0] * other[0][1]) + (v[1][1] * other[1][1]) + (v[1][2] * other[2][1]);
130  newMatrix[1][2] = (v[1][0] * other[0][2]) + (v[1][1] * other[1][2]) + (v[1][2] * other[2][2]);
131 
132  newMatrix[2][0] = (v[2][0] * other[0][0]) + (v[2][1] * other[1][0]) + (v[2][2] * other[2][0]);
133  newMatrix[2][1] = (v[2][0] * other[0][1]) + (v[2][1] * other[1][1]) + (v[2][2] * other[2][1]);
134  newMatrix[2][2] = (v[2][0] * other[0][2]) + (v[2][1] * other[1][2]) + (v[2][2] * other[2][2]);
135 
136 
137  // Translation
138  newMatrix[0][3] = v[0][3] + other[0][3];
139  newMatrix[1][3] = v[1][3] + other[1][3];
140  newMatrix[2][3] = v[2][3] + other[2][3];
141 
142  #endif
143 
144  return newMatrix;
145 }

◆ operator*=() [1/2]

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

Cellwise scaling.

Definition at line 202 of file Matrix4x4.cpp.

203 {
204  *this = *this * scalar;
205  return;
206 }

◆ operator*=() [2/2]

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

Definition at line 147 of file Matrix4x4.cpp.

148 {
149  *this = *this * other;
150  return;
151 }

◆ operator+()

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

Cellwise addition.

Definition at line 221 of file Matrix4x4.cpp.

222 {
223  Matrix4x4 m;
224 
225  #ifndef _EULE_NO_INTRINSICS_
226 
227  // Load matrix rows
228  __m256d __row0a = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]);
229  __m256d __row1a = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]);
230  __m256d __row2a = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]);
231  __m256d __row3a = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]);
232 
233  __m256d __row0b = _mm256_set_pd(other[0][3], other[0][2], other[0][1], other[0][0]);
234  __m256d __row1b = _mm256_set_pd(other[1][3], other[1][2], other[1][1], other[1][0]);
235  __m256d __row2b = _mm256_set_pd(other[2][3], other[2][2], other[2][1], other[2][0]);
236  __m256d __row3b = _mm256_set_pd(other[3][3], other[3][2], other[3][1], other[3][0]);
237 
238  // Add rows
239  __m256d __sr0 = _mm256_add_pd(__row0a, __row0b);
240  __m256d __sr1 = _mm256_add_pd(__row1a, __row1b);
241  __m256d __sr2 = _mm256_add_pd(__row2a, __row2b);
242  __m256d __sr3 = _mm256_add_pd(__row3a, __row3b);
243 
244  // Extract results
245  _mm256_storeu_pd(m.v[0].data(), __sr0);
246  _mm256_storeu_pd(m.v[1].data(), __sr1);
247  _mm256_storeu_pd(m.v[2].data(), __sr2);
248  _mm256_storeu_pd(m.v[3].data(), __sr3);
249 
250  #else
251 
252  for (std::size_t x = 0; x < 4; x++)
253  for (std::size_t y = 0; y < 4; y++)
254  m[x][y] = v[x][y] + other[x][y];
255 
256  #endif
257 
258  return m;
259 }

◆ operator+=()

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

Cellwise addition.

Definition at line 261 of file Matrix4x4.cpp.

262 {
263  #ifndef _EULE_NO_INTRINSICS_
264  // Doing it again is a tad directer, and thus faster. We avoid an intermittent Matrix4x4 instance
265 
266  // Load matrix rows
267  __m256d __row0a = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]);
268  __m256d __row1a = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]);
269  __m256d __row2a = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]);
270  __m256d __row3a = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]);
271 
272  __m256d __row0b = _mm256_set_pd(other[0][3], other[0][2], other[0][1], other[0][0]);
273  __m256d __row1b = _mm256_set_pd(other[1][3], other[1][2], other[1][1], other[1][0]);
274  __m256d __row2b = _mm256_set_pd(other[2][3], other[2][2], other[2][1], other[2][0]);
275  __m256d __row3b = _mm256_set_pd(other[3][3], other[3][2], other[3][1], other[3][0]);
276 
277  // Add rows
278  __m256d __sr0 = _mm256_add_pd(__row0a, __row0b);
279  __m256d __sr1 = _mm256_add_pd(__row1a, __row1b);
280  __m256d __sr2 = _mm256_add_pd(__row2a, __row2b);
281  __m256d __sr3 = _mm256_add_pd(__row3a, __row3b);
282 
283  // Extract results
284  _mm256_storeu_pd(v[0].data(), __sr0);
285  _mm256_storeu_pd(v[1].data(), __sr1);
286  _mm256_storeu_pd(v[2].data(), __sr2);
287  _mm256_storeu_pd(v[3].data(), __sr3);
288 
289  #else
290 
291  *this = *this + other;
292 
293  #endif
294 
295  return;
296 }

◆ operator-()

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

Cellwise subtraction.

Definition at line 298 of file Matrix4x4.cpp.

299 {
300  Matrix4x4 m;
301 
302  #ifndef _EULE_NO_INTRINSICS_
303 
304  // Load matrix rows
305  __m256d __row0a = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]);
306  __m256d __row1a = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]);
307  __m256d __row2a = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]);
308  __m256d __row3a = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]);
309 
310  __m256d __row0b = _mm256_set_pd(other[0][3], other[0][2], other[0][1], other[0][0]);
311  __m256d __row1b = _mm256_set_pd(other[1][3], other[1][2], other[1][1], other[1][0]);
312  __m256d __row2b = _mm256_set_pd(other[2][3], other[2][2], other[2][1], other[2][0]);
313  __m256d __row3b = _mm256_set_pd(other[3][3], other[3][2], other[3][1], other[3][0]);
314 
315  // Subtract rows
316  __m256d __sr0 = _mm256_sub_pd(__row0a, __row0b);
317  __m256d __sr1 = _mm256_sub_pd(__row1a, __row1b);
318  __m256d __sr2 = _mm256_sub_pd(__row2a, __row2b);
319  __m256d __sr3 = _mm256_sub_pd(__row3a, __row3b);
320 
321  // Extract results
322  _mm256_storeu_pd(m.v[0].data(), __sr0);
323  _mm256_storeu_pd(m.v[1].data(), __sr1);
324  _mm256_storeu_pd(m.v[2].data(), __sr2);
325  _mm256_storeu_pd(m.v[3].data(), __sr3);
326 
327  #else
328 
329  for (std::size_t x = 0; x < 4; x++)
330  for (std::size_t y = 0; y < 4; y++)
331  m[x][y] = v[x][y] - other[x][y];
332 
333  #endif
334 
335  return m;
336 }

◆ operator-=()

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

Cellwise subtraction.

Definition at line 338 of file Matrix4x4.cpp.

339 {
340  #ifndef _EULE_NO_INTRINSICS_
341  // Doing it again is a tad directer, and thus faster. We avoid an intermittent Matrix4x4 instance
342 
343  // Load matrix rows
344  __m256d __row0a = _mm256_set_pd(v[0][3], v[0][2], v[0][1], v[0][0]);
345  __m256d __row1a = _mm256_set_pd(v[1][3], v[1][2], v[1][1], v[1][0]);
346  __m256d __row2a = _mm256_set_pd(v[2][3], v[2][2], v[2][1], v[2][0]);
347  __m256d __row3a = _mm256_set_pd(v[3][3], v[3][2], v[3][1], v[3][0]);
348 
349  __m256d __row0b = _mm256_set_pd(other[0][3], other[0][2], other[0][1], other[0][0]);
350  __m256d __row1b = _mm256_set_pd(other[1][3], other[1][2], other[1][1], other[1][0]);
351  __m256d __row2b = _mm256_set_pd(other[2][3], other[2][2], other[2][1], other[2][0]);
352  __m256d __row3b = _mm256_set_pd(other[3][3], other[3][2], other[3][1], other[3][0]);
353 
354  // Subtract rows
355  __m256d __sr0 = _mm256_sub_pd(__row0a, __row0b);
356  __m256d __sr1 = _mm256_sub_pd(__row1a, __row1b);
357  __m256d __sr2 = _mm256_sub_pd(__row2a, __row2b);
358  __m256d __sr3 = _mm256_sub_pd(__row3a, __row3b);
359 
360  // Extract results
361  _mm256_storeu_pd(v[0].data(), __sr0);
362  _mm256_storeu_pd(v[1].data(), __sr1);
363  _mm256_storeu_pd(v[2].data(), __sr2);
364  _mm256_storeu_pd(v[3].data(), __sr3);
365 
366  #else
367 
368  * this = *this - other;
369 
370  #endif
371 
372  return;
373 }

◆ operator/() [1/2]

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

Cellwise division.

Definition at line 208 of file Matrix4x4.cpp.

209 {
210  const double precomputeDivision = 1.0 / denominator;
211 
212  return *this * precomputeDivision;
213 }

◆ operator/() [2/2]

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

Definition at line 153 of file Matrix4x4.cpp.

154 {
155  return *this * other.Inverse3x3();
156 }

◆ operator/=() [1/2]

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

Cellwise division.

Definition at line 215 of file Matrix4x4.cpp.

216 {
217  *this = *this / denominator;
218  return;
219 }

◆ operator/=() [2/2]

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

Definition at line 158 of file Matrix4x4.cpp.

159 {
160  *this = *this * other.Inverse3x3();
161  return;
162 }

◆ operator=() [1/2]

void Matrix4x4::operator= ( const Matrix4x4 other)

Definition at line 385 of file Matrix4x4.cpp.

386 {
387  v = other.v;
388  return;
389 }

◆ operator=() [2/2]

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

Definition at line 391 of file Matrix4x4.cpp.

392 {
393  v = std::move(other.v);
394  return;
395 }

◆ operator==()

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

Definition at line 397 of file Matrix4x4.cpp.

398 {
399  return v == other.v;
400 }

◆ operator[]() [1/2]

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

Definition at line 375 of file Matrix4x4.cpp.

376 {
377  return v[y];
378 }

◆ operator[]() [2/2]

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

Definition at line 380 of file Matrix4x4.cpp.

381 {
382  return v[y];
383 }

◆ 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.

413 {
414  d = trans.x;
415  h = trans.y;
416  l = trans.z;
417  return;
418 }

◆ 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.

609 {
610  for (std::size_t i = 0; i < 4; i++)
611  for (std::size_t j = 0; j < 4; j++)
612  if (!Math::Similar(v[i][j], other[i][j], epsilon))
613  return false;
614 
615  return true;
616 }

◆ Transpose3x3()

Matrix4x4 Matrix4x4::Transpose3x3 ( ) const

Will return the 3x3 transpose of this matrix.

Definition at line 429 of file Matrix4x4.cpp.

430 {
431  Matrix4x4 trans(*this); // Keep other cells
432 
433  for (std::size_t i = 0; i < 3; i++)
434  for (std::size_t j = 0; j < 3; j++)
435  trans[j][i] = v[i][j];
436 
437  return trans;
438 }

◆ Transpose4x4()

Matrix4x4 Matrix4x4::Transpose4x4 ( ) const

Will return the 4x4 transpose of this matrix.

Definition at line 440 of file Matrix4x4.cpp.

441 {
442  Matrix4x4 trans;
443 
444  for (std::size_t i = 0; i < 4; i++)
445  for (std::size_t j = 0; j < 4; j++)
446  trans[j][i] = v[i][j];
447 
448  return trans;
449 }

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.

621  {
622  os << std::endl;
623 
624  for (std::size_t y = 0; y < 4; y++)
625  {
626  for (std::size_t x = 0; x < 4; x++)
627  os << " | " << m[y][x];
628 
629  os << " |" << std::endl;
630  }
631 
632  return os;
633  }

◆ operator<< [2/2]

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

Definition at line 635 of file Matrix4x4.cpp.

636  {
637  os << std::endl;
638 
639  for (std::size_t y = 0; y < 4; y++)
640  {
641  for (std::size_t x = 0; x < 4; x++)
642  os << L" | " << m[y][x];
643 
644  os << L" |" << std::endl;
645  }
646 
647  return os;
648  }

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::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::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.
Definition: Math.h:102
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::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