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