1 #ifndef ORG_EEROS_MATH_MATRIX_HPP_ 2 #define ORG_EEROS_MATH_MATRIX_HPP_ 15 template <
unsigned int M,
unsigned int N = 1,
typename T =
double >
19 static_assert((M > 1 && N >= 1) || (M >=1 && N > 1),
"Matrix dimension must be greater or equal than 1x1!");
23 template <
unsigned int IM,
unsigned int IN,
typename IT >
45 template<
typename... S>
47 static_assert(
sizeof...(S) == M * N,
"Invalid number of constructor arguments!");
53 for(
unsigned int i = 0; i < M * N; i++) {
60 unsigned int j = (M < N) ? M : N;
61 for(
unsigned int i = 0; i < j; i++) {
72 if(M == 3 && N == 3) {
78 m(1,1) = std::cos(angle);
79 m(2,1) = std::sin(angle);
82 m(1,2) = -std::sin(angle);
83 m(2,2) = std::cos(angle);
86 throw Fault(
"rotx(double) is only implemented for 3x3 matrices");
92 if(M == 3 && N == 3) {
93 m(0,0) = std::cos(angle);
95 m(2,0) = -std::sin(angle);
101 m(0,2) = std::sin(angle);
103 m(2,2) = std::cos(angle);
106 throw Fault(
"roty(double) is only implemented for 3x3 matrices");
112 if(M == 3 && N == 3) {
113 m(0,0) = std::cos(angle);
114 m(1,0) = std::sin(angle);
117 m(0,1) = -std::sin(angle);
118 m(1,1) = std::cos(angle);
126 throw Fault(
"rotz(double) is only implemented for 3x3 matrices");
132 return MatrixInitializer<M, N, T>(*
this, 1);
137 const T
get(
unsigned int m,
unsigned int n)
const {
138 return (*
this)(m, n);
143 for(
unsigned int m = 0; m < M; m++) {
144 col(m, 0) = (*this)(m, n);
151 for(
unsigned int m = 0; m < M; m++) {
152 col.push_back( (*
this)(m, n) );
159 for(
unsigned int n = 0; n < N; n++) {
160 row(0, n) = (*this)(m, n);
167 for(
unsigned int n = 0; n < N; n++) {
168 row.push_back( (*
this)(m, n) );
173 template<
unsigned int U,
unsigned int V>
175 static_assert(U <= M && V <= N,
"Dimension of the sub matrix must be lower or equal than of the origin!");
176 if(m + U <= M && n + V <= N) {
178 for(
unsigned int u = 0; u < U; u++) {
179 for(
unsigned int v = 0; v < V; v++) {
180 sub(u, v) = (*this)(m + u, n + v);
190 void set(
unsigned int m,
unsigned int n, T
value) {
191 (*this)(m, n) =
value;
195 for(
unsigned int m = 0; m < M; m++) {
196 (*this)(m, n) = col(m, 0);
200 void setCol(
unsigned int n,
const std::vector<T>& col) {
201 for(
unsigned int m = 0; m < M; m++) {
202 (*this)(m, n) = col[m];
207 for(
unsigned int n = 0; n < N; n++) {
208 (*this)(m, n) = row(0, n);
212 void setRow(
unsigned int m,
const std::vector<T>& col) {
213 for(
unsigned int n = 0; n < N; n++) {
214 (*this)(m, n) = col[n];
219 if(m >= 0 && m < M && n >= 0 && n < N) {
220 return value[M * n + m];
228 if(m >= 0 && m < M && n >= 0 && n < N) {
229 return value[M * n + m];
237 if(i >= 0 && i < M * N) {
246 if(i >= 0 && i < M * N) {
255 if(i >= 0 && i < M * N) {
264 if(i >= 0 && i < M * N) {
282 result = (*this) * transposed;
283 return result ==
eye;
291 for(
unsigned int m = 0; m < M; m++) {
292 for(
unsigned int n = 0; n < N; n++) {
294 if((*
this)(m, n) != 0){
304 for(
unsigned int m = 0; m < M; m++) {
305 for(
unsigned int n = 0; n < N; n++) {
307 if((*
this)(m, n) != 0){
317 for(
unsigned int m = 0; m < M; m++) {
318 for(
unsigned int n = 0; n < N; n++) {
320 if((*
this)(m, n) != 0){
331 return (M == N) && (this->
det() != 0);
342 constexpr
unsigned int size()
const {
347 unsigned int numberOfNonZeroRows = 0;
350 for(
unsigned int m = 0; m < M; m++) {
351 for(
unsigned int n = 0; n < N; n++) {
353 numberOfNonZeroRows++;
358 return numberOfNonZeroRows;
364 return (*
this)(0, 0) * (*
this)(1, 1) - (*
this)(0, 1) * (*
this)(1,0);
368 det = (*this)(0, 0) * (*
this)(1, 1) * (*
this)(2, 2) +
369 (*
this)(0, 1) * (*
this)(1, 2) * (*
this)(2, 0) +
370 (*
this)(0, 2) * (*
this)(1, 0) * (*
this)(2, 1) -
371 (*
this)(0, 2) * (*
this)(1, 1) * (*
this)(2, 0) -
372 (*
this)(0, 0) * (*
this)(1, 2) * (*
this)(2, 1) -
373 (*
this)(0, 1) * (*
this)(1, 0) * (*
this)(2, 2);
381 unsigned int ignoredRow = 0;
382 for(
unsigned int m = 0; m < M; m++) {
383 Matrix<M - 1, N - 1, T> subMatrix;
384 unsigned int x = 0, y = 0;
385 unsigned int a = 0, b = 1;
388 if(a != ignoredRow) {
389 subMatrix(y, x) = (*this)(a, b);
396 if(a != ignoredRow) {
402 T detSubMatrix = subMatrix.
det();
404 det = det + (*this)(m, 0) * detSubMatrix;
407 det = det - (*this)(m, 0) * detSubMatrix;
414 throw Fault(
"Calculating determinant failed: Matrix must be square");
421 unsigned int j = (M < N) ? M : N;
422 for(
unsigned int i = 0; i < j; i++) {
423 result += (*this)(i, i);
430 for(
unsigned int m = 0; m < M; m++) {
431 for(
unsigned int n = 0; n < N; n++) {
432 result(n, m) = (*this)(m, n);
446 for(
unsigned int m = 0; m < M; m++) {
447 for(
unsigned int n = 0; n < N; n++) {
448 if((*
this)(m, n) != right(m, n))
461 for(
unsigned int m = 0; m < M; m++) {
462 for(
unsigned int n = 0; n < N; n++) {
463 if((*
this)(m, n) != right(m, n)) {
476 bool operator<(const Matrix<M, N, T>& right)
const {
477 for(
unsigned int m = 0; m < M; m++) {
478 for(
unsigned int n = 0; n < N; n++) {
479 if((*
this)(m, n) >= right(m, n)) {
492 bool operator<=(const Matrix<M, N, T>& right)
const {
493 for(
unsigned int m = 0; m < M; m++) {
494 for(
unsigned int n = 0; n < N; n++) {
495 if((*
this)(m, n) > right(m, n)) {
509 for(
unsigned int m = 0; m < M; m++) {
510 for(
unsigned int n = 0; n < N; n++) {
511 if((*
this)(m, n) <= right(m, n)) {
525 for(
unsigned int m = 0; m < M; m++) {
526 for(
unsigned int n = 0; n < N; n++) {
527 if((*
this)(m, n) < right(m, n)) {
536 for(
unsigned int m = 0; m < M; m++) {
537 for(
unsigned int n = 0; n < N; n++) {
538 (*this)(m, n) = right;
544 template <
unsigned int K >
547 for(
unsigned int m = 0; m < M; m++) {
548 for(
unsigned int k = 0; k < K; k++) {
550 for(
unsigned int n = 0; n < N; n++) {
551 result(m, k) += (*this)(m, n) * right(n, k);
560 for(
unsigned int m = 0; m < M; m++) {
561 for(
unsigned int n = 0; n < N; n++) {
562 result(m,n) = (*this)(m,n) * right;
570 for(
unsigned int m = 0; m < M; m++) {
571 for(
unsigned int n = 0; n < N; n++) {
572 result(m, n) = (*this)(m, n) * right(m, n);
580 for(
unsigned int m = 0; m < M; m++) {
581 for(
unsigned int n = 0; n < N; n++) {
582 result(m, n) = (*this)(m, n) + right(m, n);
590 for(
unsigned int m = 0; m < M; m++) {
591 for(
unsigned int n = 0; n < N; n++) {
592 result(m, n) = (*this)(m, n) + right;
599 (*this) = (*this) + right;
605 for(
unsigned int m = 0; m < M; m++) {
606 for(
unsigned int n = 0; n < N; n++) {
607 result(m, n) = (*this)(m, n) - right(m, n);
615 for(
unsigned int m = 0; m < M; m++) {
616 for(
unsigned int n = 0; n < N; n++) {
617 result(m, n) = (*this)(m, n) - right;
624 (*this) = (*this) - right;
630 for(
unsigned int m = 0; m < M; m++) {
631 for(
unsigned int n = 0; n < N; n++) {
632 result(m, n) = -(*this)(m, n);
640 for(
unsigned int m = 0; m < M; m++) {
641 for(
unsigned int n = 0; n < N; n++) {
642 result(m, n) = (*this)(m, n) / right;
649 T determinant = this->
det();
651 throw Fault(
"Invert failed: matrix not square");
653 else if(determinant == 0) {
654 throw Fault(
"Invert failed: determinat of matrix is 0");
661 result(0, 0) = (*this)(1, 1);
662 result(1, 0) = -(*this)(1, 0);
663 result(0, 1) = -(*this)(0, 1);
664 result(1, 1) = (*this)(0, 0);
665 return result / determinant;
669 result(0, 0) = (*this)(1, 1) * (*
this)(2, 2) - (*
this)(1, 2) * (*
this)(2, 1);
670 result(1, 0) = (*this)(1, 2) * (*
this)(2, 0) - (*
this)(1, 0) * (*
this)(2, 2);
671 result(2, 0) = (*this)(1, 0) * (*
this)(2, 1) - (*
this)(1, 1) * (*
this)(2, 0);
672 result(0, 1) = (*this)(0, 2) * (*
this)(2, 1) - (*
this)(0, 1) * (*
this)(2, 2);
673 result(1, 1) = (*this)(0, 0) * (*
this)(2, 2) - (*
this)(0, 2) * (*
this)(2, 0);
674 result(2, 1) = (*this)(0, 1) * (*
this)(2, 0) - (*
this)(0, 0) * (*
this)(2, 1);
675 result(0, 2) = (*this)(0, 1) * (*
this)(1, 2) - (*
this)(0, 2) * (*
this)(1, 1);
676 result(1, 2) = (*this)(0, 2) * (*
this)(1, 0) - (*
this)(0, 0) * (*
this)(1, 2);
677 result(2, 2) = (*this)(0, 0) * (*
this)(1, 1) - (*
this)(0, 1) * (*
this)(1, 0);
678 return result / determinant;
683 Matrix<M - 1, N - 1, T> smallerPart;
684 unsigned int ignoredRow = 0, ignoredColum = 0;
685 for(
unsigned int m = 0; m < M; m++) {
686 for(
unsigned int n = 0; n < N; n++) {
687 unsigned int a = 0, b = 0;
689 for(
unsigned int u = 0; u < M; u++) {
690 for(
unsigned int w = 0; w < N; w++) {
691 if(u != m && w != n){
692 smallerPart(a, b) = (*this)(u, w);
705 result(m,n) = -smallerPart.
det();
708 result(m, n) = smallerPart.
det();
713 result(m, n) = smallerPart.
det();
716 result(m, n) = -smallerPart.
det();
720 result(m, n) = result(m, n) / determinant;
730 for(
unsigned int m = 0; m < M; m++) {
731 for(
unsigned int n = 0; n < N; n++) {
732 result += (*this)(m, n) * (*
this)(m, n);
735 return std::sqrt(result);
782 result(0, 1) = -a(2);
786 result(1, 2) = -a(0);
787 result(2, 0) = -a(1);
795 result(0, 0) = a(1, 0) * b(2, 0) - a(2, 0) * b(1, 0);
796 result(1, 0) = a(2, 0) * b(0, 0) - a(0, 0) * b(2, 0);
797 result(2, 0) = a(0, 0) * b(1, 0) - a(1, 0) * b(0, 0);
804 unsigned int completedColum = 0, completedRow = 0;
805 unsigned int checkingRow = 0, rootRow = 0;
809 while(completedColum < N) {
810 rootRow = completedRow;
811 checkingRow = rootRow + 1;
812 while(checkingRow < M && (*
this)(rootRow, completedColum) != 0) {
813 if((*
this)(checkingRow, completedColum) != 0) {
814 rowFactor = (*this)(checkingRow, completedColum) / (*
this)(rootRow, completedColum);
815 for(
unsigned int n = completedColum; n < N; n++) {
816 (*this)(checkingRow, n) = (*
this)(checkingRow, n) - rowFactor * (*
this)(rootRow, n);
827 unsigned int completedColum = 0, completedRow = 0;
828 unsigned int swapRow = completedRow + 1;
830 while(completedColum < N) {
831 while(completedRow < M) {
832 if((*
this)(completedRow, completedColum) == 0 && swapRow < M && completedRow < M - 1) {
841 swapRow = completedRow + 1;
845 void swapRows(
unsigned int rowA,
unsigned int rowB) {
846 for(
unsigned int n = 0; n < N; n++) {
847 T t = (*this)(rowA, n);
848 (*this)(rowA, n) = (*
this)(rowB, n);
849 (*this)(rowB, n) = t;
860 template <
unsigned int M,
unsigned int N = 1,
typename T =
double >
863 for(
unsigned int m = 0; m < M; m++) {
864 for(
unsigned int n = 0; n < N; n++) {
865 result(m, n) = left + right(m, n);
871 template <
unsigned int M,
unsigned int N = 1,
typename T =
double >
874 for(
unsigned int m = 0; m < M; m++) {
875 for(
unsigned int n = 0; n < N; n++) {
876 result(m, n) = left - right(m, n);
882 template <
unsigned int M,
unsigned int N = 1,
typename T =
double >
885 for(
unsigned int m = 0; m < M; m++) {
886 for(
unsigned int n = 0; n < N; n++) {
887 result(m, n) = -right(m, n);
893 template <
unsigned int M,
unsigned int N = 1,
typename T =
double >
896 for(
unsigned int m = 0; m < M; m++) {
897 for(
unsigned int n = 0; n < N; n++) {
898 result(m, n) = left * right(m, n);
904 template <
unsigned int M,
unsigned int N = 1,
typename T =
double >
907 for(
unsigned int m = 0; m < M; m++) {
908 for(
unsigned int n = 0; n < N; n++) {
909 result(m, n) = left / right(m, n);
917 template <
unsigned int M,
unsigned int N = 1,
typename T =
double >
918 std::ostream& operator<<(std::ostream& os, const Matrix<M, N, T>& right) {
919 if(N > 1) os <<
"[ ";
920 for(
unsigned int n = 0; n < N; n++) {
922 for(
unsigned int m = 0; m < M; m++) {
924 if(m < M - 1) os <<
' ';
938 template <
unsigned int M,
typename T =
double >
943 template <
typename T >
960 const T
get(uint8_t m, uint8_t n)
const {
return (*
this)(m, n); }
966 void set(uint8_t m, uint8_t n, T
value) { (*this)(m, n) =
value; }
998 constexpr
unsigned int size()
const {
return 1; }
1011 (*this) = (*this) + right;
1016 (*this) = (*this) - right;
T & operator()(unsigned int i)
Definition: Matrix.hpp:236
bool isUpperTriangular() const
Definition: Matrix.hpp:316
bool isDiagonal() const
Definition: Matrix.hpp:290
MatrixInitializer< IM, IN, IT > operator,(IT right)
Definition: Matrix.hpp:28
Matrix< M, N, T > & operator+=(const Matrix< M, N, T > right)
Definition: Matrix.hpp:598
std::vector< T > getRowVector(unsigned int m) const
Definition: Matrix.hpp:165
unsigned int rank() const
Definition: Matrix.hpp:346
Matrix< 1, 1, T > operator!() const
Definition: Matrix.hpp:1006
Matrix< IM, IN, IT > & mat
Definition: Matrix.hpp:33
T trace() const
Definition: Matrix.hpp:1004
static Matrix< 3, 1, T > createVector3(T x, T y, T z)
Definition: Matrix.hpp:765
constexpr bool isLowerTriangular() const
Definition: Matrix.hpp:988
Definition: MatrixIndexOutOfBoundException.hpp:9
constexpr unsigned int getNofRows() const
Definition: Matrix.hpp:334
Matrix< N, M, T > transpose() const
Definition: Matrix.hpp:428
void roty(double angle)
Definition: Matrix.hpp:90
Definition: Matrix.hpp:24
bool operator>(const Matrix< M, N, T > &right) const
Definition: Matrix.hpp:508
Matrix< M, N, T > operator+(const Matrix< M, N, T > right) const
Definition: Matrix.hpp:578
const T operator[](unsigned int i) const
Definition: Matrix.hpp:978
constexpr bool isSquare() const
Definition: Matrix.hpp:274
bool isOrthogonal() const
Definition: Matrix.hpp:982
constexpr unsigned int getNofColums() const
Definition: Matrix.hpp:338
constexpr bool isSymmetric() const
Definition: Matrix.hpp:984
Matrix< M, N, T > & operator=(T right)
Definition: Matrix.hpp:535
Matrix< M, N, T > operator!() const
Definition: Matrix.hpp:648
void eye()
Definition: Matrix.hpp:956
static Matrix< 3, 3, T > createSkewSymmetric(Matrix< 3, 1, T > a)
Definition: Matrix.hpp:779
Matrix< 1, 1, T > & operator+=(const Matrix< 1, 1, T > right)
Definition: Matrix.hpp:1010
Matrix< M, N, T > operator-()
Definition: Matrix.hpp:628
void swapRows(unsigned int rowA, unsigned int rowB)
Definition: Matrix.hpp:845
bool isInvertible() const
Definition: Matrix.hpp:329
bool operator>=(const Matrix< M, N, T > &right) const
Definition: Matrix.hpp:524
Matrix< M, N, T > operator-(const T right) const
Definition: Matrix.hpp:613
Definition: Config.hpp:14
const T operator()(unsigned int m, unsigned int n) const
Definition: Matrix.hpp:227
constexpr bool isSquare() const
Definition: Matrix.hpp:980
T & operator()(unsigned int i)
Definition: Matrix.hpp:972
Matrix< M, 1, T > getCol(unsigned int n) const
Definition: Matrix.hpp:141
void setRow(unsigned int m, const Matrix< 1, N, T > &row)
Definition: Matrix.hpp:206
static Matrix< 3, 1, T > crossProduct(Matrix< 3, 1, T > a, Matrix< 3, 1, T > b)
Definition: Matrix.hpp:793
Matrix< M, N, T > operator*(T right) const
Definition: Matrix.hpp:558
T det() const
Definition: Matrix.hpp:1002
T & operator[](unsigned int i)
Definition: Matrix.hpp:976
T norm() const
Definition: Matrix.hpp:728
Matrix< 1, 1, T > getRow(uint8_t m) const
Definition: Matrix.hpp:964
const T operator()(unsigned int i) const
Definition: Matrix.hpp:245
Matrix< M, N, T > operator+(const T right) const
Definition: Matrix.hpp:588
double value_type
Definition: Matrix.hpp:21
T & operator[](unsigned int i)
Definition: Matrix.hpp:254
Matrix()
Definition: Matrix.hpp:950
bool isSymmetric() const
Definition: Matrix.hpp:286
unsigned int rank() const
Definition: Matrix.hpp:1000
void setCol(unsigned int n, const std::vector< T > &col)
Definition: Matrix.hpp:200
void zero()
Definition: Matrix.hpp:954
constexpr bool isDiagonal() const
Definition: Matrix.hpp:986
T & operator()(uint8_t m, uint8_t n)
Definition: Matrix.hpp:968
Matrix< 3, 1 > Vector3
Definition: Matrix.hpp:935
static Matrix< M, N, T > createRotZ(double angle)
Definition: Matrix.hpp:752
Matrix< M, K, T > operator*(const Matrix< N, K, T > right) const
Definition: Matrix.hpp:545
Definition: Matrix.hpp:944
bool isInvertible() const
Definition: Matrix.hpp:992
void rotx(double angle)
Definition: Matrix.hpp:70
constexpr unsigned int size() const
Definition: Matrix.hpp:342
Matrix< M, N, T > operator/(T right) const
Definition: Matrix.hpp:638
const T operator[](unsigned int i) const
Definition: Matrix.hpp:263
constexpr unsigned int getNofRows() const
Definition: Matrix.hpp:994
Matrix< 2, 1 > Vector2
Definition: Matrix.hpp:934
static Matrix< M, N, T > createRotX(double angle)
Definition: Matrix.hpp:740
Matrix< 1, N, T > getRow(unsigned int m) const
Definition: Matrix.hpp:157
void sortForGaussAlgorithm()
Definition: Matrix.hpp:826
T det() const
Definition: Matrix.hpp:361
MatrixInitializer(Matrix< IM, IN, IT > &mat, unsigned int index=0)
Definition: Matrix.hpp:26
Matrix< M, N, T > operator-(const Matrix< M, N, T > right) const
Definition: Matrix.hpp:603
void eye()
Definition: Matrix.hpp:58
Definition: Matrix.hpp:16
constexpr unsigned int size() const
Definition: Matrix.hpp:998
T value[M *N]
Definition: Matrix.hpp:854
void gaussRowElimination()
Definition: Matrix.hpp:803
Matrix< 1, 1, T > & operator-=(const Matrix< 1, 1, T > right)
Definition: Matrix.hpp:1015
bool operator==(const Matrix< M, N, T > &right) const
Definition: Matrix.hpp:445
Matrix()
Definition: Matrix.hpp:39
void fill(T v)
Definition: Matrix.hpp:66
Matrix(const T v)
Definition: Matrix.hpp:41
T value_type
Definition: Matrix.hpp:948
bool isLowerTriangular() const
Definition: Matrix.hpp:303
void zero()
Definition: Matrix.hpp:52
unsigned int index
Definition: Matrix.hpp:34
T & operator()(unsigned int m, unsigned int n)
Definition: Matrix.hpp:218
static Matrix< M, N, T > createRotY(double angle)
Definition: Matrix.hpp:746
Matrix< 1, 1, T > getCol(uint8_t n) const
Definition: Matrix.hpp:962
Matrix< M, N, T > multiplyElementWise(const Matrix< M, N, T > right) const
Definition: Matrix.hpp:568
void setCol(unsigned int n, const Matrix< M, 1, T > &col)
Definition: Matrix.hpp:194
const T operator()(unsigned int i) const
Definition: Matrix.hpp:974
constexpr bool isUpperTriangular() const
Definition: Matrix.hpp:990
Matrix(const T v)
Definition: Matrix.hpp:952
Matrix< U, V, T > getSubMatrix(unsigned int m, unsigned int n) const
Definition: Matrix.hpp:174
const T operator()(uint8_t m, uint8_t n) const
Definition: Matrix.hpp:970
void setRow(unsigned int m, const std::vector< T > &col)
Definition: Matrix.hpp:212
void fill(T v)
Definition: Matrix.hpp:958
bool operator!=(const Matrix< M, N, T > &right) const
Definition: Matrix.hpp:460
void rotz(double angle)
Definition: Matrix.hpp:110
Matrix< M, N, T > & operator-=(const Matrix< M, N, T > right)
Definition: Matrix.hpp:623
static Matrix< M, N, T > createDiag(T v)
Definition: Matrix.hpp:773
Matrix< 4, 1 > Vector4
Definition: Matrix.hpp:936
T trace() const
Definition: Matrix.hpp:419
constexpr unsigned int getNofColums() const
Definition: Matrix.hpp:996
bool isOrthogonal() const
Definition: Matrix.hpp:278
MatrixInitializer< M, N, T > operator<<(T right)
Definition: Matrix.hpp:130
std::vector< T > getColVector(unsigned int n) const
Definition: Matrix.hpp:149
Matrix(const S...v)
Definition: Matrix.hpp:46
T value
Definition: Matrix.hpp:1021
static Matrix< 2, 1, T > createVector2(T x, T y)
Definition: Matrix.hpp:758