11 #ifndef EIGEN_SPARSEBLOCKMATRIX_H 12 #define EIGEN_SPARSEBLOCKMATRIX_H 54 template<
typename _Scalar,
int _BlockAtCompileTime=Dynamic,
int _Options=ColMajor,
typename _StorageIndex=
int>
class BlockSparseMatrix;
56 template<
typename BlockSparseMatrixT>
class BlockSparseMatrixView;
59 template<
typename _Scalar,
int _BlockAtCompileTime,
int _Options,
typename _Index>
62 typedef _Scalar Scalar;
64 typedef Sparse StorageKind;
65 typedef MatrixXpr XprKind;
67 RowsAtCompileTime = Dynamic,
68 ColsAtCompileTime = Dynamic,
69 MaxRowsAtCompileTime = Dynamic,
70 MaxColsAtCompileTime = Dynamic,
71 BlockSize = _BlockAtCompileTime,
72 Flags = _Options | NestByRefBit | LvalueBit,
73 CoeffReadCost = NumTraits<Scalar>::ReadCost,
74 SupportedAccessPatterns = InnerRandomAccessPattern
77 template<
typename BlockSparseMatrixT>
78 struct traits<BlockSparseMatrixView<BlockSparseMatrixT> >
80 typedef Ref<Matrix<typename BlockSparseMatrixT::Scalar, BlockSparseMatrixT::BlockSize, BlockSparseMatrixT::BlockSize> > Scalar;
81 typedef Ref<Matrix<typename BlockSparseMatrixT::RealScalar, BlockSparseMatrixT::BlockSize, BlockSparseMatrixT::BlockSize> > RealScalar;
86 template<
typename Iterator,
bool IsColMajor>
89 typedef typename Iterator::value_type Triplet;
90 bool operator()(
const Triplet& a,
const Triplet& b)
92 return ((a.col() == b.col() && a.row() < b.row()) || (a.col() < b.col()));
94 return ((a.row() == b.row() && a.col() < b.col()) || (a.row() < b.row()));
101 template<
typename BlockSparseMatrixT>
102 class BlockSparseMatrixView :
public SparseMatrixBase<BlockSparseMatrixT>
105 typedef Ref<typename BlockSparseMatrixT::BlockScalar> Scalar;
106 typedef Ref<typename BlockSparseMatrixT::BlockRealScalar> RealScalar;
107 typedef typename BlockSparseMatrixT::Index Index;
108 typedef BlockSparseMatrixT Nested;
110 Flags = BlockSparseMatrixT::Options,
111 Options = BlockSparseMatrixT::Options,
112 RowsAtCompileTime = BlockSparseMatrixT::RowsAtCompileTime,
113 ColsAtCompileTime = BlockSparseMatrixT::ColsAtCompileTime,
114 MaxColsAtCompileTime = BlockSparseMatrixT::MaxColsAtCompileTime,
115 MaxRowsAtCompileTime = BlockSparseMatrixT::MaxRowsAtCompileTime
118 BlockSparseMatrixView(
const BlockSparseMatrixT& spblockmat)
119 : m_spblockmat(spblockmat)
122 Index outerSize()
const 124 return (Flags&RowMajorBit) == 1 ? this->rows() : this->cols();
128 return m_spblockmat.blockCols();
132 return m_spblockmat.blockRows();
134 Scalar coeff(Index row, Index col)
136 return m_spblockmat.coeff(row, col);
138 Scalar coeffRef(Index row, Index col)
140 return m_spblockmat.coeffRef(row, col);
143 class InnerIterator :
public BlockSparseMatrixT::BlockInnerIterator
146 InnerIterator(
const BlockSparseMatrixView& mat, Index outer)
147 : BlockSparseMatrixT::BlockInnerIterator(mat.m_spblockmat, outer)
153 const BlockSparseMatrixT& m_spblockmat;
157 template<
typename BlockSparseMatrixT,
typename VectorType>
158 class BlockVectorView
162 BlockSize = BlockSparseMatrixT::BlockSize,
163 ColsAtCompileTime = VectorType::ColsAtCompileTime,
164 RowsAtCompileTime = VectorType::RowsAtCompileTime,
165 Flags = VectorType::Flags
167 typedef Ref<const Matrix<typename BlockSparseMatrixT::Scalar, (RowsAtCompileTime==1)? 1 : BlockSize, (ColsAtCompileTime==1)? 1 : BlockSize> >Scalar;
168 typedef typename BlockSparseMatrixT::Index Index;
170 BlockVectorView(
const BlockSparseMatrixT& spblockmat,
const VectorType& vec)
171 : m_spblockmat(spblockmat),m_vec(vec)
173 inline Index cols()
const 177 inline Index size()
const 179 return m_spblockmat.blockRows();
181 inline Scalar coeff(Index bi)
const 183 Index startRow = m_spblockmat.blockRowsIndex(bi);
184 Index rowSize = m_spblockmat.blockRowsIndex(bi+1) - startRow;
185 return m_vec.middleRows(startRow, rowSize);
187 inline Scalar coeff(Index bi, Index j)
const 189 Index startRow = m_spblockmat.blockRowsIndex(bi);
190 Index rowSize = m_spblockmat.blockRowsIndex(bi+1) - startRow;
191 return m_vec.block(startRow, j, rowSize, 1);
194 const BlockSparseMatrixT& m_spblockmat;
195 const VectorType& m_vec;
198 template<
typename VectorType,
typename Index>
class BlockVectorReturn;
202 template<
typename BlockSparseMatrixT,
typename VectorType>
203 class BlockVectorReturn
207 ColsAtCompileTime = VectorType::ColsAtCompileTime,
208 RowsAtCompileTime = VectorType::RowsAtCompileTime,
209 Flags = VectorType::Flags
211 typedef Ref<Matrix<typename VectorType::Scalar, RowsAtCompileTime, ColsAtCompileTime> > Scalar;
212 typedef typename BlockSparseMatrixT::Index Index;
214 BlockVectorReturn(
const BlockSparseMatrixT& spblockmat, VectorType& vec)
215 : m_spblockmat(spblockmat),m_vec(vec)
217 inline Index size()
const 219 return m_spblockmat.blockRows();
221 inline Scalar coeffRef(Index bi)
223 Index startRow = m_spblockmat.blockRowsIndex(bi);
224 Index rowSize = m_spblockmat.blockRowsIndex(bi+1) - startRow;
225 return m_vec.middleRows(startRow, rowSize);
227 inline Scalar coeffRef(Index bi, Index j)
229 Index startRow = m_spblockmat.blockRowsIndex(bi);
230 Index rowSize = m_spblockmat.blockRowsIndex(bi+1) - startRow;
231 return m_vec.block(startRow, j, rowSize, 1);
235 const BlockSparseMatrixT& m_spblockmat;
240 template<
typename Lhs,
typename Rhs>
241 class BlockSparseTimeDenseProduct;
245 template<
typename BlockSparseMatrixT,
typename VecType>
246 struct traits<BlockSparseTimeDenseProduct<BlockSparseMatrixT, VecType> >
248 typedef Dense StorageKind;
249 typedef MatrixXpr XprKind;
250 typedef typename BlockSparseMatrixT::Scalar Scalar;
251 typedef typename BlockSparseMatrixT::Index Index;
253 RowsAtCompileTime = Dynamic,
254 ColsAtCompileTime = Dynamic,
255 MaxRowsAtCompileTime = Dynamic,
256 MaxColsAtCompileTime = Dynamic,
258 CoeffReadCost = internal::traits<BlockSparseMatrixT>::CoeffReadCost
263 template<
typename Lhs,
typename Rhs>
264 class BlockSparseTimeDenseProduct
265 :
public ProductBase<BlockSparseTimeDenseProduct<Lhs,Rhs>, Lhs, Rhs>
268 EIGEN_PRODUCT_PUBLIC_INTERFACE(BlockSparseTimeDenseProduct)
270 BlockSparseTimeDenseProduct(
const Lhs& lhs,
const Rhs& rhs) : Base(lhs,rhs)
273 template<
typename Dest>
void scaleAndAddTo(Dest& dest,
const typename Rhs::Scalar& alpha)
const 275 BlockVectorReturn<Lhs,Dest> tmpDest(m_lhs, dest);
276 internal::sparse_time_dense_product( BlockSparseMatrixView<Lhs>(m_lhs), BlockVectorView<Lhs, Rhs>(m_lhs, m_rhs), tmpDest, alpha);
280 BlockSparseTimeDenseProduct& operator=(
const BlockSparseTimeDenseProduct&);
283 template<
typename _Scalar,
int _BlockAtCompileTime,
int _Options,
typename _StorageIndex>
284 class BlockSparseMatrix :
public SparseMatrixBase<BlockSparseMatrix<_Scalar,_BlockAtCompileTime, _Options,_StorageIndex> >
287 typedef _Scalar Scalar;
288 typedef typename NumTraits<Scalar>::Real RealScalar;
289 typedef _StorageIndex StorageIndex;
290 typedef typename internal::ref_selector<BlockSparseMatrix<_Scalar, _BlockAtCompileTime, _Options, _StorageIndex> >::type Nested;
295 BlockSize=_BlockAtCompileTime,
296 RowsAtCompileTime = Dynamic,
297 ColsAtCompileTime = Dynamic,
298 MaxRowsAtCompileTime = Dynamic,
299 MaxColsAtCompileTime = Dynamic,
300 IsVectorAtCompileTime = 0,
301 IsColMajor = Flags&RowMajorBit ? 0 : 1
303 typedef Matrix<Scalar, _BlockAtCompileTime, _BlockAtCompileTime,IsColMajor ? ColMajor : RowMajor> BlockScalar;
304 typedef Matrix<RealScalar, _BlockAtCompileTime, _BlockAtCompileTime,IsColMajor ? ColMajor : RowMajor> BlockRealScalar;
305 typedef typename internal::conditional<_BlockAtCompileTime==Dynamic, Scalar, BlockScalar>::type BlockScalarReturnType;
310 : m_innerBSize(0),m_outerBSize(0),m_innerOffset(0),m_outerOffset(0),
311 m_nonzerosblocks(0),m_values(0),m_blockPtr(0),m_indices(0),
312 m_outerIndex(0),m_blockSize(BlockSize)
321 : m_innerBSize(IsColMajor ? brow : bcol),
322 m_outerBSize(IsColMajor ? bcol : brow),
323 m_innerOffset(0),m_outerOffset(0),m_nonzerosblocks(0),
324 m_values(0),m_blockPtr(0),m_indices(0),
325 m_outerIndex(0),m_blockSize(BlockSize)
332 : m_innerBSize(other.m_innerBSize),m_outerBSize(other.m_outerBSize),
333 m_nonzerosblocks(other.m_nonzerosblocks),m_nonzeros(other.m_nonzeros),
334 m_blockPtr(0),m_blockSize(other.m_blockSize)
337 eigen_assert(m_blockSize == BlockSize &&
" CAN NOT COPY BETWEEN FIXED-SIZE AND VARIABLE-SIZE BLOCKS");
339 std::copy(other.m_innerOffset, other.m_innerOffset+m_innerBSize+1, m_innerOffset);
340 std::copy(other.m_outerOffset, other.m_outerOffset+m_outerBSize+1, m_outerOffset);
341 std::copy(other.m_values, other.m_values+m_nonzeros, m_values);
343 if(m_blockSize != Dynamic)
344 std::copy(other.m_blockPtr, other.m_blockPtr+m_nonzerosblocks, m_blockPtr);
346 std::copy(other.m_indices, other.m_indices+m_nonzerosblocks, m_indices);
347 std::copy(other.m_outerIndex, other.m_outerIndex+m_outerBSize, m_outerIndex);
352 std::swap(first.m_innerBSize, second.m_innerBSize);
353 std::swap(first.m_outerBSize, second.m_outerBSize);
354 std::swap(first.m_innerOffset, second.m_innerOffset);
355 std::swap(first.m_outerOffset, second.m_outerOffset);
356 std::swap(first.m_nonzerosblocks, second.m_nonzerosblocks);
357 std::swap(first.m_nonzeros, second.m_nonzeros);
358 std::swap(first.m_values, second.m_values);
359 std::swap(first.m_blockPtr, second.m_blockPtr);
360 std::swap(first.m_indices, second.m_indices);
361 std::swap(first.m_outerIndex, second.m_outerIndex);
362 std::swap(first.m_BlockSize, second.m_blockSize);
375 delete[] m_outerIndex;
376 delete[] m_innerOffset;
377 delete[] m_outerOffset;
388 template<
typename MatrixType>
391 EIGEN_STATIC_ASSERT((m_blockSize != Dynamic), THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE);
404 template<
typename MatrixType>
407 eigen_assert((m_innerBSize != 0 && m_outerBSize != 0)
408 &&
"Trying to assign to a zero-size matrix, call resize() first");
409 eigen_assert(((MatrixType::Options&RowMajorBit) != IsColMajor) &&
"Wrong storage order");
410 typedef SparseMatrix<bool,MatrixType::Options,typename MatrixType::Index> MatrixPatternType;
411 MatrixPatternType blockPattern(blockRows(), blockCols());
415 for(StorageIndex bj = 0; bj < m_outerBSize; ++bj)
418 std::vector<bool> nzblocksFlag(m_innerBSize,
false);
419 blockPattern.startVec(bj);
420 for(StorageIndex j = blockOuterIndex(bj); j < blockOuterIndex(bj+1); ++j)
422 typename MatrixType::InnerIterator it_spmat(spmat, j);
423 for(; it_spmat; ++it_spmat)
425 StorageIndex bi = innerToBlock(it_spmat.index());
426 if(!nzblocksFlag[bi])
429 nzblocksFlag[bi] =
true;
430 blockPattern.insertBackByOuterInnerUnordered(bj, bi) =
true;
432 m_nonzeros += blockOuterSize(bj) * blockInnerSize(bi);
437 blockPattern.finalize();
440 setBlockStructure(blockPattern);
442 for(StorageIndex nz = 0; nz < m_nonzeros; ++nz) m_values[nz] = Scalar(0);
443 for(StorageIndex bj = 0; bj < m_outerBSize; ++bj)
446 for(StorageIndex j = blockOuterIndex(bj); j < blockOuterIndex(bj+1); ++j)
449 typename MatrixType::InnerIterator it_spmat(spmat, j);
450 for(; it_spmat; ++it_spmat)
452 StorageIndex idx = 0;
453 StorageIndex bi = innerToBlock(it_spmat.index());
455 while(bi > m_indices[m_outerIndex[bj]+idx]) ++idx;
457 if(m_blockSize == Dynamic)
460 idxVal = m_blockPtr[m_outerIndex[bj]+idx];
462 idxVal += (j - blockOuterIndex(bj)) * blockOuterSize(bj) + it_spmat.index() - m_innerOffset[bi];
467 idxVal = (m_outerIndex[bj] + idx) * m_blockSize * m_blockSize;
469 idxVal += (j - blockOuterIndex(bj)) * m_blockSize + (it_spmat.index()%m_blockSize);
472 m_values[idxVal] = it_spmat.value();
497 template<
typename MatrixType>
500 resize(blockPattern.rows(), blockPattern.cols());
501 reserve(blockPattern.nonZeros());
505 if(m_blockSize == Dynamic) m_blockPtr[0] = 0;
506 for(StorageIndex nz = 0; nz < m_nonzeros; ++nz) m_values[nz] = Scalar(0);
507 for(StorageIndex bj = 0; bj < m_outerBSize; ++bj)
513 std::vector<int> nzBlockIdx;
514 typename MatrixType::InnerIterator it(blockPattern, bj);
517 nzBlockIdx.push_back(it.index());
519 std::sort(nzBlockIdx.begin(), nzBlockIdx.end());
522 for(StorageIndex idx = 0; idx < nzBlockIdx.size(); ++idx)
524 StorageIndex offset = m_outerIndex[bj]+idx;
525 m_indices[offset] = nzBlockIdx[idx];
526 if(m_blockSize == Dynamic)
527 m_blockPtr[offset] = m_blockPtr[offset-1] + blockInnerSize(nzBlockIdx[idx]) * blockOuterSize(bj);
531 m_outerIndex[bj+1] = m_outerIndex[bj] + nzBlockIdx.size();
538 inline void resize(Index brow, Index bcol)
540 m_innerBSize = IsColMajor ? brow : bcol;
541 m_outerBSize = IsColMajor ? bcol : brow;
551 m_blockSize = blockSize;
565 const VectorXi& innerBlocks = IsColMajor ? rowBlocks : colBlocks;
566 const VectorXi& outerBlocks = IsColMajor ? colBlocks : rowBlocks;
567 eigen_assert(m_innerBSize == innerBlocks.size() &&
"CHECK THE NUMBER OF ROW OR COLUMN BLOCKS");
568 eigen_assert(m_outerBSize == outerBlocks.size() &&
"CHECK THE NUMBER OF ROW OR COLUMN BLOCKS");
569 m_outerBSize = outerBlocks.size();
571 m_innerOffset =
new StorageIndex[m_innerBSize+1];
572 m_outerOffset =
new StorageIndex[m_outerBSize+1];
573 m_innerOffset[0] = 0;
574 m_outerOffset[0] = 0;
575 std::partial_sum(&innerBlocks[0], &innerBlocks[m_innerBSize-1]+1, &m_innerOffset[1]);
576 std::partial_sum(&outerBlocks[0], &outerBlocks[m_outerBSize-1]+1, &m_outerOffset[1]);
580 for(StorageIndex bj = 0; bj < m_outerBSize; ++bj)
581 for(StorageIndex bi = 0; bi < m_innerBSize; ++bi)
582 m_nonzeros += outerBlocks[bj] * innerBlocks[bi];
596 inline void reserve(
const Index nonzerosblocks)
598 eigen_assert((m_innerBSize != 0 && m_outerBSize != 0) &&
599 "TRYING TO RESERVE ZERO-SIZE MATRICES, CALL resize() first");
602 m_outerIndex =
new StorageIndex[m_outerBSize+1];
604 m_nonzerosblocks = nonzerosblocks;
605 if(m_blockSize != Dynamic)
607 m_nonzeros = nonzerosblocks * (m_blockSize * m_blockSize);
613 m_blockPtr =
new StorageIndex[m_nonzerosblocks+1];
615 m_indices =
new StorageIndex[m_nonzerosblocks+1];
616 m_values =
new Scalar[m_nonzeros];
630 template<
typename InputIterator>
633 eigen_assert((m_innerBSize!=0 && m_outerBSize !=0) &&
"ZERO BLOCKS, PLEASE CALL resize() before");
639 internal::TripletComp<InputIterator, IsColMajor> tripletcomp;
640 std::sort(begin, end, tripletcomp);
645 VectorXi rowBlocks(m_innerBSize);
646 VectorXi colBlocks(m_outerBSize);
647 rowBlocks.setZero(); colBlocks.setZero();
648 VectorXi nzblock_outer(m_outerBSize);
649 VectorXi nz_outer(m_outerBSize);
650 nzblock_outer.setZero();
652 for(InputIterator it(begin); it !=end; ++it)
654 eigen_assert(it->row() >= 0 && it->row() < this->blockRows() && it->col() >= 0 && it->col() < this->blockCols());
655 eigen_assert((it->value().rows() == it->value().cols() && (it->value().rows() == m_blockSize))
656 || (m_blockSize == Dynamic));
658 if(m_blockSize == Dynamic)
660 eigen_assert((rowBlocks[it->row()] == 0 || rowBlocks[it->row()] == it->value().rows()) &&
661 "NON CORRESPONDING SIZES FOR ROW BLOCKS");
662 eigen_assert((colBlocks[it->col()] == 0 || colBlocks[it->col()] == it->value().cols()) &&
663 "NON CORRESPONDING SIZES FOR COLUMN BLOCKS");
664 rowBlocks[it->row()] =it->value().rows();
665 colBlocks[it->col()] = it->value().cols();
667 nz_outer(IsColMajor ? it->col() : it->row()) += it->value().rows() * it->value().cols();
668 nzblock_outer(IsColMajor ? it->col() : it->row())++;
671 if(m_blockSize == Dynamic) setBlockLayout(rowBlocks, colBlocks);
672 StorageIndex nzblocks = nzblock_outer.sum();
676 VectorXi block_id(m_outerBSize);
680 if (m_blockSize == Dynamic) m_blockPtr[0] = 0;
681 for(StorageIndex bj = 0; bj < m_outerBSize; ++bj)
683 m_outerIndex[bj+1] = m_outerIndex[bj] + nzblock_outer(bj);
684 block_id(bj) = m_outerIndex[bj];
685 if(m_blockSize==Dynamic)
687 m_blockPtr[m_outerIndex[bj+1]] = m_blockPtr[m_outerIndex[bj]] + nz_outer(bj);
692 for(InputIterator it(begin); it!=end; ++it)
694 StorageIndex outer = IsColMajor ? it->col() : it->row();
695 StorageIndex inner = IsColMajor ? it->row() : it->col();
696 m_indices[block_id(outer)] = inner;
697 StorageIndex block_size = it->value().rows()*it->value().cols();
698 StorageIndex nz_marker = blockPtr(block_id[outer]);
699 memcpy(&(m_values[nz_marker]), it->value().data(), block_size *
sizeof(Scalar));
700 if(m_blockSize == Dynamic)
702 m_blockPtr[block_id(outer)+1] = m_blockPtr[block_id(outer)] + block_size;
741 return (IsColMajor ? innerSize() : outerSize());
750 return (IsColMajor ? outerSize() : innerSize());
753 inline Index innerSize()
const 755 if(m_blockSize == Dynamic)
return m_innerOffset[m_innerBSize];
756 else return (m_innerBSize * m_blockSize) ;
759 inline Index outerSize()
const 761 if(m_blockSize == Dynamic)
return m_outerOffset[m_outerBSize];
762 else return (m_outerBSize * m_blockSize) ;
767 return (IsColMajor ? m_innerBSize : m_outerBSize);
772 return (IsColMajor ? m_outerBSize : m_innerBSize);
775 inline Index outerBlocks()
const {
return m_outerBSize; }
776 inline Index innerBlocks()
const {
return m_innerBSize; }
781 eigen_assert(outer < outerSize() &&
"OUTER INDEX OUT OF BOUNDS");
783 if(m_blockSize != Dynamic)
784 return (outer / m_blockSize);
786 StorageIndex b_outer = 0;
787 while(m_outerOffset[b_outer] <= outer) ++b_outer;
793 eigen_assert(inner < innerSize() &&
"OUTER INDEX OUT OF BOUNDS");
795 if(m_blockSize != Dynamic)
796 return (inner / m_blockSize);
798 StorageIndex b_inner = 0;
799 while(m_innerOffset[b_inner] <= inner) ++b_inner;
808 eigen_assert(brow < blockRows() &&
"BLOCK ROW INDEX OUT OF BOUNDS");
809 eigen_assert(bcol < blockCols() &&
"BLOCK nzblocksFlagCOLUMN OUT OF BOUNDS");
811 StorageIndex rsize = IsColMajor ? blockInnerSize(brow): blockOuterSize(bcol);
812 StorageIndex csize = IsColMajor ? blockOuterSize(bcol) : blockInnerSize(brow);
813 StorageIndex inner = IsColMajor ? brow : bcol;
814 StorageIndex outer = IsColMajor ? bcol : brow;
815 StorageIndex offset = m_outerIndex[outer];
816 while(offset < m_outerIndex[outer+1] && m_indices[offset] != inner)
818 if(m_indices[offset] == inner)
820 return Map<BlockScalar>(&(m_values[blockPtr(offset)]), rsize, csize);
825 eigen_assert(
"DYNAMIC INSERTION IS NOT YET SUPPORTED");
832 Map<const BlockScalar>
coeff(Index brow, Index bcol)
const 834 eigen_assert(brow < blockRows() &&
"BLOCK ROW INDEX OUT OF BOUNDS");
835 eigen_assert(bcol < blockCols() &&
"BLOCK COLUMN OUT OF BOUNDS");
837 StorageIndex rsize = IsColMajor ? blockInnerSize(brow): blockOuterSize(bcol);
838 StorageIndex csize = IsColMajor ? blockOuterSize(bcol) : blockInnerSize(brow);
839 StorageIndex inner = IsColMajor ? brow : bcol;
840 StorageIndex outer = IsColMajor ? bcol : brow;
841 StorageIndex offset = m_outerIndex[outer];
842 while(offset < m_outerIndex[outer+1] && m_indices[offset] != inner) offset++;
843 if(m_indices[offset] == inner)
845 return Map<const BlockScalar> (&(m_values[blockPtr(offset)]), rsize, csize);
849 eigen_assert(
"NOT YET SUPPORTED");
853 template<
typename VecType>
854 BlockSparseTimeDenseProduct<BlockSparseMatrix, VecType> operator*(
const VecType& lhs)
const 856 return BlockSparseTimeDenseProduct<BlockSparseMatrix, VecType>(*
this, lhs);
862 inline Index
nonZeros()
const {
return m_nonzeros; }
864 inline BlockScalarReturnType *valuePtr() {
return static_cast<BlockScalarReturnType *
>(m_values);}
866 inline StorageIndex *innerIndexPtr() {
return m_indices; }
867 inline const StorageIndex *innerIndexPtr()
const {
return m_indices; }
868 inline StorageIndex *outerIndexPtr() {
return m_outerIndex; }
869 inline const StorageIndex* outerIndexPtr()
const {
return m_outerIndex; }
878 return IsColMajor ? blockInnerIndex(bi) : blockOuterIndex(bi);
886 return IsColMajor ? blockOuterIndex(bj) : blockInnerIndex(bj);
889 inline Index blockOuterIndex(Index bj)
const 891 return (m_blockSize == Dynamic) ? m_outerOffset[bj] : (bj * m_blockSize);
893 inline Index blockInnerIndex(Index bi)
const 895 return (m_blockSize == Dynamic) ? m_innerOffset[bi] : (bi * m_blockSize);
899 inline Index blockInnerSize(Index bi)
const 901 return (m_blockSize == Dynamic) ? (m_innerOffset[bi+1] - m_innerOffset[bi]) : m_blockSize;
903 inline Index blockOuterSize(Index bj)
const 905 return (m_blockSize == Dynamic) ? (m_outerOffset[bj+1]- m_outerOffset[bj]) : m_blockSize;
916 class BlockInnerIterator;
920 for (StorageIndex j = 0; j < m.outerBlocks(); ++j)
922 BlockInnerIterator itb(m, j);
925 s <<
"("<<itb.row() <<
", " << itb.col() <<
")\n";
926 s << itb.value() <<
"\n";
938 if(m_blockSize == Dynamic)
return m_blockPtr[id];
939 else return id * m_blockSize * m_blockSize;
956 Map<BlockScalar> insert(Index brow, Index bcol);
960 StorageIndex *m_innerOffset;
961 StorageIndex *m_outerOffset;
962 Index m_nonzerosblocks;
965 StorageIndex *m_blockPtr;
966 StorageIndex *m_indices;
967 StorageIndex *m_outerIndex;
971 template<
typename _Scalar,
int _BlockAtCompileTime,
int _Options,
typename _StorageIndex>
972 class BlockSparseMatrix<_Scalar, _BlockAtCompileTime, _Options, _StorageIndex>::BlockInnerIterator
981 : m_mat(mat),m_outer(outer),
982 m_id(mat.m_outerIndex[outer]),
983 m_end(mat.m_outerIndex[outer+1])
987 inline BlockInnerIterator& operator++() {m_id++;
return *
this; }
989 inline const Map<const BlockScalar> value()
const 991 return Map<const BlockScalar>(&(m_mat.m_values[m_mat.blockPtr(m_id)]),
994 inline Map<BlockScalar> valueRef()
996 return Map<BlockScalar>(&(m_mat.m_values[m_mat.blockPtr(m_id)]),
1000 inline Index index()
const {
return m_mat.m_indices[m_id]; }
1001 inline Index outer()
const {
return m_outer; }
1003 inline Index row()
const {
return index(); }
1005 inline Index col()
const {
return outer(); }
1007 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; }
1009 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;}
1010 inline operator bool()
const {
return (m_id < m_end); }
1014 const Index m_outer;
1019 template<
typename _Scalar,
int _BlockAtCompileTime,
int _Options,
typename _StorageIndex>
1020 class BlockSparseMatrix<_Scalar, _BlockAtCompileTime, _Options, _StorageIndex>::InnerIterator
1024 : m_mat(mat),m_outerB(mat.
outerToBlock(outer)),m_outer(outer),
1026 m_offset(outer - mat.blockOuterIndex(m_outerB))
1030 m_id = m_mat.blockInnerIndex(itb.index());
1032 m_end = m_mat.blockInnerIndex(itb.index()+1);
1035 inline InnerIterator& operator++()
1043 m_id = m_mat.blockInnerIndex(itb.index());
1045 m_end = m_mat.blockInnerIndex(itb.index()+1);
1050 inline const Scalar& value()
const 1052 return itb.value().coeff(m_id - m_start, m_offset);
1054 inline Scalar& valueRef()
1056 return itb.valueRef().coeff(m_id - m_start, m_offset);
1058 inline Index index()
const {
return m_id; }
1059 inline Index outer()
const {
return m_outer; }
1060 inline Index col()
const {
return outer(); }
1061 inline Index row()
const {
return index();}
1062 inline operator bool()
const 1068 const Index m_outer;
1069 const Index m_outerB;
1070 BlockInnerIterator itb;
1071 const Index m_offset;
1079 #endif // EIGEN_SPARSEBLOCKMATRIX_H void setBlockSize(Index blockSize)
set the block size at runtime for fixed-size block layout
Definition: BlockSparseMatrix.h:549
void setFromTriplets(const InputIterator &begin, const InputIterator &end)
Fill values in a matrix from a triplet list.
Definition: BlockSparseMatrix.h:631
Index innerToBlock(Index inner) const
Definition: BlockSparseMatrix.h:791
Index blockRowsIndex(Index bi) const
Definition: BlockSparseMatrix.h:876
void setBlockStructure(const MatrixType &blockPattern)
Set the nonzero block pattern of the matrix.
Definition: BlockSparseMatrix.h:498
BlockSparseMatrix(const MatrixType &spmat)
Constructor from a sparse matrix.
Definition: BlockSparseMatrix.h:389
Namespace containing all symbols from the Eigen library.
Definition: AdolcForward:45
BlockSparseMatrix(Index brow, Index bcol)
Construct and resize.
Definition: BlockSparseMatrix.h:320
Index cols() const
Definition: BlockSparseMatrix.h:747
void reserve(const Index nonzerosblocks)
Allocate the internal array of pointers to blocks and their inner indices.
Definition: BlockSparseMatrix.h:596
BlockSparseMatrix & operator=(const MatrixType &spmat)
Assignment from a sparse matrix with the same storage order.
Definition: BlockSparseMatrix.h:405
bool isCompressed() const
for compatibility purposes with the SparseMatrix class
Definition: BlockSparseMatrix.h:872
void setBlockLayout(const VectorXi &rowBlocks, const VectorXi &colBlocks)
Set the row and column block layouts,.
Definition: BlockSparseMatrix.h:563
BlockSparseMatrix(const BlockSparseMatrix &other)
Copy-constructor.
Definition: BlockSparseMatrix.h:331
Index outerToBlock(Index outer) const
Definition: BlockSparseMatrix.h:779
Index nonZeros() const
Definition: BlockSparseMatrix.h:862
Index blockCols() const
Definition: BlockSparseMatrix.h:770
Map< const BlockScalar > coeff(Index brow, Index bcol) const
Definition: BlockSparseMatrix.h:832
Index blockPtr(Index id) const
Definition: BlockSparseMatrix.h:936
A versatile sparse matrix representation where each element is a block.
Definition: BlockSparseMatrix.h:54
Index nonZerosBlocks() const
Definition: BlockSparseMatrix.h:860
Index blockRows() const
Definition: BlockSparseMatrix.h:765
Index rows() const
Definition: BlockSparseMatrix.h:738
Index blockColsIndex(Index bj) const
Definition: BlockSparseMatrix.h:884
void resize(Index brow, Index bcol)
Set the number of rows and columns blocks.
Definition: BlockSparseMatrix.h:538
Ref< BlockScalar > coeffRef(Index brow, Index bcol)
Definition: BlockSparseMatrix.h:806