11#ifndef EIGEN_SPARSE_BLOCK_H
12#define EIGEN_SPARSE_BLOCK_H
15#include "./InternalHeaderCheck.h"
20template <
typename XprType,
int BlockRows,
int BlockCols>
21class BlockImpl<XprType, BlockRows, BlockCols, true,
Sparse>
23 using BlockType = Block<XprType, BlockRows, BlockCols, true>;
26 enum { IsRowMajor = internal::traits<BlockType>::IsRowMajor };
29 enum { OuterSize = IsRowMajor ? BlockRows : BlockCols };
30 using Base = SparseCompressedBase<BlockType>;
31 using Base::convert_index;
34 EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)
36 inline BlockImpl(XprType& xpr, Index i) : m_matrix(xpr), m_outerStart(convert_index(i)), m_outerSize(OuterSize) {}
38 inline BlockImpl(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
40 m_outerStart(convert_index(IsRowMajor ? startRow : startCol)),
41 m_outerSize(convert_index(IsRowMajor ? blockRows : blockCols)) {}
43 EIGEN_STRONG_INLINE Index rows()
const {
return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
44 EIGEN_STRONG_INLINE Index cols()
const {
return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
46 Index nonZeros()
const {
47 return nonZerosImpl(std::integral_constant<
bool, (internal::traits<XprType>::Flags &
CompressedAccessBit) != 0>());
51 Index nonZerosImpl(std::true_type)
const {
52 if (m_outerSize.value() == 0)
return 0;
53 const StorageIndex* outer = m_matrix.outerIndexPtr();
54 if (!outer)
return m_matrix.nonZeros();
55 const StorageIndex* innerNonZeros = m_matrix.innerNonZeroPtr();
56 if (!innerNonZeros)
return outer[m_outerStart + m_outerSize.value()] - outer[m_outerStart];
58 for (Index j = m_outerStart; j < m_outerStart + m_outerSize.value(); ++j) nnz += innerNonZeros[j];
62 Index nonZerosImpl(std::false_type)
const {
63 using EvaluatorType = internal::evaluator<XprType>;
64 EvaluatorType matEval(m_matrix);
66 Index end = m_outerStart + m_outerSize.value();
67 for (Index j = m_outerStart; j < end; ++j)
68 for (
typename EvaluatorType::InnerIterator it(matEval, j); it; ++it) ++nnz;
73 inline const Scalar coeff(Index row, Index col)
const {
74 return m_matrix.coeff(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart));
77 inline const Scalar coeff(Index index)
const {
78 return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart);
81 inline const XprType& nestedExpression()
const {
return m_matrix; }
82 inline XprType& nestedExpression() {
return m_matrix; }
83 Index startRow()
const {
return IsRowMajor ? m_outerStart : 0; }
84 Index startCol()
const {
return IsRowMajor ? 0 : m_outerStart; }
85 Index blockRows()
const {
return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
86 Index blockCols()
const {
return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
88 inline const Scalar* valuePtr()
const {
return m_matrix.valuePtr(); }
89 inline Scalar* valuePtr() {
return m_matrix.valuePtr(); }
91 inline const StorageIndex* innerIndexPtr()
const {
return m_matrix.innerIndexPtr(); }
92 inline StorageIndex* innerIndexPtr() {
return m_matrix.innerIndexPtr(); }
94 inline const StorageIndex* outerIndexPtr()
const {
95 const StorageIndex* p = m_matrix.outerIndexPtr();
96 return p ? p + m_outerStart : 0;
98 inline StorageIndex* outerIndexPtr() {
99 StorageIndex* p = m_matrix.outerIndexPtr();
100 return p ? p + m_outerStart : 0;
103 inline const StorageIndex* innerNonZeroPtr()
const {
104 const StorageIndex* p = m_matrix.innerNonZeroPtr();
105 return p ? p + m_outerStart : 0;
107 inline StorageIndex* innerNonZeroPtr() {
108 StorageIndex* p = m_matrix.innerNonZeroPtr();
109 return p ? p + m_outerStart : 0;
112 bool isCompressed()
const {
return m_matrix.innerNonZeroPtr() == 0; }
115 typename internal::ref_selector<XprType>::non_const_type m_matrix;
117 const internal::variable_if_dynamic<Index, OuterSize> m_outerSize;
122 template <
typename T>
123 BlockImpl& operator=(
const T&) {
124 EIGEN_STATIC_ASSERT(
sizeof(T) == 0, THIS_SPARSE_BLOCK_SUBEXPRESSION_IS_READ_ONLY);
135template <
typename SparseMatrixType,
int BlockRows,
int BlockCols>
136class sparse_matrix_block_impl :
public SparseCompressedBase<Block<SparseMatrixType, BlockRows, BlockCols, true> > {
137 using BlockType = Block<SparseMatrixType, BlockRows, BlockCols, true>;
139 using Base::convert_index;
142 enum { IsRowMajor = internal::traits<BlockType>::IsRowMajor };
143 EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)
145 enum { OuterSize = IsRowMajor ? BlockRows : BlockCols };
148 inline sparse_matrix_block_impl(SparseMatrixType& xpr,
Index i)
149 : m_matrix(xpr), m_outerStart(convert_index(i)), m_outerSize(OuterSize) {}
151 inline sparse_matrix_block_impl(SparseMatrixType& xpr,
Index startRow,
Index startCol,
Index blockRows,
154 m_outerStart(convert_index(IsRowMajor ? startRow : startCol)),
155 m_outerSize(convert_index(IsRowMajor ? blockRows : blockCols)) {}
157 template <
typename OtherDerived>
158 inline BlockType& operator=(
const SparseMatrixBase<OtherDerived>& other) {
159 using NestedMatrixType_ = internal::remove_all_t<typename SparseMatrixType::Nested>;
160 NestedMatrixType_& matrix = m_matrix;
165 Ref<const SparseMatrix<Scalar, IsRowMajor ? RowMajor : ColMajor, StorageIndex> > tmp(other.derived());
166 eigen_internal_assert(tmp.outerSize() == m_outerSize.value());
169 Index nnz = tmp.nonZeros();
171 m_outerStart == 0 ? 0 : m_matrix.outerIndexPtr()[m_outerStart];
172 Index end = m_matrix.outerIndexPtr()[m_outerStart + m_outerSize.value()];
173 Index block_size = end - start;
174 Index tail_size = m_matrix.outerIndexPtr()[m_matrix.outerSize()] - end;
176 Index free_size = m_matrix.isCompressed() ?
Index(matrix.data().allocatedSize()) + block_size : block_size;
178 Index tmp_start = tmp.outerIndexPtr()[0];
180 bool update_trailing_pointers =
false;
181 if (nnz > free_size) {
183 typename SparseMatrixType::Storage newdata(m_matrix.data().allocatedSize() - block_size + nnz);
185 internal::smart_copy(m_matrix.valuePtr(), m_matrix.valuePtr() + start, newdata.valuePtr());
186 internal::smart_copy(m_matrix.innerIndexPtr(), m_matrix.innerIndexPtr() + start, newdata.indexPtr());
188 internal::smart_copy(tmp.valuePtr() + tmp_start, tmp.valuePtr() + tmp_start + nnz, newdata.valuePtr() + start);
189 internal::smart_copy(tmp.innerIndexPtr() + tmp_start, tmp.innerIndexPtr() + tmp_start + nnz,
190 newdata.indexPtr() + start);
192 internal::smart_copy(matrix.valuePtr() + end, matrix.valuePtr() + end + tail_size,
193 newdata.valuePtr() + start + nnz);
194 internal::smart_copy(matrix.innerIndexPtr() + end, matrix.innerIndexPtr() + end + tail_size,
195 newdata.indexPtr() + start + nnz);
197 newdata.resize(m_matrix.outerIndexPtr()[m_matrix.outerSize()] - block_size + nnz);
199 matrix.data().swap(newdata);
201 update_trailing_pointers =
true;
203 if (m_matrix.isCompressed() && nnz != block_size) {
205 matrix.data().resize(start + nnz + tail_size);
207 internal::smart_memmove(matrix.valuePtr() + end, matrix.valuePtr() + end + tail_size,
208 matrix.valuePtr() + start + nnz);
209 internal::smart_memmove(matrix.innerIndexPtr() + end, matrix.innerIndexPtr() + end + tail_size,
210 matrix.innerIndexPtr() + start + nnz);
212 update_trailing_pointers =
true;
215 internal::smart_copy(tmp.valuePtr() + tmp_start, tmp.valuePtr() + tmp_start + nnz, matrix.valuePtr() + start);
216 internal::smart_copy(tmp.innerIndexPtr() + tmp_start, tmp.innerIndexPtr() + tmp_start + nnz,
217 matrix.innerIndexPtr() + start);
222 if (!m_matrix.isCompressed()) matrix.innerNonZeroPtr()[m_outerStart] =
StorageIndex(nnz);
223 matrix.outerIndexPtr()[m_outerStart] =
StorageIndex(start);
226 for (
Index k = 0; k < m_outerSize.value(); ++k) {
227 StorageIndex nnz_k = internal::convert_index<StorageIndex>(tmp.innerVector(k).nonZeros());
228 if (!m_matrix.isCompressed()) matrix.innerNonZeroPtr()[m_outerStart + k] = nnz_k;
229 matrix.outerIndexPtr()[m_outerStart + k] = p;
234 if (update_trailing_pointers) {
235 StorageIndex offset = internal::convert_index<StorageIndex>(nnz - block_size);
236 for (
Index k = m_outerStart + m_outerSize.value(); k <= matrix.outerSize(); ++k) {
237 matrix.outerIndexPtr()[k] += offset;
244 inline BlockType& operator=(
const BlockType& other) {
return operator= <BlockType>(other); }
246 inline const Scalar* valuePtr()
const {
return m_matrix.valuePtr(); }
247 inline Scalar* valuePtr() {
return m_matrix.valuePtr(); }
249 inline const StorageIndex* innerIndexPtr()
const {
return m_matrix.innerIndexPtr(); }
250 inline StorageIndex* innerIndexPtr() {
return m_matrix.innerIndexPtr(); }
252 inline const StorageIndex* outerIndexPtr()
const {
return m_matrix.outerIndexPtr() + m_outerStart; }
253 inline StorageIndex* outerIndexPtr() {
return m_matrix.outerIndexPtr() + m_outerStart; }
256 return isCompressed() ? 0 : (m_matrix.innerNonZeroPtr() + m_outerStart);
258 inline StorageIndex* innerNonZeroPtr() {
return isCompressed() ? 0 : (m_matrix.innerNonZeroPtr() + m_outerStart); }
260 bool isCompressed()
const {
return m_matrix.innerNonZeroPtr() == 0; }
263 return m_matrix.coeffRef(
row + (IsRowMajor ? m_outerStart : 0),
col + (IsRowMajor ? 0 : m_outerStart));
267 return m_matrix.coeff(
row + (IsRowMajor ? m_outerStart : 0),
col + (IsRowMajor ? 0 : m_outerStart));
270 inline const Scalar coeff(
Index index)
const {
271 return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart);
274 const Scalar& lastCoeff()
const {
275 EIGEN_STATIC_ASSERT_VECTOR_ONLY(sparse_matrix_block_impl);
277 if (m_matrix.isCompressed())
278 return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart + 1] - 1];
280 return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart] + m_matrix.innerNonZeroPtr()[m_outerStart] - 1];
283 EIGEN_STRONG_INLINE
Index rows()
const {
return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
284 EIGEN_STRONG_INLINE
Index cols()
const {
return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
286 inline const SparseMatrixType& nestedExpression()
const {
return m_matrix; }
287 inline SparseMatrixType& nestedExpression() {
return m_matrix; }
288 Index startRow()
const {
return IsRowMajor ? m_outerStart : 0; }
289 Index startCol()
const {
return IsRowMajor ? 0 : m_outerStart; }
290 Index blockRows()
const {
return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
291 Index blockCols()
const {
return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
294 typename internal::ref_selector<SparseMatrixType>::non_const_type m_matrix;
296 const internal::variable_if_dynamic<Index, OuterSize> m_outerSize;
301template <
typename Scalar_,
int Options_,
typename StorageIndex_,
int BlockRows,
int BlockCols>
302class BlockImpl<
SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols, true,
Sparse>
303 :
public internal::sparse_matrix_block_impl<SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols> {
305 using StorageIndex = StorageIndex_;
306 using SparseMatrixType = SparseMatrix<Scalar_, Options_, StorageIndex_>;
307 using Base = internal::sparse_matrix_block_impl<SparseMatrixType, BlockRows, BlockCols>;
308 inline BlockImpl(SparseMatrixType& xpr, Index i) : Base(xpr, i) {}
310 inline BlockImpl(SparseMatrixType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
311 : Base(xpr, startRow, startCol, blockRows, blockCols) {}
313 using Base::operator=;
316template <
typename Scalar_,
int Options_,
typename StorageIndex_,
int BlockRows,
int BlockCols>
317class BlockImpl<const
SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols, true,
Sparse>
318 :
public internal::sparse_matrix_block_impl<const SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows,
321 using StorageIndex = StorageIndex_;
322 using SparseMatrixType =
const SparseMatrix<Scalar_, Options_, StorageIndex_>;
323 using Base = internal::sparse_matrix_block_impl<SparseMatrixType, BlockRows, BlockCols>;
324 inline BlockImpl(SparseMatrixType& xpr, Index i) : Base(xpr, i) {}
326 inline BlockImpl(SparseMatrixType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
327 : Base(xpr, startRow, startCol, blockRows, blockCols) {}
329 using Base::operator=;
332 template <
typename Derived>
333 BlockImpl(
const SparseMatrixBase<Derived>& xpr, Index i);
334 template <
typename Derived>
335 BlockImpl(
const SparseMatrixBase<Derived>& xpr);
343template <
typename XprType,
int BlockRows,
int BlockCols,
bool InnerPanel>
345 :
public SparseMatrixBase<Block<XprType, BlockRows, BlockCols, InnerPanel> >, internal::no_assignment_operator {
347 using Base = SparseMatrixBase<BlockType>;
348 using Base::convert_index;
351 enum { IsRowMajor = internal::traits<BlockType>::IsRowMajor };
352 EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)
354 using MatrixTypeNested_ = internal::remove_all_t<typename XprType::Nested>;
360 m_startRow((BlockRows == 1) && (BlockCols == XprType::
ColsAtCompileTime) ? convert_index(i) : 0),
361 m_startCol((BlockRows == XprType::
RowsAtCompileTime) && (BlockCols == 1) ? convert_index(i) : 0),
362 m_blockRows(BlockRows == 1 ? 1 : xpr.rows()),
363 m_blockCols(BlockCols == 1 ? 1 : xpr.cols()) {}
367 inline BlockImpl(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
369 m_startRow(convert_index(startRow)),
370 m_startCol(convert_index(startCol)),
371 m_blockRows(convert_index(blockRows)),
372 m_blockCols(convert_index(blockCols)) {}
374 inline Index rows()
const {
return m_blockRows.value(); }
375 inline Index cols()
const {
return m_blockCols.value(); }
377 inline Scalar& coeffRef(Index row, Index col) {
378 return m_matrix.coeffRef(row + m_startRow.value(), col + m_startCol.value());
381 inline const Scalar coeff(Index row, Index col)
const {
382 return m_matrix.coeff(row + m_startRow.value(), col + m_startCol.value());
385 inline Scalar& coeffRef(Index index) {
386 return m_matrix.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
387 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
390 inline const Scalar coeff(Index index)
const {
391 return m_matrix.coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
392 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
395 inline const XprType& nestedExpression()
const {
return m_matrix; }
396 inline XprType& nestedExpression() {
return m_matrix; }
397 Index startRow()
const {
return m_startRow.value(); }
398 Index startCol()
const {
return m_startCol.value(); }
399 Index blockRows()
const {
return m_blockRows.value(); }
400 Index blockCols()
const {
return m_blockCols.value(); }
403 friend struct internal::unary_evaluator<Block<XprType, BlockRows, BlockCols, InnerPanel>, internal::IteratorBased,
406 Index nonZeros() const {
return Dynamic; }
408 typename internal::ref_selector<XprType>::non_const_type m_matrix;
409 const internal::variable_if_dynamic<Index, XprType::RowsAtCompileTime == 1 ? 0 : Dynamic> m_startRow;
410 const internal::variable_if_dynamic<Index, XprType::ColsAtCompileTime == 1 ? 0 : Dynamic> m_startCol;
411 const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_blockRows;
412 const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_blockCols;
417 template <
typename T>
418 BlockImpl& operator=(
const T&) {
419 EIGEN_STATIC_ASSERT(
sizeof(T) == 0, THIS_SPARSE_BLOCK_SUBEXPRESSION_IS_READ_ONLY);
426template <
typename ArgType,
int BlockRows,
int BlockCols,
bool InnerPanel>
427struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IteratorBased>
428 :
public evaluator_base<Block<ArgType, BlockRows, BlockCols, InnerPanel> > {
429 class InnerVectorInnerIterator;
430 class OuterVectorInnerIterator;
433 using XprType = Block<ArgType, BlockRows, BlockCols, InnerPanel>;
434 using StorageIndex =
typename XprType::StorageIndex;
435 using Scalar =
typename XprType::Scalar;
438 IsRowMajor = XprType::IsRowMajor,
439 OuterVector = (BlockCols == 1 && ArgType::IsRowMajor) || (BlockRows == 1 && !ArgType::IsRowMajor),
440 CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
441 Flags = XprType::Flags
444 using InnerIterator = std::conditional_t<OuterVector, OuterVectorInnerIterator, InnerVectorInnerIterator>;
446 explicit unary_evaluator(
const XprType& op) : m_argImpl(op.nestedExpression()), m_block(op) {}
448 inline Index nonZerosEstimate()
const {
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;
460 using EvalIterator =
typename evaluator<ArgType>::InnerIterator;
462 evaluator<ArgType> m_argImpl;
463 const XprType& m_block;
466template <
typename ArgType,
int BlockRows,
int BlockCols,
bool InnerPanel>
467class unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IteratorBased>::InnerVectorInnerIterator
468 :
public EvalIterator {
472 enum { XprIsRowMajor = unary_evaluator::IsRowMajor };
473 const XprType& m_block;
477 EIGEN_STRONG_INLINE InnerVectorInnerIterator(
const unary_evaluator& aEval, Index outer)
478 : EvalIterator(aEval.m_argImpl, outer + (XprIsRowMajor ? aEval.m_block.startRow() : aEval.m_block.startCol())),
479 m_block(aEval.m_block),
480 m_end(XprIsRowMajor ? aEval.m_block.startCol() + aEval.m_block.blockCols()
481 : aEval.m_block.startRow() + aEval.m_block.blockRows()) {
482 while ((EvalIterator::operator
bool()) &&
483 (EvalIterator::index() < (XprIsRowMajor ? m_block.startCol() : m_block.startRow())))
484 EvalIterator::operator++();
487 inline StorageIndex index()
const {
488 return EvalIterator::index() - convert_index<StorageIndex>(XprIsRowMajor ? m_block.startCol() : m_block.startRow());
490 inline Index outer()
const {
491 return EvalIterator::outer() - (XprIsRowMajor ? m_block.startRow() : m_block.startCol());
493 inline Index row()
const {
return EvalIterator::row() - m_block.startRow(); }
494 inline Index col()
const {
return EvalIterator::col() - m_block.startCol(); }
496 inline operator bool()
const {
return EvalIterator::operator bool() && EvalIterator::index() < m_end; }
499template <
typename ArgType,
int BlockRows,
int BlockCols,
bool InnerPanel>
500class unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IteratorBased>::OuterVectorInnerIterator {
502 enum { XprIsRowMajor = unary_evaluator::IsRowMajor };
503 const unary_evaluator& m_eval;
505 const Index m_innerIndex;
510 EIGEN_STRONG_INLINE OuterVectorInnerIterator(
const unary_evaluator& aEval, Index outer)
512 m_outerPos((XprIsRowMajor ? aEval.m_block.startCol() : aEval.m_block.startRow())),
513 m_innerIndex(XprIsRowMajor ? aEval.m_block.startRow() : aEval.m_block.startCol()),
514 m_end(XprIsRowMajor ? aEval.m_block.startCol() + aEval.m_block.blockCols()
515 : aEval.m_block.startRow() + aEval.m_block.blockRows()),
516 m_it(m_eval.m_argImpl, m_outerPos) {
517 EIGEN_UNUSED_VARIABLE(outer);
518 eigen_assert(outer == 0);
520 while (m_it && m_it.index() < m_innerIndex) ++m_it;
521 if ((!m_it) || (m_it.index() != m_innerIndex)) ++(*this);
524 inline StorageIndex index()
const {
525 return convert_index<StorageIndex>(m_outerPos -
526 (XprIsRowMajor ? m_eval.m_block.startCol() : m_eval.m_block.startRow()));
528 inline Index outer()
const {
return 0; }
529 inline Index row()
const {
return XprIsRowMajor ? 0 : index(); }
530 inline Index col()
const {
return XprIsRowMajor ? index() : 0; }
532 inline Scalar value()
const {
return m_it.value(); }
533 inline Scalar& valueRef() {
return m_it.valueRef(); }
535 inline OuterVectorInnerIterator& operator++() {
537 while (++m_outerPos < m_end) {
539 internal::destroy_at(&m_it);
540 internal::construct_at(&m_it, m_eval.m_argImpl, m_outerPos);
542 while (m_it && m_it.index() < m_innerIndex) ++m_it;
543 if (m_it && m_it.index() == m_innerIndex)
break;
548 inline operator bool()
const {
return m_outerPos < m_end; }
551template <
typename Scalar_,
int Options_,
typename StorageIndex_,
int BlockRows,
int BlockCols>
552struct unary_evaluator<Block<SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols, true>, IteratorBased>
554 SparseCompressedBase<Block<SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols, true> > > {
555 using XprType = Block<SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols,
true>;
556 using Base = evaluator<SparseCompressedBase<XprType>>;
557 explicit unary_evaluator(
const XprType& xpr) : Base(xpr) {}
560template <
typename Scalar_,
int Options_,
typename StorageIndex_,
int BlockRows,
int BlockCols>
561struct unary_evaluator<Block<const SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols, true>,
563 : evaluator<SparseCompressedBase<
564 Block<const SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols, true> > > {
565 using XprType = Block<const SparseMatrix<Scalar_, Options_, StorageIndex_>, BlockRows, BlockCols,
true>;
566 using Base = evaluator<SparseCompressedBase<XprType>>;
567 explicit unary_evaluator(
const XprType& xpr) : Base(xpr) {}
BlockImpl(XprType &xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
Definition SparseBlock.h:367
BlockImpl(XprType &xpr, Index i)
Definition SparseBlock.h:358
Expression of a fixed-size or dynamic-size block.
Definition Block.h:111
Common base class for sparse [compressed]-{row|column}-storage format.
Definition SparseCompressedBase.h:44
Index nonZeros() const
Definition SparseCompressedBase.h:65
SparseCompressedBase()=default
constexpr RowXpr row(Index i)
Definition SparseMatrixBase.h:1094
typename internal::traits< Derived >::StorageIndex StorageIndex
Definition SparseMatrixBase.h:45
constexpr ColXpr col(Index i)
Definition SparseMatrixBase.h:1081
@ IsVectorAtCompileTime
Definition SparseMatrixBase.h:82
@ ColsAtCompileTime
Definition SparseMatrixBase.h:66
@ RowsAtCompileTime
Definition SparseMatrixBase.h:60
A versatile sparse matrix representation.
Definition SparseMatrix.h:122
constexpr unsigned int CompressedAccessBit
Definition Constants.h:196
constexpr Derived & derived()
Definition EigenBase.h:50
Eigen::Index Index
The interface type of indices.
Definition EigenBase.h:44
Definition Constants.h:545