EEROS  1.0.0.0
API for the EEROS Real-Time Robotics Framework
Matrix.hpp
Go to the documentation of this file.
1 #ifndef ORG_EEROS_MATH_MATRIX_HPP_
2 #define ORG_EEROS_MATH_MATRIX_HPP_
3 
4 #include <eeros/core/Fault.hpp>
6 
7 #include <utility>
8 #include <sstream>
9 #include <cstdlib>
10 #include <cmath>
11 #include <vector>
12 
13 namespace eeros {
14  namespace math {
15  template < unsigned int M, unsigned int N = 1, typename T = double >
16  class Matrix {
17  public:
18 
19  static_assert((M > 1 && N >= 1) || (M >=1 && N > 1), "Matrix dimension must be greater or equal than 1x1!");
20 
21  using value_type = T;
22 
23  template < unsigned int IM, unsigned int IN, typename IT >
25  public:
26  MatrixInitializer(Matrix<IM, IN, IT>& mat, unsigned int index = 0) : mat(mat), index(index) { }
27 
29  mat(index / N, index % N) = right;
31  }
32 
34  unsigned int index;
35  }; // END class MatrixInitializer
36 
37  /********** Constructors **********/
38 
39  Matrix() { }
40 
41  Matrix(const T v) {
42  (*this) = v;
43  }
44 
45  template<typename... S>
46  Matrix(const S... v) : value{std::forward<const T>(v)...} {
47  static_assert(sizeof...(S) == M * N, "Invalid number of constructor arguments!");
48  }
49 
50  /********** Initializing the matrix **********/
51 
52  void zero() {
53  for(unsigned int i = 0; i < M * N; i++) {
54  value[i] = 0;
55  }
56  }
57 
58  void eye() {
59  zero();
60  unsigned int j = (M < N) ? M : N;
61  for(unsigned int i = 0; i < j; i++) {
62  (*this)(i, i) = 1;
63  }
64  }
65 
66  void fill(T v) {
67  (*this) = v;
68  }
69 
70  void rotx(double angle) {
71  Matrix<M, N, T>& m = *this;
72  if(M == 3 && N == 3) {
73  m(0,0) = 1;
74  m(1,0) = 0;
75  m(2,0) = 0;
76 
77  m(0,1) = 0;
78  m(1,1) = std::cos(angle);
79  m(2,1) = std::sin(angle);
80 
81  m(0,2) = 0;
82  m(1,2) = -std::sin(angle);
83  m(2,2) = std::cos(angle);
84  }
85  else {
86  throw Fault("rotx(double) is only implemented for 3x3 matrices");
87  }
88  }
89 
90  void roty(double angle) {
91  Matrix<M, N, T>& m = *this;
92  if(M == 3 && N == 3) {
93  m(0,0) = std::cos(angle);
94  m(1,0) = 0;
95  m(2,0) = -std::sin(angle);
96 
97  m(0,1) = 0;
98  m(1,1) = 1;
99  m(2,1) = 0;
100 
101  m(0,2) = std::sin(angle);
102  m(1,2) = 0;
103  m(2,2) = std::cos(angle);
104  }
105  else {
106  throw Fault("roty(double) is only implemented for 3x3 matrices");
107  }
108  }
109 
110  void rotz(double angle) {
111  Matrix<M, N, T>& m = *this;
112  if(M == 3 && N == 3) {
113  m(0,0) = std::cos(angle);
114  m(1,0) = std::sin(angle);
115  m(2,0) = 0;
116 
117  m(0,1) = -std::sin(angle);
118  m(1,1) = std::cos(angle);
119  m(2,1) = 0;
120 
121  m(0,2) = 0;
122  m(1,2) = 0;
123  m(2,2) = 1;
124  }
125  else {
126  throw Fault("rotz(double) is only implemented for 3x3 matrices");
127  }
128  }
129 
130  MatrixInitializer<M, N, T> operator<<(T right) {
131  (*this)[0] = right;
132  return MatrixInitializer<M, N, T>(*this, 1);
133  }
134 
135  /********** Element access **********/
136 
137  const T get(unsigned int m, unsigned int n) const {
138  return (*this)(m, n);
139  }
140 
141  Matrix<M, 1, T> getCol(unsigned int n) const {
142  Matrix<M, 1, T> col;
143  for(unsigned int m = 0; m < M; m++) {
144  col(m, 0) = (*this)(m, n);
145  }
146  return col;
147  }
148 
149  std::vector<T> getColVector(unsigned int n) const {
150  std::vector<T> col;
151  for(unsigned int m = 0; m < M; m++) {
152  col.push_back( (*this)(m, n) );
153  }
154  return col;
155  }
156 
157  Matrix<1, N, T> getRow(unsigned int m) const {
158  Matrix<1, N, T> row;
159  for(unsigned int n = 0; n < N; n++) {
160  row(0, n) = (*this)(m, n);
161  }
162  return row;
163  }
164 
165  std::vector<T> getRowVector(unsigned int m) const {
166  std::vector<T> row;
167  for(unsigned int n = 0; n < N; n++) {
168  row.push_back( (*this)(m, n) );
169  }
170  return row;
171  }
172 
173  template<unsigned int U, unsigned int V>
174  Matrix<U, V, T> getSubMatrix(unsigned int m, unsigned int n) const {
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) {
177  Matrix<U, V, T> sub;
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);
181  }
182  }
183  return sub;
184  }
185  else {
186  throw MatrixIndexOutOfBoundException(m + U - 1, M, n + V - 1, N);
187  }
188  }
189 
190  void set(unsigned int m, unsigned int n, T value) {
191  (*this)(m, n) = value;
192  }
193 
194  void setCol(unsigned int n, const Matrix<M, 1, T>& col) {
195  for(unsigned int m = 0; m < M; m++) {
196  (*this)(m, n) = col(m, 0);
197  }
198  }
199 
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];
203  }
204  }
205 
206  void setRow(unsigned int m, const Matrix<1, N, T>& row) {
207  for(unsigned int n = 0; n < N; n++) {
208  (*this)(m, n) = row(0, n);
209  }
210  }
211 
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];
215  }
216  }
217 
218  T& operator()(unsigned int m, unsigned int n) {
219  if(m >= 0 && m < M && n >= 0 && n < N) {
220  return value[M * n + m];
221  }
222  else {
223  throw MatrixIndexOutOfBoundException(m, M, n, N);
224  }
225  }
226 
227  const T operator()(unsigned int m, unsigned int n) const {
228  if(m >= 0 && m < M && n >= 0 && n < N) {
229  return value[M * n + m];
230  }
231  else {
232  throw MatrixIndexOutOfBoundException(m, M, n, N);
233  }
234  }
235 
236  T& operator()(unsigned int i) {
237  if(i >= 0 && i < M * N) {
238  return value[i];
239  }
240  else {
241  throw MatrixIndexOutOfBoundException(i, M * N);
242  }
243  }
244 
245  const T operator()(unsigned int i) const {
246  if(i >= 0 && i < M * N) {
247  return value[i];
248  }
249  else {
250  throw MatrixIndexOutOfBoundException(i, M * N);
251  }
252  }
253 
254  T& operator[](unsigned int i) {
255  if(i >= 0 && i < M * N) {
256  return value[i];
257  }
258  else {
259  throw MatrixIndexOutOfBoundException(i, M * N);
260  }
261  }
262 
263  const T operator[](unsigned int i) const {
264  if(i >= 0 && i < M * N) {
265  return value[i];
266  }
267  else {
268  throw MatrixIndexOutOfBoundException(i, M * N);
269  }
270  }
271 
272  /********** Matrix characteristics **********/
273 
274  constexpr bool isSquare() const {
275  return M == N;
276  }
277 
278  bool isOrthogonal() const {
279  Matrix<N, M, T> result, transposed, eye;
280  eye.eye();
281  transposed = this->transpose();
282  result = (*this) * transposed;
283  return result == eye;
284  }
285 
286  bool isSymmetric() const {
287  return (*this) == this->transpose();
288  }
289 
290  bool isDiagonal() const {
291  for(unsigned int m = 0; m < M; m++) {
292  for(unsigned int n = 0; n < N; n++) {
293  if(m != n){
294  if((*this)(m, n) != 0){
295  return false;
296  }
297  }
298  }
299  }
300  return true;
301  }
302 
303  bool isLowerTriangular() const {
304  for(unsigned int m = 0; m < M; m++) {
305  for(unsigned int n = 0; n < N; n++) {
306  if(m < n){
307  if((*this)(m, n) != 0){
308  return false;
309  }
310  }
311  }
312  }
313  return true;
314  }
315 
316  bool isUpperTriangular() const {
317  for(unsigned int m = 0; m < M; m++) {
318  for(unsigned int n = 0; n < N; n++) {
319  if(m > n){
320  if((*this)(m, n) != 0){
321  return false;
322  }
323  }
324  }
325  }
326  return true;
327  }
328 
329  bool isInvertible() const {
330  // non square matrices can't be inverted, if the determinat of a matrix is zero it is not invertible
331  return (M == N) && (this->det() != 0);
332  }
333 
334  constexpr unsigned int getNofRows() const {
335  return M;
336  }
337 
338  constexpr unsigned int getNofColums() const {
339  return N;
340  }
341 
342  constexpr unsigned int size() const {
343  return M * N;
344  }
345 
346  unsigned int rank() const {
347  unsigned int numberOfNonZeroRows = 0;
348  Matrix<M, N, T> temp = (*this);
349  temp.gaussRowElimination();
350  for(unsigned int m = 0; m < M; m++) {
351  for(unsigned int n = 0; n < N; n++) {
352  if(temp(m, n) != 0){
353  numberOfNonZeroRows++;
354  break;
355  }
356  }
357  }
358  return numberOfNonZeroRows;
359  }
360 
361  T det() const {
362  if(M == N) { // Determinat can only be calculated of a square matrix
363  if(M == 2) { // 2x2 matrix
364  return (*this)(0, 0) * (*this)(1, 1) - (*this)(0, 1) * (*this)(1,0);
365  }
366  else if(M == 3) { // 3x3 matrix
367  T det = 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);
374  return det;
375  }
376  else { // 4x4 and bigger square matrices
377  // Use recurcive laplace formula to calculate the determinat.
378  // For big matrices this method needs a lot of time, this
379  // could be improved with another algorithm.
380  T det = 0;
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;
386  while(a < M) {
387  while(b < N) {
388  if(a != ignoredRow) {
389  subMatrix(y, x) = (*this)(a, b);
390  x++;
391  }
392  b++;
393  }
394  b = 1;
395  x = 0;
396  if(a != ignoredRow) {
397  y++;
398  }
399  a++;
400  }
401  ignoredRow++;
402  T detSubMatrix = subMatrix.det();
403  if(m % 2 == 0) { // even
404  det = det + (*this)(m, 0) * detSubMatrix;
405  }
406  else { // odd
407  det = det - (*this)(m, 0) * detSubMatrix;
408  }
409  }
410  return det;
411  }
412  }
413  else {
414  throw Fault("Calculating determinant failed: Matrix must be square");
415  }
416  return 0;
417  }
418 
419  T trace() const {
420  T result = 0;
421  unsigned int j = (M < N) ? M : N;
422  for(unsigned int i = 0; i < j; i++) {
423  result += (*this)(i, i);
424  }
425  return result;
426  }
427 
429  Matrix<N, M, T> result;
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);
433  }
434  }
435  return result;
436  }
437 
438  /********** Base operations **********/
439 
445  bool operator==(const Matrix<M, N, T>& right) const {
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))
449  return false;
450  }
451  }
452  return true;
453  }
454 
460  bool operator!=(const Matrix<M, N, T>& right) const {
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)) {
464  return true;
465  }
466  }
467  }
468  return false;
469  }
470 
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)) {
480  return false;
481  }
482  }
483  }
484  return true;
485  }
486 
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)) {
496  return false;
497  }
498  }
499  }
500  return true;
501  }
502 
508  bool operator>(const Matrix<M, N, T>& right) const {
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)) {
512  return false;
513  }
514  }
515  }
516  return true;
517  }
518 
524  bool operator>=(const Matrix<M, N, T>& right) const {
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)) {
528  return false;
529  }
530  }
531  }
532  return true;
533  }
534 
536  for(unsigned int m = 0; m < M; m++) {
537  for(unsigned int n = 0; n < N; n++) {
538  (*this)(m, n) = right;
539  }
540  }
541  return *this;
542  }
543 
544  template < unsigned int K >
546  Matrix<M, K, T> result;
547  for(unsigned int m = 0; m < M; m++) {
548  for(unsigned int k = 0; k < K; k++) {
549  result(m, k) = 0;
550  for(unsigned int n = 0; n < N; n++) {
551  result(m, k) += (*this)(m, n) * right(n, k);
552  }
553  }
554  }
555  return result;
556  }
557 
558  Matrix<M, N, T> operator*(T right) const {
559  Matrix<M, N, T> result;
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;
563  }
564  }
565  return result;
566  }
567 
569  Matrix<M, N, T> result;
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);
573  }
574  }
575  return result;
576  }
577 
579  Matrix<M, N, T> result;
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);
583  }
584  }
585  return result;
586  }
587 
588  Matrix<M, N, T> operator+(const T right) const {
589  Matrix<M, N, T> result;
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;
593  }
594  }
595  return result;
596  }
597 
599  (*this) = (*this) + right;
600  return (*this);
601  }
602 
604  Matrix<M, N, T> result;
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);
608  }
609  }
610  return result;
611  }
612 
613  Matrix<M, N, T> operator-(const T right) const {
614  Matrix<M, N, T> result;
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;
618  }
619  }
620  return result;
621  }
622 
624  (*this) = (*this) - right;
625  return (*this);
626  }
627 
629  Matrix<M, N, T> result;
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);
633  }
634  }
635  return result;
636  }
637 
638  Matrix<M, N, T> operator/(T right) const {
639  Matrix<M, N, T> result;
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;
643  }
644  }
645  return result;
646  }
647 
649  T determinant = this->det();
650  if(N != M) {
651  throw Fault("Invert failed: matrix not square");
652  }
653  else if(determinant == 0) {
654  throw Fault("Invert failed: determinat of matrix is 0");
655  }
656  else if(this->isOrthogonal() == true) {
657  return transpose();
658  }
659  else if(M == 2) { // 2x2 matrix
660  Matrix<M, N, T> result;
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;
666  }
667  else if(M == 3) { // 3x3 matrix
668  Matrix<M, N, T> result;
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;
679  }
680  else {
681  // This algorithm needs a lot of time maybe there is a better one?
682  Matrix<M, N, T> result;
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;
688  // 1. Create "matrix of minors"
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);
693  b++;
694  b = b % (N - 1);
695  }
696  }
697  if(u != m) {
698  a++;
699  a = a&(M - 1);
700  }
701  }
702  // 2. Swapp signs
703  if(m % 2 == 0) {
704  if(n % 2 != 0) {
705  result(m,n) = -smallerPart.det();
706  }
707  else {
708  result(m, n) = smallerPart.det();
709  }
710  }
711  else {
712  if(n % 2 != 0){
713  result(m, n) = smallerPart.det();
714  }
715  else {
716  result(m, n) = -smallerPart.det();
717  }
718  }
719  // 3. Divide throu det of the original matrix
720  result(m, n) = result(m, n) / determinant;
721  }
722  }
723  // 4. transpose
724  return result.transpose();
725  }
726  }
727 
728  T norm() const {
729  T result = 0;
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);
733  }
734  }
735  return std::sqrt(result);
736  }
737 
738  /********** Static functions **********/
739 
740  static Matrix<M, N, T> createRotX(double angle) {
741  Matrix<M, N, T> m;
742  m.rotx(angle);
743  return m;
744  }
745 
746  static Matrix<M, N, T> createRotY(double angle) {
747  Matrix<M, N, T> m;
748  m.roty(angle);
749  return m;
750  }
751 
752  static Matrix<M, N, T> createRotZ(double angle) {
753  Matrix<M, N, T> m;
754  m.rotz(angle);
755  return m;
756  }
757 
758  static Matrix<2, 1, T> createVector2(T x, T y) {
759  Matrix<2, 1, T> v;
760  v(0) = x;
761  v(1) = y;
762  return v;
763  }
764 
765  static Matrix<3, 1, T> createVector3(T x, T y, T z) {
766  Matrix<3, 1, T> v;
767  v(0) = x;
768  v(1) = y;
769  v(2) = z;
770  return v;
771  }
772 
774  Matrix<M, N, T> d;
775  d.eye();
776  return d * v;
777  }
778 
780  Matrix<3, 3, T> result;
781  result(0, 0) = 0;
782  result(0, 1) = -a(2);
783  result(0, 2) = a(1);
784  result(1, 0) = a(2);
785  result(1, 1) = 0;
786  result(1, 2) = -a(0);
787  result(2, 0) = -a(1);
788  result(2, 1) = a(0);
789  result(2, 2) = 0;
790  return result;
791  }
792 
794  Matrix<3, 1, T> result;
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);
798  return result;
799  }
800 
801  /********** Helper functions **********/
802 
804  unsigned int completedColum = 0, completedRow = 0;
805  unsigned int checkingRow = 0, rootRow = 0;
806  T rowFactor = 0;
807 
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);
817  }
818  }
819  checkingRow++;
820  }
821  completedRow++;
822  completedColum++;
823  }
824  }
825 
827  unsigned int completedColum = 0, completedRow = 0;
828  unsigned int swapRow = completedRow + 1;
829 
830  while(completedColum < N) {
831  while(completedRow < M) {
832  if((*this)(completedRow, completedColum) == 0 && swapRow < M && completedRow < M - 1) {
833  swapRows(completedRow, swapRow);
834  swapRow++;
835  }
836  else {
837  completedRow++;
838  }
839  }
840  completedColum++;
841  swapRow = completedRow + 1;
842  }
843  }
844 
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;
850  }
851  }
852 
853  protected:
854  T value[M * N];
855 
856  }; // END class Matrix
857 
858  /********** Operators **********/
859 
860  template < unsigned int M, unsigned int N = 1, typename T = double >
862  Matrix<M, N, T> result;
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);
866  }
867  }
868  return result;
869  }
870 
871  template < unsigned int M, unsigned int N = 1, typename T = double >
873  Matrix<M, N, T> result;
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);
877  }
878  }
879  return result;
880  }
881 
882  template < unsigned int M, unsigned int N = 1, typename T = double >
884  Matrix<M, N, T> result;
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);
888  }
889  }
890  return result;
891  }
892 
893  template < unsigned int M, unsigned int N = 1, typename T = double >
895  Matrix<M, N, T> result;
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);
899  }
900  }
901  return result;
902  }
903 
904  template < unsigned int M, unsigned int N = 1, typename T = double >
906  Matrix<M, N, T> result;
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);
910  }
911  }
912  return result;
913  }
914 
915  /********** Print functions **********/
916 
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++) {
921  os << '[';
922  for(unsigned int m = 0; m < M; m++) {
923  os << right(m, n);
924  if(m < M - 1) os << ' ';
925  }
926  os << "]' ";
927  }
928  if(N > 1) os << "]";
929  return os;
930  }
931 
932  /********** Type definitions **********/
933 
937 
938  template < unsigned int M, typename T = double >
940 
941  /********** Specialization for a 1x1 matrix **********/
942 
943  template < typename T >
944  class Matrix<1, 1, T> {
945 
946  public:
947 
948  using value_type = T;
949 
950  Matrix() { }
951 
952  Matrix(const T v) { value = v; }
953 
954  void zero() { value = 0; }
955 
956  void eye() { value = 1; }
957 
958  void fill(T v) { value = v; }
959 
960  const T get(uint8_t m, uint8_t n) const { return (*this)(m, n); }
961 
962  Matrix<1, 1, T> getCol(uint8_t n) const { return (*this); }
963 
964  Matrix<1, 1, T> getRow(uint8_t m) const { return (*this); }
965 
966  void set(uint8_t m, uint8_t n, T value) { (*this)(m, n) = value; }
967 
968  T& operator()(uint8_t m, uint8_t n) { if(m == 0 && n == 0) return value; else throw MatrixIndexOutOfBoundException(m, 1, n, 1); }
969 
970  const T operator()(uint8_t m, uint8_t n) const { if(m == 0 && n == 0) return value; else throw MatrixIndexOutOfBoundException(m, 1, n, 1); }
971 
972  T& operator()(unsigned int i) { if(i == 0) return value; else throw MatrixIndexOutOfBoundException(i, 1); }
973 
974  const T operator()(unsigned int i) const { if(i == 0) return value; else throw MatrixIndexOutOfBoundException(i, 1); }
975 
976  T& operator[](unsigned int i) { if(i == 0) return value; else throw MatrixIndexOutOfBoundException(i, 1); }
977 
978  const T operator[](unsigned int i) const { if(i == 0) return value; else throw MatrixIndexOutOfBoundException(i, 1); }
979 
980  constexpr bool isSquare() const { return true; }
981 
982  bool isOrthogonal() const { return value == 1; }
983 
984  constexpr bool isSymmetric() const { return true; }
985 
986  constexpr bool isDiagonal() const { return true; }
987 
988  constexpr bool isLowerTriangular() const { return true; }
989 
990  constexpr bool isUpperTriangular() const { return true; }
991 
992  bool isInvertible() const { return value != 0; }
993 
994  constexpr unsigned int getNofRows() const { return 1; }
995 
996  constexpr unsigned int getNofColums() const { return 1; }
997 
998  constexpr unsigned int size() const { return 1; }
999 
1000  unsigned int rank() const { return (value == 0) ? 1 : 0; }
1001 
1002  T det() const { return value; }
1003 
1004  T trace() const { return value; }
1005 
1006  Matrix<1, 1, T> operator!() const { Matrix<1, 1, T> inv(1/value); return inv; }
1007 
1008  operator T() const { return value; }
1009 
1011  (*this) = (*this) + right;
1012  return (*this);
1013  }
1014 
1016  (*this) = (*this) - right;
1017  return (*this);
1018  }
1019 
1020  protected:
1022  };
1023 
1024  } // END namespace math
1025 } // END namespache eeros
1026 
1027 #endif /* ORG_EEROS_MATH_MATRIX_HPP_ */
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
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
Definition: Fault.hpp:9
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