Loading...
Searching...
No Matches
MatrixCSR-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_CSR_IMPL_HPP
12#define CUBBYFLOW_MATRIX_CSR_IMPL_HPP
13
17
18#include <utility>
19
20namespace CubbyFlow
21{
22template <typename T, typename ME>
24 const ME& m2)
25 : m_m1(m1),
26 m_m2(m2),
27 m_nnz(m1.NonZeroData()),
28 m_rp(m1.RowPointersData()),
29 m_ci(m1.ColumnIndicesData())
30{
31 // Do nothing
32}
33
34template <typename T, typename ME>
36{
37 return m_m1.GetRows();
38}
39
40template <typename T, typename ME>
42{
43 return m_m2.GetCols();
44}
45
46template <typename T, typename ME>
48{
49 const size_t colBegin = m_rp[i];
50 const size_t colEnd = m_rp[i + 1];
51
52 T sum = 0;
53
54 for (size_t kk = colBegin; kk < colEnd; ++kk)
55 {
56 size_t k = m_ci[kk];
57 sum += m_nnz[kk] * m_m2(k, j);
58 }
59
60 return sum;
61}
62
63template <typename T>
64MatrixCSR<T>::Element::Element() : i(0), j(0), value(0)
65{
66 // Do nothing
67}
68
69template <typename T>
71 : i(i_), j(j_), value(value_)
72{
73 // Do nothing
74}
75
76template <typename T>
81
82template <typename T>
84 const std::initializer_list<std::initializer_list<T>>& lst, T epsilon)
85{
87}
88
89template <typename T>
90template <size_t R, size_t C, typename ME>
95
96template <typename T>
98
99template <typename T>
101 : m_size(std::exchange(other.m_size, Vector2UZ{})),
102 m_nonZeros(std::move(other.m_nonZeros)),
103 m_rowPointers(std::move(other.m_rowPointers)),
104 m_columnIndices(std::move(other.m_columnIndices))
105{
106 // Do nothing
107}
108
109template <typename T>
111
112template <typename T>
114{
115 m_size = other.m_size;
116 other.m_size = Vector2UZ{};
117 m_nonZeros = std::move(other.m_nonZeros);
118 m_rowPointers = std::move(other.m_rowPointers);
119 m_columnIndices = std::move(other.m_columnIndices);
120
121 return *this;
122}
123
124template <typename T>
126{
127 m_size = { 0, 0 };
128 m_nonZeros.clear();
129 m_rowPointers.clear();
130 m_columnIndices.clear();
131 m_rowPointers.push_back(0);
132}
133
134template <typename T>
136{
137 std::fill(m_nonZeros.begin(), m_nonZeros.end(), s);
138}
140template <typename T>
142{
143 m_size = other.m_size;
144 m_nonZeros = other.m_nonZeros;
145 m_rowPointers = other.m_rowPointers;
146 m_columnIndices = other.m_columnIndices;
147}
149template <typename T>
150void MatrixCSR<T>::Reserve(size_t rows, size_t cols, size_t numNonZeros)
152 m_size = Vector2UZ(rows, cols);
153 m_rowPointers.resize(m_size.x + 1);
154 m_nonZeros.resize(numNonZeros);
155 m_columnIndices.resize(numNonZeros);
156}
158template <typename T>
160 const std::initializer_list<std::initializer_list<T>>& lst, T epsilon)
161{
162 const size_t numRows = lst.size();
163 const size_t numCols = (numRows > 0) ? lst.begin()->size() : 0;
164
165 m_size = { numRows, numCols };
166 m_nonZeros.clear();
167 m_rowPointers.clear();
168 m_columnIndices.clear();
169
170 auto rowIter = lst.begin();
171 for (size_t i = 0; i < numRows; ++i)
172 {
173 assert(numCols == rowIter->size());
174
175 m_rowPointers.push_back(m_nonZeros.size());
176
177 auto colIter = rowIter->begin();
178 for (size_t j = 0; j < numCols; ++j)
179 {
180 if (std::fabs(*colIter) > epsilon)
181 {
182 m_nonZeros.push_back(*colIter);
183 m_columnIndices.push_back(j);
184 }
185
186 ++colIter;
187 }
188
189 ++rowIter;
190 }
192 m_rowPointers.push_back(m_nonZeros.size());
193}
194
195template <typename T>
196template <size_t R, size_t C, typename E>
199{
200 const size_t numRows = other.GetRows();
201 const size_t numCols = other.GetCols();
202
203 m_size = { numRows, numCols };
204 m_nonZeros.clear();
205 m_columnIndices.clear();
207 const E& expression = other.GetDerived();
208
209 for (size_t i = 0; i < numRows; ++i)
211 m_rowPointers.push_back(m_nonZeros.size());
212
213 for (size_t j = 0; j < numCols; ++j)
214 {
215 if (T val = expression(i, j); std::fabs(val) > epsilon)
216 {
217 m_nonZeros.push_back(val);
218 m_columnIndices.push_back(j);
220 }
221 }
222
223 m_rowPointers.push_back(m_nonZeros.size());
225
226template <typename T>
227void MatrixCSR<T>::AddElement(size_t i, size_t j, const T& value)
228{
229 AddElement({ i, j, value });
231
232template <typename T>
234{
235 if (const ssize_t numRowsToAdd = static_cast<ssize_t>(element.i) -
236 static_cast<ssize_t>(m_size.x) + 1;
237 numRowsToAdd > 0)
238 {
239 for (ssize_t i = 0; i < numRowsToAdd; ++i)
240 {
241 AddRow({}, {});
243 }
244
245 m_size.y = std::max(m_size.y, element.j + 1);
246
247 const size_t rowBegin = m_rowPointers[element.i];
248 const size_t rowEnd = m_rowPointers[element.i + 1];
249
250 auto colIdxIter =
251 std::lower_bound(m_columnIndices.begin() + rowBegin,
252 m_columnIndices.begin() + rowEnd, element.j);
253 auto offset = colIdxIter - m_columnIndices.begin();
255 m_columnIndices.insert(colIdxIter, element.j);
256 m_nonZeros.insert(m_nonZeros.begin() + offset, element.value);
258 for (size_t i = element.i + 1; i < m_rowPointers.size(); ++i)
259 {
260 ++m_rowPointers[i];
261 }
262}
264template <typename T>
267{
268 assert(nonZeros.size() == columnIndices.size());
270 ++m_size.x;
271
272 // TODO: Implement zip iterator
273 std::vector<std::pair<T, size_t>> zipped;
274 for (size_t i = 0; i < nonZeros.size(); ++i)
276 zipped.emplace_back(nonZeros[i], columnIndices[i]);
277 m_size.y = std::max(m_size.y, columnIndices[i] + 1);
279
280 std::sort(zipped.begin(), zipped.end(),
281 [](std::pair<T, size_t> a, std::pair<T, size_t> b) {
282 return a.second < b.second;
283 });
285 for (size_t i = 0; i < zipped.size(); ++i)
286 {
287 m_nonZeros.push_back(zipped[i].first);
288 m_columnIndices.push_back(zipped[i].second);
289 }
291 m_rowPointers.push_back(m_nonZeros.size());
292}
294template <typename T>
295void MatrixCSR<T>::SetElement(size_t i, size_t j, const T& value)
297 SetElement({ i, j, value });
298}
300template <typename T>
303 if (size_t nzIndex = HasElement(element.i, element.j);
304 nzIndex == std::numeric_limits<size_t>::max())
307 }
308 else
309 {
310 m_nonZeros[nzIndex] = element.value;
312}
313
314template <typename T>
316{
317 if (m_size != other.m_size)
318 {
319 return false;
320 }
321
322 if (m_nonZeros.size() != other.m_nonZeros.size())
323 {
324 return false;
326
327 for (size_t i = 0; i < m_nonZeros.size(); ++i)
329 if (m_nonZeros[i] != other.m_nonZeros[i])
330 {
331 return false;
332 }
333
334 if (m_columnIndices[i] != other.m_columnIndices[i])
335 {
336 return false;
338 }
339
340 for (size_t i = 0; i < m_rowPointers.size(); ++i)
341 {
342 if (m_rowPointers[i] != other.m_rowPointers[i])
344 return false;
345 }
347
348 return true;
350
351template <typename T>
352bool MatrixCSR<T>::IsSimilar(const MatrixCSR& other, double tol) const
353{
354 if (m_size != other.m_size)
355 {
356 return false;
357 }
358
359 if (m_nonZeros.size() != other.m_nonZeros.size())
360 {
361 return false;
363
364 for (size_t i = 0; i < m_nonZeros.size(); ++i)
366 if (std::fabs(m_nonZeros[i] - other.m_nonZeros[i]) > tol)
367 {
368 return false;
369 }
370
371 if (m_columnIndices[i] != other.m_columnIndices[i])
372 {
373 return false;
375 }
376
377 for (size_t i = 0; i < m_rowPointers.size(); ++i)
378 {
379 if (m_rowPointers[i] != other.m_rowPointers[i])
380 {
381 return false;
382 }
383 }
384
385 return true;
386}
387
388template <typename T>
390{
391 return GetRows() == GetCols();
392}
393
394template <typename T>
396{
397 return m_size;
399
400template <typename T>
402{
403 return m_size.x;
405
406template <typename T>
408{
409 return m_size.y;
411
412template <typename T>
414{
415 return m_nonZeros.size();
416}
418template <typename T>
419const T& MatrixCSR<T>::NonZero(size_t i) const
421 return m_nonZeros[i];
422}
424template <typename T>
427 return m_nonZeros[i];
428}
429
430template <typename T>
431const size_t& MatrixCSR<T>::RowPointer(size_t i) const
432{
433 return m_rowPointers[i];
434}
435
436template <typename T>
437const size_t& MatrixCSR<T>::ColumnIndex(size_t i) const
438{
439 return m_columnIndices[i];
440}
441
442template <typename T>
444{
445 return m_nonZeros.data();
446}
447
448template <typename T>
450{
451 return m_nonZeros.data();
452}
453
454template <typename T>
455const size_t* MatrixCSR<T>::RowPointersData() const
456{
457 return m_rowPointers.data();
458}
459
460template <typename T>
462{
463 return m_columnIndices.data();
464}
465
466template <typename T>
468{
469 return m_nonZeros.begin();
470}
471
472template <typename T>
474{
475 return m_nonZeros.cbegin();
476}
477
478template <typename T>
480{
481 return m_nonZeros.end();
482}
483
484template <typename T>
486{
487 return m_nonZeros.cend();
488}
489
490template <typename T>
492{
493 return m_rowPointers.begin();
494}
495
496template <typename T>
498{
499 return m_rowPointers.cbegin();
500}
501
502template <typename T>
504{
505 return m_rowPointers.end();
506}
507
508template <typename T>
510{
511 return m_rowPointers.cend();
512}
513
514template <typename T>
516{
517 return m_columnIndices.begin();
518}
519
520template <typename T>
522 const
523{
524 return m_columnIndices.cbegin();
525}
526
527template <typename T>
529{
530 return m_columnIndices.end();
531}
532
533template <typename T>
535{
536 return m_columnIndices.cend();
537}
538
539template <typename T>
541{
542 MatrixCSR ret(*this);
543
544 ParallelFor(ZERO_SIZE, ret.m_nonZeros.size(),
545 [&ret, &s](size_t i) { ret.m_nonZeros[i] += s; });
546
547 return ret;
548}
549
550template <typename T>
552{
553 return BinaryOp(m, std::plus<T>());
554}
555
556template <typename T>
558{
559 MatrixCSR ret(*this);
560
561 ParallelFor(ZERO_SIZE, ret.m_nonZeros.size(),
562 [&ret, &s](size_t i) { ret.m_nonZeros[i] -= s; });
563
564 return ret;
565}
566
567template <typename T>
569{
570 return BinaryOp(m, std::minus<T>());
571}
572
573template <typename T>
575{
576 MatrixCSR ret(*this);
577
578 ParallelFor(ZERO_SIZE, ret.m_nonZeros.size(),
579 [&ret, &s](size_t i) { ret.m_nonZeros[i] *= s; });
580
581 return ret;
582}
583
584template <typename T>
585template <size_t R, size_t C, typename ME>
591
592template <typename T>
594{
595 MatrixCSR ret(*this);
596
597 ParallelFor(ZERO_SIZE, ret.m_nonZeros.size(),
598 [&ret, &s](size_t i) { ret.m_nonZeros[i] /= s; });
599
600 return ret;
601}
602
603template <typename T>
605{
606 return Add(s);
607}
608
609template <typename T>
611{
612 return Add(m);
613}
614
615template <typename T>
617{
618 MatrixCSR ret(*this);
619
620 ParallelFor(ZERO_SIZE, ret.m_nonZeros.size(), [&ret, &s](size_t i) {
621 ret.m_nonZeros[i] = s - ret.m_nonZeros[i];
622 });
623
624 return ret;
625}
626
627template <typename T>
629{
630 return m.Sub(*this);
631}
632
633template <typename T>
635{
636 return Mul(s);
637}
638
639template <typename T>
641{
642 MatrixCSR ret(*this);
643
644 ParallelFor(ZERO_SIZE, ret.m_nonZeros.size(), [&ret, &s](size_t i) {
645 ret.m_nonZeros[i] = s / ret.m_nonZeros[i];
646 });
647
648 return ret;
649}
650
651template <typename T>
653{
654 ParallelFor(ZERO_SIZE, m_nonZeros.size(),
655 [this, &s](size_t i) { m_nonZeros[i] += s; });
656}
657
658template <typename T>
660{
661 Set(Add(m));
662}
663
664template <typename T>
666{
667 ParallelFor(ZERO_SIZE, m_nonZeros.size(),
668 [this, &s](size_t i) { m_nonZeros[i] -= s; });
669}
670
671template <typename T>
673{
674 Set(Sub(m));
675}
676
677template <typename T>
679{
680 ParallelFor(ZERO_SIZE, m_nonZeros.size(),
681 [this, &s](size_t i) { m_nonZeros[i] *= s; });
682}
683
684template <typename T>
685template <size_t R, size_t C, typename ME>
687{
689
690 *this = std::move(result);
691}
692
693template <typename T>
695{
696 ParallelFor(ZERO_SIZE, m_nonZeros.size(),
697 [this, &s](size_t i) { m_nonZeros[i] /= s; });
698}
699
700template <typename T>
702{
703 return ParallelReduce(
705 [this](size_t start, size_t end, T init) {
706 T result = init;
707
708 for (size_t i = start; i < end; ++i)
709 {
710 result += m_nonZeros[i];
711 }
712
713 return result;
714 },
715 std::plus<T>());
716}
717
718template <typename T>
720{
721 return Sum() / NumberOfNonZeros();
722}
723
724template <typename T>
726{
727 return ParallelReduce(
728 ZERO_SIZE, NumberOfNonZeros(), std::numeric_limits<T>::max(),
729 [this](size_t start, size_t end, T init) {
730 T result = init;
731
732 for (size_t i = start; i < end; ++i)
733 {
734 result = std::min(result, m_nonZeros[i]);
735 }
736
737 return result;
738 },
739 [](const T& a, const T& b) { return std::min(a, b); });
740}
741
742template <typename T>
744{
745 return ParallelReduce(
746 ZERO_SIZE, NumberOfNonZeros(), std::numeric_limits<T>::min(),
747 [this](size_t start, size_t end, T init) {
748 T result = init;
749
750 for (size_t i = start; i < end; ++i)
751 {
752 result = std::max(result, m_nonZeros[i]);
753 }
754
755 return result;
756 },
757 [](const T& a, const T& b) { return std::max(a, b); });
758}
759
760template <typename T>
762{
763 return ParallelReduce(
764 ZERO_SIZE, NumberOfNonZeros(), std::numeric_limits<T>::max(),
765 [this](size_t start, size_t end, T init) {
766 T result = init;
767
768 for (size_t i = start; i < end; ++i)
769 {
770 result = CubbyFlow::AbsMin(result, m_nonZeros[i]);
771 }
772
773 return result;
774 },
776}
777
778template <typename T>
780{
781 return ParallelReduce(
783 [this](size_t start, size_t end, T init) {
784 T result = init;
785
786 for (size_t i = start; i < end; ++i)
787 {
788 result = CubbyFlow::AbsMax(result, m_nonZeros[i]);
789 }
790
791 return result;
792 },
794}
795
796template <typename T>
798{
799 assert(IsSquare());
800
801 return ParallelReduce(
802 ZERO_SIZE, GetRows(), T(0),
803 [this](size_t start, size_t end, T init) {
804 T result = init;
805
806 for (size_t i = start; i < end; ++i)
807 {
808 result += (*this)(i, i);
809 }
810
811 return result;
812 },
813 std::plus<T>());
814}
815
816template <typename T>
817template <typename U>
819{
821 ret.Reserve(GetRows(), GetCols(), NumberOfNonZeros());
822
823 auto nnz = ret.NonZeroBegin();
824 auto ci = ret.ColumnIndicesBegin();
825 auto rp = ret.RowPointersBegin();
826
827 ParallelFor(ZERO_SIZE, m_nonZeros.size(), [&nnz, this, &ci](size_t i) {
828 nnz[i] = static_cast<U>(m_nonZeros[i]);
829 ci[i] = m_columnIndices[i];
830 });
831
832 ParallelFor(ZERO_SIZE, m_rowPointers.size(),
833 [&rp, this](size_t i) { rp[i] = m_rowPointers[i]; });
834
835 return ret;
836}
837
838template <typename T>
839template <size_t R, size_t C, typename E>
841{
842 Set(m);
843
844 return *this;
845}
846
847template <typename T>
849{
850 IAdd(s);
851
852 return *this;
853}
854
855template <typename T>
857{
858 IAdd(m);
859
860 return *this;
861}
862
863template <typename T>
865{
866 ISub(s);
867
868 return *this;
869}
870
871template <typename T>
873{
874 ISub(m);
875
876 return *this;
877}
878
879template <typename T>
881{
882 IMul(s);
883
884 return *this;
885}
886
887template <typename T>
888template <size_t R, size_t C, typename ME>
890{
891 IMul(m);
892
893 return *this;
894}
895
896template <typename T>
898{
899 IDiv(s);
900
901 return *this;
902}
903
904template <typename T>
905T MatrixCSR<T>::operator()(size_t i, size_t j) const
906{
907 size_t nzIndex = HasElement(i, j);
908
909 if (nzIndex == std::numeric_limits<size_t>::max())
910 {
911 return 0.0;
912 }
913
914 return m_nonZeros[nzIndex];
915}
916
917template <typename T>
919{
920 return IsEqual(m);
921}
922
923template <typename T>
925{
926 return !IsEqual(m);
927}
928
929template <typename T>
931{
933
934 ret.m_size = Vector2UZ(m, m);
935 ret.m_nonZeros.resize(m, 1.0);
936 ret.m_columnIndices.resize(m);
937 std::iota(ret.m_columnIndices.begin(), ret.m_columnIndices.end(), 0);
938 ret.m_rowPointers.resize(m + 1);
939 std::iota(ret.m_rowPointers.begin(), ret.m_rowPointers.end(), 0);
940
941 return ret;
942}
943
944template <typename T>
945size_t MatrixCSR<T>::HasElement(size_t i, size_t j) const
946{
947 if (i >= m_size.x || j >= m_size.y)
948 {
949 return std::numeric_limits<size_t>::max();
950 }
951
952 const size_t rowBegin = m_rowPointers[i];
953 const size_t rowEnd = m_rowPointers[i + 1];
954
955 if (const auto iter = BinaryFind(m_columnIndices.begin() + rowBegin,
956 m_columnIndices.begin() + rowEnd, j);
957 iter != m_columnIndices.begin() + rowEnd)
958 {
959 return static_cast<size_t>(iter - m_columnIndices.begin());
960 }
961
962 return std::numeric_limits<size_t>::max();
963}
964
965template <typename T>
966template <typename Op>
968{
969 assert(m_size == m.m_size);
970
972
973 for (size_t i = 0; i < m_size.x; ++i)
974 {
975 std::vector<size_t> col;
976 std::vector<double> nnz;
977
978 auto colIterA = m_columnIndices.begin() + m_rowPointers[i];
979 auto colIterB = m.m_columnIndices.begin() + m.m_rowPointers[i];
980 auto colEndA = m_columnIndices.begin() + m_rowPointers[i + 1];
981 auto colEndB = m.m_columnIndices.begin() + m.m_rowPointers[i + 1];
982 auto nnzIterA = m_nonZeros.begin() + m_rowPointers[i];
983 auto nnzIterB = m.m_nonZeros.begin() + m.m_rowPointers[i];
984
985 while (colIterA != colEndA || colIterB != colEndB)
986 {
987 if (colIterB == colEndB || *colIterA < *colIterB)
988 {
989 col.push_back(*colIterA);
990 nnz.push_back(op(*nnzIterA, 0));
991 ++colIterA;
992 ++nnzIterA;
993 }
994 else if (colIterA == colEndA || *colIterA > *colIterB)
995 {
996 col.push_back(*colIterB);
997 nnz.push_back(op(0, *nnzIterB));
998 ++colIterB;
999 ++nnzIterB;
1000 }
1001 else
1002 {
1003 assert(*colIterA == *colIterB);
1004
1005 col.push_back(*colIterB);
1006 nnz.push_back(op(*nnzIterA, *nnzIterB));
1007 ++colIterA;
1008 ++nnzIterA;
1009 ++colIterB;
1010 ++nnzIterB;
1011 }
1012 }
1013
1014 ret.AddRow(nnz, col);
1015 }
1016
1017 return ret;
1018}
1019
1020template <typename T>
1022{
1023 return a.Mul(-1);
1024}
1025
1026template <typename T>
1028{
1029 return a.Add(b);
1030}
1031
1032template <typename T>
1034{
1035 return a.Add(b);
1036}
1037
1038template <typename T>
1040{
1041 return b.Add(a);
1042}
1043
1044template <typename T>
1046{
1047 return a.Sub(b);
1048}
1049
1050template <typename T>
1052{
1053 return a.Sub(b);
1054}
1055
1056template <typename T>
1058{
1059 return b.RSub(a);
1060}
1061
1062template <typename T>
1064{
1065 return a.Mul(b);
1066}
1067
1068template <typename T>
1070{
1071 return b.RMul(a);
1072}
1073
1074template <typename T, size_t R, size_t C, typename ME>
1077{
1078 return a.Mul(b);
1079}
1080
1081template <typename T>
1083{
1084 return a.Div(b);
1085}
1086
1087template <typename T>
1089{
1090 return b.RDiv(a);
1091}
1092} // namespace CubbyFlow
1093
1094#endif
Compressed Sparse Row (CSR) matrix class.
Definition MatrixCSR.hpp:70
MatrixCSR< U > CastTo() const
Type-casts to different value-typed matrix.
Definition MatrixCSR-Impl.hpp:818
bool IsEqual(const MatrixCSR &other) const
Definition MatrixCSR-Impl.hpp:315
typename NonZeroContainerType::const_iterator ConstNonZeroIterator
Definition MatrixCSR.hpp:89
MatrixCSR RSub(const T &s) const
Returns input scalar - this matrix.
Definition MatrixCSR-Impl.hpp:616
T AbsMax() const
Returns absolute maximum among all elements.
Definition MatrixCSR-Impl.hpp:779
IndexContainerType::iterator IndexIterator
Definition MatrixCSR.hpp:92
IndexContainerType::const_iterator ConstIndexIterator
Definition MatrixCSR.hpp:93
MatrixCSR Add(const T &s) const
Returns this matrix + input scalar.
Definition MatrixCSR-Impl.hpp:540
void AddElement(size_t i, size_t j, const T &value)
Adds non-zero element to (i, j).
Definition MatrixCSR-Impl.hpp:227
void IAdd(const T &s)
Adds input scalar to this matrix.
Definition MatrixCSR-Impl.hpp:652
void Set(const T &s)
Sets whole matrix with input scalar.
Definition MatrixCSR-Impl.hpp:135
IndexIterator RowPointersBegin()
Returns the begin iterator of the row pointers.
Definition MatrixCSR-Impl.hpp:491
size_t NumberOfNonZeros() const
Returns the number of non-zero elements.
Definition MatrixCSR-Impl.hpp:413
size_t GetRows() const
Returns number of rows of this matrix.
Definition MatrixCSR-Impl.hpp:401
const size_t & RowPointer(size_t i) const
Returns i-th row pointer.
Definition MatrixCSR-Impl.hpp:431
IndexIterator ColumnIndicesEnd()
Returns the end iterator of the column indices.
Definition MatrixCSR-Impl.hpp:528
const T & NonZero(size_t i) const
Returns i-th non-zero element.
Definition MatrixCSR-Impl.hpp:419
T Sum() const
Returns sum of all elements.
Definition MatrixCSR-Impl.hpp:701
void Compress(const std::initializer_list< std::initializer_list< T > > &lst, T epsilon=std::numeric_limits< T >::epsilon())
Compresses given initializer list lst into a sparse matrix.
Definition MatrixCSR-Impl.hpp:159
std::vector< T > NonZeroContainerType
Definition MatrixCSR.hpp:87
void IDiv(const T &s)
Divides this matrix with input scalar.
Definition MatrixCSR-Impl.hpp:694
T operator()(size_t i, size_t j) const
Returns (i,j) element.
Definition MatrixCSR-Impl.hpp:905
MatrixCSR & operator/=(const T &s)
Division assignment with input scalar.
Definition MatrixCSR-Impl.hpp:897
bool IsSquare() const
Returns true if this matrix is a square matrix.
Definition MatrixCSR-Impl.hpp:389
MatrixCSR & operator*=(const T &s)
Multiplication assignment with input scalar.
Definition MatrixCSR-Impl.hpp:880
const size_t * RowPointersData() const
Returns constant pointer of the row pointers data.
Definition MatrixCSR-Impl.hpp:455
T * NonZeroData()
Returns pointer of the non-zero elements data.
Definition MatrixCSR-Impl.hpp:443
bool operator==(const MatrixCSR &m) const
Returns true if is equal to m.
Definition MatrixCSR-Impl.hpp:918
NonZeroIterator NonZeroBegin()
Returns the begin iterator of the non-zero elements.
Definition MatrixCSR-Impl.hpp:467
const size_t & ColumnIndex(size_t i) const
Returns i-th column index.
Definition MatrixCSR-Impl.hpp:437
static MatrixCSR< T > MakeIdentity(size_t m)
Definition MatrixCSR-Impl.hpp:930
void AddRow(const NonZeroContainerType &nonZeros, const IndexContainerType &columnIndices)
Definition MatrixCSR-Impl.hpp:265
void Clear()
Clears the matrix and make it zero-dimensional.
Definition MatrixCSR-Impl.hpp:125
void IMul(const T &s)
Multiplies input scalar to this matrix.
Definition MatrixCSR-Impl.hpp:678
MatrixCSR()
Constructs an empty matrix.
Definition MatrixCSR-Impl.hpp:77
T Min() const
Returns minimum among all elements.
Definition MatrixCSR-Impl.hpp:725
bool operator!=(const MatrixCSR &m) const
Returns true if is not equal to m.
Definition MatrixCSR-Impl.hpp:924
bool IsSimilar(const MatrixCSR &other, double tol=std::numeric_limits< double >::epsilon()) const
Definition MatrixCSR-Impl.hpp:352
IndexIterator ColumnIndicesBegin()
Returns the begin iterator of the column indices.
Definition MatrixCSR-Impl.hpp:515
T AbsMin() const
Returns absolute minimum among all elements.
Definition MatrixCSR-Impl.hpp:761
Vector2UZ Size() const
Returns the size of this matrix.
Definition MatrixCSR-Impl.hpp:395
MatrixCSR Sub(const T &s) const
Returns this matrix - input scalar.
Definition MatrixCSR-Impl.hpp:557
T Avg() const
Returns average of all elements.
Definition MatrixCSR-Impl.hpp:719
void SetElement(size_t i, size_t j, const T &value)
Sets non-zero element to (i, j).
Definition MatrixCSR-Impl.hpp:295
MatrixCSR Div(const T &s) const
Returns this matrix / input scalar.
Definition MatrixCSR-Impl.hpp:593
size_t GetCols() const
Returns number of columns of this matrix.
Definition MatrixCSR-Impl.hpp:407
std::vector< size_t > IndexContainerType
Definition MatrixCSR.hpp:91
T Max() const
Returns maximum among all elements.
Definition MatrixCSR-Impl.hpp:743
MatrixCSR RMul(const T &s) const
Returns input scalar * this matrix.
Definition MatrixCSR-Impl.hpp:634
T Trace() const
Definition MatrixCSR-Impl.hpp:797
MatrixCSR RAdd(const T &s) const
Returns input scalar + this matrix.
Definition MatrixCSR-Impl.hpp:604
const size_t * ColumnIndicesData() const
Returns constant pointer of the column indices data.
Definition MatrixCSR-Impl.hpp:461
void ISub(const T &s)
Subtracts input scalar from this matrix.
Definition MatrixCSR-Impl.hpp:665
IndexIterator RowPointersEnd()
Returns the end iterator of the row pointers.
Definition MatrixCSR-Impl.hpp:503
MatrixCSR RDiv(const T &s) const
Returns input matrix / this scalar.
Definition MatrixCSR-Impl.hpp:640
NonZeroIterator NonZeroEnd()
Returns the end iterator of the non-zero elements.
Definition MatrixCSR-Impl.hpp:479
MatrixCSR & operator=(const MatrixCSR &other)
Copies to this matrix.
MatrixCSR & operator-=(const T &s)
Subtraction assignment with input scalar.
Definition MatrixCSR-Impl.hpp:864
void Reserve(size_t rows, size_t cols, size_t numNonZeros)
Reserves memory space of this matrix.
Definition MatrixCSR-Impl.hpp:150
typename NonZeroContainerType::iterator NonZeroIterator
Definition MatrixCSR.hpp:88
MatrixCSR & operator+=(const T &s)
Addition assignment with input scalar.
Definition MatrixCSR-Impl.hpp:848
MatrixCSR Mul(const T &s) const
Returns this matrix * input scalar.
Definition MatrixCSR-Impl.hpp:574
size_t GetCols() const
Number of columns.
Definition MatrixCSR-Impl.hpp:41
T operator()(size_t i, size_t j) const
Returns matrix element at (i, j).
Definition MatrixCSR-Impl.hpp:47
MatrixCSRMatrixMul(const MatrixCSR< T > &m1, const ME &m2)
Definition MatrixCSR-Impl.hpp:23
size_t GetRows() const
Number of rows.
Definition MatrixCSR-Impl.hpp:35
Derived & GetDerived()
Returns actual implementation (the subclass).
Definition MatrixExpression-Impl.hpp:508
Definition Matrix.hpp:30
constexpr size_t GetCols() const
Definition Matrix-Impl.hpp:266
Iterator begin()
Definition Matrix-Impl.hpp:272
constexpr size_t GetRows() const
Definition Matrix-Impl.hpp:260
Iterator end()
Definition Matrix-Impl.hpp:285
Definition pybind11Utils.hpp:22
constexpr size_t ZERO_SIZE
Zero size_t.
Definition Constants.hpp:20
ForwardIter BinaryFind(ForwardIter first, ForwardIter last, const T &value, Compare comp)
Definition CppUtils-Impl.hpp:21
MatrixCSR< T > operator-(const MatrixCSR< T > &a)
Definition MatrixCSR-Impl.hpp:1021
std::enable_if_t< std::is_arithmetic< T >::value, T > AbsMax(T x, T y)
Returns the absolute maximum value among the two inputs.
Definition MathUtils-Impl.hpp:84
void ParallelFor(IndexType beginIndex, IndexType endIndex, const Function &function, ExecutionPolicy policy)
Makes a for-loop from beginIndex to endIndex in parallel.
Definition Parallel-Impl.hpp:203
Matrix< T, Rows, 1 > Vector
Definition Matrix.hpp:648
Vector2< size_t > Vector2UZ
Definition Matrix.hpp:686
MatrixCSR< T > operator+(const MatrixCSR< T > &a, const MatrixCSR< T > &b)
Definition MatrixCSR-Impl.hpp:1027
MatrixCSR< T > operator/(const MatrixCSR< T > &a, T b)
Definition MatrixCSR-Impl.hpp:1082
Value ParallelReduce(IndexType beginIndex, IndexType endIndex, const Value &identity, const Function &function, const Reduce &reduce, ExecutionPolicy policy)
Performs reduce operation in parallel.
Definition Parallel-Impl.hpp:431
Vector< T, 3 > operator*(const Quaternion< T > &q, const Vector< T, 3 > &v)
Returns quaternion q * vector v.
Definition Quaternion-Impl.hpp:529
std::enable_if_t< std::is_arithmetic< T >::value, T > AbsMin(T x, T y)
Returns the absolute minimum value among the two inputs.
Definition MathUtils-Impl.hpp:78
Definition MatrixCSR.hpp:77
Element()
Definition MatrixCSR-Impl.hpp:64