Loading...
Searching...
No Matches
Matrix-Impl.hpp
Go to the documentation of this file.
1// This code is based on Jet framework.
2// Copyright (c) 2018 Doyub Kim
3// CubbyFlow is voxel-based fluid simulation engine for computer games.
4// Copyright (c) 2020 CubbyFlow Team
5// Core Part: Chris Ohk, Junwoo Hwang, Jihong Sin, Seungwoo Yoo
6// AI Part: Dongheon Cho, Minseo Kim
7// We are making my contributions/submissions to this project solely in our
8// personal capacity and are not conveying any rights to any intellectual
9// property of any third parties.
10
11#ifndef CUBBYFLOW_MATRIX_IMPL_HPP
12#define CUBBYFLOW_MATRIX_IMPL_HPP
13
15
16#include <numeric>
17
18namespace CubbyFlow
19{
20namespace Internal
21{
22// TODO: With C++17, fold expression could be used instead.
23template <typename M1, typename M2, size_t J>
25{
26 constexpr static auto call(const M1& a, const M2& b, size_t i, size_t j)
27 {
28 return DotProduct<M1, M2, J - 1>::call(a, b, i, j) + a(i, J) * b(J, j);
29 }
30};
31
32template <typename M1, typename M2>
33struct DotProduct<M1, M2, 0>
34{
35 constexpr static auto call(const M1& a, const M2& b, size_t i, size_t j)
36 {
37 return a(i, 0) * b(0, j);
38 }
39};
40
41// TODO: With C++17, fold expression could be used instead.
42template <typename T, size_t Rows, size_t Cols, typename ReduceOperation,
43 typename UnaryOperation, size_t I>
44struct Reduce
45{
46 // For vector-like Matrix
47 template <typename U = T>
48 constexpr static std::enable_if_t<(Cols == 1), U> Call(
51 {
52 return op(
54 a, init, op, uop),
55 uop(a(I, 0)));
56 }
57
58 // For vector-like Matrix with zero init
59 template <typename U = T>
60 constexpr static std::enable_if_t<(Cols == 1), U> Call(
62 {
63 return op(
65 a, op, uop),
66 uop(a(I, 0)));
67 }
68
69 // For Matrix
78
79 // For Matrix with zero init
88
89 // For diagonal elements on Matrix
90 constexpr static T CallDiag(const Matrix<T, Rows, Cols>& a, const T& init,
92 {
94 I - 1>::CallDiag(a, init, op, uop),
95 uop(a(I, I)));
96 }
97};
98
99template <typename T, size_t Rows, size_t Cols, typename ReduceOperation,
100 typename UnaryOperation>
102{
103 // For vector-like Matrix
104 template <typename U = T>
105 constexpr static std::enable_if_t<(Cols > 1), U> Call(
108 {
109 return op(uop(a(0, 0)), init);
110 }
112 // For vector-like Matrix with zero init
113 template <typename U = T>
114 constexpr static std::enable_if_t<(Cols == 1), U> Call(
116 {
117 return uop(a(0, 0));
118 }
120 // For Matrix
121 constexpr static T Call(const Matrix<T, Rows, Cols>& a, const T& init,
123 {
124 return op(uop(a[0]), init);
125 }
126
127 // For MatrixBase with zero init
128 constexpr static T Call(const Matrix<T, Rows, Cols>& a, ReduceOperation op,
130 {
131 return uop(a[0]);
132 }
133
134 // For diagonal elements on MatrixBase
135 constexpr static T CallDiag(const Matrix<T, Rows, Cols>& a, const T& init,
137 {
138 return op(uop(a(0, 0)), init);
139 }
140};
141
142// We can use std::logical_and<>, but explicitly putting && helps compiler
143// to early terminate the loop (at least for gcc 8.1 as I checked the
144// assembly).
145// TODO: With C++17, fold expression could be used instead.
146template <typename T, size_t Rows, size_t Cols, typename BinaryOperation,
147 size_t I>
149{
150 constexpr static bool Call(const Matrix<T, Rows, Cols>& a,
151 const Matrix<T, Rows, Cols>& b,
153 {
155 op) &&
156 op(a[I], b[I]);
157 }
158};
159
160template <typename T, size_t Rows, size_t Cols, typename BinaryOperation>
162{
163 constexpr static bool Call(const Matrix<T, Rows, Cols>& a,
164 const Matrix<T, Rows, Cols>& b,
166 {
167 return op(a[0], b[0]);
168 }
169};
170
171} // namespace Internal
172
173template <typename T, size_t Rows, size_t Cols>
178
179template <typename T, size_t Rows, size_t Cols>
180template <size_t R, size_t C, typename E>
187
188template <typename T, size_t Rows, size_t Cols>
190{
191 size_t i = 0;
192
193 for (auto rows : lst)
194 {
195 assert(i < Rows);
196
197 size_t j = 0;
198
199 for (auto col : rows)
200 {
201 assert(j < Cols);
202
203 (*this)(i, j) = col;
204 ++j;
205 }
206
207 ++i;
208 }
209}
210
211template <typename T, size_t Rows, size_t Cols>
213{
214 size_t cnt = 0;
215
216 for (size_t i = 0; i < Rows; ++i)
217 {
218 for (size_t j = 0; j < Cols; ++j)
219 {
220 (*this)(i, j) = ptr[cnt++];
221 }
222 }
223}
224
225template <typename T, size_t Rows, size_t Cols>
227{
228 m_elements.fill(val);
229}
230
231template <typename T, size_t Rows, size_t Cols>
232void Matrix<T, Rows, Cols>::Fill(const std::function<T(size_t i)>& func)
233{
234 for (size_t i = 0; i < Rows * Cols; ++i)
235 {
236 m_elements[i] = func(i);
237 }
238}
239
240template <typename T, size_t Rows, size_t Cols>
242 const std::function<T(size_t i, size_t j)>& func)
243{
244 for (size_t i = 0; i < Rows; ++i)
245 {
246 for (size_t j = 0; j < Cols; ++j)
247 {
248 (*this)(i, j) = func(i, j);
249 }
250 }
251}
252
253template <typename T, size_t Rows, size_t Cols>
255{
256 m_elements.swap(other.m_elements);
257}
258
259template <typename T, size_t Rows, size_t Cols>
260constexpr size_t Matrix<T, Rows, Cols>::GetRows() const
261{
262 return Rows;
263}
264
265template <typename T, size_t Rows, size_t Cols>
266constexpr size_t Matrix<T, Rows, Cols>::GetCols() const
267{
268 return Cols;
269}
270
271template <typename T, size_t Rows, size_t Cols>
273{
274 return &m_elements[0];
275}
276
277template <typename T, size_t Rows, size_t Cols>
280{
281 return &m_elements[0];
282}
283
284template <typename T, size_t Rows, size_t Cols>
289
290template <typename T, size_t Rows, size_t Cols>
293{
294 return begin() + Rows * Cols;
295}
296
297template <typename T, size_t Rows, size_t Cols>
299{
300 return &m_elements[0];
301}
302
303template <typename T, size_t Rows, size_t Cols>
306{
307 return &m_elements[0];
308}
309
310template <typename T, size_t Rows, size_t Cols>
312 size_t i)
313{
314 assert(i < Rows * Cols);
315
316 return m_elements[i];
317}
318
319template <typename T, size_t Rows, size_t Cols>
322{
323 assert(i < Rows * Cols);
324
325 return m_elements[i];
326}
327
328template <typename T>
329template <size_t R, size_t C, typename E>
336
337template <typename T>
338Matrix<T, 1, 1>::Matrix(const std::initializer_list<T>& lst)
339{
340 assert(lst.size() > 0);
341
342 x = *lst.begin();
343}
344
345template <typename T>
347{
348 x = val;
349}
350
351template <typename T>
352void Matrix<T, 1, 1>::Fill(const std::function<T(size_t i)>& func)
353{
354 x = func(0);
355}
356
357template <typename T>
358void Matrix<T, 1, 1>::Fill(const std::function<T(size_t i, size_t j)>& func)
359{
360 x = func(0, 0);
361}
362
363template <typename T>
365{
366 std::swap(x, other.x);
367}
368
369template <typename T>
370constexpr size_t Matrix<T, 1, 1>::GetRows() const
371{
372 return 1;
373}
374
375template <typename T>
376constexpr size_t Matrix<T, 1, 1>::GetCols() const
377{
378 return 1;
379}
380
381template <typename T>
383{
384 return &x;
385}
386
387template <typename T>
389{
390 return &x;
391}
392
393template <typename T>
395{
396 return begin() + 1;
397}
398
399template <typename T>
401{
402 return begin() + 1;
403}
404
405template <typename T>
407{
408 return &x;
409}
410
411template <typename T>
413{
414 return &x;
415}
416
417template <typename T>
419{
420 assert(i < 1);
421
422 return (&x)[i];
423}
424
425template <typename T>
427 size_t i) const
428{
429 assert(i < 1);
430
431 return (&x)[i];
432}
433
434template <typename T>
436{
437 return Matrix<T, 1, 1>{ 1 };
438}
439
440template <typename T>
442{
443 return MakeUnitX();
444}
445
446template <typename T>
447template <size_t R, size_t C, typename E>
455
456template <typename T>
457Matrix<T, 2, 1>::Matrix(const std::initializer_list<T>& lst)
458{
459 assert(lst.size() > 1);
460
461 auto iter = lst.begin();
462 x = *(iter++);
463 y = *(iter);
464}
465
466template <typename T>
468{
469 x = y = val;
470}
471
472template <typename T>
473void Matrix<T, 2, 1>::Fill(const std::function<T(size_t i)>& func)
474{
475 x = func(0);
476 y = func(1);
477}
478
479template <typename T>
480void Matrix<T, 2, 1>::Fill(const std::function<T(size_t i, size_t j)>& func)
481{
482 x = func(0, 0);
483 y = func(1, 0);
484}
485
486template <typename T>
488{
489 std::swap(x, other.x);
490 std::swap(y, other.y);
491}
492
493template <typename T>
494constexpr size_t Matrix<T, 2, 1>::GetRows() const
495{
496 return 2;
497}
498
499template <typename T>
500constexpr size_t Matrix<T, 2, 1>::GetCols() const
501{
502 return 1;
503}
504
505template <typename T>
507{
508 return &x;
509}
510
511template <typename T>
513{
514 return &x;
515}
516
517template <typename T>
519{
520 return begin() + 2;
521}
522
523template <typename T>
525{
526 return begin() + 2;
527}
528
529template <typename T>
531{
532 return &x;
533}
534
535template <typename T>
537{
538 return &x;
539}
540
541template <typename T>
543{
544 assert(i < 2);
545
546 return (&x)[i];
547}
548
549template <typename T>
551 size_t i) const
552{
553 assert(i < 2);
554
555 return (&x)[i];
556}
557
558template <typename T>
560{
561 return Matrix<T, 2, 1>{ 1, 0 };
562}
563
564template <typename T>
566{
567 return Matrix<T, 2, 1>{ 0, 1 };
568}
569
570template <typename T>
572{
573 return Matrix<T, 2, 1>(i == 0, i == 1);
574}
575
576template <typename T>
577template <size_t R, size_t C, typename E>
579{
580 assert(expression.GetRows() == 3 && expression.GetCols() == 1);
581
582 x = expression.Eval(0, 0);
583 y = expression.Eval(1, 0);
584 z = expression.Eval(2, 0);
585}
586
587template <typename T>
588Matrix<T, 3, 1>::Matrix(const std::initializer_list<T>& lst)
589{
590 assert(lst.size() > 2);
591
592 auto iter = lst.begin();
593 x = *(iter++);
594 y = *(iter++);
595 z = *(iter);
596}
597
598template <typename T>
600{
601 x = y = z = val;
602}
603
604template <typename T>
605void Matrix<T, 3, 1>::Fill(const std::function<T(size_t i)>& func)
606{
607 x = func(0);
608 y = func(1);
609 z = func(2);
610}
612template <typename T>
613void Matrix<T, 3, 1>::Fill(const std::function<T(size_t i, size_t j)>& func)
615 x = func(0, 0);
616 y = func(1, 0);
617 z = func(2, 0);
619
620template <typename T>
623 std::swap(x, other.x);
624 std::swap(y, other.y);
625 std::swap(z, other.z);
627
628template <typename T>
629constexpr size_t Matrix<T, 3, 1>::GetRows() const
631 return 3;
633
634template <typename T>
635constexpr size_t Matrix<T, 3, 1>::GetCols() const
637 return 1;
639
640template <typename T>
643 return &x;
645
646template <typename T>
649 return &x;
651
652template <typename T>
655 return begin() + 3;
657
658template <typename T>
661 return begin() + 3;
663
664template <typename T>
666{
667 return &x;
668}
669
670template <typename T>
672{
673 return &x;
674}
675
676template <typename T>
678{
679 assert(i < 3);
680
681 return (&x)[i];
682}
683
684template <typename T>
686 size_t i) const
687{
688 assert(i < 3);
689
690 return (&x)[i];
691}
692
693template <typename T>
695{
696 return Matrix<T, 3, 1>{ 1, 0, 0 };
697}
698
699template <typename T>
701{
702 return Matrix<T, 3, 1>{ 0, 1, 0 };
703}
704
705template <typename T>
707{
708 return Matrix<T, 3, 1>{ 0, 0, 1 };
709}
710
711template <typename T>
713{
714 return Matrix<T, 3, 1>(i == 0, i == 1, i == 2);
715}
716
717template <typename T>
718template <size_t R, size_t C, typename E>
720{
721 assert(expression.GetRows() == 4 && expression.GetCols() == 1);
722
723 x = expression.Eval(0, 0);
724 y = expression.Eval(1, 0);
725 z = expression.Eval(2, 0);
726 w = expression.Eval(3, 0);
727}
728
729template <typename T>
730Matrix<T, 4, 1>::Matrix(const std::initializer_list<T>& lst)
731{
732 assert(lst.size() > 3);
733
734 auto iter = lst.begin();
735 x = *(iter++);
736 y = *(iter++);
737 z = *(iter++);
738 w = *(iter);
739}
740
741template <typename T>
743{
744 x = y = z = w = val;
745}
746
747template <typename T>
748void Matrix<T, 4, 1>::Fill(const std::function<T(size_t i)>& func)
749{
750 x = func(0);
751 y = func(1);
752 z = func(2);
753 w = func(3);
754}
755
756template <typename T>
757void Matrix<T, 4, 1>::Fill(const std::function<T(size_t i, size_t j)>& func)
758{
759 x = func(0, 0);
760 y = func(1, 0);
761 z = func(2, 0);
762 w = func(3, 0);
763}
764
765template <typename T>
767{
768 std::swap(x, other.x);
769 std::swap(y, other.y);
770 std::swap(z, other.z);
771 std::swap(w, other.w);
772}
773
774template <typename T>
775constexpr size_t Matrix<T, 4, 1>::GetRows() const
776{
777 return 4;
778}
779
780template <typename T>
781constexpr size_t Matrix<T, 4, 1>::GetCols() const
782{
783 return 1;
784}
785
786template <typename T>
788{
789 return &x;
790}
791
792template <typename T>
794{
795 return &x;
796}
797
798template <typename T>
800{
801 return begin() + 4;
802}
803
804template <typename T>
806{
807 return begin() + 4;
808}
809
810template <typename T>
812{
813 return &x;
814}
815
816template <typename T>
818{
819 return &x;
820}
821
822template <typename T>
824{
825 assert(i < 4);
826
827 return (&x)[i];
828}
829
830template <typename T>
832 size_t i) const
833{
834 assert(i < 4);
835
836 return (&x)[i];
837}
838
839template <typename T>
841{
842 return Matrix<T, 4, 1>{ 1, 0, 0, 0 };
843}
844
845template <typename T>
847{
848 return Matrix<T, 4, 1>{ 0, 1, 0, 0 };
849}
850
851template <typename T>
853{
854 return Matrix<T, 4, 1>{ 0, 0, 1, 0 };
855}
856
857template <typename T>
859{
860 return Matrix<T, 4, 1>{ 0, 0, 0, 1 };
861}
862
863template <typename T>
865{
866 return Matrix<T, 4, 1>(i == 0, i == 1, i == 2, i == 3);
867}
868
869template <typename T>
871
872template <typename T>
874 size_t rows, size_t cols, ConstReference value)
875{
876 m_elements.resize(rows * cols);
877 m_rows = rows;
878 m_cols = cols;
879
880 Fill(value);
881}
882
883template <typename T>
884template <size_t R, size_t C, typename E>
891
892template <typename T>
895{
896 size_t i = 0;
897
898 for (auto rows : lst)
899 {
900 size_t j = 0;
901
902 for (auto col : rows)
903 {
904 (void)col;
905 ++j;
906 }
907
908 m_cols = j;
909 ++i;
910 }
911
912 m_rows = i;
913 m_elements.resize(m_rows * m_cols);
914
915 i = 0;
916
917 for (auto rows : lst)
918 {
919 assert(i < m_rows);
920
921 size_t j = 0;
922
923 for (auto col : rows)
924 {
925 assert(j < m_cols);
926
927 (*this)(i, j) = col;
928 ++j;
929 }
930
931 ++i;
932 }
933}
934
935template <typename T>
937 size_t cols,
939 : Matrix(rows, cols)
940{
941 size_t cnt = 0;
942
943 for (size_t i = 0; i < rows; ++i)
944 {
945 for (size_t j = 0; j < cols; ++j)
946 {
947 (*this)(i, j) = ptr[cnt++];
948 }
949 }
950}
951
952template <typename T>
954 : m_elements(other.m_elements), m_rows(other.m_rows), m_cols(other.m_cols)
955{
956 // Do nothing
957}
958
959template <typename T>
962 : m_elements(std::move(other.m_elements)),
963 m_rows(other.m_rows),
964 m_cols(other.m_cols)
965{
966 // Do nothing
967}
968
969template <typename T>
972 const Matrix& other)
973{
974 m_elements = other.m_elements;
975 m_rows = other.m_rows;
976 m_cols = other.m_cols;
977 return *this;
978}
979
980template <typename T>
983 Matrix&& other) noexcept
984{
985 m_elements = std::move(other.m_elements);
986 m_rows = other.m_rows;
987 m_cols = other.m_cols;
988 other.m_rows = 0;
989 other.m_cols = 0;
990 return *this;
991}
992
993template <typename T>
995{
996 std::fill(m_elements.begin(), m_elements.end(), val);
997}
998
999template <typename T>
1001 const std::function<T(size_t i)>& func)
1002{
1003 for (size_t i = 0; i < m_elements.size(); ++i)
1004 {
1005 m_elements[i] = func(i);
1006 }
1007}
1008
1009template <typename T>
1011 const std::function<T(size_t i, size_t j)>& func)
1012{
1013 for (size_t i = 0; i < GetRows(); ++i)
1014 {
1015 for (size_t j = 0; j < GetCols(); ++j)
1016 {
1017 (*this)(i, j) = func(i, j);
1018 }
1019 }
1020}
1021
1022template <typename T>
1024{
1025 m_elements.swap(other.m_elements);
1026
1027 std::swap(m_rows, other.m_rows);
1028 std::swap(m_cols, other.m_cols);
1029}
1030
1031template <typename T>
1033 size_t rows, size_t cols, ConstReference val)
1034{
1036 const size_t minRows = std::min(rows, m_rows);
1037 const size_t minCols = std::min(cols, m_cols);
1038
1039 for (size_t i = 0; i < minRows; ++i)
1040 {
1041 for (size_t j = 0; j < minCols; ++j)
1042 {
1043 newMatrix(i, j) = (*this)(i, j);
1044 }
1045 }
1046
1047 *this = std::move(newMatrix);
1048}
1049
1050template <typename T>
1052{
1053 m_elements.clear();
1054
1055 m_rows = 0;
1056 m_cols = 0;
1057}
1058
1059template <typename T>
1061{
1062 return m_rows;
1063}
1064
1065template <typename T>
1067{
1068 return m_cols;
1069}
1070
1071template <typename T>
1074{
1075 return &m_elements[0];
1076}
1077
1078template <typename T>
1081{
1082 return &m_elements[0];
1083}
1084
1085template <typename T>
1088{
1089 return begin() + m_rows * m_cols;
1090}
1091
1092template <typename T>
1095{
1096 return begin() + m_rows * m_cols;
1097}
1098
1099template <typename T>
1102{
1103 return &m_elements[0];
1104}
1105
1106template <typename T>
1109{
1110 return &m_elements[0];
1111}
1112
1113template <typename T>
1116{
1117 assert(i < m_rows * m_cols);
1118
1119 return m_elements[i];
1120}
1121
1122template <typename T>
1125{
1126 assert(i < m_rows * m_cols);
1127
1128 return m_elements[i];
1129}
1130
1131template <typename T>
1133
1134template <typename T>
1136{
1137 m_elements.resize(rows, value);
1138}
1139
1140template <typename T>
1141template <size_t R, size_t C, typename E>
1148
1149template <typename T>
1150Matrix<T, MATRIX_SIZE_DYNAMIC, 1>::Matrix(const std::initializer_list<T>& lst)
1151{
1152 size_t sz = lst.size();
1153 m_elements.resize(sz);
1154
1155 size_t i = 0;
1156
1157 for (auto row : lst)
1158 {
1159 m_elements[i] = static_cast<T>(row);
1160 ++i;
1161 }
1162}
1163
1164template <typename T>
1166 : Matrix(rows)
1167{
1168 size_t cnt = 0;
1169
1170 for (size_t i = 0; i < rows; ++i)
1171 {
1172 (*this)[i] = ptr[cnt++];
1173 }
1174}
1175
1176template <typename T>
1178 : m_elements(other.m_elements)
1179{
1180 // Do nothing
1181}
1182
1183template <typename T>
1185 : m_elements(std::move(other.m_elements))
1186{
1187 // Do nothing
1188}
1189
1190template <typename T>
1192 const Matrix& other)
1193{
1194 m_elements = other.m_elements;
1195 return *this;
1196}
1197
1198template <typename T>
1200 Matrix&& other) noexcept
1201{
1202 m_elements = std::move(other.m_elements);
1203 return *this;
1204}
1205
1206template <typename T>
1208{
1209 std::fill(m_elements.begin(), m_elements.end(), val);
1210}
1211
1212template <typename T>
1214 const std::function<T(size_t i)>& func)
1215{
1216 for (size_t i = 0; i < m_elements.size(); ++i)
1217 {
1218 m_elements[i] = func(i);
1219 }
1220}
1221
1222template <typename T>
1224 const std::function<T(size_t i, size_t j)>& func)
1225{
1226 for (size_t i = 0; i < GetRows(); ++i)
1227 {
1228 m_elements[i] = func(i, 0);
1229 }
1230}
1231
1232template <typename T>
1234{
1235 m_elements.swap(other.m_elements);
1236}
1237
1238template <typename T>
1240{
1241 m_elements.resize(rows, val);
1242}
1243
1244template <typename T>
1249
1250template <typename T>
1252{
1253 m_elements.insert(m_elements.end(), newElems.m_elements.begin(),
1254 newElems.m_elements.end());
1255}
1256
1257template <typename T>
1259{
1260 m_elements.clear();
1261}
1262
1263template <typename T>
1265{
1266 return m_elements.size();
1267}
1268
1269template <typename T>
1271{
1272 return 1;
1273}
1274
1275template <typename T>
1278{
1279 return &m_elements[0];
1280}
1281
1282template <typename T>
1285{
1286 return &m_elements[0];
1287}
1288
1289template <typename T>
1292{
1293 return begin() + m_elements.size();
1294}
1295
1296template <typename T>
1299{
1300 return begin() + m_elements.size();
1301}
1302
1303template <typename T>
1306{
1307 return &m_elements[0];
1308}
1309
1310template <typename T>
1313{
1314 return &m_elements[0];
1315}
1316
1317template <typename T>
1320{
1321 assert(i < m_elements.size());
1322
1323 return m_elements[i];
1324}
1325
1326template <typename T>
1329{
1330 assert(i < m_elements.size());
1331
1332 return m_elements[i];
1333}
1334
1335template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M2>
1337{
1338 a = a + b;
1339}
1340
1341template <typename T, size_t Rows, size_t Cols>
1343{
1344 a = a + b;
1345}
1346
1347template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M2>
1349{
1350 a = a - b;
1351}
1352
1353template <typename T, size_t Rows, size_t Cols>
1355{
1356 a = a - b;
1357}
1358
1359template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M2>
1361{
1362 assert(a.GetCols() == b.GetRows());
1363
1364 Matrix<T, R1, C2> c(a * b);
1365 a = c;
1366}
1367
1368template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M2>
1370{
1371 assert(a.GetRows() == b.GetRows() && a.GetCols() == b.GetCols());
1372
1374 a, b.GetDerived()
1375 };
1376}
1377
1378template <typename T, size_t Rows, size_t Cols>
1385
1386template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M2>
1392
1393template <typename T, size_t Rows, size_t Cols>
1400
1401template <typename T, size_t Rows, size_t Cols, typename M1, typename M2>
1402constexpr std::enable_if_t<IsMatrixSizeStatic<Rows, Cols>(), bool> operator==(
1405{
1407 Rows * Cols - 1>::Call(a, b,
1408 std::equal_to<T>());
1409}
1410
1411template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M1,
1412 typename M2>
1415{
1416 if (a.GetRows() != b.GetRows() || a.GetCols() != b.GetCols())
1417 {
1418 return false;
1419 }
1420
1421 for (size_t i = 0; i < a.GetRows(); ++i)
1422 {
1423 for (size_t j = 0; j < a.GetCols(); ++j)
1424 {
1425 if (a.Eval(i, j) != b.Eval(i, j))
1426 {
1427 return false;
1428 }
1429 }
1430 }
1431
1432 return true;
1433}
1434
1435template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M1,
1436 typename M2>
1439{
1440 return !(a == b);
1441}
1442
1443template <typename T, size_t Rows, size_t Cols, typename M1,
1444 typename BinaryOperation>
1445constexpr std::enable_if_t<TraitIsMatrixSizeStatic<Rows, Cols>::value, T>
1453
1454template <typename T, size_t Rows, size_t Cols, typename M1>
1455constexpr std::enable_if_t<TraitIsMatrixSizeStatic<Rows, Cols>::value, T>
1457{
1459 Rows * Cols - 1>::Call(Matrix<T, Rows, Cols>(a),
1460 init, std::plus<T>(),
1461 NoOp<T>());
1462}
1463
1464template <typename T, size_t Rows, size_t Cols, typename M1>
1465constexpr std::enable_if_t<TraitIsMatrixSizeStatic<Rows, Cols>::value, T>
1472
1473template <typename T, size_t Rows, size_t Cols, typename M1,
1474 typename BinaryOperation>
1475constexpr std::enable_if_t<TraitIsMatrixSizeDynamic<Rows, Cols>::value, T>
1478{
1479 return std::accumulate(a.begin(), a.end(), init, op);
1480}
1481
1482template <typename T, size_t Rows, size_t Cols, typename M1>
1483constexpr std::enable_if_t<TraitIsMatrixSizeDynamic<Rows, Cols>::value, T>
1485{
1486 return std::accumulate(a.begin(), a.end(), init, std::plus<T>());
1487}
1488
1489template <typename T, size_t Rows, size_t Cols, typename M1>
1490constexpr std::enable_if_t<TraitIsMatrixSizeDynamic<Rows, Cols>::value, T>
1492{
1493 return std::accumulate(a.begin(), a.end(), T{}, std::plus<T>());
1494}
1495
1496// Product
1497
1498template <typename T, size_t Rows, size_t Cols, typename M1>
1500{
1501 return Accumulate(a, init, std::multiplies<T>());
1502}
1503
1504// Interpolation
1505template <typename T, size_t Rows, size_t Cols, typename M1, typename M2,
1506 typename M3, typename M4>
1507std::enable_if_t<IsMatrixSizeStatic<Rows, Cols>(), Matrix<T, Rows, Cols>>
1512{
1514
1515 for (size_t i = 0; i < f0.GetRows(); ++i)
1516 {
1517 for (size_t j = 0; j < f0.GetCols(); ++j)
1518 {
1519 result(i, j) = MonotonicCatmullRom(f0.Eval(i, j), f1.Eval(i, j),
1520 f2.Eval(i, j), f3.Eval(i, j), f);
1521 }
1522 }
1523
1524 return result;
1525}
1526} // namespace CubbyFlow
1527
1528#endif
const T & ConstReference
Definition Matrix.hpp:601
const T * ConstPointer
Definition Matrix.hpp:603
void CopyFrom(const MatrixExpression< T, R, C, E > &expression)
Copies from generic expression.
Definition MatrixDenseBase-Impl.hpp:21
T Eval(size_t i, size_t j) const
Returns the evaluated value for (i, j).
Definition MatrixExpression-Impl.hpp:33
Derived & GetDerived()
Returns actual implementation (the subclass).
Definition MatrixExpression-Impl.hpp:508
Definition Matrix.hpp:30
T & Reference
Definition Matrix.hpp:40
ConstPointer ConstIterator
Definition Matrix.hpp:45
void Fill(const T &val)
Definition Matrix-Impl.hpp:226
Matrix & operator=(const Matrix &other)
Definition Matrix.hpp:81
const T * ConstPointer
Definition Matrix.hpp:43
constexpr size_t GetCols() const
Definition Matrix-Impl.hpp:266
Iterator begin()
Definition Matrix-Impl.hpp:272
void Swap(Matrix &other)
Definition Matrix-Impl.hpp:254
T * Pointer
Definition Matrix.hpp:42
Pointer Iterator
Definition Matrix.hpp:44
constexpr size_t GetRows() const
Definition Matrix-Impl.hpp:260
Pointer data()
Definition Matrix-Impl.hpp:298
constexpr Matrix()
Definition Matrix.hpp:47
Iterator end()
Definition Matrix-Impl.hpp:285
Reference operator[](size_t i)
Definition Matrix-Impl.hpp:311
const T & ConstReference
Definition Matrix.hpp:41
Definition pybind11Utils.hpp:22
void ElemIDiv(Matrix< T, R1, C1 > &a, const MatrixExpression< T, R2, C2, M2 > &b)
Definition Matrix-Impl.hpp:1387
void ElemIMul(Matrix< T, R1, C1 > &a, const MatrixExpression< T, R2, C2, M2 > &b)
Definition Matrix-Impl.hpp:1369
constexpr std::enable_if_t< IsMatrixSizeStatic< Rows, Cols >(), bool > operator==(const MatrixExpression< T, Rows, Cols, M1 > &a, const MatrixExpression< T, Rows, Cols, M2 > &b)
Definition Matrix-Impl.hpp:1402
constexpr T Product(const MatrixExpression< T, Rows, Cols, M1 > &a, const T &init)
Definition Matrix-Impl.hpp:1499
std::enable_if_t< std::is_arithmetic< T >::value, T > MonotonicCatmullRom(const T &f0, const T &f1, const T &f2, const T &f3, T t)
Computes monotonic Catmull-Rom interpolation.
Definition MathUtils-Impl.hpp:336
Matrix< T, Rows, 1 > Vector
Definition Matrix.hpp:719
bool operator!=(const MatrixExpression< T, R1, C1, M1 > &a, const MatrixExpression< T, R2, C2, M2 > &b)
Definition Matrix-Impl.hpp:1437
void operator+=(Matrix< T, R1, C1 > &a, const MatrixExpression< T, R2, C2, M2 > &b)
Definition Matrix-Impl.hpp:1336
constexpr std::enable_if_t< TraitIsMatrixSizeStatic< Rows, Cols >::value, T > Accumulate(const MatrixExpression< T, Rows, Cols, M1 > &a, const T &init, BinaryOperation op)
Definition Matrix-Impl.hpp:1446
void operator*=(Matrix< T, R1, C1 > &a, const MatrixExpression< T, R2, C2, M2 > &b)
Definition Matrix-Impl.hpp:1360
void operator/=(Matrix< T, Rows, Cols > &a, const T &b)
Definition Matrix-Impl.hpp:1394
void operator-=(Matrix< T, R1, C1 > &a, const MatrixExpression< T, R2, C2, M2 > &b)
Definition Matrix-Impl.hpp:1348
static constexpr auto call(const M1 &a, const M2 &b, size_t i, size_t j)
Definition Matrix-Impl.hpp:35
Definition Matrix-Impl.hpp:25
static constexpr auto call(const M1 &a, const M2 &b, size_t i, size_t j)
Definition Matrix-Impl.hpp:26
static constexpr bool Call(const Matrix< T, Rows, Cols > &a, const Matrix< T, Rows, Cols > &b, BinaryOperation op)
Definition Matrix-Impl.hpp:163
Definition Matrix-Impl.hpp:149
static constexpr bool Call(const Matrix< T, Rows, Cols > &a, const Matrix< T, Rows, Cols > &b, BinaryOperation op)
Definition Matrix-Impl.hpp:150
static constexpr T CallDiag(const Matrix< T, Rows, Cols > &a, const T &init, ReduceOperation op, UnaryOperation uop)
Definition Matrix-Impl.hpp:135
static constexpr T Call(const Matrix< T, Rows, Cols > &a, const T &init, ReduceOperation op, UnaryOperation uop)
Definition Matrix-Impl.hpp:121
static constexpr std::enable_if_t<(Cols==1), U > Call(const Matrix< T, Rows, 1 > &a, ReduceOperation op, UnaryOperation uop)
Definition Matrix-Impl.hpp:114
static constexpr T Call(const Matrix< T, Rows, Cols > &a, ReduceOperation op, UnaryOperation uop)
Definition Matrix-Impl.hpp:128
Definition Matrix-Impl.hpp:45
static constexpr T Call(const Matrix< T, Rows, Cols > &a, ReduceOperation op, UnaryOperation uop)
Definition Matrix-Impl.hpp:80
static constexpr std::enable_if_t<(Cols==1), U > Call(const Matrix< T, Rows, 1 > &a, ReduceOperation op, UnaryOperation uop)
Definition Matrix-Impl.hpp:60
static constexpr T Call(const Matrix< T, Rows, Cols > &a, const T &init, ReduceOperation op, UnaryOperation uop)
Definition Matrix-Impl.hpp:70
static constexpr std::enable_if_t<(Cols==1), U > Call(const Matrix< T, Rows, 1 > &a, const T &init, ReduceOperation op, UnaryOperation uop)
Definition Matrix-Impl.hpp:48
static constexpr T CallDiag(const Matrix< T, Rows, Cols > &a, const T &init, ReduceOperation op, UnaryOperation uop)
Definition Matrix-Impl.hpp:90