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 
54 
64  Matrix& matrix,
65  size_t row = 0,
66  size_t col = 0)
67  : matrix(matrix), row(row), col(col) {}
68 
69 
74  ReturnType operator*() {
75  return matrix(row, col);
76  }
77 
78 
85 
86  col++;
87 
88  if(col == matrix.cols()) {
89  col = 0;
90  row++;
91  }
92 
93  return *this;
94  }
95 
96 
99  size_t row_index() {
100  return row;
101  }
102 
103 
106  size_t col_index() {
107  return col;
108  }
109 
110 
114  bool operator==(const mat_iterator& other) const {
115  return (row == other.row) &&
116  (col == other.col);
117  }
118 
119 
123  bool operator!=(const mat_iterator& other) const {
124  return !(*this == other);
125  }
126  };
127 
128 
135  template<typename Type = real, unsigned int N = 0, unsigned int K = 0>
136  class mat {
137  public:
138 
139 #ifdef THEORETICA_ROW_FIRST
140  Type data[N][K];
141 #else
142  Type data[K][N];
143 #endif
144 
145 
149  mat() {
150  algebra::mat_zeroes(*this);
151  }
152 
153 
159  template<typename Matrix>
160  mat(const Matrix& m) {
161  algebra::mat_copy(*this, m);
162  }
163 
164 
171  template<typename T = Type>
172  inline mat(const std::initializer_list<std::initializer_list<T>>& rows) {
173 
174  if(rows.size() != N) {
175  TH_MATH_ERROR("mat::mat", rows.size(), INVALID_ARGUMENT);
176  algebra::mat_error(*this);
177  return;
178  }
179 
180  unsigned int i = 0;
181  unsigned int j = 0;
182 
183  for (const auto& row : rows) {
184 
185  if (row.size() != K) {
186  TH_MATH_ERROR("mat::mat", rows.size(), INVALID_ARGUMENT);
187  algebra::mat_error(*this);
188  return;
189  }
190 
191  for (const auto& x : row) {
192 
193  at(i, j) = x;
194  j = (j + 1) % K;
195  }
196 
197  i++;
198  }
199  }
200 
201 
209  mat(Type diagonal, unsigned int n = 0, unsigned int k = 0) {
210 
211  if (n && k)
212  resize(n, k);
213 
214  algebra::mat_zeroes(*this);
215  const unsigned int m = min(n, k);
216 
217  for (unsigned int i = 0; i < m; ++i)
218  at(i, i) = diagonal;
219  }
220 
221 
226  template<typename Matrix>
227  inline mat<Type, N, K>& operator=(const Matrix& other) {
228  return algebra::mat_copy(*this, other);
229  }
230 
231 
233  inline void make_zeroes() {
234  algebra::mat_zeroes(*this);
235  }
236 
237 
240  inline static mat<Type, N, K> zeroes() {
241  mat<Type, N, K> res;
242  algebra::mat_zeroes(res);
243  return res;
244  }
245 
246 
251  template<typename Matrix>
252  inline mat<Type, N, K> operator+(const Matrix& other) const {
253  mat<Type, N, K> res;
254  return algebra::mat_sum(res, *this, other);
255  }
256 
257 
262  template<typename Matrix>
263  inline mat<Type, N, K> operator-(const Matrix& other) const {
264  mat<Type, N, K> res;
265  return algebra::mat_diff(res, *this, other);
266  }
267 
268 
272  inline mat<Type, N, K> operator*(Type scalar) const {
273  mat<Type, N, K> res;
274  return algebra::mat_scalmul(res, scalar, *this);
275  }
276 
277 
282  inline friend mat<Type, N, K> operator*(Type a, const mat<Type, N, K>& B) {
283  return B * a;
284  }
285 
286 
293  template<typename VecType, unsigned int M>
294  inline friend vec<VecType, K> operator*(
295  const vec<VecType, M>& a, const mat<Type, N, K>& B) {
296  return B * a;
297  }
298 
299 
305  inline mat<Type, N, K> operator/(Type scalar) const {
306 
307  mat<Type, N, K> res;
308 
309  if(abs(scalar) < MACH_EPSILON) {
310  TH_MATH_ERROR("mat::operator/", scalar, DIV_BY_ZERO);
311  return algebra::mat_error(res);
312  }
313 
314  return algebra::mat_scalmul(res, 1.0 / scalar, *this);
315  }
316 
317 
325  template<typename Vector>
326  inline Vector transform(const Vector& v) const {
327 
328  if(v.size() != cols()) {
329  TH_MATH_ERROR("mat::transform", v.size(), INVALID_ARGUMENT);
330  Vector res;
331  res.resize(cols());
332  algebra::vec_error(res);
333  return res;
334  }
335 
336  return algebra::transform(*this, v);
337  }
338 
339 
343  inline vec<Type, N> transform(const vec<Type, K>& v) const {
344  return algebra::transform(*this, v);
345  }
346 
347 
351  inline vec<Type, N> operator*(const vec<Type, K>& v) const {
352  return transform(v);
353  }
354 
355 
360  template<unsigned int M>
361  inline mat<Type, N, M> mul(const mat<Type, K, M>& B) const {
362  mat<Type, N, M> res;
363  return algebra::mat_mul(res, *this, B);
364  }
365 
366 
374  template<typename Matrix>
375  inline Matrix mul(const Matrix& B) const {
376 
377  Matrix res;
378  res.resize(N, B.cols());
379 
380  if(B.rows() != K) {
381  TH_MATH_ERROR("mat::transform", B.rows(), INVALID_ARGUMENT);
382  algebra::mat_error(res);
383  return res;
384  }
385 
386  return algebra::mat_mul(res, *this, B);
387  }
388 
389 
394  template<typename Matrix>
395  inline auto operator*(const Matrix& B) const {
396 
397  Matrix res;
398  res.resize(N, B.cols());
399 
400  if(B.rows() != K) {
401  TH_MATH_ERROR("mat::transform", B.rows(), INVALID_ARGUMENT);
402  algebra::mat_error(res);
403  return res;
404  }
405 
406  return algebra::mat_mul(res, *this, B);
407  }
408 
409 
414  template<typename Matrix>
415  inline mat<Type, N, K>& operator+=(const Matrix& other) {
416  return algebra::mat_sum(*this, other);
417  }
418 
419 
424  template<typename Matrix>
425  inline mat<Type, N, K>& operator-=(const Matrix& other) {
426  return algebra::mat_diff(*this, other);
427  }
428 
429 
433  inline mat<Type, N, K>& operator*=(Type scalar) {
434  return algebra::mat_scalmul(scalar, *this);
435  }
436 
437 
443  inline mat<Type, N, K>& operator/=(Type scalar) {
444 
445  if(abs(scalar) < MACH_EPSILON) {
446  TH_MATH_ERROR("mat::operator/", scalar, DIV_BY_ZERO);
447  return algebra::mat_error(*this);
448  }
449 
450  return algebra::mat_scalmul(1.0 / scalar, *this);
451  }
452 
453 
458  template<typename Matrix>
459  inline mat<Type, N, K>& operator*=(const Matrix& B) {
460  return (*this = this->operator*(B));
461  }
462 
463 
470  static_assert(
471  N == K, "The matrix must be square to be transposed in place.");
472  return algebra::make_transposed(*this);
473  }
474 
475 
478  inline mat<Type, K, N> transposed() const {
479  return algebra::transpose<mat<Type, N, K>, mat<Type, K, N>>(*this);
480  }
481 
482 
487  inline Type& at(unsigned int i, unsigned int j) {
488 
489 #ifdef THEORETICA_ROW_FIRST
490  return data[i][j];
491 #else
492  return data[j][i];
493 #endif
494  }
495 
496 
501  inline const Type& at(unsigned int i, unsigned int j) const {
502 
503 #ifdef THEORETICA_ROW_FIRST
504  return data[i][j];
505 #else
506  return data[j][i];
507 #endif
508  }
509 
510 
515  inline Type& operator()(unsigned int i, unsigned int j) {
516  return at(i, j);
517  }
518 
519 
524  inline const Type& operator()(unsigned int i, unsigned int j) const {
525  return at(i, j);
526  }
527 
528 
533  inline Type get(unsigned int i, unsigned int j) const {
534 
535 #ifdef THEORETICA_ROW_FIRST
536  return data[i][j];
537 #else
538  return data[j][i];
539 #endif
540  }
541 
542 
545 
546 
549 
550 
553  inline auto begin() {
554  return iterator(*this, 0, 0);
555  }
556 
557 
560  inline auto end() {
561  return iterator(*this, rows(), 0);
562  }
563 
564 
567  inline auto begin() const {
568  return const_iterator(*this, 0, 0);
569  }
570 
571 
574  inline auto end() const {
575  return const_iterator(*this, rows(), 0);
576  }
577 
578 
581  TH_CONSTEXPR inline unsigned int rows() const {
582  return N;
583  }
584 
585 
588  TH_CONSTEXPR inline unsigned int cols() const {
589  return K;
590  }
591 
592 
595  inline unsigned int size() const {
596  return N * K;
597  }
598 
599 
604  template<typename Matrix>
605  inline bool operator==(const Matrix& other) const {
606  return algebra::mat_equals(*this, other);
607  }
608 
609 
614  template<typename Matrix>
615  inline bool operator!=(const Matrix& other) const {
616  return !algebra::mat_equals(*this, other);
617  }
618 
619 
622  inline bool is_square() const {
623  return algebra::is_square(*this);
624  }
625 
626 
629  inline bool is_diagonal() const {
630  return algebra::is_diagonal(*this);
631  }
632 
633 
636  inline bool is_symmetric() const {
637  return algebra::is_symmetric(*this);
638  }
639 
640 
649  inline real density(real tolerance = 1E-12) {
650  return algebra::density(*this, tolerance);
651  }
652 
653 
662  inline real sparsity(real tolerance = 1E-12) {
663  return algebra::sparsity(*this, tolerance);
664  }
665 
666 
669  inline Type trace() {
670  return algebra::trace(*this);
671  }
672 
673 
676  inline Type diagonal_product() {
677  return algebra::diagonal_product(*this);
678  }
679 
680 
685  inline Type det() const {
686  static_assert(N == K, "The matrix must be square to compute the determinant.");
687  return algebra::det(*this);
688  }
689 
690 
695  inline mat<Type, N, K> inverse() const {
696  static_assert(N == K, "The matrix must be square to be invertible.");
697  return algebra::inverse(*this);
698  }
699 
700 
706  static_assert(N == K, "The matrix must be square to be invertible.");
707  return algebra::invert(*this);
708  }
709 
710 
716  inline mat<Type, N, K> resize(unsigned int n, unsigned int k) const {
717 
718  if(rows() != n) {
719  TH_MATH_ERROR("mat::resize", n, INVALID_ARGUMENT);
720  } else if(cols() != k) {
721  TH_MATH_ERROR("mat::resize", k, INVALID_ARGUMENT);
722  }
723 
724  return *this;
725  }
726 
727 
728  // Transformation matrices
729 
730 
733  inline static mat<Type, N, K> identity() {
734  return algebra::identity<mat<Type, N, K>>();
735  }
736 
737 
741  inline static mat<Type, N, K> diagonal(Type diag) {
742  return mat<Type, N, K>(diag);
743  }
744 
749  template<typename Vector = vec<real, N - 1>>
750  inline static mat<Type, N, K> translation(Vector&& t) {
751  return algebra::translation<mat<Type, N, K>>(t);
752  }
753 
754 
758  inline static mat<Type, N, K> rotation_2d(real theta) {
759  static_assert(N >= 2 && K >= 2, "The matrix must be 2x2 or bigger");
760  return algebra::rotation_2d<mat<Type, N, K>>(theta);
761  }
762 
763 
767  inline static mat<Type, N, K> rotation_3d_xaxis(real theta) {
768  static_assert(N >= 3 && K >= 3, "The matrix must be 3x3 or bigger");
769  return algebra::rotation_3d_xaxis<mat<Type, N, K>>(theta);
770  }
771 
772 
776  inline static mat<Type, N, K> rotation_3d_yaxis(real theta) {
777  static_assert(N >= 3 && K >= 3, "The matrix must be 3x3 or bigger");
778  return algebra::rotation_3d_yaxis<mat<Type, N, K>>(theta);
779  }
780 
781 
785  inline static mat<Type, N, K> rotation_3d_zaxis(real theta) {
786  static_assert(N >= 3 && K >= 3, "The matrix must be 3x3 or bigger");
787  return algebra::rotation_3d_zaxis<mat<Type, N, K>>(theta);
788  }
789 
790 
796  template<typename Vector = vec<real, 3>>
797  inline static mat<Type, N, K> rotation_3d(real theta, Vector&& axis) {
798  static_assert(N >= 3 && K >= 3, "The matrix must be 3x3 or bigger");
799  return algebra::rotation_3d<mat<Type, N, K>>(theta, axis);
800  }
801 
802 
812  real left, real right, real bottom,
813  real top, real near, real far) {
814 
815  static_assert(N >= 4 && K >= 4, "The matrix must be 4x4 or bigger");
816  return algebra::perspective<mat<Type, N, K>>(
817  left, right, bottom, top, near, far);
818  }
819 
820 
828  real fov, real aspect, real near, real far) {
829 
830  static_assert(N >= 4 && K >= 4, "The matrix must be 4x4 or bigger");
831  return algebra::perspective_fov<mat<Type, N, K>>(fov, aspect, near, far);
832  }
833 
834 
843  inline static mat<Type, N, K> ortho(
844  real left, real right, real bottom, real top, real near, real far) {
845  static_assert(N >= 4 && K >= 4, "The matrix must be 4x4 or bigger");
846  return algebra::ortho<mat<Type, N, K>>(left, right, bottom, top, near, far);
847  }
848 
849 
857  template<typename Vector1, typename Vector2, typename Vector3>
858  inline static mat<Type, 4, 4> look_at(
859  const Vector1& camera, const Vector2& target, const Vector3& up) {
860  return algebra::look_at<mat<Type, 4, 4>>(camera, target, up);
861  }
862 
863 
868  inline static mat<Type, N, K> symplectic(unsigned int n = 0, unsigned int k = 0) {
869  static_assert(N == K && (N % 2 == 0),
870  "N must equal K and they should be a multiple of 2");
871  return algebra::symplectic<mat<Type, N, K>>(n, k);
872  }
873 
874 
875 
876 #ifndef THEORETICA_NO_PRINT
877 
882  inline std::string to_string(
883  std::string separator = ", ", bool parenthesis = true) const {
884 
885  std::stringstream res;
886 
887  for (unsigned int i = 0; i < rows(); ++i) {
888 
889  if(parenthesis)
890  res << "(";
891 
892  for (unsigned int j = 0; j < cols(); ++j) {
893 
894  if(j)
895  res << separator;
896 
897  if(abs(get(i, j)) < MACH_EPSILON)
898  res << "0";
899  else
900  res << get(i, j);
901  }
902 
903  if(parenthesis)
904  res << ")" << std::endl;
905  }
906 
907  return res.str();
908  }
909 
910 
912  inline operator std::string() {
913  return to_string();
914  }
915 
916 
921  inline friend std::ostream& operator<<(
922  std::ostream& out, const mat<Type, N, K>& obj) {
923  return out << obj.to_string();
924  }
925 
926 #endif
927 
928  };
929 
930 
931 
937  template<typename Type>
938  class mat<Type, 0, 0> {
939  public:
940 
941  // Container type for storage (alias for std::vector)
942  template<typename T>
943  using Container = std::vector<T>;
944 
946  Container<Container<Type>> data;
947 
949  size_t row_sz {0};
950 
952  size_t col_sz {0};
953 
954 
956  mat() : row_sz(0), col_sz(0) {}
957 
958 
962  mat(unsigned int n, unsigned int k) {
963  resize(n, k);
964  algebra::mat_zeroes(*this);
965  }
966 
967 
971  template <
972  typename Matrix, enable_matrix<Matrix>
973  >
974  mat(const Matrix& m) {
975  resize(m.rows(), m.cols());
976  algebra::mat_copy(*this, m);
977  }
978 
979 
983  template<typename T = Type>
984  inline mat(const std::initializer_list<std::initializer_list<T>>& rows) {
985 
986  unsigned int i = 0;
987  unsigned int j = 0;
988 
989  for (const auto& row : rows) {
990 
991  for (const auto& x : row) {
992 
993  if (!i && !j) {
994  this->resize(rows.size(), row.size());
995  }
996  else if (row.size() != col_sz) {
997  TH_MATH_ERROR("mat::mat", row.size(), INVALID_ARGUMENT);
998  algebra::mat_error(*this);
999  return;
1000  }
1001 
1002  at(i, j) = x;
1003  j = (j + 1) % col_sz;
1004  }
1005 
1006  i++;
1007  }
1008  }
1009 
1010 
1014  template<typename Matrix>
1015  inline mat<Type>& operator=(const Matrix& other) {
1016  resize(other.rows(), other.cols());
1017  return algebra::mat_copy(*this, other);
1018  }
1019 
1020 
1025  mat(Type diagonal, unsigned int n, unsigned int k) {
1026 
1027  resize(n, k);
1028  algebra::mat_zeroes(*this);
1029  const unsigned int m = min(n, k);
1030 
1031  for (unsigned int i = 0; i < m; ++i)
1032  at(i, i) = diagonal;
1033  }
1034 
1035 
1037  ~mat() {
1038  row_sz = 0;
1039  col_sz = 0;
1040  }
1041 
1042 
1044  inline void make_zeroes() {
1045  algebra::mat_zeroes(*this);
1046  }
1047 
1048 
1053  inline static mat<Type> zeroes(unsigned int rows, unsigned int cols) {
1054  mat<Type> res;
1055  res.resize(rows, cols);
1056  algebra::mat_zeroes(res);
1057  return res;
1058  }
1059 
1060 
1065  template<typename Matrix>
1066  inline mat<Type> operator+(const Matrix& other) const {
1067  mat<Type> res;
1068  res.resize(rows(), cols());
1069  return algebra::mat_sum(res, *this, other);
1070  }
1071 
1072 
1077  template<typename Matrix>
1078  inline mat<Type> operator-(const Matrix& other) const {
1079  mat<Type> res;
1080  res.resize(rows(), cols());
1081  return algebra::mat_diff(res, *this, other);
1082  }
1083 
1084 
1088  inline mat<Type> operator*(Type scalar) const {
1089  mat<Type> res;
1090  res.resize(rows(), cols());
1091  return algebra::mat_scalmul(res, scalar, *this);
1092  }
1093 
1094 
1099  inline friend mat<Type> operator*(Type a, const mat<Type>& B) {
1100  return B * a;
1101  }
1102 
1103 
1110  template<typename VecType, unsigned int M>
1112  const vec<VecType, M>& a, const mat<Type, 0, 0>& B) {
1113  return B * a;
1114  }
1115 
1116 
1120  inline mat<Type> operator/(Type scalar) const {
1121 
1122  mat<Type> res;
1123  res.resize(rows(), cols());
1124 
1125  if(abs(scalar) < MACH_EPSILON) {
1126  TH_MATH_ERROR("mat::operator/", scalar, DIV_BY_ZERO);
1127  return algebra::mat_error(res);
1128  }
1129 
1130  return algebra::mat_scalmul(res, 1.0 / scalar, *this);
1131  }
1132 
1133 
1138  template<typename Vector>
1139  inline Vector transform(const Vector& v) const {
1140 
1141  if(v.size() != rows()) {
1142  TH_MATH_ERROR("mat::transform", v.size(), INVALID_ARGUMENT);
1143  Vector res;
1144  res.resize(rows());
1145  algebra::vec_error(res);
1146  return res;
1147  }
1148 
1149  return algebra::transform(*this, v);
1150  }
1151 
1152 
1157  template<unsigned int N = 0, unsigned int K = 0>
1158  inline vec<Type, N> transform(const vec<Type, K>& v) const {
1159  return algebra::transform(*this, v);
1160  }
1161 
1162 
1167  template<unsigned int N = 0, unsigned int K = 0>
1168  inline vec<Type, N> operator*(const vec<Type, K>& v) const {
1169  return transform(v);
1170  }
1171 
1172 
1174  // inline vec<Type> operator*(const vec<Type>& v) const {
1175  // return transform(v);
1176  // }
1177 
1178 
1190  inline mat<Type> mul(const mat<Type>& B) const {
1191 
1192  mat<Type> res;
1193  res.resize(rows(), B.cols());
1194 
1195  if(B.rows() != cols()) {
1196  TH_MATH_ERROR("mat::mul", B.rows(), INVALID_ARGUMENT);
1197  algebra::mat_error(res);
1198  return res;
1199  }
1200 
1201  return algebra::mat_mul(res, *this, B);
1202  }
1203 
1204 
1216  template<typename Matrix>
1217  inline Matrix mul(const Matrix& B) const {
1218 
1219  Matrix res;
1220  res.resize(rows(), B.cols());
1221 
1222  if(B.rows() != cols()) {
1223  TH_MATH_ERROR("mat::mul", B.rows(), INVALID_ARGUMENT);
1224  algebra::mat_error(res);
1225  return res;
1226  }
1227 
1228  return algebra::mat_mul(res, *this, B);
1229  }
1230 
1231 
1238  template<typename Matrix>
1239  inline auto operator*(const Matrix& B) const {
1240  return mul(B);
1241  }
1242 
1243 
1251  template<typename Matrix>
1252  inline mat<Type>& operator+=(const Matrix& other) {
1253  return algebra::mat_sum(*this, other);
1254  }
1255 
1256 
1264  template<typename Matrix>
1265  inline mat<Type>& operator-=(const Matrix& other) {
1266  return algebra::mat_diff(*this, other);
1267  }
1268 
1269 
1276  inline mat<Type>& operator*=(Type scalar) {
1277  return algebra::mat_scalmul(scalar, *this);
1278  }
1279 
1280 
1287  inline mat<Type>& operator/=(Type scalar) {
1288 
1289  if(abs(scalar) < MACH_EPSILON) {
1290  TH_MATH_ERROR("mat::operator/", scalar, DIV_BY_ZERO);
1291  return algebra::mat_error(*this);
1292  }
1293 
1294  return algebra::mat_scalmul(1.0 / scalar, *this);
1295  }
1296 
1297 
1305  template<typename Matrix>
1306  inline mat<Type>& operator*=(const Matrix& B) {
1307  return (*this = this->operator*(B));
1308  }
1309 
1310 
1317  inline mat<Type>& transpose() {
1318  return algebra::make_transposed(*this);
1319  }
1320 
1321 
1327  inline mat<Type> transposed() const {
1328  return algebra::transpose<mat<Type>, mat<Type>>(*this);
1329  }
1330 
1331 
1338  inline Type& at(unsigned int i, unsigned int j) {
1339 
1340 #ifdef THEORETICA_ROW_FIRST
1341  return data[i][j];
1342 #else
1343  return data[j][i];
1344 #endif
1345  }
1346 
1347 
1354  inline const Type& at(unsigned int i, unsigned int j) const {
1355 
1356 #ifdef THEORETICA_ROW_FIRST
1357  return data[i][j];
1358 #else
1359  return data[j][i];
1360 #endif
1361  }
1362 
1363 
1371  inline Type& operator()(unsigned int i, unsigned int j) {
1372  return at(i, j);
1373  }
1374 
1375 
1383  inline const Type& operator()(unsigned int i, unsigned int j) const {
1384  return at(i, j);
1385  }
1386 
1387 
1394  inline Type get(unsigned int i, unsigned int j) const {
1395 
1396 #ifdef THEORETICA_ROW_FIRST
1397  return data[i][j];
1398 #else
1399  return data[j][i];
1400 #endif
1401  }
1402 
1403 
1406 
1407 
1410 
1411 
1417  inline auto begin() {
1418  return iterator(*this, 0, 0);
1419  }
1420 
1421 
1428  inline auto end() {
1429  return iterator(*this, rows(), 0);
1430  }
1431 
1432 
1438  inline auto begin() const {
1439  return const_iterator(*this, 0, 0);
1440  }
1441 
1442 
1448  inline auto end() const {
1449  return const_iterator(*this, rows(), 0);
1450  }
1451 
1452 
1455  TH_CONSTEXPR inline unsigned int rows() const {
1456  return row_sz;
1457  }
1458 
1459 
1462  TH_CONSTEXPR inline unsigned int cols() const {
1463  return col_sz;
1464  }
1465 
1466 
1470  inline unsigned int size() const {
1471  return rows() * cols();
1472  }
1473 
1474 
1481  template<typename Matrix>
1482  inline bool operator==(const Matrix& other) const {
1483  return algebra::mat_equals(*this, other);
1484  }
1485 
1486 
1493  template<typename Matrix>
1494  inline bool operator!=(const Matrix& other) const {
1495  return !algebra::mat_equals(*this, other);
1496  }
1497 
1498 
1503  inline bool is_square() const {
1504  return algebra::is_square(*this);
1505  }
1506 
1507 
1512  inline bool is_diagonal() const {
1513  return algebra::is_diagonal(*this);
1514  }
1515 
1516 
1521  inline bool is_symmetric() const {
1522  return algebra::is_symmetric(*this);
1523  }
1524 
1525 
1534  inline real density(real tolerance = 1E-12) {
1535  return algebra::density(*this, tolerance);
1536  }
1537 
1538 
1547  inline real sparsity(real tolerance = 1E-12) {
1548  return algebra::sparsity(*this, tolerance);
1549  }
1550 
1551 
1556  inline Type trace() {
1557  return algebra::trace(*this);
1558  }
1559 
1560 
1565  inline Type diagonal_product() {
1566  return algebra::diagonal_product(*this);
1567  }
1568 
1569 
1575  inline Type det() const {
1576  return algebra::det(*this);
1577  }
1578 
1579 
1585  inline mat<Type> inverse() const {
1586  return algebra::inverse(*this);
1587  }
1588 
1589 
1594  inline mat<Type>& invert() {
1595  return algebra::invert(*this);
1596  }
1597 
1598 
1602  inline mat<Type>& resize(unsigned int n, unsigned int k) {
1603 
1604  // Do nothing if the size is already correct
1605  if(rows() == n && cols() == k)
1606  return *this;
1607 
1608  // Distinguish between row-first and column-first allocation
1609 #ifdef THEORETICA_ROW_FIRST
1610  size_t size1 = n, size2 = k;
1611 #else
1612  size_t size1 = k, size2 = n;
1613 #endif
1614 
1615  // The matrix must be allocated anew
1616  if(!data.size()) {
1617 
1618  data.resize(size1);
1619  for (unsigned int i = 0; i < size1; ++i)
1620  data[i].resize(size2);
1621 
1622  row_sz = n;
1623  col_sz = k;
1624  algebra::mat_zeroes(*this);
1625 
1626  // The matrix must be reallocated
1627  } else {
1628 
1629  std::vector<std::vector<Type>> new_data;
1630  new_data.resize(size1);
1631  for (unsigned int i = 0; i < size1; ++i)
1632  new_data[i].resize(size2);
1633 
1634  // Copy data to new memory location
1635 
1636  // Bounds on the region to copy
1637  const size_t row_bound = min(rows(), n);
1638  const size_t col_bound = min(cols(), n);
1639 
1640  for (unsigned int i = 0; i < row_bound; ++i) {
1641  for (unsigned int j = 0; j < col_bound; ++j) {
1642 #ifdef THEORETICA_ROW_FIRST
1643  new_data[i][j] = get(i, j);
1644 #else
1645  new_data[j][i] = get(i, j);
1646 #endif
1647  }
1648  }
1649 
1650  // If the new matrix size is bigger,
1651  // zero out all remaining entries
1652  for (unsigned int i = 0; i < n; ++i) {
1653  for (unsigned int j = col_bound; j < k; ++j) {
1654 
1655 
1656 #ifdef THEORETICA_ROW_FIRST
1657  new_data[i][j] = (Type) 0;
1658 #else
1659  new_data[j][i] = (Type) 0;
1660 #endif
1661  }
1662  }
1663 
1664 
1665  // If the new matrix size is bigger,
1666  // zero out all remaining entries
1667  for (unsigned int i = row_bound; i < n; ++i) {
1668  for (unsigned int j = 0; j < k; ++j) {
1669 
1670 
1671 #ifdef THEORETICA_ROW_FIRST
1672  new_data[i][j] = (Type) 0;
1673 #else
1674  new_data[j][i] = (Type) 0;
1675 #endif
1676  }
1677  }
1678 
1679  data.clear();
1680  data = new_data;
1681 
1682  row_sz = n;
1683  col_sz = k;
1684  }
1685 
1686  return *this;
1687  }
1688 
1689 
1690  // Transformation matrices
1691 
1692 
1699  inline static mat<Type> identity(
1700  unsigned int row_sz, unsigned int col_sz) {
1701 
1702  return algebra::identity<mat<Type>>(row_sz, col_sz);
1703  }
1704 
1705 
1711  inline static mat<Type> diagonal(
1712  Type diag, unsigned int row_sz, unsigned int col_sz) {
1713  return mat<Type>(diag, row_sz, col_sz);
1714  }
1715 
1716 
1720  template<typename Vector>
1721  inline static mat<Type> translation(Vector&& t) {
1722  return algebra::translation<mat<Type>>(t);
1723  }
1724 
1725 
1729  inline static mat<Type> rotation_2d(real theta) {
1730  return algebra::rotation_2d<mat<Type>>(theta);
1731  }
1732 
1733 
1737  inline static mat<Type> rotation_3d_xaxis(real theta) {
1738  return algebra::rotation_3d_xaxis<mat<Type>>(theta);
1739  }
1740 
1741 
1745  inline static mat<Type> rotation_3d_yaxis(real theta) {
1746  return algebra::rotation_3d_yaxis<mat<Type>>(theta);
1747  }
1748 
1749 
1753  inline static mat<Type> rotation_3d_zaxis(real theta) {
1754  return algebra::rotation_3d_zaxis<mat<Type>>(theta);
1755  }
1756 
1757 
1762  template<typename Vector = vec<real, 3>>
1763  inline static mat<Type> rotation_3d(real theta, Vector&& axis) {
1764  return algebra::rotation_3d<mat<Type>>(theta, axis);
1765  }
1766 
1775  inline static mat<Type> perspective(
1776  real left, real right, real bottom,
1777  real top, real near, real far) {
1778 
1779  return algebra::perspective<mat<Type>>(
1780  left, right, bottom, top, near, far);
1781  }
1782 
1790  real fov, real aspect, real near, real far) {
1791 
1792  return algebra::perspective_fov<mat<Type>>(fov, aspect, near, far);
1793  }
1794 
1803  inline static mat<Type> ortho(
1804  real left, real right, real bottom, real top, real near, real far) {
1805  return algebra::ortho<mat<Type>>(left, right, bottom, top, near, far);
1806  }
1807 
1808 
1815  template<typename Vector1, typename Vector2, typename Vector3>
1816  inline static mat<Type> look_at(
1817  const Vector1& camera, const Vector2& target, const Vector3& up) {
1818  return algebra::look_at<mat<Type>>(camera, target, up);
1819  }
1820 
1821 
1826  inline static mat<Type> symplectic(unsigned int rows, unsigned int cols) {
1827  return algebra::symplectic<mat<Type>>(rows, cols);
1828  }
1829 
1830 
1831 
1832 
1833 #ifndef THEORETICA_NO_PRINT
1834 
1836  inline std::string to_string(
1837  std::string separator = ", ", bool parenthesis = true) const {
1838 
1839  std::stringstream res;
1840 
1841  for (unsigned int i = 0; i < rows(); ++i) {
1842 
1843  if(parenthesis)
1844  res << "(";
1845 
1846  for (unsigned int j = 0; j < cols(); ++j) {
1847 
1848  if(j)
1849  res << separator;
1850 
1851  if(abs(get(i, j)) < MACH_EPSILON)
1852  res << "0";
1853  else
1854  res << get(i, j);
1855  }
1856 
1857  if(parenthesis)
1858  res << ")" << std::endl;
1859  }
1860 
1861  return res.str();
1862  }
1863 
1864 
1866  inline operator std::string() {
1867  return to_string();
1868  }
1869 
1870 
1872  inline friend std::ostream& operator<<(
1873  std::ostream& out, const mat<Type>& obj) {
1874  return out << obj.to_string();
1875  }
1876 
1877 #endif
1878 
1879  };
1880 
1881 }
1882 
1883 #endif
Linear algebra routines.
A generic matrix with a variable number of rows and columns.
Definition: mat.h:938
mat< Type > operator/(Type scalar) const
Divides each element in the matrix by a scalar.
Definition: mat.h:1120
Type diagonal_product()
Compute the product of the diagonal elements of a square matrix.
Definition: mat.h:1565
static mat< Type > rotation_3d_zaxis(real theta)
Get a matrix which rotates by theta radians around the z-axis.
Definition: mat.h:1753
static mat< Type > rotation_3d_xaxis(real theta)
Get a matrix which rotates by theta radians around the x-axis.
Definition: mat.h:1737
mat< Type > & operator=(const Matrix &other)
Copy assignment operator for copying from another matrix.
Definition: mat.h:1015
bool is_diagonal() const
Determine if the matrix is diagonal (all non-diagonal elements are zero).
Definition: mat.h:1512
static mat< Type > identity(unsigned int row_sz, unsigned int col_sz)
Get the identity matrix.
Definition: mat.h:1699
mat< Type > & resize(unsigned int n, unsigned int k)
Set or change the size of the matrix.
Definition: mat.h:1602
vec< Type, N > operator*(const vec< Type, K > &v) const
Transforms a vector by multiplying it with the matrix.
Definition: mat.h:1168
mat< Type > & transpose()
Transpose the current matrix in place.
Definition: mat.h:1317
vec< Type, N > transform(const vec< Type, K > &v) const
Transforms a vector by multiplying it with the matrix.
Definition: mat.h:1158
auto operator*(const Matrix &B) const
Matrix multiplication with any matrix type.
Definition: mat.h:1239
mat(unsigned int n, unsigned int k)
Constructor that initializes a matrix with the specified number of rows and columns.
Definition: mat.h:962
mat< Type > & operator-=(const Matrix &other)
Matrix subtraction with another matrix.
Definition: mat.h:1265
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:1816
const Type & operator()(unsigned int i, unsigned int j) const
Access a constant element at a specific row and column using the function call operator.
Definition: mat.h:1383
bool operator==(const Matrix &other) const
Check if two matrices are equal element by element.
Definition: mat.h:1482
static mat< Type > rotation_3d_yaxis(real theta)
Get a matrix which rotates by theta radians around the y-axis.
Definition: mat.h:1745
mat(Type diagonal, unsigned int n, unsigned int k)
Constructor that initializes a diagonal matrix with equal entries on the diagonal.
Definition: mat.h:1025
bool is_symmetric() const
Determine if the matrix is symmetric (matrix == transpose).
Definition: mat.h:1521
bool operator!=(const Matrix &other) const
Check if two matrices are unequal element by element.
Definition: mat.h:1494
Type trace()
Compute the trace (sum of elements on the diagonal) of a square matrix.
Definition: mat.h:1556
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) (Enables vector-matrix multiplication....
Definition: mat.h:1111
static mat< Type > rotation_3d(real theta, Vector &&axis)
Get a matrix which rotates by theta radians around the given axis.
Definition: mat.h:1763
bool is_square() const
Determine if the matrix is square (rows == columns).
Definition: mat.h:1503
mat(const Matrix &m)
Copy constructor for creating a matrix from another matrix.
Definition: mat.h:974
Type & operator()(unsigned int i, unsigned int j)
Access a modifiable element at a specific row and column using the function call operator.
Definition: mat.h:1371
static mat< Type > zeroes(unsigned int rows, unsigned int cols)
Static method that returns a null matrix with specified dimensions.
Definition: mat.h:1053
mat(const std::initializer_list< std::initializer_list< T >> &rows)
Constructor that initializes a matrix from a list of rows.
Definition: mat.h:984
static mat< Type > translation(Vector &&t)
Get a 4x4 matrix which translates by {x, y, z}.
Definition: mat.h:1721
static mat< Type > perspective_fov(real fov, real aspect, real near, real far)
Get a perspective projection matrix using field of view.
Definition: mat.h:1789
auto end() const
Get a const iterator to one past the last element of the matrix.
Definition: mat.h:1448
TH_CONSTEXPR unsigned int cols() const
Get the number of columns in the matrix.
Definition: mat.h:1462
mat< Type > & operator*=(const Matrix &B)
Matrix multiplication with any matrix type.
Definition: mat.h:1306
TH_CONSTEXPR unsigned int rows() const
Get the number of rows in the matrix.
Definition: mat.h:1455
mat< Type > mul(const mat< Type > &B) const
Transform a vector by the matrix.
Definition: mat.h:1190
mat< Type > operator*(Type scalar) const
Multiplies the matrix by a scalar.
Definition: mat.h:1088
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:1872
Container< Container< Type > > data
Dynamically allocated array of the elements.
Definition: mat.h:946
Vector transform(const Vector &v) const
Transforms a vector by multiplying it with the matrix.
Definition: mat.h:1139
unsigned int size() const
Get the total number of elements of the matrix (rows * columns)
Definition: mat.h:1470
mat< Type > operator+(const Matrix &other) const
Adds two matrices element-wise.
Definition: mat.h:1066
mat< Type > & invert()
Invert a generic square matrix.
Definition: mat.h:1594
auto end()
Get an iterator to one past the last element of the matrix.
Definition: mat.h:1428
static mat< Type > rotation_2d(real theta)
Get a matrix which rotates the 2D plane by theta radians.
Definition: mat.h:1729
Type & at(unsigned int i, unsigned int j)
Access a modifiable element at a specific row and column.
Definition: mat.h:1338
static mat< Type > diagonal(Type diag, unsigned int row_sz, unsigned int col_sz)
Get a diagonal matrix with a specified diagonal value.
Definition: mat.h:1711
const Type & at(unsigned int i, unsigned int j) const
Access a constant element at a specific row and column.
Definition: mat.h:1354
auto begin()
Get an iterator to the first element of the matrix.
Definition: mat.h:1417
friend mat< Type > operator*(Type a, const mat< Type > &B)
Friend operator to enable equations of the form (T) * (mat)
Definition: mat.h:1099
mat< Type > & operator+=(const Matrix &other)
Matrix addition with another matrix.
Definition: mat.h:1252
mat()
Default constructor.
Definition: mat.h:956
mat< Type > & operator*=(Type scalar)
Scalar multiplication of the matrix.
Definition: mat.h:1276
std::string to_string(std::string separator=", ", bool parenthesis=true) const
Convert the matrix to string representation.
Definition: mat.h:1836
void make_zeroes()
Sets all elements in the matrix to zero.
Definition: mat.h:1044
static mat< Type > symplectic(unsigned int rows, unsigned int cols)
A symplectic NxN matrix, where for some natural K.
Definition: mat.h:1826
mat< Type > inverse() const
Compute the inverse of a generic square matrix.
Definition: mat.h:1585
static mat< Type > ortho(real left, real right, real bottom, real top, real near, real far)
Get an orthographic projection matrix.
Definition: mat.h:1803
mat< Type > & operator/=(Type scalar)
Scalar division of the matrix.
Definition: mat.h:1287
mat< Type > operator-(const Matrix &other) const
Subtracts another matrix element-wise.
Definition: mat.h:1078
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:1547
mat< Type > transposed() const
Return a transposed copy of the current matrix.
Definition: mat.h:1327
static mat< Type > perspective(real left, real right, real bottom, real top, real near, real far)
Get a perspective projection matrix.
Definition: mat.h:1775
Matrix mul(const Matrix &B) const
Multiplies the matrix by another matrix of any compatible type.
Definition: mat.h:1217
auto begin() const
Get a const iterator to the first element of the matrix.
Definition: mat.h:1438
~mat()
Destructor that deallocates memory and resets matrix size.
Definition: mat.h:1037
Type det() const
Compute the determinant of the matrix.
Definition: mat.h:1575
Type get(unsigned int i, unsigned int j) const
Get a copy of the element at a specific row and column.
Definition: mat.h:1394
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:1534
A sequential iterator for matrices.
Definition: mat.h:34
mat_iterator(Matrix &matrix, size_t row=0, size_t col=0)
Constructs an iterator for a matrix, optionally starting at a specified row and column.
Definition: mat.h:63
size_t col_index()
Retrieves the current column index of the iterator.
Definition: mat.h:106
bool operator!=(const mat_iterator &other) const
Inequality operator to compare two iterators.
Definition: mat.h:123
ReturnType operator*()
Dereferences the iterator to access the current matrix element.
Definition: mat.h:74
bool operator==(const mat_iterator &other) const
Equality operator to compare two iterators.
Definition: mat.h:114
mat_iterator & operator++()
Advances the iterator to the next element in row-major order.
Definition: mat.h:84
size_t row_index()
Retrieves the current row index of the iterator.
Definition: mat.h:99
A generic matrix with a fixed number of rows and columns.
Definition: mat.h:136
static mat< Type, N, K > rotation_3d_zaxis(real theta)
Returns a matrix for 3D rotation around the z-axis.
Definition: mat.h:785
static mat< Type, N, K > rotation_2d(real theta)
Returns a matrix for 2D rotation by theta radians.
Definition: mat.h:758
std::string to_string(std::string separator=", ", bool parenthesis=true) const
Converts the matrix to a string representation.
Definition: mat.h:882
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:716
bool is_symmetric() const
Checks if the matrix is symmetric.
Definition: mat.h:636
static mat< Type, N, K > perspective_fov(real fov, real aspect, real near, real far)
Returns a perspective projection matrix based on field of view.
Definition: mat.h:827
mat< Type, N, K > & invert()
Inverts the matrix in place.
Definition: mat.h:705
bool operator!=(const Matrix &other) const
Checks whether this matrix is not equal to another matrix element-wise.
Definition: mat.h:615
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:858
Type & operator()(unsigned int i, unsigned int j)
Overloads the () operator to access an element.
Definition: mat.h:515
static mat< Type, N, K > zeroes()
Returns a null matrix with all elements set to zero.
Definition: mat.h:240
bool is_diagonal() const
Checks if the matrix is diagonal.
Definition: mat.h:629
void make_zeroes()
Sets all elements of the matrix to zero.
Definition: mat.h:233
auto end() const
Returns a const iterator to one past the last element of the matrix.
Definition: mat.h:574
mat< Type, N, K > inverse() const
Computes the inverse of the matrix.
Definition: mat.h:695
mat_iterator< mat< Type, N, K >, Type & > iterator
Iterator for statically allocated matrices.
Definition: mat.h:544
friend std::ostream & operator<<(std::ostream &out, const mat< Type, N, K > &obj)
Outputs the matrix to an output stream in string format.
Definition: mat.h:921
Type get(unsigned int i, unsigned int j) const
Gets the element at the specified row and column.
Definition: mat.h:533
Type trace()
Computes the trace of the matrix.
Definition: mat.h:669
static mat< Type, N, K > translation(Vector &&t)
Returns a 4x4 matrix for translation by the vector {x, y, z}.
Definition: mat.h:750
mat< Type, N, K > & operator+=(const Matrix &other)
Matrix addition.
Definition: mat.h:415
mat< Type, N, K > operator/(Type scalar) const
Scalar division.
Definition: mat.h:305
mat(const std::initializer_list< std::initializer_list< T >> &rows)
Constructs a matrix from an initializer list.
Definition: mat.h:172
mat< Type, N, M > mul(const mat< Type, K, M > &B) const
Matrix multiplication for matrices with different column counts.
Definition: mat.h:361
bool is_square() const
Checks if the matrix is square.
Definition: mat.h:622
friend vec< VecType, K > operator*(const vec< VecType, M > &a, const mat< Type, N, K > &B)
Friend operator for vector-matrix multiplication.
Definition: mat.h:294
mat< Type, N, K > & operator=(const Matrix &other)
Assignment operator to copy from another matrix.
Definition: mat.h:227
Type diagonal_product()
Computes the product of the diagonal elements.
Definition: mat.h:676
static mat< Type, N, K > ortho(real left, real right, real bottom, real top, real near, real far)
Returns an orthographic projection matrix.
Definition: mat.h:843
TH_CONSTEXPR unsigned int rows() const
Returns the number of rows in the matrix.
Definition: mat.h:581
mat(Type diagonal, unsigned int n=0, unsigned int k=0)
Constructor that initializes a diagonal matrix with equal entries on the diagonal.
Definition: mat.h:209
const Type & at(unsigned int i, unsigned int j) const
Accesses the element at the given row and column.
Definition: mat.h:501
mat_iterator< const mat< Type, N, K >, const Type & > const_iterator
Const iterator for statically allocated matrices.
Definition: mat.h:548
unsigned int size() const
Returns the total number of elements in the matrix.
Definition: mat.h:595
TH_CONSTEXPR unsigned int cols() const
Returns the number of columns in the matrix.
Definition: mat.h:588
static mat< Type, N, K > rotation_3d(real theta, Vector &&axis)
Returns a matrix for 3D rotation around an arbitrary axis.
Definition: mat.h:797
mat()
Default constructor.
Definition: mat.h:149
auto end()
Returns an iterator to one past the last element of the matrix.
Definition: mat.h:560
const Type & operator()(unsigned int i, unsigned int j) const
Overloads the () operator to access an element.
Definition: mat.h:524
static mat< Type, N, K > perspective(real left, real right, real bottom, real top, real near, real far)
Returns a perspective projection matrix.
Definition: mat.h:811
auto begin() const
Returns a const iterator to the first element of the matrix.
Definition: mat.h:567
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:649
static mat< Type, N, K > rotation_3d_yaxis(real theta)
Returns a matrix for 3D rotation around the y-axis.
Definition: mat.h:776
mat(const Matrix &m)
Copy constructor.
Definition: mat.h:160
static mat< Type, N, K > rotation_3d_xaxis(real theta)
Returns a matrix for 3D rotation around the x-axis.
Definition: mat.h:767
auto operator*(const Matrix &B) const
Overloads the * operator for matrix multiplication.
Definition: mat.h:395
Vector transform(const Vector &v) const
Transforms a vector by multiplying it with the matrix.
Definition: mat.h:326
Matrix mul(const Matrix &B) const
Matrix multiplication for matrices with any type.
Definition: mat.h:375
bool operator==(const Matrix &other) const
Checks whether this matrix is equal to another matrix element-wise.
Definition: mat.h:605
mat< Type, N, K > & operator*=(Type scalar)
Scalar multiplication.
Definition: mat.h:433
Type & at(unsigned int i, unsigned int j)
Accesses the element at the given row and column.
Definition: mat.h:487
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:662
static mat< Type, N, K > diagonal(Type diag)
Returns a diagonal matrix with the specified diagonal element.
Definition: mat.h:741
mat< Type, K, N > transposed() const
Returns a transposed version of the matrix.
Definition: mat.h:478
mat< Type, N, K > & operator/=(Type scalar)
Scalar division.
Definition: mat.h:443
Type det() const
Computes the determinant of the matrix.
Definition: mat.h:685
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:868
mat< Type, N, K > & operator*=(const Matrix &B)
Matrix multiplication with an assignment operator.
Definition: mat.h:459
static mat< Type, N, K > identity()
Returns the identity matrix.
Definition: mat.h:733
mat< Type, N, K > & operator-=(const Matrix &other)
Matrix subtraction.
Definition: mat.h:425
vec< Type, N > transform(const vec< Type, K > &v) const
Transforms a fixed-size vector by multiplying it with the matrix.
Definition: mat.h:343
mat< Type, N, K > operator+(const Matrix &other) const
Matrix addition.
Definition: mat.h:252
mat< Type, N, K > operator*(Type scalar) const
Scalar multiplication.
Definition: mat.h:272
mat< Type, N, K > & transpose()
Transposes the matrix in place.
Definition: mat.h:469
friend mat< Type, N, K > operator*(Type a, const mat< Type, N, K > &B)
Friend operator for scalar multiplication (T * mat).
Definition: mat.h:282
mat< Type, N, K > operator-(const Matrix &other) const
Matrix subtraction.
Definition: mat.h:263
vec< Type, N > operator*(const vec< Type, K > &v) const
Overloads the * operator to transform a fixed-size vector by the matrix.
Definition: mat.h:351
auto begin()
Returns an iterator to the first element of the matrix.
Definition: mat.h:553
A statically allocated N-dimensional vector with elements of the given type.
Definition: vec.h:92
#define TH_CONSTEXPR
Enable constexpr in function declarations if C++14 is supported.
Definition: constants.h:161
#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
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:198
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:198
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:207
constexpr real E
The Euler mathematical constant (e)
Definition: constants.h:237
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.