Theoretica
Scientific Computing
Loading...
Searching...
No Matches
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
25namespace theoretica {
26
27
33 template<typename Matrix, typename ReturnType = matrix_element_t<Matrix>&>
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
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 elements[N][K];
141#else
142 Type elements[K][N];
143#endif
144
145
149 mat() {
150 algebra::mat_zeroes(*this);
151 }
152
153
159 template<typename Matrix, enable_matrix<Matrix> = true>
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(), MathError::InvalidArgument);
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(), MathError::InvalidArgument);
187 algebra::mat_error(*this);
188 return;
189 }
190
191 for (const auto& x : row) {
192
193 get(i, j) = x;
194 j = (j + 1) % K;
195 }
196
197 i++;
198 }
199 }
200
201
209 mat(Type diagonal, unsigned int n, unsigned int k) {
210
211 if (n && k)
212 resize(n, k);
213
214 if (n != rows() && k != cols()) {
216 return;
217 }
218
219 algebra::mat_zeroes(*this);
220 const unsigned int m = min(rows(), cols());
221
222 for (unsigned int i = 0; i < m; ++i)
223 get(i, i) = diagonal;
224 }
225
226
230 mat(Type diagonal) {
231
232 algebra::mat_zeroes(*this);
233 const unsigned int m = min(rows(), cols());
234
235 for (unsigned int i = 0; i < m; ++i)
236 get(i, i) = diagonal;
237 }
238
239
247 template<typename Vector, enable_vector<Vector> = true>
248 mat(const Vector& v, unsigned int row_size = N, unsigned int col_size = K) {
249
250 if(row_size != N || col_size != K) {
252 algebra::mat_error(*this);
253 return;
254 }
255
256 if(v.size() != size()) {
257 TH_MATH_ERROR("mat::mat", v.size(), MathError::InvalidArgument);
258 algebra::mat_error(*this);
259 return;
260 }
261
262 for (size_t i = 0; i < rows(); i++)
263 for (size_t j = 0; j < cols(); j++)
264 get(i, j) = v[i * cols() + j];
265 }
266
267
272 template<typename Matrix>
274 return algebra::mat_copy(*this, other);
275 }
276
277
282 template<typename Matrix>
283 inline mat<Type, N, K> operator+(const Matrix& other) const {
285 return algebra::mat_sum(res, *this, other);
286 }
287
288
293 template<typename Matrix>
294 inline mat<Type, N, K> operator-(const Matrix& other) const {
296 return algebra::mat_diff(res, *this, other);
297 }
298
299
305 return algebra::mat_scalmul(res, scalar, *this);
306 }
307
308
313 inline friend mat<Type, N, K> operator*(Type a, const mat<Type, N, K>& B) {
314 return B * a;
315 }
316
317
324 template<typename VecType, unsigned int M>
326 const vec<VecType, M>& v, const mat<Type, N, K>& A) {
327 return algebra::vec_mat_mul<vec<VecType, K>>(v, A);
328 }
329
330
337
339
340 if(abs(scalar) < MACH_EPSILON) {
341 TH_MATH_ERROR("mat::operator/", scalar, MathError::DivByZero);
342 return algebra::mat_error(res);
343 }
344
345 return algebra::mat_scalmul(res, 1.0 / scalar, *this);
346 }
347
348
356 template<typename Vector, enable_vector<Vector> = true>
357 inline Vector transform(const Vector& v) const {
358
359 if(v.size() != cols()) {
360 TH_MATH_ERROR("mat::transform", v.size(), MathError::InvalidArgument);
361 Vector res;
362 res.resize(cols());
364 return res;
365 }
366
367 return algebra::transform(*this, v);
368 }
369
370
374 inline vec<Type, N> transform(const vec<Type, K>& v) const {
375
377 return algebra::transform(res, *this, v);
378 }
379
380
384 inline vec<Type, N> operator*(const vec<Type, K>& v) const {
385 return transform(v);
386 }
387
388
393 template<unsigned int M>
394 inline mat<Type, N, M> mul(const mat<Type, K, M>& B) const {
396 return algebra::mat_mul(res, *this, B);
397 }
398
399
407 template<typename Matrix, enable_matrix<Matrix> = true>
408 inline Matrix mul(const Matrix& B) const {
409
410 Matrix res;
411 res.resize(N, B.cols());
412
413 if(B.rows() != K) {
414 TH_MATH_ERROR("mat::transform", B.rows(), MathError::InvalidArgument);
416 return res;
417 }
418
419 return algebra::mat_mul(res, *this, B);
420 }
421
422
427 template<typename Matrix, enable_matrix<Matrix> = true>
428 inline auto operator*(const Matrix& B) const {
429
430 Matrix res;
431 res.resize(N, B.cols());
432
433 if(B.rows() != K) {
434 TH_MATH_ERROR("mat::transform", B.rows(), MathError::InvalidArgument);
436 return res;
437 }
438
439 return algebra::mat_mul(res, *this, B);
440 }
441
442
447 template<typename Matrix>
449 return algebra::mat_sum(*this, other);
450 }
451
452
457 template<typename Matrix>
459 return algebra::mat_diff(*this, other);
460 }
461
462
467 return algebra::mat_scalmul(scalar, *this);
468 }
469
470
477
478 if(abs(scalar) < MACH_EPSILON) {
479 TH_MATH_ERROR("mat::operator/", scalar, MathError::DivByZero);
480 return algebra::mat_error(*this);
481 }
482
483 return algebra::mat_scalmul(1.0 / scalar, *this);
484 }
485
486
491 template<typename Matrix>
493 return (*this = this->operator*(B));
494 }
495
496
503 static_assert(
504 N == K, "The matrix must be square to be transposed in place.");
505 return algebra::make_transposed(*this);
506 }
507
508
514 inline Type& get(unsigned int i, unsigned int j) {
515
516#ifdef THEORETICA_ROW_FIRST
517 return elements[i][j];
518#else
519 return elements[j][i];
520#endif
521 }
522
523
529 inline const Type& get(unsigned int i, unsigned int j) const {
530
531#ifdef THEORETICA_ROW_FIRST
532 return elements[i][j];
533#else
534 return elements[j][i];
535#endif
536 }
537
538
544 inline Type& at(unsigned int i, unsigned int j) {
545
546 if (i >= rows()) {
547 throw std::out_of_range(
548 "The provided row index in mat::at() is out of range"
549 );
550 }
551
552 if (j >= cols()) {
553 throw std::out_of_range(
554 "The provided column index in mat::at() is out of range"
555 );
556 }
557
558 return get(i, j);
559 }
560
561
567 inline const Type& at(unsigned int i, unsigned int j) const {
568
569 if (i >= rows()) {
570 throw std::out_of_range(
571 "The provided row index in mat::at() is out of range"
572 );
573 }
574
575 if (j >= cols()) {
576 throw std::out_of_range(
577 "The provided column index in mat::at() is out of range"
578 );
579 }
580
581 return get(i, j);
582 }
583
584
589 inline Type& operator()(unsigned int i, unsigned int j) {
590 return get(i, j);
591 }
592
593
598 inline const Type& operator()(unsigned int i, unsigned int j) const {
599 return get(i, j);
600 }
601
602
605
606
609
610
613 inline auto begin() {
614 return iterator(*this, 0, 0);
615 }
616
617
620 inline auto end() {
621 return iterator(*this, rows(), 0);
622 }
623
624
627 inline auto begin() const {
628 return const_iterator(*this, 0, 0);
629 }
630
631
634 inline auto end() const {
635 return const_iterator(*this, rows(), 0);
636 }
637
638
641 TH_CONSTEXPR inline unsigned int rows() const {
642 return N;
643 }
644
645
648 TH_CONSTEXPR inline unsigned int cols() const {
649 return K;
650 }
651
652
655 inline unsigned int size() const {
656 return N * K;
657 }
658
659
661 inline Type* data() {
662 return (Type*) elements;
663 }
664
665
667 inline const Type* data() const {
668 return (const Type*) elements;
669 }
670
671
676 template<typename Vector = vec<Type, N * K>>
677 inline Vector unpack() const {
678
679 Vector res;
680 res.resize(size());
681
682 if (res.size() != size()) {
683 TH_MATH_ERROR("mat::unpack", res.size(), MathError::InvalidArgument);
684 return algebra::vec_error(res);
685 }
686
687 for (size_t i = 0; i < rows(); i++)
688 for (size_t j = 0; j < cols(); j++)
689 res[i * cols() + j] = get(i, j);
690
691 return res;
692 }
693
694
699 template<typename Matrix>
700 inline bool operator==(const Matrix& other) const {
701 return algebra::mat_equals(*this, other);
702 }
703
704
709 template<typename Matrix>
710 inline bool operator!=(const Matrix& other) const {
711 return !algebra::mat_equals(*this, other);
712 }
713
714
720 static_assert(N == K, "The matrix must be square to be invertible.");
721 return algebra::invert(*this);
722 }
723
724
730 inline mat<Type, N, K> resize(unsigned int n, unsigned int k) {
731
732 if(rows() != n) {
734 algebra::mat_error(*this);
735 } else if(cols() != k) {
737 algebra::mat_error(*this);
738 }
739
740 return *this;
741 }
742
743
744#ifndef THEORETICA_NO_PRINT
745
750 inline std::string to_string(
751 std::string separator = ", ", bool parenthesis = true) const {
752
753 std::stringstream res;
754
755 for (unsigned int i = 0; i < rows(); ++i) {
756
757 if(parenthesis)
758 res << "(";
759
760 for (unsigned int j = 0; j < cols(); ++j) {
761
762 if(j)
763 res << separator;
764
765 if(abs(get(i, j)) < MACH_EPSILON)
766 res << "0";
767 else
768 res << get(i, j);
769 }
770
771 if(parenthesis)
772 res << ")" << std::endl;
773 }
774
775 return res.str();
776 }
777
778
780 inline operator std::string() {
781 return to_string();
782 }
783
784
789 inline friend std::ostream& operator<<(
790 std::ostream& out, const mat<Type, N, K>& obj) {
791 return out << obj.to_string();
792 }
793
794#endif
795
796 };
797
798
799
805 template<typename Type>
806 class mat<Type, 0, 0> {
807 public:
808
810 std::vector<Type> elements;
811
813 size_t row_sz {0};
814
816 size_t col_sz {0};
817
818
820 mat() : row_sz(0), col_sz(0) {}
821
822
826 mat(unsigned int n, unsigned int k) {
827 resize(n, k);
828 algebra::mat_zeroes(*this);
829 }
830
831
835 template <typename Matrix, enable_matrix<Matrix>>
836 mat(const Matrix& m) {
837 algebra::mat_copy(*this, m);
838 }
839
840
844 template<typename T = Type>
845 inline mat(const std::initializer_list<std::initializer_list<T>>& rows) {
846
847 unsigned int i = 0;
848 unsigned int j = 0;
849
850 for (const auto& row : rows) {
851
852 for (const auto& x : row) {
853
854 if (!i && !j) {
855 this->resize(rows.size(), row.size());
856 }
857 else if (row.size() != col_sz) {
858 TH_MATH_ERROR("mat::mat", row.size(), MathError::InvalidArgument);
859 algebra::mat_error(*this);
860 return;
861 }
862
863 get(i, j) = x;
864 j = (j + 1) % col_sz;
865 }
866
867 i++;
868 }
869 }
870
871
875 template<typename Matrix>
876 inline mat<Type>& operator=(const Matrix& other) {
877 resize(other.rows(), other.cols());
878 return algebra::mat_copy(*this, other);
879 }
880
881
886 mat(Type diagonal, unsigned int n, unsigned int k) {
887
888 resize(n, k);
889 algebra::mat_zeroes(*this);
890 const unsigned int m = min(n, k);
891
892 for (unsigned int i = 0; i < m; ++i)
893 get(i, i) = diagonal;
894 }
895
896
904 template<typename Vector, enable_vector<Vector> = true>
905 mat(const Vector& v, unsigned int row_size, unsigned int col_size) {
906
908
909 if(v.size() != size()) {
910 TH_MATH_ERROR("mat::mat", v.size(), MathError::InvalidArgument);
911 algebra::mat_error(*this);
912 return;
913 }
914
915 for (size_t i = 0; i < rows(); i++)
916 for (size_t j = 0; j < cols(); j++)
917 get(i, j) = v[i * cols() + j];
918 }
919
920
923 row_sz = 0;
924 col_sz = 0;
925 }
926
927
929 inline void make_zeroes() {
930 algebra::mat_zeroes(*this);
931 }
932
933
938 template<typename Matrix>
939 inline mat<Type> operator+(const Matrix& other) const {
941 res.resize(rows(), cols());
942 return algebra::mat_sum(res, *this, other);
943 }
944
945
950 template<typename Matrix>
951 inline mat<Type> operator-(const Matrix& other) const {
953 res.resize(rows(), cols());
954 return algebra::mat_diff(res, *this, other);
955 }
956
957
963 res.resize(rows(), cols());
964 return algebra::mat_scalmul(res, scalar, *this);
965 }
966
967
972 inline friend mat<Type> operator*(Type a, const mat<Type>& B) {
973 return B * a;
974 }
975
976
983 template<typename VecType, unsigned int M>
984 inline friend vec<VecType> operator*(
985 const vec<VecType, M>& v, const mat<Type, 0, 0>& A) {
986 return algebra::vec_mat_mul<vec<VecType>>(v, A);
987 }
988
989
994
996 res.resize(rows(), cols());
997
998 if(abs(scalar) < MACH_EPSILON) {
999 TH_MATH_ERROR("mat::operator/", scalar, MathError::DivByZero);
1000 return algebra::mat_error(res);
1001 }
1002
1003 return algebra::mat_scalmul(res, 1.0 / scalar, *this);
1004 }
1005
1006
1011 template<typename Vector, enable_vector<Vector> = true>
1012 inline Vector transform(const Vector& v) const {
1013
1014 if(v.size() != rows()) {
1015 TH_MATH_ERROR("mat::transform", v.size(), MathError::InvalidArgument);
1016 Vector res;
1017 res.resize(rows());
1018 return algebra::vec_error(res);
1019 }
1020
1021 return algebra::transform(*this, v);
1022 }
1023
1024
1029 template<unsigned int N = 0, unsigned int K = 0>
1030 inline vec<Type, N> transform(const vec<Type, K>& v) const {
1031
1033 res.resize(rows());
1034
1035 return algebra::transform(res, *this, v);
1036 }
1037
1038
1043 template<unsigned int N = 0, unsigned int K = 0>
1044 inline vec<Type, N> operator*(const vec<Type, K>& v) const {
1045 return transform(v);
1046 }
1047
1048
1050 // inline vec<Type> operator*(const vec<Type>& v) const {
1051 // return transform(v);
1052 // }
1053
1054
1066 inline mat<Type> mul(const mat<Type>& B) const {
1067
1068 mat<Type> res;
1069 res.resize(rows(), B.cols());
1070
1071 if(B.rows() != cols()) {
1074 return res;
1075 }
1076
1077 return algebra::mat_mul(res, *this, B);
1078 }
1079
1080
1092 template<typename Matrix, enable_matrix<Matrix> = true>
1093 inline Matrix mul(const Matrix& B) const {
1094
1095 Matrix res;
1096 res.resize(rows(), B.cols());
1097
1098 if(B.rows() != cols()) {
1099 TH_MATH_ERROR("mat::mul", B.rows(), MathError::InvalidArgument);
1101 return res;
1102 }
1103
1104 return algebra::mat_mul(res, *this, B);
1105 }
1106
1107
1114 template<typename Matrix>
1115 inline auto operator*(const Matrix& B) const {
1116 return mul(B);
1117 }
1118
1119
1127 template<typename Matrix>
1129 return algebra::mat_sum(*this, other);
1130 }
1131
1132
1140 template<typename Matrix>
1142 return algebra::mat_diff(*this, other);
1143 }
1144
1145
1153 return algebra::mat_scalmul(scalar, *this);
1154 }
1155
1156
1164
1165 if(abs(scalar) < MACH_EPSILON) {
1166 TH_MATH_ERROR("mat::operator/", scalar, MathError::DivByZero);
1167 return algebra::mat_error(*this);
1168 }
1169
1170 return algebra::mat_scalmul(1.0 / scalar, *this);
1171 }
1172
1173
1181 template<typename Matrix>
1182 inline mat<Type>& operator*=(const Matrix& B) {
1183 return (*this = this->operator*(B));
1184 }
1185
1186
1190
1191 mat<Type> res;
1192 res.resize(cols(), rows());
1193
1194 for (size_t i = 0; i < rows(); i++)
1195 for (size_t j = 0; j < cols(); j++)
1196 res(j, i) = get(i, j);
1197
1198 return (*this = res);
1199 }
1200
1201
1207 inline Type& get(unsigned int i, unsigned int j) {
1208
1209#ifdef THEORETICA_ROW_FIRST
1210 return elements[j + i * col_sz];
1211#else
1212 return elements[i + j * row_sz];
1213#endif
1214 }
1215
1216
1222 inline const Type& get(unsigned int i, unsigned int j) const {
1223
1224#ifdef THEORETICA_ROW_FIRST
1225 return elements[j + i * col_sz];
1226#else
1227 return elements[i + j * row_sz];
1228#endif
1229 }
1230
1231
1238 inline Type& at(unsigned int i, unsigned int j) {
1239
1240 if (i >= rows()) {
1241 throw std::out_of_range(
1242 "The provided row index in mat::at() is out of range"
1243 );
1244 }
1245
1246 if (j >= cols()) {
1247 throw std::out_of_range(
1248 "The provided column index in mat::at() is out of range"
1249 );
1250 }
1251
1252 return get(i, j);
1253 }
1254
1255
1262 inline const Type& at(unsigned int i, unsigned int j) const {
1263
1264 if (i >= rows()) {
1265 throw std::out_of_range(
1266 "The provided row index in mat::at() is out of range"
1267 );
1268 }
1269
1270 if (j >= cols()) {
1271 throw std::out_of_range(
1272 "The provided column index in mat::at() is out of range"
1273 );
1274 }
1275
1276 return get(i, j);
1277 }
1278
1279
1287 inline Type& operator()(unsigned int i, unsigned int j) {
1288 return get(i, j);
1289 }
1290
1291
1299 inline const Type& operator()(unsigned int i, unsigned int j) const {
1300 return get(i, j);
1301 }
1302
1303
1306
1307
1310
1311
1317 inline auto begin() {
1318 return iterator(*this, 0, 0);
1319 }
1320
1321
1328 inline auto end() {
1329 return iterator(*this, rows(), 0);
1330 }
1331
1332
1338 inline auto begin() const {
1339 return const_iterator(*this, 0, 0);
1340 }
1341
1342
1348 inline auto end() const {
1349 return const_iterator(*this, rows(), 0);
1350 }
1351
1352
1355 TH_CONSTEXPR inline unsigned int rows() const {
1356 return row_sz;
1357 }
1358
1359
1362 TH_CONSTEXPR inline unsigned int cols() const {
1363 return col_sz;
1364 }
1365
1366
1369 inline unsigned int size() const {
1370 return rows() * cols();
1371 }
1372
1373
1375 inline Type* data() {
1376 return elements.data();
1377 }
1378
1379
1381 inline const Type* data() const {
1382 return elements.data();
1383 }
1384
1385
1390 template<typename Vector = vec<Type>>
1391 inline Vector unpack() const {
1392
1393 Vector res;
1394 res.resize(size());
1395
1396 if (res.size() != size()) {
1397 TH_MATH_ERROR("mat::unpack", res.size(), MathError::InvalidArgument);
1398 return algebra::vec_error(res);
1399 }
1400
1401 for (size_t i = 0; i < rows(); i++)
1402 for (size_t j = 0; j < cols(); j++)
1403 res[i * cols() + j] = get(i, j);
1404
1405 return res;
1406 }
1407
1408
1415 template<typename Matrix>
1416 inline bool operator==(const Matrix& other) const {
1417 return algebra::mat_equals(*this, other);
1418 }
1419
1420
1427 template<typename Matrix>
1428 inline bool operator!=(const Matrix& other) const {
1429 return !algebra::mat_equals(*this, other);
1430 }
1431
1432
1437 inline mat<Type>& invert() {
1438 return algebra::invert(*this);
1439 }
1440
1441
1445 inline mat<Type>& resize(unsigned int rows, unsigned int cols) {
1446
1447 // Do nothing if the size is already correct
1448 if (row_sz == rows && col_sz == cols)
1449 return *this;
1450
1451 std::vector<Type> new_data (uint64_t(rows) * cols);
1452
1453 if (elements.size()) {
1454
1455 size_t min_elements = min(rows, row_sz) * min(cols, col_sz);
1456
1457 // Copy the overlapping elements
1458 for (unsigned int i = 0; i < min_elements; ++i)
1459 new_data[i] = elements[i];
1460 }
1461
1462 elements = new_data;
1463 row_sz = rows;
1464 col_sz = cols;
1465
1466 return *this;
1467 }
1468
1469
1470#ifndef THEORETICA_NO_PRINT
1471
1473 inline std::string to_string(
1474 std::string separator = ", ", bool parenthesis = true) const {
1475
1476 std::stringstream res;
1477
1478 for (unsigned int i = 0; i < rows(); ++i) {
1479
1480 if(parenthesis)
1481 res << "(";
1482
1483 for (unsigned int j = 0; j < cols(); ++j) {
1484
1485 if(j)
1486 res << separator;
1487
1488 if(abs(get(i, j)) < MACH_EPSILON)
1489 res << "0";
1490 else
1491 res << get(i, j);
1492 }
1493
1494 if(parenthesis)
1495 res << ")" << std::endl;
1496 }
1497
1498 return res.str();
1499 }
1500
1501
1503 inline operator std::string() {
1504 return to_string();
1505 }
1506
1507
1509 inline friend std::ostream& operator<<(
1510 std::ostream& out, const mat<Type>& obj) {
1511 return out << obj.to_string();
1512 }
1513
1514#endif
1515
1516 };
1517
1518}
1519
1520#endif
Linear algebra routines.
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:1509
mat< Type > operator-(const Matrix &other) const
Subtracts another matrix element-wise.
Definition mat.h:951
Vector unpack() const
Unpack the matrix elements into a vector.
Definition mat.h:1391
auto operator*(const Matrix &B) const
Matrix multiplication with any matrix type.
Definition mat.h:1115
mat(unsigned int n, unsigned int k)
Constructor that initializes a matrix with the specified number of rows and columns.
Definition mat.h:826
mat< Type > & invert()
Invert a generic square matrix.
Definition mat.h:1437
mat(const Vector &v, unsigned int row_size, unsigned int col_size)
Constructor that initializes a matrix from a vector in row-major order.
Definition mat.h:905
mat< Type > operator/(Type scalar) const
Divides each element in the matrix by a scalar.
Definition mat.h:993
bool operator==(const Matrix &other) const
Check if two matrices are equal element by element.
Definition mat.h:1416
mat< Type > & operator/=(Type scalar)
Scalar division of the matrix.
Definition mat.h:1163
mat< Type > & operator+=(const Matrix &other)
Matrix addition with another matrix.
Definition mat.h:1128
mat(Type diagonal, unsigned int n, unsigned int k)
Constructor that initializes a diagonal matrix with equal entries on the diagonal.
Definition mat.h:886
vec< Type, N > transform(const vec< Type, K > &v) const
Transforms a vector by multiplying it with the matrix.
Definition mat.h:1030
Type * data()
Get a raw pointer to the underlying elements in memory.
Definition mat.h:1375
Type & at(unsigned int i, unsigned int j)
Access a modifiable element at a specific row and column.
Definition mat.h:1238
friend mat< Type > operator*(Type a, const mat< Type > &B)
Friend operator to enable equations of the form (T) * (mat)
Definition mat.h:972
bool operator!=(const Matrix &other) const
Check if two matrices are unequal element by element.
Definition mat.h:1428
mat< Type > & operator*=(const Matrix &B)
Matrix multiplication with any matrix type.
Definition mat.h:1182
const Type & at(unsigned int i, unsigned int j) const
Access a constant element at a specific row and column.
Definition mat.h:1262
mat(const std::initializer_list< std::initializer_list< T > > &rows)
Constructor that initializes a matrix from a list of rows.
Definition mat.h:845
mat(const Matrix &m)
Copy constructor for creating a matrix from another matrix.
Definition mat.h:836
mat< Type > & resize(unsigned int rows, unsigned int cols)
Set or change the size of the matrix.
Definition mat.h:1445
std::vector< Type > elements
Dynamically allocated array of the elements.
Definition mat.h:810
auto end() const
Get a const iterator to one past the last element of the matrix.
Definition mat.h:1348
TH_CONSTEXPR unsigned int cols() const
Get the number of columns in the matrix.
Definition mat.h:1362
TH_CONSTEXPR unsigned int rows() const
Get the number of rows in the matrix.
Definition mat.h:1355
friend vec< VecType > operator*(const vec< VecType, M > &v, const mat< Type, 0, 0 > &A)
Friend operator to enable equations of the form (vec) * (mat) (Enables vector-matrix multiplication....
Definition mat.h:984
Vector transform(const Vector &v) const
Transforms a vector by multiplying it with the matrix.
Definition mat.h:1012
unsigned int size() const
Get the total number of elements of the matrix, equal to (rows * columns).
Definition mat.h:1369
vec< Type, N > operator*(const vec< Type, K > &v) const
Transforms a vector by multiplying it with the matrix.
Definition mat.h:1044
Type & get(unsigned int i, unsigned int j)
Access the element at the given row and column, by reference.
Definition mat.h:1207
mat< Type > operator*(Type scalar) const
Multiplies the matrix by a scalar.
Definition mat.h:961
auto end()
Get an iterator to one past the last element of the matrix.
Definition mat.h:1328
mat< Type > & operator*=(Type scalar)
Scalar multiplication of the matrix.
Definition mat.h:1152
auto begin()
Get an iterator to the first element of the matrix.
Definition mat.h:1317
Matrix mul(const Matrix &B) const
Multiplies the matrix by another matrix of any compatible type.
Definition mat.h:1093
mat()
Default constructor.
Definition mat.h:820
const Type * data() const
Get a raw pointer to the underlying elements in memory.
Definition mat.h:1381
mat< Type > & transpose()
Transpose the current matrix in place.
Definition mat.h:1189
std::string to_string(std::string separator=", ", bool parenthesis=true) const
Convert the matrix to string representation.
Definition mat.h:1473
mat< Type > & operator-=(const Matrix &other)
Matrix subtraction with another matrix.
Definition mat.h:1141
void make_zeroes()
Sets all elements in the matrix to zero.
Definition mat.h:929
mat< Type > operator+(const Matrix &other) const
Adds two matrices element-wise.
Definition mat.h:939
mat< Type > & operator=(const Matrix &other)
Copy assignment operator for copying from another matrix.
Definition mat.h:876
mat< Type > mul(const mat< Type > &B) const
Transform a vector by the matrix.
Definition mat.h:1066
const Type & get(unsigned int i, unsigned int j) const
Get the element at the given row and column.
Definition mat.h:1222
auto begin() const
Get a const iterator to the first element of the matrix.
Definition mat.h:1338
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:1287
~mat()
Destructor that resets the matrix size.
Definition mat.h:922
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:1299
A sequential iterator for matrices.
Definition mat.h:34
mat_iterator & operator++()
Advances the iterator to the next element in row-major order.
Definition mat.h:84
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
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
mat< Type, N, K > operator+(const Matrix &other) const
Matrix addition.
Definition mat.h:283
mat< Type, N, K > & operator=(const Matrix &other)
Assignment operator to copy from another matrix.
Definition mat.h:273
mat< Type, N, M > mul(const mat< Type, K, M > &B) const
Matrix multiplication for matrices with different column counts.
Definition mat.h:394
std::string to_string(std::string separator=", ", bool parenthesis=true) const
Converts the matrix to a string representation.
Definition mat.h:750
mat< Type, N, K > operator*(Type scalar) const
Scalar multiplication.
Definition mat.h:303
const Type & get(unsigned int i, unsigned int j) const
Get the element at the given row and column.
Definition mat.h:529
mat(const std::initializer_list< std::initializer_list< T > > &rows)
Constructs a matrix from an initializer list.
Definition mat.h:172
Vector unpack() const
Unpack the matrix elements into a vector.
Definition mat.h:677
bool operator!=(const Matrix &other) const
Checks whether this matrix is not equal to another matrix element-wise.
Definition mat.h:710
mat< Type, N, K > operator-(const Matrix &other) const
Matrix subtraction.
Definition mat.h:294
auto end() const
Returns a const iterator to one past the last element of the matrix.
Definition mat.h:634
friend vec< VecType, K > operator*(const vec< VecType, M > &v, const mat< Type, N, K > &A)
Friend operator for vector-matrix multiplication.
Definition mat.h:325
mat_iterator< mat< Type, N, K >, Type & > iterator
Iterator for statically allocated matrices.
Definition mat.h:604
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:789
mat(const Vector &v, unsigned int row_size=N, unsigned int col_size=K)
Constructor that initializes a matrix from a vector in row-major order.
Definition mat.h:248
mat< Type, N, K > & invert()
Inverts the matrix in place.
Definition mat.h:719
Type * data()
Get a raw pointer to the underlying elements in memory.
Definition mat.h:661
vec< Type, N > transform(const vec< Type, K > &v) const
Transforms a fixed-size vector by multiplying it with the matrix.
Definition mat.h:374
Matrix mul(const Matrix &B) const
Matrix multiplication for matrices with any type.
Definition mat.h:408
Vector transform(const Vector &v) const
Transforms a vector by multiplying it with the matrix.
Definition mat.h:357
mat(Type diagonal)
Constructor that initializes a diagonal matrix with equal entries on the diagonal.
Definition mat.h:230
mat< Type, N, K > & operator/=(Type scalar)
Scalar division.
Definition mat.h:476
const Type * data() const
Get a raw pointer to the underlying elements in memory.
Definition mat.h:667
mat< Type, N, K > & operator*=(const Matrix &B)
Matrix multiplication with an assignment operator.
Definition mat.h:492
mat< Type, N, K > & transpose()
Transposes the matrix in place.
Definition mat.h:502
TH_CONSTEXPR unsigned int rows() const
Returns the number of rows in the matrix.
Definition mat.h:641
mat< Type, N, K > & operator*=(Type scalar)
Scalar multiplication.
Definition mat.h:466
Type & at(unsigned int i, unsigned int j)
Accesses the element at the given row and column with bound checking.
Definition mat.h:544
mat_iterator< const mat< Type, N, K >, const Type & > const_iterator
Const iterator for statically allocated matrices.
Definition mat.h:608
unsigned int size() const
Returns the total number of elements in the matrix.
Definition mat.h:655
Type & get(unsigned int i, unsigned int j)
Access the element at the given row and column, by reference.
Definition mat.h:514
TH_CONSTEXPR unsigned int cols() const
Returns the number of columns in the matrix.
Definition mat.h:648
auto operator*(const Matrix &B) const
Overloads the * operator for matrix multiplication.
Definition mat.h:428
mat< Type, N, K > & operator-=(const Matrix &other)
Matrix subtraction.
Definition mat.h:458
mat()
Default constructor.
Definition mat.h:149
auto end()
Returns an iterator to one past the last element of the matrix.
Definition mat.h:620
friend mat< Type, N, K > operator*(Type a, const mat< Type, N, K > &B)
Friend operator for scalar multiplication (T * mat).
Definition mat.h:313
auto begin() const
Returns a const iterator to the first element of the matrix.
Definition mat.h:627
mat< Type, N, K > & operator+=(const Matrix &other)
Matrix addition.
Definition mat.h:448
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:384
mat(Type diagonal, unsigned int n, unsigned int k)
Constructor that initializes a diagonal matrix with equal entries on the diagonal.
Definition mat.h:209
mat< Type, N, K > operator/(Type scalar) const
Scalar division.
Definition mat.h:336
bool operator==(const Matrix &other) const
Checks whether this matrix is equal to another matrix element-wise.
Definition mat.h:700
const Type & at(unsigned int i, unsigned int j) const
Accesses the element at the given row and column with bound checking.
Definition mat.h:567
mat< Type, N, K > resize(unsigned int n, unsigned int k)
Compatibility function to allow for allocation or resizing of dynamic matrices.
Definition mat.h:730
mat(const Matrix &m)
Copy constructor.
Definition mat.h:160
const Type & operator()(unsigned int i, unsigned int j) const
Overloads the () operator to access an element by value.
Definition mat.h:598
Type & operator()(unsigned int i, unsigned int j)
Overloads the () operator to access an element by reference.
Definition mat.h:589
auto begin()
Returns an iterator to the first element of the matrix.
Definition mat.h:613
A statically allocated N-dimensional vector with elements of the given type.
Definition vec.h:92
void resize(size_t n) const
Compatibility function to allow for allocation or resizing of dynamic vectors.
Definition vec.h:459
#define TH_CONSTEXPR
Enable constexpr in function declarations if C++14 is supported.
Definition constants.h:170
#define TH_MATH_ERROR(F_NAME, VALUE, EXCEPTION)
TH_MATH_ERROR is a macro which throws exceptions or modifies errno (depending on which compilation op...
Definition error.h:219
Matrix2 & mat_sum(Matrix1 &A, const Matrix2 &B)
Sum two matrices and store the result in the first matrix.
Definition algebra.h:858
Matrix & mat_scalmul(Field a, Matrix &m)
Multiply a matrix by a scalar of any compatible type.
Definition algebra.h:685
Matrix & invert(Matrix &m)
Invert the given matrix and overwrite it.
Definition algebra.h:2122
Matrix2 & mat_diff(Matrix1 &A, const Matrix2 &B)
Subtract two matrices and store the result in the first matrix.
Definition algebra.h:920
Vector transform(const Matrix &A, const Vector &v)
Returns the matrix transformation of a vector.
Definition algebra.h:799
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:40
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:1054
Matrix & mat_zeroes(Matrix &m)
Overwrite a matrix with all zeroes.
Definition algebra.h:181
Matrix1 & mat_copy(Matrix1 &dest, const Matrix2 &src)
Copy a matrix by overwriting another.
Definition algebra.h:213
Matrix & make_transposed(Matrix &m)
Transpose the given matrix.
Definition algebra.h:521
Vector & vec_error(Vector &v)
Overwrite the given vector with the error vector with NaN values.
Definition algebra.h:58
bool mat_equals(const Matrix1 &A, const Matrix2 &B, real tolerance=ALGEBRA_ELEMENT_TOL)
Checks whether two matrices are equal.
Definition algebra.h:1182
Main namespace of the library which contains all functions and objects.
Definition algebra.h:27
auto min(const Vector &X)
Finds the minimum value inside a dataset.
Definition dataset.h:347
dual2 abs(dual2 x)
Compute the absolute value of a second order dual number.
Definition dual2_functions.h:242
Vector make_error()
Create a vector representing an error state, with all NaN values.
Definition algebra.h:103
@ InvalidArgument
Invalid argument.
@ ImpossibleOperation
Mathematically impossible operation.
@ DivByZero
Division by zero.
constexpr real MACH_EPSILON
Machine epsilon for the real type.
Definition constants.h:216
Linear transformations such as rotations and projective geometry.
Vector class and operations.