Theoretica
A C++ numerical and automatic mathematical library
mat.h
Go to the documentation of this file.
1 
5 
6 #ifndef THEORETICA_MATRIX_H
7 #define THEORETICA_MATRIX_H
8 
9 #ifndef THEORETICA_NO_PRINT
10 #include <sstream>
11 #include <ostream>
12 #endif
13 
14 #include <array>
15 #include <vector>
16 
17 #include "../core/error.h"
18 #include "../core/constants.h"
19 #include "../core/real_analysis.h"
20 #include "./algebra.h"
21 #include "./transform.h"
22 #include "./vec.h"
23 
24 
25 namespace theoretica {
26 
27 
33  template<typename Matrix, typename ReturnType = matrix_element_t<Matrix>&>
34  class mat_iterator {
35 
36  private:
37 
39  Matrix& matrix;
40 
42  size_t row;
43 
45  size_t col;
46 
47  public:
48 
49  using iterator_category = std::forward_iterator_tag;
50  using value_type = matrix_element_t<Matrix>;
51  using pointer = value_type*;
52  using reference = value_type&;
53 
56  Matrix& matrix,
57  size_t row = 0,
58  size_t col = 0)
59  : matrix(matrix), row(row), col(col) {}
60 
61 
64  ReturnType operator*() {
65  return matrix(row, col);
66  }
67 
68 
71 
72  col++;
73 
74  if(col == matrix.cols()) {
75  col = 0;
76  row++;
77  }
78 
79  return *this;
80  }
81 
82 
84  size_t row_index() {
85  return row;
86  }
87 
88 
90  size_t col_index() {
91  return col;
92  }
93 
94 
96  // mat_iterator& operator--() {
97  // if(row == 0) {
98  // TH_MATH_ERROR(
99  // "iterator::operator--",
100  // row, IMPOSSIBLE_OPERATION);
101  // return *this;
102  // }
103  // if(col == 0) {
104  // col = max_col;
105  // row--;
106  // }
107  // col--;
108  // return *this;
109  // }
110 
111 
112  // Comparison operators
113 
114  bool operator==(const mat_iterator& other) const {
115  return (row == other.row) &&
116  (col == other.col);
117  }
118 
119  bool operator!=(const mat_iterator& other) const {
120  return !(*this == other);
121  }
122  };
123 
124 
131  template<typename Type = real, unsigned int N = 0, unsigned int K = 0>
132  class mat {
133  public:
134 
135 #ifdef THEORETICA_ROW_FIRST
136  Type data[N][K];
137 #else
138  Type data[K][N];
139 #endif
140 
141 
143  mat() {
144  algebra::mat_zeroes(*this);
145  }
146 
147 
149  template<typename Matrix>
150  mat(const Matrix& m) {
151  algebra::mat_copy(*this, m);
152  }
153 
154 
156  template<typename T = Type>
157  inline mat(const std::initializer_list<std::initializer_list<T>>& rows) {
158 
159  if(rows.size() != N) {
160  TH_MATH_ERROR("mat::mat", rows.size(), INVALID_ARGUMENT);
161  algebra::mat_error(*this);
162  return;
163  }
164 
165  unsigned int i = 0;
166  unsigned int j = 0;
167 
168  for (const auto& row : rows) {
169 
170  if (row.size() != K) {
171  TH_MATH_ERROR("mat::mat", rows.size(), INVALID_ARGUMENT);
172  algebra::mat_error(*this);
173  return;
174  }
175 
176  for (const auto& x : row) {
177 
178  at(i, j) = x;
179  j = (j + 1) % K;
180  }
181 
182  i++;
183  }
184  }
185 
186 
188  template<typename Matrix>
189  inline mat<Type, N, K>& operator=(const Matrix& other) {
190  return algebra::mat_copy(*this, other);
191  }
192 
193 
195  inline void make_zeroes() {
196  algebra::mat_zeroes(*this);
197  }
198 
199 
201  inline static mat<Type, N, K> zeroes() {
202  mat<Type, N, K> res;
203  algebra::mat_zeroes(res);
204  return res;
205  }
206 
207 
209  template<typename Matrix>
210  inline mat<Type, N, K> operator+(const Matrix& other) const {
211  mat<Type, N, K> res;
212  return algebra::mat_sum(res, *this, other);
213  }
214 
215 
217  template<typename Matrix>
218  inline mat<Type, N, K> operator-(const Matrix& other) const {
219  mat<Type, N, K> res;
220  return algebra::mat_diff(res, *this, other);
221  }
222 
223 
225  inline mat<Type, N, K> operator*(Type scalar) const {
226  mat<Type, N, K> res;
227  return algebra::mat_scalmul(res, scalar, *this);
228  }
229 
230 
233  inline friend mat<Type, N, K> operator*(Type a, const mat<Type, N, K>& B) {
234  return B * a;
235  }
236 
237 
240  template<typename VecType, unsigned int M>
241  inline friend vec<VecType, K> operator*(
242  const vec<VecType, M>& a, const mat<Type, N, K>& B) {
243  return B * a;
244  }
245 
246 
248  inline mat<Type, N, K> operator/(Type scalar) const {
249 
250  mat<Type, N, K> res;
251 
252  if(abs(scalar) < MACH_EPSILON) {
253  TH_MATH_ERROR("mat::operator/", scalar, DIV_BY_ZERO);
254  return algebra::mat_error(res);
255  }
256 
257  return algebra::mat_scalmul(res, 1.0 / scalar, *this);
258  }
259 
260 
262  template<typename Vector>
263  inline Vector transform(const Vector& v) const {
264 
265  if(v.size() != cols()) {
266  TH_MATH_ERROR("mat::transform", v.size(), INVALID_ARGUMENT);
267  Vector res;
268  res.resize(cols());
269  algebra::vec_error(res);
270  return res;
271  }
272 
273  return algebra::transform(*this, v);
274  }
275 
276 
278  inline vec<Type, N> transform(const vec<Type, K>& v) const {
279  return algebra::transform(*this, v);
280  }
281 
282 
284  inline vec<Type, N> operator*(const vec<Type, K>& v) const {
285  return transform(v);
286  }
287 
288 
290  template<unsigned int M>
291  inline mat<Type, N, M> mul(const mat<Type, K, M>& B) const {
292  mat<Type, N, M> res;
293  return algebra::mat_mul(res, *this, B);
294  }
295 
296 
298  template<typename Matrix>
299  inline Matrix mul(const Matrix& B) const {
300 
301  Matrix res;
302  res.resize(N, B.cols());
303 
304  if(B.rows() != K) {
305  TH_MATH_ERROR("mat::transform", B.rows(), INVALID_ARGUMENT);
306  algebra::mat_error(res);
307  return res;
308  }
309 
310  return algebra::mat_mul(res, *this, B);
311  }
312 
313 
315  template<typename Matrix>
316  inline auto operator*(const Matrix& B) const {
317 
318  Matrix res;
319  res.resize(N, B.cols());
320 
321  if(B.rows() != K) {
322  TH_MATH_ERROR("mat::transform", B.rows(), INVALID_ARGUMENT);
323  algebra::mat_error(res);
324  return res;
325  }
326 
327  return algebra::mat_mul(res, *this, B);
328  }
329 
330 
332  template<typename Matrix>
333  inline mat<Type, N, K>& operator+=(const Matrix& other) {
334  return algebra::mat_sum(*this, other);
335  }
336 
337 
339  template<typename Matrix>
340  inline mat<Type, N, K>& operator-=(const Matrix& other) {
341  return algebra::mat_diff(*this, other);
342  }
343 
344 
346  inline mat<Type, N, K>& operator*=(Type scalar) {
347  return algebra::mat_scalmul(scalar, *this);
348  }
349 
350 
352  inline mat<Type, N, K>& operator/=(Type scalar) {
353 
354  if(abs(scalar) < MACH_EPSILON) {
355  TH_MATH_ERROR("mat::operator/", scalar, DIV_BY_ZERO);
356  return algebra::mat_error(*this);
357  }
358 
359  return algebra::mat_scalmul(1.0 / scalar, *this);
360  }
361 
362 
364  template<typename Matrix>
365  inline mat<Type, N, K>& operator*=(const Matrix& B) {
366  return (*this = this->operator*(B));
367  }
368 
369 
372  static_assert(
373  N == K, "The matrix must be square to be transposed in place.");
374  return algebra::make_transposed(*this);
375  }
376 
377 
380  inline mat<Type, K, N> transposed() const {
381  return algebra::transpose<mat<Type, N, K>, mat<Type, K, N>>(*this);
382  }
383 
384 
386  inline Type& at(unsigned int i, unsigned int j) {
387 
388 #ifdef THEORETICA_ROW_FIRST
389  return data[i][j];
390 #else
391  return data[j][i];
392 #endif
393  }
394 
395 
397  inline const Type& at(unsigned int i, unsigned int j) const {
398 
399 #ifdef THEORETICA_ROW_FIRST
400  return data[i][j];
401 #else
402  return data[j][i];
403 #endif
404  }
405 
406 
408  inline Type& operator()(unsigned int i, unsigned int j) {
409  return at(i, j);
410  }
411 
412 
414  inline const Type& operator()(unsigned int i, unsigned int j) const {
415  return at(i, j);
416  }
417 
418 
420  inline Type get(unsigned int i, unsigned int j) const {
421 
422 #ifdef THEORETICA_ROW_FIRST
423  return data[i][j];
424 #else
425  return data[j][i];
426 #endif
427  }
428 
429 
432 
433 
436 
437 
439  inline auto begin() {
440  return iterator(*this, 0, 0);
441  }
442 
443 
445  inline auto end() {
446  return iterator(*this, rows(), 0);
447  }
448 
449 
452  inline auto begin() const {
453  return const_iterator(*this, 0, 0);
454  }
455 
456 
459  inline auto end() const {
460  return const_iterator(*this, rows(), 0);
461  }
462 
463 
465  TH_CONSTEXPR inline unsigned int rows() const {
466  return N;
467  }
468 
469 
471  TH_CONSTEXPR inline unsigned int cols() const {
472  return K;
473  }
474 
475 
478  inline unsigned int size() const {
479  return N * K;
480  }
481 
482 
484  template<typename Matrix>
485  inline bool operator==(const Matrix& other) const {
486  return algebra::mat_equals(*this, other);
487  }
488 
489 
491  template<typename Matrix>
492  inline bool operator!=(const Matrix& other) const {
493  return !algebra::mat_equals(*this, other);
494  }
495 
496 
498  inline bool is_square() const {
499  return algebra::is_square(*this);
500  }
501 
502 
504  inline bool is_diagonal() const {
505  return algebra::is_diagonal(*this);
506  }
507 
508 
510  inline bool is_symmetric() const {
511  return algebra::is_symmetric(*this);
512  }
513 
514 
523  inline real density(real tolerance = 1E-12) {
524  return algebra::density(*this, tolerance);
525  }
526 
527 
536  inline real sparsity(real tolerance = 1E-12) {
537  return algebra::sparsity(*this, tolerance);
538  }
539 
540 
542  inline Type trace() {
543  return algebra::trace(*this);
544  }
545 
546 
548  inline Type diagonal_product() {
549  return algebra::diagonal_product(*this);
550  }
551 
552 
554  inline Type det() const {
555  static_assert(N == K, "The matrix must be square to compute the determinant.");
556  return algebra::det(*this);
557  }
558 
559 
561  inline mat<Type, N, K> inverse() const {
562  static_assert(N == K, "The matrix must be square to be invertible.");
563  return algebra::inverse(*this);
564  }
565 
566 
569  static_assert(N == K, "The matrix must be square to be invertible.");
570  return algebra::invert(*this);
571  }
572 
573 
579  inline mat<Type, N, K> resize(unsigned int n, unsigned int k) const {
580 
581  if(rows() != n) {
582  TH_MATH_ERROR("mat::resize", n, INVALID_ARGUMENT);
583  } else if(cols() != k) {
584  TH_MATH_ERROR("mat::resize", k, INVALID_ARGUMENT);
585  }
586 
587  return *this;
588  }
589 
590 
591  // Transformation matrices
592 
593 
595  inline static mat<Type, N, K> identity() {
596  return algebra::identity<mat<Type, N, K>>();
597  }
598 
599 
601  inline static mat<Type, N, K> diagonal(Type diag) {
602  return mat<Type, N, K>(diag);
603  }
604 
605 
607  template<typename Vector = vec<real, N - 1>>
608  inline static mat<Type, N, K> translation(Vector&& t) {
609  return algebra::translation<mat<Type, N, K>>(t);
610  }
611 
612 
614  inline static mat<Type, N, K> rotation_2d(real theta) {
615  static_assert(N >= 2 && K >= 2, "The matrix must be 2x2 or bigger");
616  return algebra::rotation_2d<mat<Type, N, K>>(theta);
617  }
618 
619 
621  inline static mat<Type, N, K> rotation_3d_xaxis(real theta) {
622  static_assert(N >= 3 && K >= 3, "The matrix must be 3x3 or bigger");
623  return algebra::rotation_3d_xaxis<mat<Type, N, K>>(theta);
624  }
625 
626 
628  inline static mat<Type, N, K> rotation_3d_yaxis(real theta) {
629  static_assert(N >= 3 && K >= 3, "The matrix must be 3x3 or bigger");
630  return algebra::rotation_3d_yaxis<mat<Type, N, K>>(theta);
631  }
632 
633 
635  inline static mat<Type, N, K> rotation_3d_zaxis(real theta) {
636  static_assert(N >= 3 && K >= 3, "The matrix must be 3x3 or bigger");
637  return algebra::rotation_3d_zaxis<mat<Type, N, K>>(theta);
638  }
639 
640 
642  template<typename Vector = vec<real, 3>>
643  inline static mat<Type, N, K> rotation_3d(real theta, Vector&& axis) {
644  static_assert(N >= 3 && K >= 3, "The matrix must be 3x3 or bigger");
645  return algebra::rotation_3d<mat<Type, N, K>>(theta, axis);
646  }
647 
648 
649  inline static mat<Type, N, K> perspective(
650  real left, real right, real bottom,
651  real top, real near, real far) {
652 
653  static_assert(N >= 4 && K >= 4, "The matrix must be 4x4 or bigger");
654  return algebra::perspective<mat<Type, N, K>>(
655  left, right, bottom, top, near, far);
656  }
657 
658 
659  inline static mat<Type, N, K> perspective_fov(
660  real fov, real aspect, real near, real far) {
661 
662  static_assert(N >= 4 && K >= 4, "The matrix must be 4x4 or bigger");
663  return algebra::perspective_fov<mat<Type, N, K>>(fov, aspect, near, far);
664  }
665 
666 
667  inline static mat<Type, N, K> ortho(
668  real left, real right, real bottom, real top, real near, real far) {
669  static_assert(N >= 4 && K >= 4, "The matrix must be 4x4 or bigger");
670  return algebra::ortho<mat<Type, N, K>>(left, right, bottom, top, near, far);
671  }
672 
673 
676  template<typename Vector1, typename Vector2, typename Vector3>
677  inline static mat<Type, 4, 4> look_at(
678  const Vector1& camera, const Vector2& target, const Vector3& up) {
679  return algebra::look_at<mat<Type, 4, 4>>(camera, target, up);
680  }
681 
682 
684  inline static mat<Type, N, K> symplectic(unsigned int n = 0, unsigned int k = 0) {
685  static_assert(N == K && (N % 2 == 0),
686  "N must equal K and they should be a multiple of 2");
687  return algebra::symplectic<mat<Type, N, K>>(n, k);
688  }
689 
690 
691 
692 #ifndef THEORETICA_NO_PRINT
693 
696  std::string separator = ", ", bool parenthesis = true) const {
697 
698  std::stringstream res;
699 
700  for (unsigned int i = 0; i < rows(); ++i) {
701 
702  if(parenthesis)
703  res << "(";
704 
705  for (unsigned int j = 0; j < cols(); ++j) {
706 
707  if(j)
708  res << separator;
709 
710  if(abs(get(i, j)) < MACH_EPSILON)
711  res << "0";
712  else
713  res << get(i, j);
714  }
715 
716  if(parenthesis)
717  res << ")" << std::endl;
718  }
719 
720  return res.str();
721  }
722 
723 
725  inline operator std::string() {
726  return to_string();
727  }
728 
729 
731  inline friend std::ostream& operator<<(
732  std::ostream& out, const mat<Type, N, K>& obj) {
733  return out << obj.to_string();
734  }
735 
736 #endif
737 
738  };
739 
740 
741 
747  template<typename Type>
748  class mat<Type, 0, 0> {
749  public:
750 
751  // Container type for storage (alias for std::vector)
752  template<typename T>
753  using Container = std::vector<T>;
754 
756  Container<Container<Type>> data;
757 
759  size_t row_sz {0};
760 
762  size_t col_sz {0};
763 
764 
766  mat() : row_sz(0), col_sz(0) {}
767 
768 
770  mat(unsigned int n, unsigned int k) {
771  resize(n, k);
772  algebra::mat_zeroes(*this);
773  }
774 
775 
777  template <
778  typename Matrix, enable_matrix<Matrix>
779  >
780  mat(const Matrix& m) {
781  resize(m.rows(), m.cols());
782  algebra::mat_copy(*this, m);
783  }
784 
785 
787  template<typename T = Type>
788  inline mat(const std::initializer_list<std::initializer_list<T>>& rows) {
789 
790  unsigned int i = 0;
791  unsigned int j = 0;
792 
793  for (const auto& row : rows) {
794 
795  for (const auto& x : row) {
796 
797  if (!i && !j) {
798  this->resize(rows.size(), row.size());
799  }
800  else if (row.size() != col_sz) {
801  TH_MATH_ERROR("mat::mat", row.size(), INVALID_ARGUMENT);
802  algebra::mat_error(*this);
803  return;
804  }
805 
806  at(i, j) = x;
807  j = (j + 1) % col_sz;
808  }
809 
810  i++;
811  }
812  }
813 
814 
816  template<typename Matrix>
817  inline mat<Type>& operator=(const Matrix& other) {
818  resize(other.rows(), other.cols());
819  return algebra::mat_copy(*this, other);
820  }
821 
822 
825  mat(Type diagonal, unsigned int n, unsigned int k) {
826 
827  resize(n, k);
828  algebra::mat_zeroes(*this);
829  const unsigned int m = min(n, k);
830 
831  for (unsigned int i = 0; i < m; ++i)
832  at(i, i) = diagonal;
833  }
834 
835 
837  ~mat() {
838  row_sz = 0;
839  col_sz = 0;
840  }
841 
842 
844  inline void make_zeroes() {
845  algebra::mat_zeroes(*this);
846  }
847 
848 
850  inline static mat<Type> zeroes(unsigned int rows, unsigned int cols) {
851  mat<Type> res;
852  res.resize(rows, cols);
853  algebra::mat_zeroes(res);
854  return res;
855  }
856 
857 
859  template<typename Matrix>
860  inline mat<Type> operator+(const Matrix& other) const {
861  mat<Type> res;
862  res.resize(rows(), cols());
863  return algebra::mat_sum(res, *this, other);
864  }
865 
866 
868  template<typename Matrix>
869  inline mat<Type> operator-(const Matrix& other) const {
870  mat<Type> res;
871  res.resize(rows(), cols());
872  return algebra::mat_diff(res, *this, other);
873  }
874 
875 
877  inline mat<Type> operator*(Type scalar) const {
878  mat<Type> res;
879  res.resize(rows(), cols());
880  return algebra::mat_scalmul(res, scalar, *this);
881  }
882 
883 
886  inline friend mat<Type> operator*(Type a, const mat<Type>& B) {
887  return B * a;
888  }
889 
890 
893  template<typename VecType, unsigned int M>
894  inline friend vec<VecType, 0> operator*(
895  const vec<VecType, M>& a, const mat<Type, 0, 0>& B) {
896  return B * a;
897  }
898 
899 
901  inline mat<Type> operator/(Type scalar) const {
902 
903  mat<Type> res;
904  res.resize(rows(), cols());
905 
906  if(abs(scalar) < MACH_EPSILON) {
907  TH_MATH_ERROR("mat::operator/", scalar, DIV_BY_ZERO);
908  return algebra::mat_error(res);
909  }
910 
911  return algebra::mat_scalmul(res, 1.0 / scalar, *this);
912  }
913 
914 
916  template<typename Vector>
917  inline Vector transform(const Vector& v) const {
918 
919  if(v.size() != rows()) {
920  TH_MATH_ERROR("mat::transform", v.size(), INVALID_ARGUMENT);
921  Vector res;
922  res.resize(rows());
923  algebra::vec_error(res);
924  return res;
925  }
926 
927  return algebra::transform(*this, v);
928  }
929 
930 
932  template<unsigned int N = 0, unsigned int K = 0>
933  inline vec<Type, N> transform(const vec<Type, K>& v) const {
934  return algebra::transform(*this, v);
935  }
936 
937 
939  template<unsigned int N = 0, unsigned int K = 0>
940  inline vec<Type, N> operator*(const vec<Type, K>& v) const {
941  return transform(v);
942  }
943 
944 
946  // inline vec<Type> operator*(const vec<Type>& v) const {
947  // return transform(v);
948  // }
949 
950 
952  inline mat<Type> mul(const mat<Type>& B) const {
953 
954  mat<Type> res;
955  res.resize(rows(), B.cols());
956 
957  if(B.rows() != cols()) {
958  TH_MATH_ERROR("mat::mul", B.rows(), INVALID_ARGUMENT);
959  algebra::mat_error(res);
960  return res;
961  }
962 
963  return algebra::mat_mul(res, *this, B);
964  }
965 
966 
968  template<typename Matrix>
969  inline Matrix mul(const Matrix& B) const {
970 
971  Matrix res;
972  res.resize(rows(), B.cols());
973 
974  if(B.rows() != cols()) {
975  TH_MATH_ERROR("mat::mul", B.rows(), INVALID_ARGUMENT);
976  algebra::mat_error(res);
977  return res;
978  }
979 
980  return algebra::mat_mul(res, *this, B);
981  }
982 
983 
985  template<typename Matrix>
986  inline auto operator*(const Matrix& B) const {
987  return mul(B);
988  }
989 
990 
992  template<typename Matrix>
993  inline mat<Type>& operator+=(const Matrix& other) {
994  return algebra::mat_sum(*this, other);
995  }
996 
997 
999  template<typename Matrix>
1000  inline mat<Type>& operator-=(const Matrix& other) {
1001  return algebra::mat_diff(*this, other);
1002  }
1003 
1004 
1006  inline mat<Type>& operator*=(Type scalar) {
1007  return algebra::mat_scalmul(scalar, *this);
1008  }
1009 
1010 
1012  inline mat<Type>& operator/=(Type scalar) {
1013 
1014  if(abs(scalar) < MACH_EPSILON) {
1015  TH_MATH_ERROR("mat::operator/", scalar, DIV_BY_ZERO);
1016  return algebra::mat_error(*this);
1017  }
1018 
1019  return algebra::mat_scalmul(1.0 / scalar, *this);
1020  }
1021 
1022 
1024  template<typename Matrix>
1025  inline mat<Type>& operator*=(const Matrix& B) {
1026  return (*this = this->operator*(B));
1027  }
1028 
1029 
1031  inline mat<Type>& transpose() {
1032  return algebra::make_transposed(*this);
1033  }
1034 
1035 
1038  inline mat<Type> transposed() const {
1039  return algebra::transpose<mat<Type>, mat<Type>>(*this);
1040  }
1041 
1042 
1044  inline Type& at(unsigned int i, unsigned int j) {
1045 
1046 #ifdef THEORETICA_ROW_FIRST
1047  return data[i][j];
1048 #else
1049  return data[j][i];
1050 #endif
1051  }
1052 
1053 
1055  inline const Type& at(unsigned int i, unsigned int j) const {
1056 
1057 #ifdef THEORETICA_ROW_FIRST
1058  return data[i][j];
1059 #else
1060  return data[j][i];
1061 #endif
1062  }
1063 
1064 
1066  inline Type& operator()(unsigned int i, unsigned int j) {
1067  return at(i, j);
1068  }
1069 
1070 
1072  inline const Type& operator()(unsigned int i, unsigned int j) const {
1073  return at(i, j);
1074  }
1075 
1076 
1078  inline Type get(unsigned int i, unsigned int j) const {
1079 
1080 #ifdef THEORETICA_ROW_FIRST
1081  return data[i][j];
1082 #else
1083  return data[j][i];
1084 #endif
1085  }
1086 
1087 
1090 
1091 
1094 
1095 
1097  inline auto begin() {
1098  return iterator(*this, 0, 0);
1099  }
1100 
1101 
1103  inline auto end() {
1104  return iterator(*this, rows(), 0);
1105  }
1106 
1107 
1109  inline auto begin() const {
1110  return const_iterator(*this, 0, 0);
1111  }
1112 
1113 
1115  inline auto end() const {
1116  return const_iterator(*this, rows(), 0);
1117  }
1118 
1119 
1121  TH_CONSTEXPR inline unsigned int rows() const {
1122  return row_sz;
1123  }
1124 
1125 
1127  TH_CONSTEXPR inline unsigned int cols() const {
1128  return col_sz;
1129  }
1130 
1131 
1134  inline unsigned int size() const {
1135  return rows() * cols();
1136  }
1137 
1138 
1140  template<typename Matrix>
1141  inline bool operator==(const Matrix& other) const {
1142  return algebra::mat_equals(*this, other);
1143  }
1144 
1145 
1147  template<typename Matrix>
1148  inline bool operator!=(const Matrix& other) const {
1149  return !algebra::mat_equals(*this, other);
1150  }
1151 
1152 
1154  inline bool is_square() const {
1155  return algebra::is_square(*this);
1156  }
1157 
1158 
1160  inline bool is_diagonal() const {
1161  return algebra::is_diagonal(*this);
1162  }
1163 
1164 
1166  inline bool is_symmetric() const {
1167  return algebra::is_symmetric(*this);
1168  }
1169 
1170 
1179  inline real density(real tolerance = 1E-12) {
1180  return algebra::density(*this, tolerance);
1181  }
1182 
1183 
1192  inline real sparsity(real tolerance = 1E-12) {
1193  return algebra::sparsity(*this, tolerance);
1194  }
1195 
1196 
1198  inline Type trace() {
1199  return algebra::trace(*this);
1200  }
1201 
1202 
1204  inline Type diagonal_product() {
1205  return algebra::diagonal_product(*this);
1206  }
1207 
1208 
1210  inline Type det() const {
1211  return algebra::det(*this);
1212  }
1213 
1214 
1216  inline mat<Type> inverse() const {
1217  return algebra::inverse(*this);
1218  }
1219 
1220 
1222  inline mat<Type>& invert() {
1223  return algebra::invert(*this);
1224  }
1225 
1226 
1230  inline mat<Type>& resize(unsigned int n, unsigned int k) {
1231 
1232  // Do nothing if the size is already correct
1233  if(rows() == n && cols() == k)
1234  return *this;
1235 
1236  // Distinguish between row-first and column-first
1237  // allocation
1238 #ifdef THEORETICA_ROW_FIRST
1239  size_t size1 = n, size2 = k;
1240 #else
1241  size_t size1 = k, size2 = n;
1242 #endif
1243 
1244  // The matrix must be allocated anew
1245  if(!data.size()) {
1246 
1247  data.resize(size1);
1248  for (unsigned int i = 0; i < size1; ++i)
1249  data[i].resize(size2);
1250 
1251  row_sz = n;
1252  col_sz = k;
1253  algebra::mat_zeroes(*this);
1254 
1255  // The matrix must be reallocated
1256  } else {
1257 
1258  std::vector<std::vector<Type>> new_data;
1259  new_data.resize(size1);
1260  for (unsigned int i = 0; i < size1; ++i)
1261  new_data[i].resize(size2);
1262 
1263  // Copy data to new memory location
1264 
1265  // Bounds on the region to copy
1266  const size_t row_bound = min(rows(), n);
1267  const size_t col_bound = min(cols(), n);
1268 
1269  for (unsigned int i = 0; i < row_bound; ++i) {
1270  for (unsigned int j = 0; j < col_bound; ++j) {
1271 #ifdef THEORETICA_ROW_FIRST
1272  new_data[i][j] = get(i, j);
1273 #else
1274  new_data[j][i] = get(i, j);
1275 #endif
1276  }
1277  }
1278 
1279  // If the new matrix size is bigger,
1280  // zero out all remaining entries
1281  for (unsigned int i = 0; i < n; ++i) {
1282  for (unsigned int j = col_bound; j < k; ++j) {
1283 
1284 
1285 #ifdef THEORETICA_ROW_FIRST
1286  new_data[i][j] = (Type) 0;
1287 #else
1288  new_data[j][i] = (Type) 0;
1289 #endif
1290  }
1291  }
1292 
1293 
1294  // If the new matrix size is bigger,
1295  // zero out all remaining entries
1296  for (unsigned int i = row_bound; i < n; ++i) {
1297  for (unsigned int j = 0; j < k; ++j) {
1298 
1299 
1300 #ifdef THEORETICA_ROW_FIRST
1301  new_data[i][j] = (Type) 0;
1302 #else
1303  new_data[j][i] = (Type) 0;
1304 #endif
1305  }
1306  }
1307 
1308  data.clear();
1309  data = new_data;
1310 
1311  row_sz = n;
1312  col_sz = k;
1313  }
1314 
1315  return *this;
1316  }
1317 
1318 
1319  // Transformation matrices
1320 
1321 
1323  inline static mat<Type> identity(
1324  unsigned int row_sz, unsigned int col_sz) {
1325 
1326  return algebra::identity<mat<Type>>(row_sz, col_sz);
1327  }
1328 
1329 
1331  inline static mat<Type> diagonal(
1332  Type diag, unsigned int row_sz, unsigned int col_sz) {
1333  return mat<Type>(diag, row_sz, col_sz);
1334  }
1335 
1336 
1338  template<typename Vector>
1339  inline static mat<Type> translation(Vector&& t) {
1340  return algebra::translation<mat<Type>>(t);
1341  }
1342 
1343 
1345  inline static mat<Type> rotation_2d(real theta) {
1346  return algebra::rotation_2d<mat<Type>>(theta);
1347  }
1348 
1349 
1351  inline static mat<Type> rotation_3d_xaxis(real theta) {
1352  return algebra::rotation_3d_xaxis<mat<Type>>(theta);
1353  }
1354 
1355 
1357  inline static mat<Type> rotation_3d_yaxis(real theta) {
1358  return algebra::rotation_3d_yaxis<mat<Type>>(theta);
1359  }
1360 
1361 
1363  inline static mat<Type> rotation_3d_zaxis(real theta) {
1364  return algebra::rotation_3d_zaxis<mat<Type>>(theta);
1365  }
1366 
1367 
1369  template<typename Vector = vec<real, 3>>
1370  inline static mat<Type> rotation_3d(real theta, Vector&& axis) {
1371  return algebra::rotation_3d<mat<Type>>(theta, axis);
1372  }
1373 
1374 
1375  inline static mat<Type> perspective(
1376  real left, real right, real bottom,
1377  real top, real near, real far) {
1378 
1379  return algebra::perspective<mat<Type>>(
1380  left, right, bottom, top, near, far);
1381  }
1382 
1383 
1384  inline static mat<Type> perspective_fov(
1385  real fov, real aspect, real near, real far) {
1386 
1387  return algebra::perspective_fov<mat<Type>>(fov, aspect, near, far);
1388  }
1389 
1390 
1391  inline static mat<Type> ortho(
1392  real left, real right, real bottom, real top, real near, real far) {
1393  return algebra::ortho<mat<Type>>(left, right, bottom, top, near, far);
1394  }
1395 
1396 
1399  template<typename Vector1, typename Vector2, typename Vector3>
1400  inline static mat<Type> look_at(
1401  const Vector1& camera, const Vector2& target, const Vector3& up) {
1402  return algebra::look_at<mat<Type>>(camera, target, up);
1403  }
1404 
1405 
1407  inline static mat<Type> symplectic(unsigned int rows, unsigned int cols) {
1408  return algebra::symplectic<mat<Type>>(rows, cols);
1409  }
1410 
1411 
1412 
1413 
1414 #ifndef THEORETICA_NO_PRINT
1415 
1418  std::string separator = ", ", bool parenthesis = true) const {
1419 
1420  std::stringstream res;
1421 
1422  for (unsigned int i = 0; i < rows(); ++i) {
1423 
1424  if(parenthesis)
1425  res << "(";
1426 
1427  for (unsigned int j = 0; j < cols(); ++j) {
1428 
1429  if(j)
1430  res << separator;
1431 
1432  if(abs(get(i, j)) < MACH_EPSILON)
1433  res << "0";
1434  else
1435  res << get(i, j);
1436  }
1437 
1438  if(parenthesis)
1439  res << ")" << std::endl;
1440  }
1441 
1442  return res.str();
1443  }
1444 
1445 
1447  inline operator std::string() {
1448  return to_string();
1449  }
1450 
1451 
1453  inline friend std::ostream& operator<<(
1454  std::ostream& out, const mat<Type>& obj) {
1455  return out << obj.to_string();
1456  }
1457 
1458 #endif
1459 
1460  };
1461 
1462 }
1463 
1464 #endif
Linear algebra routines.
A generic matrix with a variable number of rows and columns.
Definition: mat.h:748
mat< Type > operator/(Type scalar) const
Scalar division.
Definition: mat.h:901
Type diagonal_product()
Compute the product of the diagonal elements of a square matrix.
Definition: mat.h:1204
static mat< Type > rotation_3d_zaxis(real theta)
Get a matrix which rotates <theta> radians around the z axis.
Definition: mat.h:1363
static mat< Type > rotation_3d_xaxis(real theta)
Get a matrix which rotates <theta> radians around the x axis.
Definition: mat.h:1351
mat< Type > & operator=(const Matrix &other)
Copy constructor.
Definition: mat.h:817
bool is_diagonal() const
Return whether the matrix is diagonal.
Definition: mat.h:1160
static mat< Type > identity(unsigned int row_sz, unsigned int col_sz)
Get the identity matrix.
Definition: mat.h:1323
mat< Type > & resize(unsigned int n, unsigned int k)
Set or change the size of the matrix.
Definition: mat.h:1230
vec< Type, N > operator*(const vec< Type, K > &v) const
Transform a vector by the matrix.
Definition: mat.h:940
mat< Type > & transpose()
Transpose the matrix itself.
Definition: mat.h:1031
vec< Type, N > transform(const vec< Type, K > &v) const
Transform a vector by the matrix.
Definition: mat.h:933
auto operator*(const Matrix &B) const
Matrix multiplication.
Definition: mat.h:986
mat(unsigned int n, unsigned int k)
Construct a matrix with n rows and k columns.
Definition: mat.h:770
mat< Type > & operator-=(const Matrix &other)
Matrix subtraction.
Definition: mat.h:1000
static mat< Type > look_at(const Vector1 &camera, const Vector2 &target, const Vector3 &up)
Return a 4x4 transformation matrix that points the field of view towards a given point from the <came...
Definition: mat.h:1400
const Type & operator()(unsigned int i, unsigned int j) const
Get the element at the i-th row and j-th column.
Definition: mat.h:1072
bool operator==(const Matrix &other) const
Check whether two matrices are equal element by element.
Definition: mat.h:1141
static mat< Type > rotation_3d_yaxis(real theta)
Get a matrix which rotates <theta> radians around the y axis.
Definition: mat.h:1357
mat(Type diagonal, unsigned int n, unsigned int k)
Construct a diagonal matrix with all equal entries with n rows and k columns.
Definition: mat.h:825
bool is_symmetric() const
Return whether the matrix is symmetric.
Definition: mat.h:1166
bool operator!=(const Matrix &other) const
Check whether two matrices are unequal element by element.
Definition: mat.h:1148
Type trace()
Compute the trace (sum of elements on the diagonal) of a square matrix.
Definition: mat.h:1198
friend vec< VecType, 0 > operator*(const vec< VecType, M > &a, const mat< Type, 0, 0 > &B)
Friend operator to enable equations of the form (vec) * (mat)
Definition: mat.h:894
static mat< Type > rotation_3d(real theta, Vector &&axis)
Get a matrix which rotates <theta> radians around the <axis> axis.
Definition: mat.h:1370
bool is_square() const
Return whether the matrix is square.
Definition: mat.h:1154
mat(const Matrix &m)
Copy constructor.
Definition: mat.h:780
Type & operator()(unsigned int i, unsigned int j)
Access the element at the i-th row and j-th column.
Definition: mat.h:1066
static mat< Type > zeroes(unsigned int rows, unsigned int cols)
Get the null matrix.
Definition: mat.h:850
mat(const std::initializer_list< std::initializer_list< T >> &rows)
Construct from a list of the rows.
Definition: mat.h:788
static mat< Type > translation(Vector &&t)
Get a 4x4 matrix which translates by {x, y, z}.
Definition: mat.h:1339
auto end() const
Get a const iterator to one plus the last element of the matrix.
Definition: mat.h:1115
TH_CONSTEXPR unsigned int cols() const
Get the number of columns of the matrix.
Definition: mat.h:1127
mat< Type > & operator*=(const Matrix &B)
Matrix multiplication.
Definition: mat.h:1025
TH_CONSTEXPR unsigned int rows() const
Get the number of rows of the matrix.
Definition: mat.h:1121
mat< Type > mul(const mat< Type > &B) const
Transform a vector by the matrix.
Definition: mat.h:952
mat< Type > operator*(Type scalar) const
Scalar multiplication.
Definition: mat.h:877
friend std::ostream & operator<<(std::ostream &out, const mat< Type > &obj)
Stream the matrix in string representation to an output stream (std::ostream)
Definition: mat.h:1453
Container< Container< Type > > data
Dynamically allocated array of the elements.
Definition: mat.h:756
Vector transform(const Vector &v) const
Transform a vector v by the matrix.
Definition: mat.h:917
unsigned int size() const
Get the total number of elements of the matrix (rows * columns)
Definition: mat.h:1134
mat< Type > operator+(const Matrix &other) const
Matrix addition.
Definition: mat.h:860
mat< Type > & invert()
Invert a generic square matrix.
Definition: mat.h:1222
auto end()
Get an iterator to one plus the last element of the matrix.
Definition: mat.h:1103
static mat< Type > rotation_2d(real theta)
Get a matrix which rotates the 2D plane of <theta> radians.
Definition: mat.h:1345
Type & at(unsigned int i, unsigned int j)
Access the element at the i-th row and j-th column.
Definition: mat.h:1044
static mat< Type > diagonal(Type diag, unsigned int row_sz, unsigned int col_sz)
Get a diagonal matrix.
Definition: mat.h:1331
const Type & at(unsigned int i, unsigned int j) const
Access the element at the i-th row and j-th column.
Definition: mat.h:1055
auto begin()
Get an iterator to the first element of the matrix.
Definition: mat.h:1097
friend mat< Type > operator*(Type a, const mat< Type > &B)
Friend operator to enable equations of the form (T) * (mat)
Definition: mat.h:886
mat< Type > & operator+=(const Matrix &other)
Matrix addition.
Definition: mat.h:993
mat()
Default constructor.
Definition: mat.h:766
mat< Type > & operator*=(Type scalar)
Scalar multiplication.
Definition: mat.h:1006
std::string to_string(std::string separator=", ", bool parenthesis=true) const
Convert the matrix to string representation.
Definition: mat.h:1417
void make_zeroes()
Set all elements to zero.
Definition: mat.h:844
static mat< Type > symplectic(unsigned int rows, unsigned int cols)
A symplectic NxN matrix, where for some natural K.
Definition: mat.h:1407
mat< Type > inverse() const
Compute the inverse of a generic square matrix.
Definition: mat.h:1216
mat< Type > & operator/=(Type scalar)
Scalar division.
Definition: mat.h:1012
mat< Type > operator-(const Matrix &other) const
Matrix subtraction.
Definition: mat.h:869
real sparsity(real tolerance=1E-12)
Compute the sparsity of the matrix, counting the proportion of zero (smaller in module than the given...
Definition: mat.h:1192
mat< Type > transposed() const
Return the transposed matrix, without modifying the matrix itself.
Definition: mat.h:1038
Matrix mul(const Matrix &B) const
Matrix multiplication by any matrix type.
Definition: mat.h:969
auto begin() const
Get a const iterator to the first element of the matrix.
Definition: mat.h:1109
~mat()
Deallocate memory.
Definition: mat.h:837
Type det() const
Compute the determinant of the matrix.
Definition: mat.h:1210
Type get(unsigned int i, unsigned int j) const
Get the element at the i-th row and j-th column.
Definition: mat.h:1078
real density(real tolerance=1E-12)
Compute the density of the matrix, counting the proportion of non-zero (bigger in module than the giv...
Definition: mat.h:1179
A sequential iterator for matrices.
Definition: mat.h:34
mat_iterator(Matrix &matrix, size_t row=0, size_t col=0)
Construct iterator from a matrix.
Definition: mat.h:55
size_t col_index()
Get the index of the current column.
Definition: mat.h:90
ReturnType operator*()
Dereference the iterator to get the current element by reference.
Definition: mat.h:64
bool operator==(const mat_iterator &other) const
Move to the previous element in the matrix.
Definition: mat.h:114
mat_iterator & operator++()
Move to the next element in the matrix.
Definition: mat.h:70
size_t row_index()
Get the index of the current row.
Definition: mat.h:84
A generic matrix with a fixed number of rows and columns.
Definition: mat.h:132
static mat< Type, N, K > rotation_3d_zaxis(real theta)
Get a matrix which rotates <theta> radians around the z axis.
Definition: mat.h:635
static mat< Type, N, K > rotation_2d(real theta)
Get a matrix which rotates the 2D plane of <theta> radians.
Definition: mat.h:614
std::string to_string(std::string separator=", ", bool parenthesis=true) const
Convert the matrix to string representation.
Definition: mat.h:695
mat< Type, N, K > resize(unsigned int n, unsigned int k) const
Compatibility function to allow for allocation or resizing of dynamic matrices.
Definition: mat.h:579
bool is_symmetric() const
Return whether the matrix is symmetric.
Definition: mat.h:510
mat< Type, N, K > & invert()
Invert a generic square matrix.
Definition: mat.h:568
bool operator!=(const Matrix &other) const
Check whether two matrices are unequal element by element.
Definition: mat.h:492
static mat< Type, 4, 4 > look_at(const Vector1 &camera, const Vector2 &target, const Vector3 &up)
Return a 4x4 transformation matrix that points the field of view towards a given point from the <came...
Definition: mat.h:677
Type & operator()(unsigned int i, unsigned int j)
Access the element at the i-th row and j-th column.
Definition: mat.h:408
static mat< Type, N, K > zeroes()
Get the null matrix.
Definition: mat.h:201
bool is_diagonal() const
Return whether the matrix is diagonal.
Definition: mat.h:504
void make_zeroes()
Set all elements to zero.
Definition: mat.h:195
auto end() const
Get a const iterator to one plus the last element of the matrix.
Definition: mat.h:459
mat< Type, N, K > inverse() const
Compute the inverse of a generic square matrix.
Definition: mat.h:561
mat_iterator< mat< Type, N, K >, Type & > iterator
Iterator for statically allocated matrices.
Definition: mat.h:431
friend std::ostream & operator<<(std::ostream &out, const mat< Type, N, K > &obj)
Stream the matrix in string representation to an output stream (std::ostream)
Definition: mat.h:731
Type get(unsigned int i, unsigned int j) const
Get the element at the i-th row and j-th column.
Definition: mat.h:420
Type trace()
Compute the trace (sum of elements on the diagonal) of a square matrix.
Definition: mat.h:542
static mat< Type, N, K > translation(Vector &&t)
Get a 4x4 matrix which translates by {x, y, z}.
Definition: mat.h:608
mat< Type, N, K > & operator+=(const Matrix &other)
Matrix addition.
Definition: mat.h:333
mat< Type, N, K > operator/(Type scalar) const
Scalar division.
Definition: mat.h:248
mat(const std::initializer_list< std::initializer_list< T >> &rows)
Construct from a list of the rows.
Definition: mat.h:157
mat< Type, N, M > mul(const mat< Type, K, M > &B) const
Matrix multiplication.
Definition: mat.h:291
bool is_square() const
Return whether the matrix is square.
Definition: mat.h:498
friend vec< VecType, K > operator*(const vec< VecType, M > &a, const mat< Type, N, K > &B)
Friend operator to enable equations of the form (vec) * (mat)
Definition: mat.h:241
mat< Type, N, K > & operator=(const Matrix &other)
Copy constructor.
Definition: mat.h:189
Type diagonal_product()
Compute the product of the diagonal elements of a square matrix.
Definition: mat.h:548
TH_CONSTEXPR unsigned int rows() const
Get the number of rows of the matrix.
Definition: mat.h:465
const Type & at(unsigned int i, unsigned int j) const
Access the element at the i-th row and j-th column.
Definition: mat.h:397
mat_iterator< const mat< Type, N, K >, const Type & > const_iterator
Const iterator for statically allocated matrices.
Definition: mat.h:435
unsigned int size() const
Get the total number of elements of the matrix (rows * columns)
Definition: mat.h:478
TH_CONSTEXPR unsigned int cols() const
Get the number of columns of the matrix.
Definition: mat.h:471
static mat< Type, N, K > rotation_3d(real theta, Vector &&axis)
Get a matrix which rotates <theta> radians around the <axis> axis.
Definition: mat.h:643
mat()
Default constructor.
Definition: mat.h:143
auto end()
Get an iterator to one plus the last element of the matrix.
Definition: mat.h:445
const Type & operator()(unsigned int i, unsigned int j) const
Get the element at the i-th row and j-th column.
Definition: mat.h:414
auto begin() const
Get a const iterator to the first element of the matrix.
Definition: mat.h:452
real density(real tolerance=1E-12)
Compute the density of the matrix, counting the proportion of non-zero (bigger in module than the giv...
Definition: mat.h:523
static mat< Type, N, K > rotation_3d_yaxis(real theta)
Get a matrix which rotates <theta> radians around the y axis.
Definition: mat.h:628
mat(const Matrix &m)
Copy constructor.
Definition: mat.h:150
static mat< Type, N, K > rotation_3d_xaxis(real theta)
Get a matrix which rotates <theta> radians around the x axis.
Definition: mat.h:621
auto operator*(const Matrix &B) const
Matrix multiplication.
Definition: mat.h:316
Vector transform(const Vector &v) const
Transform a vector v by the matrix.
Definition: mat.h:263
Matrix mul(const Matrix &B) const
Matrix multiplication by any matrix type.
Definition: mat.h:299
bool operator==(const Matrix &other) const
Check whether two matrices are equal element by element.
Definition: mat.h:485
mat< Type, N, K > & operator*=(Type scalar)
Scalar multiplication.
Definition: mat.h:346
Type & at(unsigned int i, unsigned int j)
Access the element at the i-th row and j-th column.
Definition: mat.h:386
real sparsity(real tolerance=1E-12)
Compute the sparsity of the matrix, counting the proportion of zero (smaller in module than the given...
Definition: mat.h:536
static mat< Type, N, K > diagonal(Type diag)
Get a diagonal matrix.
Definition: mat.h:601
mat< Type, K, N > transposed() const
Return the transposed matrix, without modifying the matrix itself.
Definition: mat.h:380
mat< Type, N, K > & operator/=(Type scalar)
Scalar division.
Definition: mat.h:352
Type det() const
Compute the determinant of the matrix.
Definition: mat.h:554
static mat< Type, N, K > symplectic(unsigned int n=0, unsigned int k=0)
A symplectic NxN matrix, where for some natural K.
Definition: mat.h:684
mat< Type, N, K > & operator*=(const Matrix &B)
Matrix multiplication.
Definition: mat.h:365
static mat< Type, N, K > identity()
Get the identity matrix.
Definition: mat.h:595
mat< Type, N, K > & operator-=(const Matrix &other)
Matrix subtraction.
Definition: mat.h:340
vec< Type, N > transform(const vec< Type, K > &v) const
Transform a vector by the matrix.
Definition: mat.h:278
mat< Type, N, K > operator+(const Matrix &other) const
Matrix addition.
Definition: mat.h:210
mat< Type, N, K > operator*(Type scalar) const
Scalar multiplication.
Definition: mat.h:225
mat< Type, N, K > & transpose()
Transpose the matrix itself.
Definition: mat.h:371
friend mat< Type, N, K > operator*(Type a, const mat< Type, N, K > &B)
Friend operator to enable equations of the form (T) * (mat)
Definition: mat.h:233
mat< Type, N, K > operator-(const Matrix &other) const
Matrix subtraction.
Definition: mat.h:218
vec< Type, N > operator*(const vec< Type, K > &v) const
Transform a vector by the matrix.
Definition: mat.h:284
auto begin()
Get an iterator to the first element of the matrix.
Definition: mat.h:439
A statically allocated N-dimensional vector with elements of the given type.
Definition: vec.h:88
#define TH_CONSTEXPR
Enable constexpr in function declarations if C++14 is supported.
Definition: constants.h:151
#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
TH_MATH_ERROR is a macro which throws exceptions or modifies errno (depending on which compiling opti...
Definition: error.h:219
std::string string(size_t length)
Generate a random string made of human-readable ASCII characters.
Definition: random.h:102
Matrix & mat_zeroes(Matrix &m)
Overwrite a matrix with all zeroes.
Definition: algebra.h:93
Matrix & make_transposed(Matrix &m)
Transpose the given matrix.
Definition: algebra.h:420
bool is_square(const Matrix &m)
Returns whether the matrix is square.
Definition: algebra.h:1232
auto trace(const Matrix &m)
Compute the trace of the given matrix.
Definition: algebra.h:555
bool is_symmetric(const Matrix &m, real tolerance=ALGEBRA_ELEMENT_TOL)
Returns whether the matrix is symmetric.
Definition: algebra.h:1259
bool mat_equals(const Matrix1 &A, const Matrix2 &B, real tolerance=10 *MACH_EPSILON)
Checks whether two matrices are equal.
Definition: algebra.h:1109
Vector & vec_error(Vector &v)
Overwrite the given vector with the error vector with NaN values.
Definition: algebra.h:62
Matrix & mat_scalmul(Field a, Matrix &m)
Multiply a matrix by a scalar of any compatible type.
Definition: algebra.h:590
Vector transform(const Matrix &A, const Vector &v)
Returns the matrix transformation of a vector.
Definition: algebra.h:702
bool is_diagonal(const Matrix &m, real tolerance=10 *MACH_EPSILON)
Returns whether the matrix is diagonal.
Definition: algebra.h:1243
real density(const Matrix &A, real tolerance=1E-12)
Compute the density of a matrix, counting the proportion of non-zero (bigger in module than the given...
Definition: algebra.h:1323
Matrix2 & mat_sum(Matrix1 &A, const Matrix2 &B)
Sum two matrices and store the result in the first matrix.
Definition: algebra.h:764
real sparsity(const Matrix &A, real tolerance=1E-12)
Compute the sparsity of a matrix, counting the proportion of zero (smaller in module than the given t...
Definition: algebra.h:1346
Matrix3 mat_mul(const Matrix1 &A, const Matrix2 &B)
Multiply two matrices and store the result in the first matrix, equivalent to the operation .
Definition: algebra.h:977
Matrix1 & mat_copy(Matrix1 &dest, const Matrix2 &src)
Copy a matrix by overwriting another.
Definition: algebra.h:125
auto diagonal_product(const Matrix &m)
Compute the product of the elements of the main diagonal of a generic matrix.
Definition: algebra.h:573
Matrix & mat_error(Matrix &m)
Overwrite the given matrix with the error matrix with NaN values on the diagonal and zeroes everywher...
Definition: algebra.h:44
auto det(const Matrix &A)
Compute the determinant of a square matrix.
Definition: algebra.h:2024
Matrix & invert(Matrix &m)
Invert the given matrix and overwrite it.
Definition: algebra.h:1997
Matrix1 & inverse(Matrix1 &dest, const Matrix2 &src)
Invert the given matrix.
Definition: algebra.h:1883
Matrix2 & mat_diff(Matrix1 &A, const Matrix2 &B)
Subtract two matrices and store the result in the first matrix.
Definition: algebra.h:832
Main namespace of the library which contains all functions and objects.
Definition: algebra.h:27
double real
A real number, defined as a floating point type.
Definition: constants.h:188
auto min(const Vector &X)
Finds the minimum value inside a dataset.
Definition: dataset.h:351
dual2 abs(dual2 x)
Compute the absolute value of a second order dual number.
Definition: dual2_functions.h:183
std::remove_reference_t< decltype(std::declval< Structure >()(0, 0))> matrix_element_t
Extract the type of a matrix (or any doubly indexable container) from its operator().
Definition: core_traits.h:140
constexpr real MACH_EPSILON
Machine epsilon for the real type.
Definition: constants.h:197
constexpr real E
The Euler mathematical constant (e)
Definition: constants.h:227
std::enable_if_t< is_matrix< Structure >::value, T > enable_matrix
Enable a function overload if the template typename is considerable a matrix.
Definition: core_traits.h:160
Linear transformations such as rotations and projective geometry.
Vector class and operations.