11 #ifndef EIGEN_SPARSEBLOCKMATRIX_H
12 #define EIGEN_SPARSEBLOCKMATRIX_H
14 #include "./InternalHeaderCheck.h"
56 template<
typename Scalar_,
int _BlockAtCompileTime=Dynamic,
int Options_=ColMajor,
typename StorageIndex_=
int>
class BlockSparseMatrix;
58 template<
typename BlockSparseMatrixT>
class BlockSparseMatrixView;
61 template<
typename Scalar_,
int _BlockAtCompileTime,
int Options_,
typename Index_>
62 struct traits<BlockSparseMatrix<Scalar_,_BlockAtCompileTime,Options_, Index_> >
64 typedef Scalar_ Scalar;
66 typedef Sparse StorageKind;
67 typedef MatrixXpr XprKind;
73 BlockSize = _BlockAtCompileTime,
74 Flags = Options_ | NestByRefBit |
LvalueBit,
75 CoeffReadCost = NumTraits<Scalar>::ReadCost,
76 SupportedAccessPatterns = InnerRandomAccessPattern
79 template<
typename BlockSparseMatrixT>
80 struct traits<BlockSparseMatrixView<BlockSparseMatrixT> >
82 typedef Ref<Matrix<typename BlockSparseMatrixT::Scalar, BlockSparseMatrixT::BlockSize, BlockSparseMatrixT::BlockSize> > Scalar;
83 typedef Ref<Matrix<typename BlockSparseMatrixT::RealScalar, BlockSparseMatrixT::BlockSize, BlockSparseMatrixT::BlockSize> > RealScalar;
88 template<
typename Iterator,
bool IsColMajor>
91 typedef typename Iterator::value_type Triplet;
92 bool operator()(
const Triplet& a,
const Triplet& b)
94 return ((a.col() == b.col() && a.row() < b.row()) || (a.col() < b.col()));
96 return ((a.row() == b.row() && a.col() < b.col()) || (a.row() < b.row()));
103 template<
typename BlockSparseMatrixT>
104 class BlockSparseMatrixView :
public SparseMatrixBase<BlockSparseMatrixT>
107 typedef Ref<typename BlockSparseMatrixT::BlockScalar> Scalar;
108 typedef Ref<typename BlockSparseMatrixT::BlockRealScalar> RealScalar;
109 typedef typename BlockSparseMatrixT::Index
Index;
110 typedef BlockSparseMatrixT Nested;
112 Flags = BlockSparseMatrixT::Options,
113 Options = BlockSparseMatrixT::Options,
114 RowsAtCompileTime = BlockSparseMatrixT::RowsAtCompileTime,
115 ColsAtCompileTime = BlockSparseMatrixT::ColsAtCompileTime,
116 MaxColsAtCompileTime = BlockSparseMatrixT::MaxColsAtCompileTime,
117 MaxRowsAtCompileTime = BlockSparseMatrixT::MaxRowsAtCompileTime
120 BlockSparseMatrixView(
const BlockSparseMatrixT& spblockmat)
121 : m_spblockmat(spblockmat)
124 Index outerSize()
const
126 return (Flags&
RowMajorBit) == 1 ? this->rows() : this->cols();
130 return m_spblockmat.blockCols();
134 return m_spblockmat.blockRows();
138 return m_spblockmat.coeff(row, col);
142 return m_spblockmat.coeffRef(row, col);
145 class InnerIterator :
public BlockSparseMatrixT::BlockInnerIterator
148 InnerIterator(
const BlockSparseMatrixView& mat,
Index outer)
149 : BlockSparseMatrixT::BlockInnerIterator(mat.m_spblockmat, outer)
155 const BlockSparseMatrixT& m_spblockmat;
159 template<
typename BlockSparseMatrixT,
typename VectorType>
160 class BlockVectorView
164 BlockSize = BlockSparseMatrixT::BlockSize,
165 ColsAtCompileTime = VectorType::ColsAtCompileTime,
166 RowsAtCompileTime = VectorType::RowsAtCompileTime,
167 Flags = VectorType::Flags
169 typedef Ref<
const Matrix<
typename BlockSparseMatrixT::Scalar, (RowsAtCompileTime==1)? 1 : BlockSize, (ColsAtCompileTime==1)? 1 : BlockSize> >Scalar;
170 typedef typename BlockSparseMatrixT::Index
Index;
172 BlockVectorView(
const BlockSparseMatrixT& spblockmat,
const VectorType& vec)
173 : m_spblockmat(spblockmat),m_vec(vec)
175 inline Index cols()
const
179 inline Index size()
const
181 return m_spblockmat.blockRows();
183 inline Scalar coeff(
Index bi)
const
185 Index startRow = m_spblockmat.blockRowsIndex(bi);
186 Index rowSize = m_spblockmat.blockRowsIndex(bi+1) - startRow;
187 return m_vec.middleRows(startRow, rowSize);
191 Index startRow = m_spblockmat.blockRowsIndex(bi);
192 Index rowSize = m_spblockmat.blockRowsIndex(bi+1) - startRow;
193 return m_vec.block(startRow, j, rowSize, 1);
196 const BlockSparseMatrixT& m_spblockmat;
197 const VectorType& m_vec;
200 template<
typename VectorType,
typename Index>
class BlockVectorReturn;
204 template<
typename BlockSparseMatrixT,
typename VectorType>
205 class BlockVectorReturn
209 ColsAtCompileTime = VectorType::ColsAtCompileTime,
210 RowsAtCompileTime = VectorType::RowsAtCompileTime,
211 Flags = VectorType::Flags
213 typedef Ref<Matrix<typename VectorType::Scalar, RowsAtCompileTime, ColsAtCompileTime> > Scalar;
214 typedef typename BlockSparseMatrixT::Index
Index;
216 BlockVectorReturn(
const BlockSparseMatrixT& spblockmat, VectorType& vec)
217 : m_spblockmat(spblockmat),m_vec(vec)
219 inline Index size()
const
221 return m_spblockmat.blockRows();
223 inline Scalar coeffRef(
Index bi)
225 Index startRow = m_spblockmat.blockRowsIndex(bi);
226 Index rowSize = m_spblockmat.blockRowsIndex(bi+1) - startRow;
227 return m_vec.middleRows(startRow, rowSize);
231 Index startRow = m_spblockmat.blockRowsIndex(bi);
232 Index rowSize = m_spblockmat.blockRowsIndex(bi+1) - startRow;
233 return m_vec.block(startRow, j, rowSize, 1);
237 const BlockSparseMatrixT& m_spblockmat;
242 template<
typename Lhs,
typename Rhs>
243 class BlockSparseTimeDenseProduct;
247 template<
typename BlockSparseMatrixT,
typename VecType>
248 struct traits<BlockSparseTimeDenseProduct<BlockSparseMatrixT, VecType> >
250 typedef Dense StorageKind;
251 typedef MatrixXpr XprKind;
252 typedef typename BlockSparseMatrixT::Scalar Scalar;
253 typedef typename BlockSparseMatrixT::Index
Index;
257 MaxRowsAtCompileTime =
Dynamic,
258 MaxColsAtCompileTime =
Dynamic,
260 CoeffReadCost = internal::traits<BlockSparseMatrixT>::CoeffReadCost
265 template<
typename Lhs,
typename Rhs>
266 class BlockSparseTimeDenseProduct
267 :
public ProductBase<BlockSparseTimeDenseProduct<Lhs,Rhs>, Lhs, Rhs>
270 EIGEN_PRODUCT_PUBLIC_INTERFACE(BlockSparseTimeDenseProduct)
272 BlockSparseTimeDenseProduct(
const Lhs& lhs,
const Rhs& rhs) : Base(lhs,rhs)
275 template<
typename Dest>
void scaleAndAddTo(Dest& dest,
const typename Rhs::Scalar& alpha)
const
277 BlockVectorReturn<Lhs,Dest> tmpDest(m_lhs, dest);
278 internal::sparse_time_dense_product( BlockSparseMatrixView<Lhs>(m_lhs), BlockVectorView<Lhs, Rhs>(m_lhs, m_rhs), tmpDest, alpha);
282 BlockSparseTimeDenseProduct& operator=(
const BlockSparseTimeDenseProduct&);
285 template<
typename Scalar_,
int _BlockAtCompileTime,
int Options_,
typename StorageIndex_>
289 typedef Scalar_ Scalar;
291 typedef StorageIndex_ StorageIndex;
292 typedef typename internal::ref_selector<BlockSparseMatrix<Scalar_, _BlockAtCompileTime, Options_, StorageIndex_> >::type Nested;
297 BlockSize=_BlockAtCompileTime,
300 MaxRowsAtCompileTime =
Dynamic,
301 MaxColsAtCompileTime =
Dynamic,
302 IsVectorAtCompileTime = 0,
307 typedef std::conditional_t<_BlockAtCompileTime==Dynamic, Scalar, BlockScalar> BlockScalarReturnType;
312 : m_innerBSize(0),m_outerBSize(0),m_innerOffset(0),m_outerOffset(0),
313 m_nonzerosblocks(0),m_values(0),m_blockPtr(0),m_indices(0),
314 m_outerIndex(0),m_blockSize(BlockSize)
323 : m_innerBSize(IsColMajor ? brow : bcol),
324 m_outerBSize(IsColMajor ? bcol : brow),
325 m_innerOffset(0),m_outerOffset(0),m_nonzerosblocks(0),
326 m_values(0),m_blockPtr(0),m_indices(0),
327 m_outerIndex(0),m_blockSize(BlockSize)
334 : m_innerBSize(other.m_innerBSize),m_outerBSize(other.m_outerBSize),
335 m_nonzerosblocks(other.m_nonzerosblocks),m_nonzeros(other.m_nonzeros),
336 m_blockPtr(0),m_blockSize(other.m_blockSize)
339 eigen_assert(m_blockSize == BlockSize &&
" CAN NOT COPY BETWEEN FIXED-SIZE AND VARIABLE-SIZE BLOCKS");
341 std::copy(other.m_innerOffset, other.m_innerOffset+m_innerBSize+1, m_innerOffset);
342 std::copy(other.m_outerOffset, other.m_outerOffset+m_outerBSize+1, m_outerOffset);
343 std::copy(other.m_values, other.m_values+m_nonzeros, m_values);
346 std::copy(other.m_blockPtr, other.m_blockPtr+m_nonzerosblocks, m_blockPtr);
348 std::copy(other.m_indices, other.m_indices+m_nonzerosblocks, m_indices);
349 std::copy(other.m_outerIndex, other.m_outerIndex+m_outerBSize, m_outerIndex);
354 std::swap(first.m_innerBSize, second.m_innerBSize);
355 std::swap(first.m_outerBSize, second.m_outerBSize);
356 std::swap(first.m_innerOffset, second.m_innerOffset);
357 std::swap(first.m_outerOffset, second.m_outerOffset);
358 std::swap(first.m_nonzerosblocks, second.m_nonzerosblocks);
359 std::swap(first.m_nonzeros, second.m_nonzeros);
360 std::swap(first.m_values, second.m_values);
361 std::swap(first.m_blockPtr, second.m_blockPtr);
362 std::swap(first.m_indices, second.m_indices);
363 std::swap(first.m_outerIndex, second.m_outerIndex);
364 std::swap(first.m_BlockSize, second.m_blockSize);
367 BlockSparseMatrix& operator=(BlockSparseMatrix other)
377 delete[] m_outerIndex;
378 delete[] m_innerOffset;
379 delete[] m_outerOffset;
390 template<
typename MatrixType>
393 EIGEN_STATIC_ASSERT((m_blockSize !=
Dynamic), THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE);
406 template<
typename MatrixType>
409 eigen_assert((m_innerBSize != 0 && m_outerBSize != 0)
410 &&
"Trying to assign to a zero-size matrix, call resize() first");
411 eigen_assert(((MatrixType::Options&
RowMajorBit) != IsColMajor) &&
"Wrong storage order");
417 for(StorageIndex bj = 0; bj < m_outerBSize; ++bj)
420 std::vector<bool> nzblocksFlag(m_innerBSize,
false);
421 blockPattern.startVec(bj);
422 for(StorageIndex j = blockOuterIndex(bj); j < blockOuterIndex(bj+1); ++j)
424 typename MatrixType::InnerIterator it_spmat(spmat, j);
425 for(; it_spmat; ++it_spmat)
428 if(!nzblocksFlag[bi])
431 nzblocksFlag[bi] =
true;
432 blockPattern.insertBackByOuterInnerUnordered(bj, bi) =
true;
434 m_nonzeros += blockOuterSize(bj) * blockInnerSize(bi);
439 blockPattern.finalize();
444 for(StorageIndex nz = 0; nz < m_nonzeros; ++nz) m_values[nz] = Scalar(0);
445 for(StorageIndex bj = 0; bj < m_outerBSize; ++bj)
448 for(StorageIndex j = blockOuterIndex(bj); j < blockOuterIndex(bj+1); ++j)
451 typename MatrixType::InnerIterator it_spmat(spmat, j);
452 for(; it_spmat; ++it_spmat)
454 StorageIndex idx = 0;
457 while(bi > m_indices[m_outerIndex[bj]+idx]) ++idx;
462 idxVal = m_blockPtr[m_outerIndex[bj]+idx];
464 idxVal += (j - blockOuterIndex(bj)) * blockOuterSize(bj) + it_spmat.index() - m_innerOffset[bi];
469 idxVal = (m_outerIndex[bj] + idx) * m_blockSize * m_blockSize;
471 idxVal += (j - blockOuterIndex(bj)) * m_blockSize + (it_spmat.index()%m_blockSize);
474 m_values[idxVal] = it_spmat.value();
499 template<
typename MatrixType>
502 resize(blockPattern.rows(), blockPattern.cols());
503 reserve(blockPattern.nonZeros());
507 if(m_blockSize ==
Dynamic) m_blockPtr[0] = 0;
508 for(StorageIndex nz = 0; nz < m_nonzeros; ++nz) m_values[nz] = Scalar(0);
509 for(StorageIndex bj = 0; bj < m_outerBSize; ++bj)
515 std::vector<int> nzBlockIdx;
516 typename MatrixType::InnerIterator it(blockPattern, bj);
519 nzBlockIdx.push_back(it.index());
521 std::sort(nzBlockIdx.begin(), nzBlockIdx.end());
524 for(StorageIndex idx = 0; idx < nzBlockIdx.size(); ++idx)
526 StorageIndex offset = m_outerIndex[bj]+idx;
527 m_indices[offset] = nzBlockIdx[idx];
529 m_blockPtr[offset] = m_blockPtr[offset-1] + blockInnerSize(nzBlockIdx[idx]) * blockOuterSize(bj);
533 m_outerIndex[bj+1] = m_outerIndex[bj] + nzBlockIdx.size();
542 m_innerBSize = IsColMajor ? brow : bcol;
543 m_outerBSize = IsColMajor ? bcol : brow;
553 m_blockSize = blockSize;
567 const VectorXi& innerBlocks = IsColMajor ? rowBlocks : colBlocks;
568 const VectorXi& outerBlocks = IsColMajor ? colBlocks : rowBlocks;
569 eigen_assert(m_innerBSize == innerBlocks.
size() &&
"CHECK THE NUMBER OF ROW OR COLUMN BLOCKS");
570 eigen_assert(m_outerBSize == outerBlocks.
size() &&
"CHECK THE NUMBER OF ROW OR COLUMN BLOCKS");
571 m_outerBSize = outerBlocks.
size();
573 m_innerOffset =
new StorageIndex[m_innerBSize+1];
574 m_outerOffset =
new StorageIndex[m_outerBSize+1];
575 m_innerOffset[0] = 0;
576 m_outerOffset[0] = 0;
577 std::partial_sum(&innerBlocks[0], &innerBlocks[m_innerBSize-1]+1, &m_innerOffset[1]);
578 std::partial_sum(&outerBlocks[0], &outerBlocks[m_outerBSize-1]+1, &m_outerOffset[1]);
582 for(StorageIndex bj = 0; bj < m_outerBSize; ++bj)
583 for(StorageIndex bi = 0; bi < m_innerBSize; ++bi)
584 m_nonzeros += outerBlocks[bj] * innerBlocks[bi];
600 eigen_assert((m_innerBSize != 0 && m_outerBSize != 0) &&
601 "TRYING TO RESERVE ZERO-SIZE MATRICES, CALL resize() first");
604 m_outerIndex =
new StorageIndex[m_outerBSize+1];
606 m_nonzerosblocks = nonzerosblocks;
609 m_nonzeros = nonzerosblocks * (m_blockSize * m_blockSize);
615 m_blockPtr =
new StorageIndex[m_nonzerosblocks+1];
617 m_indices =
new StorageIndex[m_nonzerosblocks+1];
618 m_values =
new Scalar[m_nonzeros];
632 template<
typename InputIterator>
635 eigen_assert((m_innerBSize!=0 && m_outerBSize !=0) &&
"ZERO BLOCKS, PLEASE CALL resize() before");
641 internal::TripletComp<InputIterator, IsColMajor> tripletcomp;
642 std::sort(begin,
end, tripletcomp);
650 VectorXi nzblock_outer(m_outerBSize);
654 for(InputIterator it(begin); it !=
end; ++it)
656 eigen_assert(it->row() >= 0 && it->row() < this->blockRows() && it->col() >= 0 && it->col() < this->blockCols());
657 eigen_assert((it->value().rows() == it->value().cols() && (it->value().rows() == m_blockSize))
662 eigen_assert((rowBlocks[it->row()] == 0 || rowBlocks[it->row()] == it->
value().rows()) &&
663 "NON CORRESPONDING SIZES FOR ROW BLOCKS");
664 eigen_assert((colBlocks[it->col()] == 0 || colBlocks[it->col()] == it->
value().cols()) &&
665 "NON CORRESPONDING SIZES FOR COLUMN BLOCKS");
666 rowBlocks[it->row()] =it->
value().rows();
667 colBlocks[it->col()] = it->
value().cols();
669 nz_outer(IsColMajor ? it->col() : it->row()) += it->
value().rows() * it->value().cols();
670 nzblock_outer(IsColMajor ? it->col() : it->row())++;
674 StorageIndex nzblocks = nzblock_outer.
sum();
682 if (m_blockSize ==
Dynamic) m_blockPtr[0] = 0;
683 for(StorageIndex bj = 0; bj < m_outerBSize; ++bj)
685 m_outerIndex[bj+1] = m_outerIndex[bj] + nzblock_outer(bj);
686 block_id(bj) = m_outerIndex[bj];
689 m_blockPtr[m_outerIndex[bj+1]] = m_blockPtr[m_outerIndex[bj]] + nz_outer(bj);
694 for(InputIterator it(begin); it!=
end; ++it)
696 StorageIndex outer = IsColMajor ? it->col() : it->row();
697 StorageIndex inner = IsColMajor ? it->row() : it->col();
698 m_indices[block_id(outer)] = inner;
699 StorageIndex block_size = it->value().rows()*it->value().cols();
700 StorageIndex nz_marker =
blockPtr(block_id[outer]);
701 memcpy(&(m_values[nz_marker]), it->value().data(), block_size *
sizeof(Scalar));
704 m_blockPtr[block_id(outer)+1] = m_blockPtr[block_id(outer)] + block_size;
743 return (IsColMajor ? innerSize() : outerSize());
752 return (IsColMajor ? outerSize() : innerSize());
755 inline Index innerSize()
const
757 if(m_blockSize ==
Dynamic)
return m_innerOffset[m_innerBSize];
758 else return (m_innerBSize * m_blockSize) ;
761 inline Index outerSize()
const
763 if(m_blockSize ==
Dynamic)
return m_outerOffset[m_outerBSize];
764 else return (m_outerBSize * m_blockSize) ;
769 return (IsColMajor ? m_innerBSize : m_outerBSize);
774 return (IsColMajor ? m_outerBSize : m_innerBSize);
777 inline Index outerBlocks()
const {
return m_outerBSize; }
778 inline Index innerBlocks()
const {
return m_innerBSize; }
783 eigen_assert(outer < outerSize() &&
"OUTER INDEX OUT OF BOUNDS");
786 return (outer / m_blockSize);
788 StorageIndex b_outer = 0;
789 while(m_outerOffset[b_outer] <= outer) ++b_outer;
795 eigen_assert(inner < innerSize() &&
"OUTER INDEX OUT OF BOUNDS");
798 return (inner / m_blockSize);
800 StorageIndex b_inner = 0;
801 while(m_innerOffset[b_inner] <= inner) ++b_inner;
810 eigen_assert(brow <
blockRows() &&
"BLOCK ROW INDEX OUT OF BOUNDS");
811 eigen_assert(bcol <
blockCols() &&
"BLOCK nzblocksFlagCOLUMN OUT OF BOUNDS");
813 StorageIndex rsize = IsColMajor ? blockInnerSize(brow): blockOuterSize(bcol);
814 StorageIndex csize = IsColMajor ? blockOuterSize(bcol) : blockInnerSize(brow);
815 StorageIndex inner = IsColMajor ? brow : bcol;
816 StorageIndex outer = IsColMajor ? bcol : brow;
817 StorageIndex offset = m_outerIndex[outer];
818 while(offset < m_outerIndex[outer+1] && m_indices[offset] != inner)
820 if(m_indices[offset] == inner)
827 eigen_assert(
"DYNAMIC INSERTION IS NOT YET SUPPORTED");
836 eigen_assert(brow <
blockRows() &&
"BLOCK ROW INDEX OUT OF BOUNDS");
837 eigen_assert(bcol <
blockCols() &&
"BLOCK COLUMN OUT OF BOUNDS");
839 StorageIndex rsize = IsColMajor ? blockInnerSize(brow): blockOuterSize(bcol);
840 StorageIndex csize = IsColMajor ? blockOuterSize(bcol) : blockInnerSize(brow);
841 StorageIndex inner = IsColMajor ? brow : bcol;
842 StorageIndex outer = IsColMajor ? bcol : brow;
843 StorageIndex offset = m_outerIndex[outer];
844 while(offset < m_outerIndex[outer+1] && m_indices[offset] != inner) offset++;
845 if(m_indices[offset] == inner)
851 eigen_assert(
"NOT YET SUPPORTED");
855 template<
typename VecType>
856 BlockSparseTimeDenseProduct<BlockSparseMatrix, VecType> operator*(
const VecType& lhs)
const
858 return BlockSparseTimeDenseProduct<BlockSparseMatrix, VecType>(*
this, lhs);
866 inline BlockScalarReturnType *valuePtr() {
return static_cast<BlockScalarReturnType *
>(m_values);}
868 inline StorageIndex *innerIndexPtr() {
return m_indices; }
869 inline const StorageIndex *innerIndexPtr()
const {
return m_indices; }
870 inline StorageIndex *outerIndexPtr() {
return m_outerIndex; }
871 inline const StorageIndex* outerIndexPtr()
const {
return m_outerIndex; }
880 return IsColMajor ? blockInnerIndex(bi) : blockOuterIndex(bi);
888 return IsColMajor ? blockOuterIndex(bj) : blockInnerIndex(bj);
893 return (m_blockSize ==
Dynamic) ? m_outerOffset[bj] : (bj * m_blockSize);
897 return (m_blockSize ==
Dynamic) ? m_innerOffset[bi] : (bi * m_blockSize);
903 return (m_blockSize ==
Dynamic) ? (m_innerOffset[bi+1] - m_innerOffset[bi]) : m_blockSize;
907 return (m_blockSize ==
Dynamic) ? (m_outerOffset[bj+1]- m_outerOffset[bj]) : m_blockSize;
918 class BlockInnerIterator;
920 friend std::ostream & operator << (std::ostream & s,
const BlockSparseMatrix& m)
922 for (StorageIndex j = 0; j < m.outerBlocks(); ++j)
924 BlockInnerIterator itb(m, j);
927 s <<
"("<<itb.row() <<
", " << itb.col() <<
")\n";
928 s << itb.value() <<
"\n";
940 if(m_blockSize ==
Dynamic)
return m_blockPtr[id];
941 else return id * m_blockSize * m_blockSize;
962 StorageIndex *m_innerOffset;
963 StorageIndex *m_outerOffset;
964 Index m_nonzerosblocks;
967 StorageIndex *m_blockPtr;
968 StorageIndex *m_indices;
969 StorageIndex *m_outerIndex;
973 template<
typename Scalar_,
int _BlockAtCompileTime,
int Options_,
typename StorageIndex_>
974 class BlockSparseMatrix<Scalar_, _BlockAtCompileTime, Options_, StorageIndex_>::BlockInnerIterator
982 BlockInnerIterator(
const BlockSparseMatrix& mat,
const Index outer)
983 : m_mat(mat),m_outer(outer),
984 m_id(mat.m_outerIndex[outer]),
985 m_end(mat.m_outerIndex[outer+1])
989 inline BlockInnerIterator& operator++() {m_id++;
return *
this; }
991 inline const Map<const BlockScalar> value()
const
993 return Map<const BlockScalar>(&(m_mat.m_values[m_mat.blockPtr(m_id)]),
996 inline Map<BlockScalar> valueRef()
998 return Map<BlockScalar>(&(m_mat.m_values[m_mat.blockPtr(m_id)]),
1002 inline Index index()
const {
return m_mat.m_indices[m_id]; }
1003 inline Index outer()
const {
return m_outer; }
1005 inline Index row()
const {
return index(); }
1007 inline Index col()
const {
return outer(); }
1009 inline Index rows()
const {
return (m_mat.m_blockSize==
Dynamic) ? (m_mat.m_innerOffset[index()+1] - m_mat.m_innerOffset[index()]) : m_mat.m_blockSize; }
1011 inline Index cols()
const {
return (m_mat.m_blockSize==
Dynamic) ? (m_mat.m_outerOffset[m_outer+1]-m_mat.m_outerOffset[m_outer]) : m_mat.m_blockSize;}
1012 inline operator bool()
const {
return (m_id < m_end); }
1015 const BlockSparseMatrix<Scalar_, _BlockAtCompileTime, Options_, StorageIndex>& m_mat;
1016 const Index m_outer;
1021 template<
typename Scalar_,
int _BlockAtCompileTime,
int Options_,
typename StorageIndex_>
1022 class BlockSparseMatrix<Scalar_, _BlockAtCompileTime, Options_, StorageIndex_>::InnerIterator
1025 InnerIterator(
const BlockSparseMatrix& mat,
Index outer)
1026 : m_mat(mat),m_outerB(mat.
outerToBlock(outer)),m_outer(outer),
1028 m_offset(outer - mat.blockOuterIndex(m_outerB))
1032 m_id = m_mat.blockInnerIndex(itb.index());
1034 m_end = m_mat.blockInnerIndex(itb.index()+1);
1037 inline InnerIterator& operator++()
1045 m_id = m_mat.blockInnerIndex(itb.index());
1047 m_end = m_mat.blockInnerIndex(itb.index()+1);
1052 inline const Scalar& value()
const
1054 return itb.value().coeff(m_id - m_start, m_offset);
1056 inline Scalar& valueRef()
1058 return itb.valueRef().coeff(m_id - m_start, m_offset);
1060 inline Index index()
const {
return m_id; }
1061 inline Index outer()
const {
return m_outer; }
1062 inline Index col()
const {
return outer(); }
1063 inline Index row()
const {
return index();}
1064 inline operator bool()
const
1069 const BlockSparseMatrix& m_mat;
1070 const Index m_outer;
1071 const Index m_outerB;
1072 BlockInnerIterator itb;
1073 const Index m_offset;
A versatile sparse matrix representation where each element is a block.
Definition: BlockSparseMatrix.h:287
BlockSparseMatrix & operator=(const MatrixType &spmat)
Assignment from a sparse matrix with the same storage order.
Definition: BlockSparseMatrix.h:407
Index innerToBlock(Index inner) const
Definition: BlockSparseMatrix.h:793
void setBlockStructure(const MatrixType &blockPattern)
Set the nonzero block pattern of the matrix.
Definition: BlockSparseMatrix.h:500
Index blockCols() const
Definition: BlockSparseMatrix.h:772
BlockSparseMatrix(Index brow, Index bcol)
Construct and resize.
Definition: BlockSparseMatrix.h:322
Index blockPtr(Index id) const
Definition: BlockSparseMatrix.h:938
void reserve(const Index nonzerosblocks)
Allocate the internal array of pointers to blocks and their inner indices.
Definition: BlockSparseMatrix.h:598
Index outerToBlock(Index outer) const
Definition: BlockSparseMatrix.h:781
Map< const BlockScalar > coeff(Index brow, Index bcol) const
Definition: BlockSparseMatrix.h:834
Index blockRowsIndex(Index bi) const
Definition: BlockSparseMatrix.h:878
Index cols() const
Definition: BlockSparseMatrix.h:749
BlockSparseMatrix(const MatrixType &spmat)
Constructor from a sparse matrix.
Definition: BlockSparseMatrix.h:391
Index rows() const
Definition: BlockSparseMatrix.h:740
void setFromTriplets(const InputIterator &begin, const InputIterator &end)
Fill values in a matrix from a triplet list.
Definition: BlockSparseMatrix.h:633
void setBlockLayout(const VectorXi &rowBlocks, const VectorXi &colBlocks)
Set the row and column block layouts,.
Definition: BlockSparseMatrix.h:565
Ref< BlockScalar > coeffRef(Index brow, Index bcol)
Definition: BlockSparseMatrix.h:808
Index nonZeros() const
Definition: BlockSparseMatrix.h:864
BlockSparseMatrix(const BlockSparseMatrix &other)
Copy-constructor.
Definition: BlockSparseMatrix.h:333
Index blockRows() const
Definition: BlockSparseMatrix.h:767
void resize(Index brow, Index bcol)
Set the number of rows and columns blocks.
Definition: BlockSparseMatrix.h:540
bool isCompressed() const
for compatibility purposes with the SparseMatrix class
Definition: BlockSparseMatrix.h:874
Index blockColsIndex(Index bj) const
Definition: BlockSparseMatrix.h:886
Index nonZerosBlocks() const
Definition: BlockSparseMatrix.h:862
void setBlockSize(Index blockSize)
set the block size at runtime for fixed-size block layout
Definition: BlockSparseMatrix.h:551
CoeffReturnType value() const
EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT
Matrix< Scalar_, Rows_, Cols_, Options_, MaxRows_, MaxCols_ > & setZero(Index size)
static const lastp1_t end
const unsigned int LvalueBit
const unsigned int RowMajorBit
Namespace containing all symbols from the Eigen library.
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index