9 #ifndef CUBBYFLOW_MATRIX_CSR_IMPL_H 10 #define CUBBYFLOW_MATRIX_CSR_IMPL_H 19 template <
typename T,
typename VE>
22 assert(m_m.Cols() == m_v.size());
25 template <
typename T,
typename VE>
31 template <
typename T,
typename VE>
37 template <
typename T,
typename VE>
40 auto rp = m_m.RowPointersBegin();
41 auto ci = m_m.ColumnIndicesBegin();
42 auto nnz = m_m.NonZeroBegin();
44 size_t colBegin = rp[i];
45 size_t colEnd = rp[i + 1];
48 for (
size_t jj = colBegin; jj < colEnd; ++jj)
51 sum += nnz[jj] * m_v[j];
57 template <
typename T,
typename ME>
59 m_m1(m1), m_m2(m2), m_nnz(m1.NonZeroData()), m_rp(m1.RowPointersData()), m_ci(m1.ColumnIndicesData())
64 template <
typename T,
typename ME>
67 return { Rows(), Cols() };
70 template <
typename T,
typename ME>
76 template <
typename T,
typename ME>
82 template <
typename T,
typename ME>
85 size_t colBegin = m_rp[i];
86 size_t colEnd = m_rp[i + 1];
89 for (
size_t kk = colBegin; kk < colEnd; ++kk)
92 sum += m_nnz[kk] * m_m2(k, j);
104 template <
typename T>
110 template <
typename T>
116 template <
typename T>
122 template <
typename T>
123 template <
typename E>
129 template <
typename T>
135 template <
typename T>
138 (*this) = std::move(other);
141 template <
typename T>
146 m_rowPointers.clear();
147 m_columnIndices.clear();
148 m_rowPointers.push_back(0);
151 template <
typename T>
154 std::fill(m_nonZeros.begin(), m_nonZeros.end(), s);
157 template <
typename T>
160 m_size = other.m_size;
161 m_nonZeros = other.m_nonZeros;
162 m_rowPointers = other.m_rowPointers;
163 m_columnIndices = other.m_columnIndices;
166 template <
typename T>
169 m_size =
Size2(rows, cols);
170 m_rowPointers.resize(m_size.
x + 1);
171 m_nonZeros.resize(numNonZeros);
172 m_columnIndices.resize(numNonZeros);
175 template <
typename T>
178 size_t numRows = list.size();
179 size_t numCols = (numRows > 0) ? list.begin()->size() : 0;
181 m_size = { numRows, numCols };
183 m_rowPointers.clear();
184 m_columnIndices.clear();
186 auto rowIter = list.begin();
187 for (
size_t i = 0; i < numRows; ++i)
189 assert(numCols == rowIter->size());
190 m_rowPointers.push_back(m_nonZeros.size());
192 auto colIter = rowIter->begin();
193 for (
size_t j = 0; j < numCols; ++j)
195 if (std::fabs(*colIter) > epsilon)
197 m_nonZeros.push_back(*colIter);
198 m_columnIndices.push_back(j);
207 m_rowPointers.push_back(m_nonZeros.size());
210 template <
typename T>
211 template <
typename E>
214 size_t numRows = other.
Rows();
215 size_t numCols = other.
Cols();
217 m_size = { numRows, numCols };
219 m_columnIndices.clear();
221 const E& expression = other();
223 for (
size_t i = 0; i < numRows; ++i)
225 m_rowPointers.push_back(m_nonZeros.size());
227 for (
size_t j = 0; j < numCols; ++j)
229 T val = expression(i, j);
231 if (std::fabs(val) > epsilon)
233 m_nonZeros.push_back(val);
234 m_columnIndices.push_back(j);
239 m_rowPointers.push_back(m_nonZeros.size());
242 template <
typename T>
248 template <
typename T>
251 ssize_t numRowsToAdd =
static_cast<ssize_t
>(element.i) - static_cast<ssize_t>(m_size.
x) + 1;
252 if (numRowsToAdd > 0)
254 for (ssize_t i = 0; i < numRowsToAdd; ++i)
260 m_size.
y = std::max(m_size.
y, element.j + 1);
262 size_t rowBegin = m_rowPointers[element.i];
263 size_t rowEnd = m_rowPointers[element.i + 1];
265 auto colIdxIter = std::lower_bound(m_columnIndices.begin() + rowBegin, m_columnIndices.begin() + rowEnd, element.j);
266 auto offset = colIdxIter - m_columnIndices.begin();
268 m_columnIndices.insert(colIdxIter, element.j);
269 m_nonZeros.insert(m_nonZeros.begin() + offset, element.value);
271 for (
size_t i = element.i + 1; i < m_rowPointers.size(); ++i)
277 template <
typename T>
280 assert(nonZeros.size() == columnIndices.size());
285 std::vector<std::pair<T, size_t>> zipped;
286 for (
size_t i = 0; i < nonZeros.size(); ++i)
288 zipped.emplace_back(nonZeros[i], columnIndices[i]);
289 m_size.
y = std::max(m_size.
y, columnIndices[i] + 1);
292 std::sort(zipped.begin(), zipped.end(), [](std::pair<T, size_t> a, std::pair<T, size_t> b)
294 return a.second < b.second;
297 for (
size_t i = 0; i < zipped.size(); ++i)
299 m_nonZeros.push_back(zipped[i].first);
300 m_columnIndices.push_back(zipped[i].second);
303 m_rowPointers.push_back(m_nonZeros.size());
306 template <
typename T>
312 template <
typename T>
315 size_t nzIndex = HasElement(element.i, element.j);
317 if (nzIndex == std::numeric_limits<size_t>::max())
323 m_nonZeros[nzIndex] = element.value;
327 template <
typename T>
330 if (m_size != other.m_size)
335 if (m_nonZeros.size() != other.m_nonZeros.size())
340 for (
size_t i = 0; i < m_nonZeros.size(); ++i)
342 if (m_nonZeros[i] != other.m_nonZeros[i])
347 if (m_columnIndices[i] != other.m_columnIndices[i])
353 for (
size_t i = 0; i < m_rowPointers.size(); ++i)
355 if (m_rowPointers[i] != other.m_rowPointers[i])
364 template <
typename T>
367 if (m_size != other.m_size)
372 if (m_nonZeros.size() != other.m_nonZeros.size())
377 for (
size_t i = 0; i < m_nonZeros.size(); ++i)
379 if (std::fabs(m_nonZeros[i] - other.m_nonZeros[i]) > tol)
384 if (m_columnIndices[i] != other.m_columnIndices[i])
390 for (
size_t i = 0; i < m_rowPointers.size(); ++i)
392 if (m_rowPointers[i] != other.m_rowPointers[i])
401 template <
typename T>
407 template <
typename T>
413 template <
typename T>
419 template <
typename T>
425 template <
typename T>
428 return m_nonZeros.size();
431 template <
typename T>
434 return m_nonZeros[i];
437 template <
typename T>
440 return m_nonZeros[i];
443 template <
typename T>
446 return m_rowPointers[i];
449 template <
typename T>
452 return m_columnIndices[i];
455 template <
typename T>
458 return m_nonZeros.data();
461 template <
typename T>
464 return m_nonZeros.data();
467 template <
typename T>
470 return m_rowPointers.data();
473 template <
typename T>
476 return m_columnIndices.data();
479 template <
typename T>
482 return m_nonZeros.begin();
485 template <
typename T>
488 return m_nonZeros.cbegin();
491 template <
typename T>
494 return m_nonZeros.end();
497 template <
typename T>
500 return m_nonZeros.cend();
503 template <
typename T>
506 return m_rowPointers.begin();
509 template <
typename T>
512 return m_rowPointers.cbegin();
515 template <
typename T>
518 return m_rowPointers.end();
521 template <
typename T>
524 return m_rowPointers.cend();
527 template <
typename T>
530 return m_columnIndices.begin();
533 template <
typename T>
536 return m_columnIndices.cbegin();
539 template <
typename T>
542 return m_columnIndices.end();
545 template <
typename T>
548 return m_columnIndices.cend();
551 template <
typename T>
559 template <
typename T>
562 return BinaryOp(m, std::plus<T>());
565 template <
typename T>
573 template <
typename T>
576 return BinaryOp(m, std::minus<T>());
579 template <
typename T>
587 template <
typename T>
588 template <
typename VE>
594 template <
typename T>
595 template <
typename ME>
601 template <
typename T>
609 template <
typename T>
615 template <
typename T>
621 template <
typename T>
625 ParallelFor(
ZERO_SIZE, ret.m_nonZeros.size(), [&](
size_t i) { ret.m_nonZeros[i] = s - ret.m_nonZeros[i]; });
629 template <
typename T>
635 template <
typename T>
641 template <
typename T>
645 ParallelFor(
ZERO_SIZE, ret.m_nonZeros.size(), [&](
size_t i) { ret.m_nonZeros[i] = s / ret.m_nonZeros[i]; });
649 template <
typename T>
655 template <
typename T>
661 template <
typename T>
667 template <
typename T>
673 template <
typename T>
679 template <
typename T>
680 template <
typename ME>
684 *
this = std::move(result);
687 template <
typename T>
693 template <
typename T>
697 [&](
size_t start,
size_t end, T init)
701 for (
size_t i = start; i < end; ++i)
703 result += m_nonZeros[i];
710 template <
typename T>
716 template <
typename T>
719 const T& (*m_min)(
const T&,
const T&) = std::min<T>;
722 [&](
size_t start,
size_t end, T init)
726 for (
size_t i = start; i < end; ++i)
728 result = std::min(result, m_nonZeros[i]);
735 template <
typename T>
738 const T& (*m_max)(
const T&,
const T&) = std::max<T>;
741 [&](
size_t start,
size_t end, T init)
745 for (
size_t i = start; i < end; ++i)
747 result = std::max(result, m_nonZeros[i]);
754 template <
typename T>
758 [&](
size_t start,
size_t end, T init)
762 for (
size_t i = start; i < end; ++i)
767 }, CubbyFlow::AbsMin<T>);
770 template <
typename T>
774 [&](
size_t start,
size_t end, T init)
778 for (
size_t i = start; i < end; ++i)
784 }, CubbyFlow::AbsMax<T>);
787 template <
typename T>
793 [&](
size_t start,
size_t end, T init)
797 for (
size_t i = start; i < end; ++i)
799 result += (*this)(i, i);
806 template <
typename T>
807 template <
typename U>
819 nnz[i] =
static_cast<U
>(m_nonZeros[i]);
820 ci[i] = m_columnIndices[i];
828 template <
typename T>
829 template <
typename E>
836 template <
typename T>
843 template <
typename T>
846 m_size = other.m_size;
847 other.m_size =
Size2();
848 m_nonZeros = std::move(other.m_nonZeros);
849 m_rowPointers = std::move(other.m_rowPointers);
850 m_columnIndices = std::move(other.m_columnIndices);
854 template <
typename T>
861 template <
typename T>
868 template <
typename T>
875 template <
typename T>
882 template <
typename T>
889 template <
typename T>
890 template <
typename ME>
897 template <
typename T>
904 template <
typename T>
907 size_t nzIndex = HasElement(i, j);
909 if (nzIndex == std::numeric_limits<size_t>::max())
914 return m_nonZeros[nzIndex];
917 template <
typename T>
923 template <
typename T>
929 template <
typename T>
933 ret.m_size =
Size2(m, m);
934 ret.m_nonZeros.resize(m, 1.0);
935 ret.m_columnIndices.resize(m);
936 std::iota(ret.m_columnIndices.begin(), ret.m_columnIndices.end(),
ZERO_SIZE);
937 ret.m_rowPointers.resize(m + 1);
938 std::iota(ret.m_rowPointers.begin(), ret.m_rowPointers.end(),
ZERO_SIZE);
942 template <
typename T>
945 if (i >= m_size.
x || j >= m_size.
y)
947 return std::numeric_limits<size_t>::max();
950 size_t rowBegin = m_rowPointers[i];
951 size_t rowEnd = m_rowPointers[i + 1];
953 auto iter =
BinaryFind(m_columnIndices.begin() + rowBegin, m_columnIndices.begin() + rowEnd, j);
954 if (iter != m_columnIndices.begin() + rowEnd)
956 return static_cast<size_t>(iter - m_columnIndices.begin());
959 return std::numeric_limits<size_t>::max();
962 template <
typename T>
963 template <
typename Op>
966 assert(m_size == m.m_size);
970 for (
size_t i = 0; i < m_size.
x; ++i)
972 std::vector<size_t> col;
973 std::vector<double> nnz;
975 auto colIterA = m_columnIndices.begin() + m_rowPointers[i];
976 auto colIterB = m.m_columnIndices.begin() + m.m_rowPointers[i];
977 auto colEndA = m_columnIndices.begin() + m_rowPointers[i + 1];
978 auto colEndB = m.m_columnIndices.begin() + m.m_rowPointers[i + 1];
979 auto nnzIterA = m_nonZeros.begin() + m_rowPointers[i];
980 auto nnzIterB = m.m_nonZeros.begin() + m.m_rowPointers[i];
982 while (colIterA != colEndA || colIterB != colEndB)
984 if (colIterB == colEndB || *colIterA < *colIterB)
986 col.push_back(*colIterA);
987 nnz.push_back(op(*nnzIterA, 0));
991 else if (colIterA == colEndA || *colIterA > *colIterB)
993 col.push_back(*colIterB);
994 nnz.push_back(op(0, *nnzIterB));
1000 assert(*colIterA == *colIterB);
1001 col.push_back(*colIterB);
1002 nnz.push_back(op(*nnzIterA, *nnzIterB));
1017 template <
typename T>
1023 template <
typename T>
1029 template <
typename T>
1035 template <
typename T>
1041 template <
typename T>
1047 template <
typename T>
1053 template <
typename T>
1059 template <
typename T>
1065 template <
typename T>
1071 template <
typename T,
typename VE>
1077 template <
typename T,
typename ME>
1083 template <
typename T>
1089 template <
typename T>
Vector expression for CSR matrix-vector multiplication.
Definition: MatrixCSR.h:31
void ISub(const T &s)
Subtracts input scalar from this matrix.
Definition: MatrixCSR-Impl.h:662
bool operator!=(const MatrixCSR &m) const
Returns true if is not equal to m.
Definition: MatrixCSR-Impl.h:924
T Trace() const
Definition: MatrixCSR-Impl.h:788
MatrixCSR< U > CastTo() const
Type-casts to different value-typed matrix.
Definition: MatrixCSR-Impl.h:808
T AbsMin(T x, T y)
Returns the absolute minimum value among the two inputs.
Definition: MathUtils-Impl.h:39
void Clear()
Clears the matrix and make it zero-dimensional.
Definition: MatrixCSR-Impl.h:142
const T & NonZero(size_t i) const
Returns i-th non-zero element.
Definition: MatrixCSR-Impl.h:432
Matrix expression for CSR matrix-matrix multiplication.
Definition: MatrixCSR.h:60
const size_t * RowPointersData() const
Returns constant pointer of the row pointers data.
Definition: MatrixCSR-Impl.h:468
T AbsMax() const
Returns absolute maximum among all elements.
Definition: MatrixCSR-Impl.h:771
Matrix< T, 2, 2 > operator+(const Matrix< T, 2, 2 > &a, const Matrix< T, 2, 2 > &b)
Returns a + b (element-size).
Definition: Matrix2x2-Impl.h:660
T x
X (or the first) component of the point.
Definition: Point2.h:28
MatrixCSR & operator+=(const T &s)
Addition assignment with input scalar.
Definition: MatrixCSR-Impl.h:855
bool IsEqual(const MatrixCSR &other) const
Definition: MatrixCSR-Impl.h:328
MatrixCSRMatrixMul(const MatrixCSR< T > &m1, const ME &m2)
Definition: MatrixCSR-Impl.h:58
size_t Cols() const
Number of columns.
Definition: MatrixCSR-Impl.h:77
Base class for vector expression.
Definition: VectorExpression.h:28
std::vector< size_t > IndexContainerType
Definition: MatrixCSR.h:116
void IMul(const T &s)
Multiplies input scalar to this matrix.
Definition: MatrixCSR-Impl.h:674
T Sum() const
Returns sum of all elements.
Definition: MatrixCSR-Impl.h:694
2-D point class.
Definition: Point2.h:25
const size_t * ColumnIndicesData() const
Returns constant pointer of the column indices data.
Definition: MatrixCSR-Impl.h:474
IndexIterator ColumnIndicesEnd()
Returns the end iterator of the column indices.
Definition: MatrixCSR-Impl.h:540
IndexContainerType::const_iterator ConstIndexIterator
Definition: MatrixCSR.h:118
T Min() const
Returns minimum among all elements.
Definition: MatrixCSR-Impl.h:717
T * NonZeroData()
Returns pointer of the non-zero elements data.
Definition: MatrixCSR-Impl.h:456
void IDiv(const T &s)
Divides this matrix with input scalar.
Definition: MatrixCSR-Impl.h:688
const size_t & RowPointer(size_t i) const
Returns i-th row pointer.
Definition: MatrixCSR-Impl.h:444
MatrixCSR Div(const T &s) const
Returns this matrix / input scalar.
Definition: MatrixCSR-Impl.h:602
bool IsSimilar(const MatrixCSR &other, double tol=std::numeric_limits< double >::epsilon()) const
Returns true if this matrix is similar to the input matrix within the given tolerance.
Definition: MatrixCSR-Impl.h:365
ForwardIter BinaryFind(ForwardIter first, ForwardIter last, const T &value, Compare comp)
Definition: CppUtils-Impl.h:19
Point2< size_t > Size2
Definition: Size2.h:16
T operator[](size_t i) const
Returns vector element at i.
Definition: MatrixCSR-Impl.h:38
Size2 size() const
Returns the size of this matrix.
Definition: MatrixCSR-Impl.h:408
void Set(const T &s)
Sets whole matrix with input scalar.
Definition: MatrixCSR-Impl.h:152
MatrixCSR Add(const T &s) const
Returns this matrix + input scalar.
Definition: MatrixCSR-Impl.h:552
MatrixCSR Mul(const T &s) const
Returns this matrix * input scalar.
Definition: MatrixCSR-Impl.h:580
T y
Y (or the second) component of the point.
Definition: Point2.h:34
void AddElement(size_t i, size_t j, const T &value)
Adds non-zero element to (i, j).
Definition: MatrixCSR-Impl.h:243
void SetElement(size_t i, size_t j, const T &value)
Sets non-zero element to (i, j).
Definition: MatrixCSR-Impl.h:307
IndexContainerType::iterator IndexIterator
Definition: MatrixCSR.h:117
size_t Rows() const
Returns number of rows of this matrix.
Definition: MatrixCSR-Impl.h:414
Matrix< T, 2, 2 > operator/(const Matrix< T, 2, 2 > &a, T b)
Definition: Matrix2x2-Impl.h:720
Definition: pybind11Utils.h:24
void ParallelFor(IndexType beginIndex, IndexType endIndex, const Function &function, ExecutionPolicy policy)
Makes a for-loop from beginIndex to endIndex in parallel.
Definition: Parallel-Impl.h:201
bool IsSquare() const
Returns true if this matrix is a square matrix.
Definition: MatrixCSR-Impl.h:402
Size2 size() const
Size of the matrix.
Definition: MatrixCSR-Impl.h:65
IndexIterator ColumnIndicesBegin()
Returns the begin iterator of the column indices.
Definition: MatrixCSR-Impl.h:528
size_t NumberOfNonZeros() const
Returns the number of non-zero elements.
Definition: MatrixCSR-Impl.h:426
MatrixCSR Sub(const T &s) const
Returns this matrix - input scalar.
Definition: MatrixCSR-Impl.h:566
MatrixCSRVectorMul(const MatrixCSR< T > &m, const VE &v)
Definition: MatrixCSR-Impl.h:20
NonZeroIterator NonZeroEnd()
Returns the end iterator of the non-zero elements.
Definition: MatrixCSR-Impl.h:492
void Compress(const std::initializer_list< std::initializer_list< T >> &list, T epsilon=std::numeric_limits< T >::epsilon())
Compresses given initializer list list into a sparse matrix.
Definition: MatrixCSR-Impl.h:176
IndexIterator RowPointersEnd()
Returns the end iterator of the row pointers.
Definition: MatrixCSR-Impl.h:516
MatrixCSR RMul(const T &s) const
Returns input scalar * this matrix.
Definition: MatrixCSR-Impl.h:636
typename NonZeroContainerType::iterator NonZeroIterator
Definition: MatrixCSR.h:113
size_t Rows() const
Number of rows.
Definition: MatrixExpression-Impl.h:22
MatrixCSR & operator*=(const T &s)
Multiplication assignment with input scalar.
Definition: MatrixCSR-Impl.h:883
static MatrixCSR< T > MakeIdentity(size_t m)
Makes a m x m matrix with all diagonal elements to 1, and other elements to 0.
Definition: MatrixCSR-Impl.h:930
Element()
Definition: MatrixCSR-Impl.h:99
Compressed Sparse Row (CSR) matrix class.
Definition: MatrixCSR.h:19
Matrix< T, 2, 2 > operator-(const Matrix< T, 2, 2 > &a)
Returns a matrix with opposite sign.
Definition: Matrix2x2-Impl.h:654
typename NonZeroContainerType::const_iterator ConstNonZeroIterator
Definition: MatrixCSR.h:114
MatrixCSR RAdd(const T &s) const
Returns input scalar + this matrix.
Definition: MatrixCSR-Impl.h:610
const MatrixCSRMatrixMul< T, ME > & operator()() const
Returns actual implementation (the subclass).
Definition: MatrixExpression-Impl.h:34
constexpr size_t ZERO_SIZE
Zero size_t.
Definition: Constants.h:18
void Reserve(size_t rows, size_t cols, size_t numNonZeros)
Reserves memory space of this matrix.
Definition: MatrixCSR-Impl.h:167
void IAdd(const T &s)
Adds input scalar to this matrix.
Definition: MatrixCSR-Impl.h:650
T Max() const
Returns maximum among all elements.
Definition: MatrixCSR-Impl.h:736
Base class for matrix expression.
Definition: MatrixExpression.h:27
size_t Rows() const
Number of rows.
Definition: MatrixCSR-Impl.h:71
size_t Cols() const
Returns number of columns of this matrix.
Definition: MatrixCSR-Impl.h:420
MatrixCSR & operator=(const E &m)
Compresses input (dense) matrix expression into a sparse matrix.
MatrixCSR & operator/=(const T &s)
Division assignment with input scalar.
Definition: MatrixCSR-Impl.h:898
MatrixCSR RDiv(const T &s) const
Returns input matrix / this scalar.
Definition: MatrixCSR-Impl.h:642
Vector< T, 3 > operator*(const Quaternion< T > &q, const Vector< T, 3 > &v)
Returns quaternion q * vector v.
Definition: Quaternion-Impl.h:481
const size_t & ColumnIndex(size_t i) const
Returns i-th column index.
Definition: MatrixCSR-Impl.h:450
MatrixCSR & operator-=(const T &s)
Subtraction assignment with input scalar.
Definition: MatrixCSR-Impl.h:869
T AbsMax(T x, T y)
Returns the absolute maximum value among the two inputs.
Definition: MathUtils-Impl.h:45
size_t size() const
Size of the vector.
Definition: MatrixCSR-Impl.h:32
MatrixCSR()
Constructs an empty matrix.
Definition: MatrixCSR-Impl.h:111
MatrixCSR RSub(const T &s) const
Returns input scalar - this matrix.
Definition: MatrixCSR-Impl.h:622
size_t Cols() const
Number of columns.
Definition: MatrixExpression-Impl.h:28
T Avg() const
Returns average of all elements.
Definition: MatrixCSR-Impl.h:711
bool operator==(const MatrixCSR &m) const
Returns true if is equal to m.
Definition: MatrixCSR-Impl.h:918
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.h:407
NonZeroIterator NonZeroBegin()
Returns the begin iterator of the non-zero elements.
Definition: MatrixCSR-Impl.h:480
T AbsMin() const
Returns absolute minimum among all elements.
Definition: MatrixCSR-Impl.h:755
void AddRow(const NonZeroContainerType &nonZeros, const IndexContainerType &columnIndices)
Definition: MatrixCSR-Impl.h:278
IndexIterator RowPointersBegin()
Returns the begin iterator of the row pointers.
Definition: MatrixCSR-Impl.h:504
std::vector< double > NonZeroContainerType
Definition: MatrixCSR.h:112