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}
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
631 return 3;
632}
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}
646template <typename T>
648{
649 return &x;
650}
652template <typename T>
654{
655 return begin() + 3;
656}
658template <typename T>
660{
661 return begin() + 3;
662}
664template <typename T>
666{
667 return &x;
668}
670template <typename T>
672{
673 return &x;
674}
676template <typename T>
678{
679 assert(i < 3);
680
681 return (&x)[i];
682}
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>
874
875template <typename T>
877 size_t rows, size_t cols, ConstReference value)
878{
879 m_elements.resize(rows * cols);
880 m_rows = rows;
881 m_cols = cols;
882
883 Fill(value);
884}
885
886template <typename T>
887template <size_t R, size_t C, typename E>
894
895template <typename T>
898{
899 size_t i = 0;
900
901 for (auto rows : lst)
902 {
903 size_t j = 0;
904
905 for (auto col : rows)
906 {
907 (void)col;
908 ++j;
909 }
910
911 m_cols = j;
912 ++i;
913 }
914
915 m_rows = i;
916 m_elements.resize(m_rows * m_cols);
917
918 i = 0;
919
920 for (auto rows : lst)
921 {
922 assert(i < m_rows);
923
924 size_t j = 0;
925
926 for (auto col : rows)
927 {
928 assert(j < m_cols);
929
930 (*this)(i, j) = col;
931 ++j;
932 }
933
934 ++i;
935 }
936}
937
938template <typename T>
940 size_t cols,
942 : Matrix(rows, cols)
943{
944 size_t cnt = 0;
945
946 for (size_t i = 0; i < rows; ++i)
947 {
948 for (size_t j = 0; j < cols; ++j)
949 {
950 (*this)(i, j) = ptr[cnt++];
951 }
952 }
953}
954
955template <typename T>
957 : m_elements(other.m_elements), m_rows(other.m_rows), m_cols(other.m_cols)
958{
959 // Do nothing
960}
961
962template <typename T>
965 : m_elements(std::move(other.m_elements)),
966 m_rows(other.m_rows),
967 m_cols(other.m_cols)
968{
969 // Do nothing
970}
971
972template <typename T>
975 const Matrix& other)
976{
977 m_elements = other.m_elements;
978 m_rows = other.m_rows;
979 m_cols = other.m_cols;
980 return *this;
981}
982
983template <typename T>
986 Matrix&& other) noexcept
987{
988 m_elements = std::move(other.m_elements);
989 m_rows = other.m_rows;
990 m_cols = other.m_cols;
991 other.m_rows = 0;
992 other.m_cols = 0;
993 return *this;
994}
995
996template <typename T>
998{
999 std::fill(m_elements.begin(), m_elements.end(), val);
1000}
1001
1002template <typename T>
1004 const std::function<T(size_t i)>& func)
1005{
1006 for (size_t i = 0; i < m_elements.size(); ++i)
1007 {
1008 m_elements[i] = func(i);
1009 }
1010}
1011
1012template <typename T>
1014 const std::function<T(size_t i, size_t j)>& func)
1015{
1016 for (size_t i = 0; i < GetRows(); ++i)
1017 {
1018 for (size_t j = 0; j < GetCols(); ++j)
1019 {
1020 (*this)(i, j) = func(i, j);
1021 }
1022 }
1023}
1024
1025template <typename T>
1027{
1028 m_elements.swap(other.m_elements);
1029
1030 std::swap(m_rows, other.m_rows);
1031 std::swap(m_cols, other.m_cols);
1032}
1033
1034template <typename T>
1036 size_t rows, size_t cols, ConstReference val)
1037{
1039 const size_t minRows = std::min(rows, m_rows);
1040 const size_t minCols = std::min(cols, m_cols);
1041
1042 for (size_t i = 0; i < minRows; ++i)
1043 {
1044 for (size_t j = 0; j < minCols; ++j)
1045 {
1046 newMatrix(i, j) = (*this)(i, j);
1047 }
1048 }
1049
1050 *this = std::move(newMatrix);
1051}
1052
1053template <typename T>
1055{
1056 m_elements.clear();
1057
1058 m_rows = 0;
1059 m_cols = 0;
1060}
1061
1062template <typename T>
1064{
1065 return m_rows;
1066}
1067
1068template <typename T>
1070{
1071 return m_cols;
1072}
1073
1074template <typename T>
1077{
1078 return &m_elements[0];
1079}
1080
1081template <typename T>
1084{
1085 return &m_elements[0];
1086}
1087
1088template <typename T>
1091{
1092 return begin() + m_rows * m_cols;
1093}
1094
1095template <typename T>
1098{
1099 return begin() + m_rows * m_cols;
1100}
1101
1102template <typename T>
1105{
1106 return &m_elements[0];
1107}
1108
1109template <typename T>
1112{
1113 return &m_elements[0];
1114}
1115
1116template <typename T>
1119{
1120 assert(i < m_rows * m_cols);
1121
1122 return m_elements[i];
1123}
1124
1125template <typename T>
1128{
1129 assert(i < m_rows * m_cols);
1130
1131 return m_elements[i];
1132}
1133
1134template <typename T>
1136{
1137 // Do nothing
1138}
1139
1140template <typename T>
1142{
1143 m_elements.resize(rows, value);
1144}
1145
1146template <typename T>
1147template <size_t R, size_t C, typename E>
1154
1155template <typename T>
1156Matrix<T, MATRIX_SIZE_DYNAMIC, 1>::Matrix(const std::initializer_list<T>& lst)
1157{
1158 size_t sz = lst.size();
1159 m_elements.resize(sz);
1160
1161 size_t i = 0;
1162
1163 for (auto row : lst)
1164 {
1165 m_elements[i] = static_cast<T>(row);
1166 ++i;
1167 }
1168}
1169
1170template <typename T>
1172 : Matrix(rows)
1173{
1174 size_t cnt = 0;
1175
1176 for (size_t i = 0; i < rows; ++i)
1177 {
1178 (*this)[i] = ptr[cnt++];
1179 }
1180}
1181
1182template <typename T>
1184 : m_elements(other.m_elements)
1185{
1186 // Do nothing
1187}
1188
1189template <typename T>
1191 : m_elements(std::move(other.m_elements))
1192{
1193 // Do nothing
1194}
1195
1196template <typename T>
1198 const Matrix& other)
1199{
1200 m_elements = other.m_elements;
1201 return *this;
1202}
1203
1204template <typename T>
1206 Matrix&& other) noexcept
1207{
1208 m_elements = std::move(other.m_elements);
1209 return *this;
1210}
1211
1212template <typename T>
1214{
1215 std::fill(m_elements.begin(), m_elements.end(), val);
1216}
1217
1218template <typename T>
1220 const std::function<T(size_t i)>& func)
1221{
1222 for (size_t i = 0; i < m_elements.size(); ++i)
1223 {
1224 m_elements[i] = func(i);
1225 }
1226}
1227
1228template <typename T>
1230 const std::function<T(size_t i, size_t j)>& func)
1231{
1232 for (size_t i = 0; i < GetRows(); ++i)
1233 {
1234 m_elements[i] = func(i, 0);
1235 }
1236}
1237
1238template <typename T>
1240{
1241 m_elements.swap(other.m_elements);
1242}
1243
1244template <typename T>
1246{
1247 m_elements.resize(rows, val);
1248}
1249
1250template <typename T>
1255
1256template <typename T>
1258{
1259 m_elements.insert(m_elements.end(), newElems.m_elements.begin(),
1260 newElems.m_elements.end());
1261}
1262
1263template <typename T>
1265{
1266 m_elements.clear();
1267}
1268
1269template <typename T>
1271{
1272 return m_elements.size();
1273}
1274
1275template <typename T>
1277{
1278 return 1;
1279}
1280
1281template <typename T>
1284{
1285 return &m_elements[0];
1286}
1287
1288template <typename T>
1291{
1292 return &m_elements[0];
1293}
1294
1295template <typename T>
1298{
1299 return begin() + m_elements.size();
1300}
1301
1302template <typename T>
1305{
1306 return begin() + m_elements.size();
1307}
1308
1309template <typename T>
1312{
1313 return &m_elements[0];
1314}
1315
1316template <typename T>
1319{
1320 return &m_elements[0];
1321}
1322
1323template <typename T>
1326{
1327 assert(i < m_elements.size());
1328
1329 return m_elements[i];
1330}
1331
1332template <typename T>
1335{
1336 assert(i < m_elements.size());
1337
1338 return m_elements[i];
1339}
1340
1341template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M2>
1343{
1344 a = a + b;
1345}
1346
1347template <typename T, size_t Rows, size_t Cols>
1349{
1350 a = a + b;
1351}
1352
1353template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M2>
1355{
1356 a = a - b;
1357}
1358
1359template <typename T, size_t Rows, size_t Cols>
1361{
1362 a = a - b;
1363}
1364
1365template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M2>
1367{
1368 assert(a.GetCols() == b.GetRows());
1369
1370 Matrix<T, R1, C2> c = a * b;
1371 a = c;
1372}
1373
1374template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M2>
1376{
1377 assert(a.GetRows() == b.GetRows() && a.GetCols() == b.GetCols());
1378
1380 a, b.GetDerived()
1381 };
1382}
1383
1384template <typename T, size_t Rows, size_t Cols>
1391
1392template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M2>
1398
1399template <typename T, size_t Rows, size_t Cols>
1406
1407template <typename T, size_t Rows, size_t Cols, typename M1, typename M2>
1408constexpr std::enable_if_t<IsMatrixSizeStatic<Rows, Cols>(), bool> operator==(
1411{
1413 Rows * Cols - 1>::Call(a, b,
1414 std::equal_to<T>());
1415}
1416
1417template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M1,
1418 typename M2>
1421{
1422 if (a.GetRows() != b.GetRows() || a.GetCols() != b.GetCols())
1423 {
1424 return false;
1425 }
1426
1427 for (size_t i = 0; i < a.GetRows(); ++i)
1428 {
1429 for (size_t j = 0; j < a.GetCols(); ++j)
1430 {
1431 if (a.Eval(i, j) != b.Eval(i, j))
1432 {
1433 return false;
1434 }
1435 }
1436 }
1437
1438 return true;
1439}
1440
1441template <typename T, size_t R1, size_t C1, size_t R2, size_t C2, typename M1,
1442 typename M2>
1445{
1446 return !(a == b);
1447}
1448
1449template <typename T, size_t Rows, size_t Cols, typename M1,
1450 typename BinaryOperation>
1451constexpr std::enable_if_t<TraitIsMatrixSizeStatic<Rows, Cols>::value, T>
1458
1459template <typename T, size_t Rows, size_t Cols, typename M1>
1460constexpr std::enable_if_t<TraitIsMatrixSizeStatic<Rows, Cols>::value, T>
1462{
1464 Rows * Cols - 1>::Call(a, init, std::plus<T>(),
1465 NoOp<T>());
1466}
1467
1468template <typename T, size_t Rows, size_t Cols, typename M1>
1469constexpr std::enable_if_t<TraitIsMatrixSizeStatic<Rows, Cols>::value, T>
1471{
1473 Rows * Cols - 1>::Call(a, std::plus<T>(),
1474 NoOp<T>());
1475}
1476
1477template <typename T, size_t Rows, size_t Cols, typename M1,
1478 typename BinaryOperation>
1479constexpr std::enable_if_t<TraitIsMatrixSizeDynamic<Rows, Cols>::value, T>
1482{
1483 return std::accumulate(a.begin(), a.end(), init, op);
1484}
1485
1486template <typename T, size_t Rows, size_t Cols, typename M1>
1487constexpr std::enable_if_t<TraitIsMatrixSizeDynamic<Rows, Cols>::value, T>
1489{
1490 return std::accumulate(a.begin(), a.end(), init, std::plus<T>());
1491}
1492
1493template <typename T, size_t Rows, size_t Cols, typename M1>
1494constexpr std::enable_if_t<TraitIsMatrixSizeDynamic<Rows, Cols>::value, T>
1496{
1497 return std::accumulate(a.begin(), a.end(), T{}, std::plus<T>());
1498}
1499
1500// Product
1501
1502template <typename T, size_t Rows, size_t Cols, typename M1>
1504{
1505 return Accumulate(a, init, std::multiplies<T>());
1506}
1507
1508// Interpolation
1509template <typename T, size_t Rows, size_t Cols, typename M1, typename M2,
1510 typename M3, typename M4>
1511std::enable_if_t<IsMatrixSizeStatic<Rows, Cols>(), Matrix<T, Rows, Cols>>
1516{
1518
1519 for (size_t i = 0; i < f0.GetRows(); ++i)
1520 {
1521 for (size_t j = 0; j < f0.GetCols(); ++j)
1522 {
1523 result(i, j) = MonotonicCatmullRom(f0.Eval(i, j), f1.Eval(i, j),
1524 f2.Eval(i, j), f3.Eval(i, j), f);
1525 }
1526 }
1527
1528 return result;
1529}
1530} // namespace CubbyFlow
1531
1532#endif
const T & ConstReference
Definition Matrix.hpp:620
const T * ConstPointer
Definition Matrix.hpp:622
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:509
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:21
void ElemIDiv(Matrix< T, R1, C1 > &a, const MatrixExpression< T, R2, C2, M2 > &b)
Definition Matrix-Impl.hpp:1393
void ElemIMul(Matrix< T, R1, C1 > &a, const MatrixExpression< T, R2, C2, M2 > &b)
Definition Matrix-Impl.hpp:1375
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:1408
constexpr T Product(const MatrixExpression< T, Rows, Cols, M1 > &a, const T &init)
Definition Matrix-Impl.hpp:1503
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:738
bool operator!=(const MatrixExpression< T, R1, C1, M1 > &a, const MatrixExpression< T, R2, C2, M2 > &b)
Definition Matrix-Impl.hpp:1443
void operator+=(Matrix< T, R1, C1 > &a, const MatrixExpression< T, R2, C2, M2 > &b)
Definition Matrix-Impl.hpp:1342
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:1452
void operator*=(Matrix< T, R1, C1 > &a, const MatrixExpression< T, R2, C2, M2 > &b)
Definition Matrix-Impl.hpp:1366
void operator/=(Matrix< T, Rows, Cols > &a, const T &b)
Definition Matrix-Impl.hpp:1400
void operator-=(Matrix< T, R1, C1 > &a, const MatrixExpression< T, R2, C2, M2 > &b)
Definition Matrix-Impl.hpp:1354
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