1 #ifndef ORG_EEROS_MATH_MATRIX_HPP_
2 #define ORG_EEROS_MATH_MATRIX_HPP_
14 template <
unsigned int M,
unsigned int N = 1,
typename T =
double >
18 static_assert((M > 1 && N >= 1) || (M >=1 && N > 1),
"Matrix dimension must be greater or equal than 1x1!");
22 template <
unsigned int IM,
unsigned int IN,
typename IT >
44 template<
typename... S>
46 static_assert(
sizeof...(S) == M * N,
"Invalid number of constructor arguments!");
52 for(
unsigned int i = 0;
i < M * N;
i++) {
59 unsigned int j = (M < N) ? M : N;
60 for(
unsigned int i = 0;
i <
j;
i++) {
71 if(M == 3 && N == 3) {
77 m(1,1) = std::cos(angle);
78 m(2,1) = std::sin(angle);
81 m(1,2) = -std::sin(angle);
82 m(2,2) = std::cos(angle);
85 throw EEROSException(
"rotx(double) is only implemented for 3x3 matrices");
91 if(M == 3 && N == 3) {
92 m(0,0) = std::cos(angle);
94 m(2,0) = -std::sin(angle);
100 m(0,2) = std::sin(angle);
102 m(2,2) = std::cos(angle);
105 throw EEROSException(
"roty(double) is only implemented for 3x3 matrices");
111 if(M == 3 && N == 3) {
112 m(0,0) = std::cos(angle);
113 m(1,0) = std::sin(angle);
116 m(0,1) = -std::sin(angle);
117 m(1,1) = std::cos(angle);
125 throw EEROSException(
"rotz(double) is only implemented for 3x3 matrices");
131 return MatrixInitializer<M, N, T>(*
this, 1);
136 const T
get(
unsigned int m,
unsigned int n)
const {
137 return (*
this)(m, n);
142 for(
unsigned int m = 0; m < M; m++) {
143 col(m, 0) = (*this)(m, n);
150 for(
unsigned int n = 0; n < N; n++) {
151 row(0, n) = (*this)(m, n);
156 template<
unsigned int U,
unsigned int V>
158 static_assert(U <= M && V <= N,
"Dimension of the sub matrix must be lower or equal than of the origin!");
159 if(m + U <= M && n + V <= N) {
161 for(
unsigned int u = 0; u < U; u++) {
162 for(
unsigned int v = 0;
v < V;
v++) {
163 sub(u,
v) = (*this)(m + u, n +
v);
173 void set(
unsigned int m,
unsigned int n, T
value) {
174 (*this)(m, n) = value;
178 for(
unsigned int m = 0; m < M; m++) {
179 (*this)(m, n) = col(m, 0);
184 for(
unsigned int n = 0; n < N; n++) {
185 (*this)(m, n) = row(0, n);
190 if(m >= 0 && m < M && n >= 0 && n < N) {
191 return value[M * n + m];
199 if(m >= 0 && m < M && n >= 0 && n < N) {
200 return value[M * n + m];
208 if(i >= 0 && i < M * N) {
217 if(i >= 0 && i < M * N) {
226 if(i >= 0 && i < M * N) {
235 if(i >= 0 && i < M * N) {
253 result = (*this) * transposed;
254 return result ==
eye;
262 for(
unsigned int m = 0; m < M; m++) {
263 for(
unsigned int n = 0; n < N; n++) {
265 if((*
this)(m, n) != 0){
275 for(
unsigned int m = 0; m < M; m++) {
276 for(
unsigned int n = 0; n < N; n++) {
278 if((*
this)(m, n) != 0){
288 for(
unsigned int m = 0; m < M; m++) {
289 for(
unsigned int n = 0; n < N; n++) {
291 if((*
this)(m, n) != 0){
302 return (M == N) && (this->
det() != 0);
313 constexpr
unsigned int size()
const {
318 unsigned int numberOfNonZeroRows = 0;
321 for(
unsigned int m = 0; m < M; m++) {
322 for(
unsigned int n = 0; n < N; n++) {
324 numberOfNonZeroRows++;
329 return numberOfNonZeroRows;
335 return (*
this)(0, 0) * (*
this)(1, 1) - (*
this)(0, 1) * (*
this)(1,0);
339 det = (*this)(0, 0) * (*
this)(1, 1) * (*
this)(2, 2) +
340 (*
this)(0, 1) * (*
this)(1, 2) * (*
this)(2, 0) +
341 (*
this)(0, 2) * (*
this)(1, 0) * (*
this)(2, 1) -
342 (*
this)(0, 2) * (*
this)(1, 1) * (*
this)(2, 0) -
343 (*
this)(0, 0) * (*
this)(1, 2) * (*
this)(2, 1) -
344 (*
this)(0, 1) * (*
this)(1, 0) * (*
this)(2, 2);
352 unsigned int ignoredRow = 0;
353 for(
unsigned int m = 0; m < M; m++) {
354 Matrix<M - 1, N - 1, T> subMatrix;
355 unsigned int x = 0, y = 0;
356 unsigned int a = 0, b = 1;
359 if(a != ignoredRow) {
360 subMatrix(y, x) = (*this)(a, b);
367 if(a != ignoredRow) {
373 T detSubMatrix = subMatrix.
det();
375 det = det + (*this)(m, 0) * detSubMatrix;
378 det = det - (*this)(m, 0) * detSubMatrix;
385 throw EEROSException(
"Calculating determinant failed: Matrix must be square");
392 unsigned int j = (M < N) ? M : N;
393 for(
unsigned int i = 0;
i <
j;
i++) {
394 result += (*this)(
i,
i);
401 for(
unsigned int m = 0; m < M; m++) {
402 for(
unsigned int n = 0; n < N; n++) {
403 result(n, m) = (*this)(m, n);
412 for(
unsigned int m = 0; m < M; m++) {
413 for(
unsigned int n = 0; n < N; n++) {
414 if((*
this)(m, n) != right(m, n))
422 for(
unsigned int m = 0; m < M; m++) {
423 for(
unsigned int n = 0; n < N; n++) {
424 if((*
this)(m, n) != right(m, n)) {
432 bool operator<(const Matrix<M, N, T>& right)
const {
433 for(
unsigned int m = 0; m < M; m++) {
434 for(
unsigned int n = 0; n < N; n++) {
435 if((*
this)(m, n) >= right(m, n)) {
443 bool operator<=(const Matrix<M, N, T>& right)
const {
444 for(
unsigned int m = 0; m < M; m++) {
445 for(
unsigned int n = 0; n < N; n++) {
446 if((*
this)(m, n) > right(m, n)) {
455 for(
unsigned int m = 0; m < M; m++) {
456 for(
unsigned int n = 0; n < N; n++) {
457 if((*
this)(m, n) <= right(m, n)) {
466 for(
unsigned int m = 0; m < M; m++) {
467 for(
unsigned int n = 0; n < N; n++) {
468 if((*
this)(m, n) < right(m, n)) {
477 for(
unsigned int m = 0; m < M; m++) {
478 for(
unsigned int n = 0; n < N; n++) {
479 (*this)(m, n) = right;
485 template <
unsigned int K >
488 for(
unsigned int m = 0; m < M; m++) {
489 for(
unsigned int k = 0; k < K; k++) {
491 for(
unsigned int n = 0; n < N; n++) {
492 result(m, k) += (*this)(m, n) * right(n, k);
501 for(
unsigned int m = 0; m < M; m++) {
502 for(
unsigned int n = 0; n < N; n++) {
503 result(m,n) = (*this)(m,n) * right;
511 for(
unsigned int m = 0; m < M; m++) {
512 for(
unsigned int n = 0; n < N; n++) {
513 result(m, n) = (*this)(m, n) * right(m, n);
521 for(
unsigned int m = 0; m < M; m++) {
522 for(
unsigned int n = 0; n < N; n++) {
523 result(m, n) = (*this)(m, n) + right(m, n);
531 for(
unsigned int m = 0; m < M; m++) {
532 for(
unsigned int n = 0; n < N; n++) {
533 result(m, n) = (*this)(m, n) + right;
540 (*this) = (*this) + right;
546 for(
unsigned int m = 0; m < M; m++) {
547 for(
unsigned int n = 0; n < N; n++) {
548 result(m, n) = (*this)(m, n) - right(m, n);
556 for(
unsigned int m = 0; m < M; m++) {
557 for(
unsigned int n = 0; n < N; n++) {
558 result(m, n) = (*this)(m, n) - right;
565 (*this) = (*this) - right;
571 for(
unsigned int m = 0; m < M; m++) {
572 for(
unsigned int n = 0; n < N; n++) {
573 result(m, n) = -(*this)(m, n);
581 for(
unsigned int m = 0; m < M; m++) {
582 for(
unsigned int n = 0; n < N; n++) {
583 result(m, n) = (*this)(m, n) / right;
590 T determinant = this->
det();
594 else if(determinant == 0) {
602 result(0, 0) = (*this)(1, 1);
603 result(1, 0) = -(*this)(1, 0);
604 result(0, 1) = -(*this)(0, 1);
605 result(1, 1) = (*this)(0, 0);
606 return result / determinant;
610 result(0, 0) = (*this)(1, 1) * (*
this)(2, 2) - (*
this)(1, 2) * (*
this)(2, 1);
611 result(1, 0) = (*this)(1, 2) * (*
this)(2, 0) - (*
this)(1, 0) * (*
this)(2, 2);
612 result(2, 0) = (*this)(1, 0) * (*
this)(2, 1) - (*
this)(1, 1) * (*
this)(2, 0);
613 result(0, 1) = (*this)(0, 2) * (*
this)(2, 1) - (*
this)(0, 1) * (*
this)(2, 2);
614 result(1, 1) = (*this)(0, 0) * (*
this)(2, 2) - (*
this)(0, 2) * (*
this)(2, 0);
615 result(2, 1) = (*this)(0, 1) * (*
this)(2, 0) - (*
this)(0, 0) * (*
this)(2, 1);
616 result(0, 2) = (*this)(0, 1) * (*
this)(1, 2) - (*
this)(0, 2) * (*
this)(1, 1);
617 result(1, 2) = (*this)(0, 2) * (*
this)(1, 0) - (*
this)(0, 0) * (*
this)(1, 2);
618 result(2, 2) = (*this)(0, 0) * (*
this)(1, 1) - (*
this)(0, 1) * (*
this)(1, 0);
619 return result / determinant;
624 Matrix<M - 1, N - 1, T> smallerPart;
625 unsigned int ignoredRow = 0, ignoredColum = 0;
626 for(
unsigned int m = 0; m < M; m++) {
627 for(
unsigned int n = 0; n < N; n++) {
628 unsigned int a = 0, b = 0;
630 for(
unsigned int u = 0; u < M; u++) {
631 for(
unsigned int w = 0; w < N; w++) {
632 if(u != m && w != n){
633 smallerPart(a, b) = (*this)(u, w);
646 result(m,n) = -smallerPart.
det();
649 result(m, n) = smallerPart.
det();
654 result(m, n) = smallerPart.
det();
657 result(m, n) = -smallerPart.
det();
661 result(m, n) = result(m, n) / determinant;
713 result(0, 1) = -a(2);
717 result(1, 2) = -a(0);
718 result(2, 0) = -a(1);
726 result(0, 0) = a(1, 0) * b(2, 0) - a(2, 0) * b(1, 0);
727 result(1, 0) = a(2, 0) * b(0, 0) - a(0, 0) * b(2, 0);
728 result(2, 0) = a(0, 0) * b(1, 0) - a(1, 0) * b(0, 0);
735 unsigned int completedColum = 0, completedRow = 0;
736 unsigned int checkingRow = 0, rootRow = 0;
740 while(completedColum < N) {
741 rootRow = completedRow;
742 checkingRow = rootRow + 1;
743 while(checkingRow < M && (*
this)(rootRow, completedColum) != 0) {
744 if((*
this)(checkingRow, completedColum) != 0) {
745 rowFactor = (*this)(checkingRow, completedColum) / (*
this)(rootRow, completedColum);
746 for(
unsigned int n = completedColum; n < N; n++) {
747 (*this)(checkingRow, n) = (*
this)(checkingRow, n) - rowFactor * (*
this)(rootRow, n);
758 unsigned int completedColum = 0, completedRow = 0;
759 unsigned int swapRow = completedRow + 1;
761 while(completedColum < N) {
762 while(completedRow < M) {
763 if((*
this)(completedRow, completedColum) == 0 && swapRow < M && completedRow < M - 1) {
772 swapRow = completedRow + 1;
776 void swapRows(
unsigned int rowA,
unsigned int rowB) {
777 for(
unsigned int n = 0; n < N; n++) {
778 T t = (*this)(rowA, n);
779 (*this)(rowA, n) = (*
this)(rowB, n);
780 (*this)(rowB, n) = t;
791 template <
unsigned int M,
unsigned int N = 1,
typename T =
double >
794 for(
unsigned int m = 0; m < M; m++) {
795 for(
unsigned int n = 0; n < N; n++) {
796 result(m, n) = left + right(m, n);
802 template <
unsigned int M,
unsigned int N = 1,
typename T =
double >
805 for(
unsigned int m = 0; m < M; m++) {
806 for(
unsigned int n = 0; n < N; n++) {
807 result(m, n) = left - right(m, n);
813 template <
unsigned int M,
unsigned int N = 1,
typename T =
double >
816 for(
unsigned int m = 0; m < M; m++) {
817 for(
unsigned int n = 0; n < N; n++) {
818 result(m, n) = -right(m, n);
824 template <
unsigned int M,
unsigned int N = 1,
typename T =
double >
827 for(
unsigned int m = 0; m < M; m++) {
828 for(
unsigned int n = 0; n < N; n++) {
829 result(m, n) = left * right(m, n);
835 template <
unsigned int M,
unsigned int N = 1,
typename T =
double >
838 for(
unsigned int m = 0; m < M; m++) {
839 for(
unsigned int n = 0; n < N; n++) {
840 result(m, n) = left / right(m, n);
848 template <
unsigned int M,
unsigned int N = 1,
typename T =
double >
849 std::ostream& operator<<(std::ostream& os, const Matrix<M, N, T>& right) {
850 if(N > 1) os <<
"[ ";
851 for(
unsigned int n = 0; n < N; n++) {
853 for(
unsigned int m = 0; m < M; m++) {
855 if(m < M - 1) os <<
' ';
869 template <
unsigned int M,
typename T =
double >
874 template <
typename T >
891 const T
get(uint8_t m, uint8_t n)
const {
return (*
this)(m, n); }
897 void set(uint8_t m, uint8_t n, T
value) { (*this)(m, n) = value; }
929 constexpr
unsigned int size()
const {
return 1; }
931 unsigned int rank()
const {
return (
value == 0) ? 1 : 0; }
939 operator T()
const {
return value; }
T & operator()(unsigned int i)
Definition: Matrix.hpp:207
bool isUpperTriangular() const
Definition: Matrix.hpp:287
bool isDiagonal() const
Definition: Matrix.hpp:261
MatrixInitializer< IM, IN, IT > operator,(IT right)
Definition: Matrix.hpp:27
Matrix< M, N, T > & operator+=(const Matrix< M, N, T > right)
Definition: Matrix.hpp:539
unsigned int rank() const
Definition: Matrix.hpp:317
Matrix< 1, 1, T > operator!() const
Definition: Matrix.hpp:937
Matrix< IM, IN, IT > & mat
Definition: Matrix.hpp:32
void set(uint8_t m, uint8_t n, T value)
Definition: Matrix.hpp:897
T trace() const
Definition: Matrix.hpp:935
static Matrix< 3, 1, T > createVector3(T x, T y, T z)
Definition: Matrix.hpp:696
constexpr bool isLowerTriangular() const
Definition: Matrix.hpp:919
Definition: MatrixIndexOutOfBoundException.hpp:9
constexpr unsigned int getNofRows() const
Definition: Matrix.hpp:305
Matrix< N, M, T > transpose() const
Definition: Matrix.hpp:399
void roty(double angle)
Definition: Matrix.hpp:89
Definition: Matrix.hpp:23
bool operator>(const Matrix< M, N, T > &right) const
Definition: Matrix.hpp:454
Matrix< M, N, T > operator+(const Matrix< M, N, T > right) const
Definition: Matrix.hpp:519
const T operator[](unsigned int i) const
Definition: Matrix.hpp:909
constexpr bool isSquare() const
Definition: Matrix.hpp:245
bool isOrthogonal() const
Definition: Matrix.hpp:913
constexpr unsigned int getNofColums() const
Definition: Matrix.hpp:309
constexpr bool isSymmetric() const
Definition: Matrix.hpp:915
Matrix< M, N, T > & operator=(T right)
Definition: Matrix.hpp:476
Matrix< M, N, T > operator!() const
Definition: Matrix.hpp:589
void eye()
Definition: Matrix.hpp:887
Definition: EEROSException.hpp:9
static Matrix< 3, 3, T > createSkewSymmetric(Matrix< 3, 1, T > a)
Definition: Matrix.hpp:710
int v
Definition: RingBufferTest.cpp:14
Matrix< M, N, T > operator-()
Definition: Matrix.hpp:569
void swapRows(unsigned int rowA, unsigned int rowB)
Definition: Matrix.hpp:776
bool isInvertible() const
Definition: Matrix.hpp:300
bool operator>=(const Matrix< M, N, T > &right) const
Definition: Matrix.hpp:465
Matrix< M, N, T > operator-(const T right) const
Definition: Matrix.hpp:554
const T operator()(unsigned int m, unsigned int n) const
Definition: Matrix.hpp:198
constexpr bool isSquare() const
Definition: Matrix.hpp:911
T & operator()(unsigned int i)
Definition: Matrix.hpp:903
Matrix< M, 1, T > getCol(unsigned int n) const
Definition: Matrix.hpp:140
void setRow(unsigned int m, const Matrix< 1, N, T > &row)
Definition: Matrix.hpp:183
static Matrix< 3, 1, T > crossProduct(Matrix< 3, 1, T > a, Matrix< 3, 1, T > b)
Definition: Matrix.hpp:724
Matrix< M, N, T > operator*(T right) const
Definition: Matrix.hpp:499
T det() const
Definition: Matrix.hpp:933
T & operator[](unsigned int i)
Definition: Matrix.hpp:907
Matrix< 1, 1, T > getRow(uint8_t m) const
Definition: Matrix.hpp:895
const T operator()(unsigned int i) const
Definition: Matrix.hpp:216
Matrix< M, N, T > operator+(const T right) const
Definition: Matrix.hpp:529
T value_type
Definition: Matrix.hpp:20
T & operator[](unsigned int i)
Definition: Matrix.hpp:225
Matrix()
Definition: Matrix.hpp:881
bool isSymmetric() const
Definition: Matrix.hpp:257
unsigned int rank() const
Definition: Matrix.hpp:931
void zero()
Definition: Matrix.hpp:885
constexpr bool isDiagonal() const
Definition: Matrix.hpp:917
T & operator()(uint8_t m, uint8_t n)
Definition: Matrix.hpp:899
Matrix< 3, 1 > Vector3
Definition: Matrix.hpp:866
static Matrix< M, N, T > createRotZ(double angle)
Definition: Matrix.hpp:683
Matrix< M, K, T > operator*(const Matrix< N, K, T > right) const
Definition: Matrix.hpp:486
Definition: Matrix.hpp:875
bool isInvertible() const
Definition: Matrix.hpp:923
void rotx(double angle)
Definition: Matrix.hpp:69
constexpr unsigned int size() const
Definition: Matrix.hpp:313
Matrix< M, N, T > operator/(T right) const
Definition: Matrix.hpp:579
const T operator[](unsigned int i) const
Definition: Matrix.hpp:234
constexpr unsigned int getNofRows() const
Definition: Matrix.hpp:925
Matrix< 2, 1 > Vector2
Definition: Matrix.hpp:865
static Matrix< M, N, T > createRotX(double angle)
Definition: Matrix.hpp:671
Matrix< 1, N, T > getRow(unsigned int m) const
Definition: Matrix.hpp:148
void sortForGaussAlgorithm()
Definition: Matrix.hpp:757
T det() const
Definition: Matrix.hpp:332
MatrixInitializer(Matrix< IM, IN, IT > &mat, unsigned int index=0)
Definition: Matrix.hpp:25
Matrix< M, N, T > operator-(const Matrix< M, N, T > right) const
Definition: Matrix.hpp:544
void eye()
Definition: Matrix.hpp:57
Definition: Matrix.hpp:15
constexpr unsigned int size() const
Definition: Matrix.hpp:929
T value[M *N]
Definition: Matrix.hpp:785
int j
Definition: RingBufferTest.cpp:13
void gaussRowElimination()
Definition: Matrix.hpp:734
bool operator==(const Matrix< M, N, T > &right) const
Definition: Matrix.hpp:411
Matrix()
Definition: Matrix.hpp:38
void fill(T v)
Definition: Matrix.hpp:65
Matrix(const T v)
Definition: Matrix.hpp:40
T value_type
Definition: Matrix.hpp:879
bool isLowerTriangular() const
Definition: Matrix.hpp:274
void zero()
Definition: Matrix.hpp:51
unsigned int index
Definition: Matrix.hpp:33
T & operator()(unsigned int m, unsigned int n)
Definition: Matrix.hpp:189
static Matrix< M, N, T > createRotY(double angle)
Definition: Matrix.hpp:677
Matrix< 1, 1, T > getCol(uint8_t n) const
Definition: Matrix.hpp:893
Matrix< M, N, T > multiplyElementWise(const Matrix< M, N, T > right) const
Definition: Matrix.hpp:509
void setCol(unsigned int n, const Matrix< M, 1, T > &col)
Definition: Matrix.hpp:177
const T operator()(unsigned int i) const
Definition: Matrix.hpp:905
constexpr bool isUpperTriangular() const
Definition: Matrix.hpp:921
Matrix(const T v)
Definition: Matrix.hpp:883
Matrix< U, V, T > getSubMatrix(unsigned int m, unsigned int n) const
Definition: Matrix.hpp:157
const T operator()(uint8_t m, uint8_t n) const
Definition: Matrix.hpp:901
int i
Definition: RingBufferTest.cpp:12
void fill(T v)
Definition: Matrix.hpp:889
bool operator!=(const Matrix< M, N, T > &right) const
Definition: Matrix.hpp:421
void rotz(double angle)
Definition: Matrix.hpp:109
Matrix< M, N, T > & operator-=(const Matrix< M, N, T > right)
Definition: Matrix.hpp:564
static Matrix< M, N, T > createDiag(T v)
Definition: Matrix.hpp:704
void set(unsigned int m, unsigned int n, T value)
Definition: Matrix.hpp:173
Matrix< 4, 1 > Vector4
Definition: Matrix.hpp:867
T trace() const
Definition: Matrix.hpp:390
constexpr unsigned int getNofColums() const
Definition: Matrix.hpp:927
bool isOrthogonal() const
Definition: Matrix.hpp:249
MatrixInitializer< M, N, T > operator<<(T right)
Definition: Matrix.hpp:129
Matrix(const S...v)
Definition: Matrix.hpp:45
T value
Definition: Matrix.hpp:942
static Matrix< 2, 1, T > createVector2(T x, T y)
Definition: Matrix.hpp:689