10 #ifndef EIGEN_SPARSE_BLOCK_H
11 #define EIGEN_SPARSE_BLOCK_H
16 template<
typename XprType,
int BlockRows,
int BlockCols>
25 enum { OuterSize = IsRowMajor ? BlockRows : BlockCols };
32 : m_matrix(xpr), m_outerStart(
convert_index(
i)), m_outerSize(OuterSize)
36 : m_matrix(xpr), m_outerStart(
convert_index(IsRowMajor ? startRow : startCol)), m_outerSize(
convert_index(IsRowMajor ? blockRows : blockCols))
45 EvaluatorType matEval(m_matrix);
47 Index end = m_outerStart + m_outerSize.value();
49 for(
typename EvaluatorType::InnerIterator it(matEval,
j); it; ++it)
56 return m_matrix.coeff(
row + (IsRowMajor ? m_outerStart : 0),
col + (IsRowMajor ? 0 : m_outerStart));
61 return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart);
68 Index blockRows()
const {
return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
69 Index blockCols()
const {
return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
95 template<
typename SparseMatrixType,
int BlockRows,
int BlockCols>
96 class sparse_matrix_block_impl
97 :
public SparseCompressedBase<Block<SparseMatrixType,BlockRows,BlockCols,true> >
119 template<
typename OtherDerived>
132 Index nnz = tmp.nonZeros();
139 ?
Index(
matrix.data().allocatedSize()) + block_size
142 Index tmp_start = tmp.outerIndexPtr()[0];
144 bool update_trailing_pointers =
false;
148 typename SparseMatrixType::Storage newdata(
m_matrix.data().allocatedSize() - block_size + nnz);
153 internal::smart_copy(tmp.valuePtr() + tmp_start, tmp.valuePtr() + tmp_start + nnz, newdata.valuePtr() + start);
154 internal::smart_copy(tmp.innerIndexPtr() + tmp_start, tmp.innerIndexPtr() + tmp_start + nnz, newdata.indexPtr() + start);
159 newdata.resize(
m_matrix.outerIndexPtr()[
m_matrix.outerSize()] - block_size + nnz);
161 matrix.data().swap(newdata);
163 update_trailing_pointers =
true;
167 if(
m_matrix.isCompressed() && nnz!=block_size)
170 matrix.data().resize(start + nnz + tail_size);
175 update_trailing_pointers =
true;
183 if(IsVectorAtCompileTime)
191 StorageIndex
p = StorageIndex(start);
194 StorageIndex nnz_k = internal::convert_index<StorageIndex>(tmp.innerVector(k).nonZeros());
202 if(update_trailing_pointers)
204 StorageIndex
offset = internal::convert_index<StorageIndex>(nnz - block_size);
227 {
return m_matrix.innerIndexPtr(); }
286 template<
typename _Scalar,
int _Options,
typename _StorageIndex,
int BlockRows,
int BlockCols>
299 :
Base(xpr, startRow, startCol, blockRows, blockCols)
302 using Base::operator=;
305 template<
typename _Scalar,
int _Options,
typename _StorageIndex,
int BlockRows,
int BlockCols>
318 :
Base(xpr, startRow, startCol, blockRows, blockCols)
321 using Base::operator=;
332 template<
typename XprType,
int BlockRows,
int BlockCols,
bool InnerPanel>
351 m_blockRows(BlockRows==1 ? 1 : xpr.
rows()),
352 m_blockCols(BlockCols==1 ? 1 : xpr.
cols())
361 inline Index rows()
const {
return m_blockRows.value(); }
362 inline Index cols()
const {
return m_blockCols.value(); }
366 return m_matrix.coeffRef(
row + m_startRow.value(),
col + m_startCol.value());
371 return m_matrix.coeff(
row + m_startRow.value(),
col + m_startCol.value());
376 return m_matrix.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
377 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
382 return m_matrix.coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
383 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
419 template<
typename ArgType,
int BlockRows,
int BlockCols,
bool InnerPanel>
421 :
public evaluator_base<Block<ArgType,BlockRows,BlockCols,InnerPanel> >
423 class InnerVectorInnerIterator;
424 class OuterVectorInnerIterator;
431 IsRowMajor = XprType::IsRowMajor,
433 OuterVector = (BlockCols==1 && ArgType::IsRowMajor)
436 (BlockRows==1 && !ArgType::IsRowMajor),
439 Flags = XprType::Flags
445 : m_argImpl(op.nestedExpression()), m_block(op)
449 const Index nnz = m_block.nonZeros();
453 const Index nested_sz = m_block.nestedExpression().size();
454 return nested_sz == 0 ? 0 : m_argImpl.nonZerosEstimate() * m_block.size() / nested_sz;
466 template<
typename ArgType,
int BlockRows,
int BlockCols,
bool InnerPanel>
473 enum { XprIsRowMajor = unary_evaluator::IsRowMajor };
479 :
EvalIterator(aEval.m_argImpl, outer + (XprIsRowMajor ? aEval.m_block.startRow() : aEval.m_block.startCol())),
480 m_block(aEval.m_block),
481 m_end(XprIsRowMajor ? aEval.m_block.startCol()+aEval.m_block.blockCols() : aEval.m_block.startRow()+aEval.m_block.blockRows())
483 while( (EvalIterator::operator
bool()) && (EvalIterator::index() < (XprIsRowMajor ? m_block.startCol() : m_block.startRow())) )
487 inline StorageIndex index()
const {
return EvalIterator::index() - convert_index<StorageIndex>(XprIsRowMajor ? m_block.startCol() : m_block.startRow()); }
488 inline Index outer()
const {
return EvalIterator::outer() - (XprIsRowMajor ? m_block.startRow() : m_block.startCol()); }
492 inline operator bool()
const {
return EvalIterator::operator bool() && EvalIterator::index() < m_end; }
495 template<
typename ArgType,
int BlockRows,
int BlockCols,
bool InnerPanel>
499 enum { XprIsRowMajor = unary_evaluator::IsRowMajor };
509 m_outerPos( (XprIsRowMajor ? aEval.m_block.startCol() : aEval.m_block.startRow()) ),
510 m_innerIndex(XprIsRowMajor ? aEval.m_block.startRow() : aEval.m_block.startCol()),
511 m_end(XprIsRowMajor ? aEval.m_block.startCol()+aEval.m_block.blockCols() : aEval.m_block.startRow()+aEval.m_block.blockRows()),
512 m_it(m_eval.m_argImpl, m_outerPos)
517 while(m_it && m_it.index() < m_innerIndex) ++m_it;
518 if((!m_it) || (m_it.index()!=m_innerIndex))
522 inline StorageIndex index()
const {
return convert_index<StorageIndex>(m_outerPos - (XprIsRowMajor ? m_eval.m_block.startCol() : m_eval.m_block.startRow())); }
524 inline Index row()
const {
return XprIsRowMajor ? 0 : index(); }
525 inline Index col()
const {
return XprIsRowMajor ? index() : 0; }
533 while(++m_outerPos<m_end)
536 m_it.~EvalIterator();
537 ::new (&m_it)
EvalIterator(m_eval.m_argImpl, m_outerPos);
539 while(m_it && m_it.index() < m_innerIndex) ++m_it;
540 if(m_it && m_it.index()==m_innerIndex)
break;
545 inline operator bool()
const {
return m_outerPos < m_end; }
548 template<
typename _Scalar,
int _Options,
typename _StorageIndex,
int BlockRows,
int BlockCols>
550 :
evaluator<SparseCompressedBase<Block<SparseMatrix<_Scalar, _Options, _StorageIndex>,BlockRows,BlockCols,true> > >
557 template<
typename _Scalar,
int _Options,
typename _StorageIndex,
int BlockRows,
int BlockCols>
559 :
evaluator<SparseCompressedBase<Block<const SparseMatrix<_Scalar, _Options, _StorageIndex>,BlockRows,BlockCols,true> > >
571 #endif // EIGEN_SPARSE_BLOCK_H