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
79 // For Matrix with zero init
80 constexpr static T Call(const Matrix<T, Rows, Cols>& a, ReduceOperation op,
82 {
83 return op(
85 a, op, uop),
86 uop(a[I]));
87 }
89 // For diagonal elements on Matrix
90 constexpr static T CallDiag(const Matrix<T, Rows, Cols>& a, const T& init,
92 {
93 return op(Reduce<T, Rows, Cols, ReduceOperation, UnaryOperation,
95 uop(a(I, I)));
96 }
97};
99template <typename T, size_t Rows, size_t Cols, typename ReduceOperation,
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 }
111
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 }
119
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}
541template <typename T>
544 assert(i < 2);
546 return (&x)[i];
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}
564template <typename T>
566{
567 return Matrix<T, 2, 1>{ 0, 1 };
568}
570template <typename T>
572{
573 return Matrix<T, 2, 1>(i == 0, i == 1);
574}
576template <typename T>
577template <size_t R, size_t C, typename E>
580 assert(expression.GetRows() == 3 && expression.GetCols() == 1);
582 x = expression.Eval(0, 0);
583 y = expression.Eval(1, 0);
584 z = expression.Eval(2, 0);
586
587template <typename T>
588Matrix<T, 3, 1>::Matrix(const std::initializer_list<T>& lst)
590 assert(lst.size() > 2);
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}
611
612template <typename T>
613void Matrix<T, 3, 1>::Fill(const std::function<T(size_t i, size_t j)>& func)
614{
615 x = func(0, 0);
616 y = func(1, 0);
617 z = func(2, 0);
618}
619
620template <typename T>
622{
623 std::swap(x, other.x);
624 std::swap(y, other.y);
625 std::swap(z, other.z);
626}
627
628template <typename T>
629constexpr size_t Matrix<T, 3, 1>::GetRows() const
630{
631 return 3;
632}
633
634template <typename T>
635constexpr size_t Matrix<T, 3, 1>::GetCols() const
636{
637 return 1;
638}
639
640template <typename T>
642{
643 return &x;
644}
645
646template <typename T>
648{
649 return &x;
650}
651
652template <typename T>
654{
655 return begin() + 3;
656}
657
658template <typename T>
660{
661 return begin() + 3;
662}
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 const Matrix& other) = default;
955
956template <typename T>
958 Matrix&& other) noexcept = default;
959
960template <typename T>
963 const Matrix& other) = default;
964
965template <typename T>
968 Matrix&& other) noexcept
969{
970 m_elements = std::move(other.m_elements);
971 m_rows = other.m_rows;
972 m_cols = other.m_cols;
973 other.m_rows = 0;
974 other.m_cols = 0;
975 return *this;
976}
977
978template <typename T>
980{
981 std::fill(m_elements.begin(), m_elements.end(), val);
982}
983
984template <typename T>
986 const std::function<T(size_t i)>& func)
987{
988 for (size_t i = 0; i < m_elements.size(); ++i)
989 {
990 m_elements[i] = func(i);
991 }
992}
993
994template <typename T>
996 const std::function<T(size_t i, size_t j)>& func)
997{
998 for (size_t i = 0; i < GetRows(); ++i)
999 {
1000 for (size_t j = 0; j < GetCols(); ++j)
1001 {
1002 (*this)(i, j) = func(i, j);
1003 }
1004 }
1005}
1006
1007template <typename T>
1009{
1010 m_elements.swap(other.m_elements);
1011
1012 std::swap(m_rows, other.m_rows);
1013 std::swap(m_cols, other.m_cols);
1014}
1015
1016template <typename T>
1018 size_t rows, size_t cols, ConstReference val)
1019{
1021 const size_t minRows = std::min(rows, m_rows);
1022 const size_t minCols = std::min(cols, m_cols);
1023
1024 for (size_t i = 0; i < minRows; ++i)
1025 {
1026 for (size_t j = 0; j < minCols; ++j)
1027 {
1028 newMatrix(i, j) = (*this)(i, j);
1029 }
1030 }
1031
1032 *this = std::move(newMatrix);
1033}
1034
1035template <typename T>
1037{
1038 m_elements.clear();
1039
1040 m_rows = 0;
1041 m_cols = 0;
1042}
1043
1044template <typename T>
1046{
1047 return m_rows;
1048}
1049
1050template <typename T>
1052{
1053 return m_cols;
1054}
1055
1056template <typename T>
1059{
1060 return &m_elements[0];
1061}
1062
1063template <typename T>
1066{
1067 return &m_elements[0];
1068}
1069
1070template <typename T>
1073{
1074 return begin() + m_rows * m_cols;
1075}
1076
1077template <typename T>
1080{
1081 return begin() + m_rows * m_cols;
1082}
1083
1084template <typename T>
1087{
1088 return &m_elements[0];
1089}
1090
1091template <typename T>
1094{
1095 return &m_elements[0];
1096}
1097
1098template <typename T>
1101{
1102 assert(i < m_rows * m_cols);
1103
1104 return m_elements[i];
1105}
1106
1107template <typename T>
1110{
1111 assert(i < m_rows * m_cols);
1112
1113 return m_elements[i];
1114}
1115
1116template <typename T>
1118
1119template <typename T>
1121{
1122 m_elements.resize(rows, value);
1123}
1124
1125template <typename T>
1126template <size_t R, size_t C, typename E>
1133
1134template <typename T>
1135Matrix<T, MATRIX_SIZE_DYNAMIC, 1>::Matrix(const std::initializer_list<T>& lst)
1136{
1137 size_t sz = lst.size();
1138 m_elements.resize(sz);
1139
1140 size_t i = 0;
1141
1142 for (auto row : lst)
1143 {
1144 m_elements[i] = static_cast<T>(row);
1145 ++i;
1146 }
1147}
1148
1149template <typename T>
1151 : Matrix(rows)
1152{
1153 size_t cnt = 0;
1154
1155 for (size_t i = 0; i < rows; ++i)
1156 {
1157 (*this)[i] = ptr[cnt++];
1158 }
1159}
1160
1161template <typename T>
1163
1164template <typename T>
1166
1167template <typename T>
1169 const Matrix& other) = default;
1170
1171template <typename T>
1173 Matrix&& other) noexcept = default;
1174
1175template <typename T>
1177{
1178 std::fill(m_elements.begin(), m_elements.end(), val);
1179}
1180
1181template <typename T>
1183 const std::function<T(size_t i)>& func)
1184{
1185 for (size_t i = 0; i < m_elements.size(); ++i)
1186 {
1187 m_elements[i] = func(i);
1188 }
1189}
1190
1191template <typename T>
1193 const std::function<T(size_t i, size_t j)>& func)
1194{
1195 for (size_t i = 0; i < GetRows(); ++i)
1196 {
1197 m_elements[i] = func(i, 0);
1198 }
1199}
1200
1201template <typename T>
1203{
1204 m_elements.swap(other.m_elements);
1205}
1206
1207template <typename T>
1209{
1210 m_elements.resize(rows, val);
1211}
1212
1213template <typename T>
1218
1219template <typename T>
1221{
1222 m_elements.insert(m_elements.end(), newElems.m_elements.begin(),
1223 newElems.m_elements.end());
1224}
1225
1226template <typename T>
1228{
1229 m_elements.clear();
1230}
1231
1232template <typename T>
1234{
1235 return m_elements.size();
1236}
1237
1238template <typename T>
1240{
1241 return 1;
1242}
1243
1244template <typename T>
1247{
1248 return &m_elements[0];
1249}
1250
1251template <typename T>
1254{
1255 return &m_elements[0];
1256}
1257
1258template <typename T>
1261{
1262 return begin() + m_elements.size();
1263}
1264
1265template <typename T>
1268{
1269 return begin() + m_elements.size();
1270}
1271
1272template <typename T>
1275{
1276 return &m_elements[0];
1277}
1278
1279template <typename T>
1282{
1283 return &m_elements[0];
1284}
1285
1286template <typename T>
1289{
1290 assert(i < m_elements.size());
1291
1292 return m_elements[i];
1293}
1294
1295template <typename T>
1298{
1299 assert(i < m_elements.size());
1300
1301 return m_elements[i];
1302}
1303
1304template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M2>
1306{
1307 a = a + b;
1308}
1309
1310template <typename T, size_t Rows, size_t Cols>
1312{
1313 a = a + b;
1314}
1315
1316template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M2>
1318{
1319 a = a - b;
1320}
1321
1322template <typename T, size_t Rows, size_t Cols>
1324{
1325 a = a - b;
1326}
1327
1328template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M2>
1330{
1331 assert(a.GetCols() == b.GetRows());
1332
1333 Matrix<T, R1, C2> c(a * b);
1334 a = c;
1335}
1336
1337template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M2>
1339{
1340 assert(a.GetRows() == b.GetRows() && a.GetCols() == b.GetCols());
1341
1343 a, b.GetDerived()
1344 };
1345}
1346
1347template <typename T, size_t Rows, size_t Cols>
1354
1355template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M2>
1361
1362template <typename T, size_t Rows, size_t Cols>
1369
1370template <typename T, size_t Rows, size_t Cols, typename M1, typename M2>
1371constexpr std::enable_if_t<IsMatrixSizeStatic<Rows, Cols>(), bool> operator==(
1374{
1376 Rows * Cols - 1>::Call(a, b,
1377 std::equal_to<T>());
1378}
1379
1380template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M1,
1381 typename M2>
1384{
1385 if (a.GetRows() != b.GetRows() || a.GetCols() != b.GetCols())
1386 {
1387 return false;
1388 }
1389
1390 for (size_t i = 0; i < a.GetRows(); ++i)
1391 {
1392 for (size_t j = 0; j < a.GetCols(); ++j)
1393 {
1394 if (a.Eval(i, j) != b.Eval(i, j))
1395 {
1396 return false;
1397 }
1398 }
1399 }
1400
1401 return true;
1402}
1403
1404template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M1,
1405 typename M2>
1408{
1409 return !(a == b);
1410}
1411
1412template <typename T, size_t Rows, size_t Cols, typename M1,
1413 typename BinaryOperation>
1414constexpr std::enable_if_t<TraitIsMatrixSizeStatic<Rows, Cols>::value, T>
1422
1423template <typename T, size_t Rows, size_t Cols, typename M1>
1424constexpr std::enable_if_t<TraitIsMatrixSizeStatic<Rows, Cols>::value, T>
1426{
1428 Rows * Cols - 1>::Call(Matrix<T, Rows, Cols>(a),
1429 init, std::plus<T>(),
1430 NoOp<T>());
1431}
1432
1433template <typename T, size_t Rows, size_t Cols, typename M1>
1434constexpr std::enable_if_t<TraitIsMatrixSizeStatic<Rows, Cols>::value, T>
1441
1442template <typename T, size_t Rows, size_t Cols, typename M1,
1443 typename BinaryOperation>
1444constexpr std::enable_if_t<TraitIsMatrixSizeDynamic<Rows, Cols>::value, T>
1447{
1448 return std::accumulate(a.begin(), a.end(), init, op);
1449}
1450
1451template <typename T, size_t Rows, size_t Cols, typename M1>
1452constexpr std::enable_if_t<TraitIsMatrixSizeDynamic<Rows, Cols>::value, T>
1454{
1455 return std::accumulate(a.begin(), a.end(), init, std::plus<T>());
1456}
1457
1458template <typename T, size_t Rows, size_t Cols, typename M1>
1459constexpr std::enable_if_t<TraitIsMatrixSizeDynamic<Rows, Cols>::value, T>
1461{
1462 return std::accumulate(a.begin(), a.end(), T{}, std::plus<T>());
1463}
1464
1465// Product
1466
1467template <typename T, size_t Rows, size_t Cols, typename M1>
1469{
1470 return Accumulate(a, init, std::multiplies<T>());
1471}
1472
1473// Interpolation
1474template <typename T, size_t Rows, size_t Cols, typename M1, typename M2,
1475 typename M3, typename M4>
1476std::enable_if_t<IsMatrixSizeStatic<Rows, Cols>(), Matrix<T, Rows, Cols>>
1481{
1483
1484 for (size_t i = 0; i < f0.GetRows(); ++i)
1485 {
1486 for (size_t j = 0; j < f0.GetCols(); ++j)
1487 {
1488 result(i, j) = MonotonicCatmullRom(f0.Eval(i, j), f1.Eval(i, j),
1489 f2.Eval(i, j), f3.Eval(i, j), f);
1490 }
1491 }
1492
1493 return result;
1494}
1495} // namespace CubbyFlow
1496
1497#endif
const T & ConstReference
Definition Matrix.hpp:530
const T * ConstPointer
Definition Matrix.hpp:532
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 &)=default
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:1356
void ElemIMul(Matrix< T, R1, C1 > &a, const MatrixExpression< T, R2, C2, M2 > &b)
Definition Matrix-Impl.hpp:1338
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:1371
constexpr T Product(const MatrixExpression< T, Rows, Cols, M1 > &a, const T &init)
Definition Matrix-Impl.hpp:1468
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:648
bool operator!=(const MatrixExpression< T, R1, C1, M1 > &a, const MatrixExpression< T, R2, C2, M2 > &b)
Definition Matrix-Impl.hpp:1406
void operator+=(Matrix< T, R1, C1 > &a, const MatrixExpression< T, R2, C2, M2 > &b)
Definition Matrix-Impl.hpp:1305
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:1415
void operator*=(Matrix< T, R1, C1 > &a, const MatrixExpression< T, R2, C2, M2 > &b)
Definition Matrix-Impl.hpp:1329
void operator/=(Matrix< T, Rows, Cols > &a, const T &b)
Definition Matrix-Impl.hpp:1363
void operator-=(Matrix< T, R1, C1 > &a, const MatrixExpression< T, R2, C2, M2 > &b)
Definition Matrix-Impl.hpp:1317
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
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:105
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