Remove deprecated code not used by evaluators

This commit is contained in:
Gael Guennebaud
2014-09-18 15:15:27 +02:00
parent 8b3be4907d
commit 0ca43f7e9a
137 changed files with 41 additions and 7806 deletions

View File

@@ -39,10 +39,8 @@ static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& r
// Therefore, we have nnz(lhs*rhs) = nnz(lhs) + nnz(rhs)
Index estimated_nnz_prod = lhs.nonZeros() + rhs.nonZeros();
#ifdef EIGEN_TEST_EVALUATORS
typename evaluator<Lhs>::type lhsEval(lhs);
typename evaluator<Rhs>::type rhsEval(rhs);
#endif
res.setZero();
res.reserve(Index(estimated_nnz_prod));
@@ -52,19 +50,11 @@ static void conservative_sparse_sparse_product_impl(const Lhs& lhs, const Rhs& r
res.startVec(j);
Index nnz = 0;
#ifndef EIGEN_TEST_EVALUATORS
for (typename Rhs::InnerIterator rhsIt(rhs, j); rhsIt; ++rhsIt)
#else
for (typename evaluator<Rhs>::InnerIterator rhsIt(rhsEval, j); rhsIt; ++rhsIt)
#endif
{
Scalar y = rhsIt.value();
Index k = rhsIt.index();
#ifndef EIGEN_TEST_EVALUATORS
for (typename Lhs::InnerIterator lhsIt(lhs, k); lhsIt; ++lhsIt)
#else
for (typename evaluator<Lhs>::InnerIterator lhsIt(lhsEval, k); lhsIt; ++lhsIt)
#endif
{
Index i = lhsIt.index();
Scalar x = lhsIt.value();

View File

@@ -176,7 +176,6 @@ class MappedSparseMatrix<Scalar,_Flags,_Index>::ReverseInnerIterator
const Index m_end;
};
#ifdef EIGEN_ENABLE_EVALUATORS
namespace internal {
template<typename _Scalar, int _Options, typename _Index>
@@ -202,7 +201,6 @@ struct evaluator<MappedSparseMatrix<_Scalar,_Options,_Index> >
};
}
#endif
} // end namespace Eigen

View File

@@ -12,117 +12,6 @@
namespace Eigen {
#ifndef EIGEN_TEST_EVALUATORS
template<typename Derived>
template<typename OtherDerived>
Derived& SparseMatrixBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
{
other.derived().evalTo(derived());
return derived();
}
template<typename Derived>
template<typename OtherDerived>
Derived& SparseMatrixBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
{
other.evalTo(derived());
return derived();
}
template<typename Derived>
template<typename OtherDerived>
inline Derived& SparseMatrixBase<Derived>::operator=(const SparseMatrixBase<OtherDerived>& other)
{
return assign(other.derived());
}
template<typename Derived>
inline Derived& SparseMatrixBase<Derived>::operator=(const Derived& other)
{
// if (other.isRValue())
// derived().swap(other.const_cast_derived());
// else
return assign(other.derived());
}
template<typename Derived>
template<typename OtherDerived>
inline Derived& SparseMatrixBase<Derived>::assign(const OtherDerived& other)
{
const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? Index(other.rows()) : Index(other.cols());
if ((!transpose) && other.isRValue())
{
// eval without temporary
derived().resize(Index(other.rows()), Index(other.cols()));
derived().setZero();
derived().reserve((std::max)(this->rows(),this->cols())*2);
for (Index j=0; j<outerSize; ++j)
{
derived().startVec(j);
for (typename OtherDerived::InnerIterator it(other, typename OtherDerived::Index(j)); it; ++it)
{
Scalar v = it.value();
derived().insertBackByOuterInner(j,Index(it.index())) = v;
}
}
derived().finalize();
}
else
{
assignGeneric(other);
}
return derived();
}
template<typename Derived>
template<typename OtherDerived>
inline void SparseMatrixBase<Derived>::assignGeneric(const OtherDerived& other)
{
//const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
eigen_assert(( ((internal::traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) ||
(!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) &&
"the transpose operation is supposed to be handled in SparseMatrix::operator=");
enum { Flip = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit) };
const Index outerSize = Index(other.outerSize());
//typedef typename internal::conditional<transpose, LinkedVectorMatrix<Scalar,Flags&RowMajorBit>, Derived>::type TempType;
// thanks to shallow copies, we always eval to a tempary
Derived temp(Index(other.rows()), Index(other.cols()));
temp.reserve((std::max)(this->rows(),this->cols())*2);
for (Index j=0; j<outerSize; ++j)
{
temp.startVec(j);
for (typename OtherDerived::InnerIterator it(other.derived(), typename OtherDerived::Index(j)); it; ++it)
{
Scalar v = it.value();
temp.insertBackByOuterInner(Flip?Index(it.index()):j,Flip?j:Index(it.index())) = v;
}
}
temp.finalize();
derived() = temp.markAsRValue();
}
// template<typename Lhs, typename Rhs>
// inline Derived& operator=(const SparseSparseProduct<Lhs,Rhs>& product);
//
// template<typename OtherDerived>
// Derived& operator+=(const SparseMatrixBase<OtherDerived>& other);
// template<typename OtherDerived>
// Derived& operator-=(const SparseMatrixBase<OtherDerived>& other);
//
// Derived& operator*=(const Scalar& other);
// Derived& operator/=(const Scalar& other);
//
// template<typename OtherDerived>
// Derived& operator*=(const SparseMatrixBase<OtherDerived>& other);
#else // EIGEN_TEST_EVALUATORS
template<typename Derived>
template<typename OtherDerived>
Derived& SparseMatrixBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
@@ -298,8 +187,6 @@ struct Assignment<DstXprType, Solve<DecType,RhsType>, internal::assign_op<Scalar
} // end namespace internal
#endif // EIGEN_TEST_EVALUATORS
} // end namespace Eigen
#endif // EIGEN_SPARSEASSIGN_H

View File

@@ -25,33 +25,6 @@ protected:
enum { OuterSize = IsRowMajor ? BlockRows : BlockCols };
public:
EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)
#ifndef EIGEN_TEST_EVALUATORS
class InnerIterator: public XprType::InnerIterator
{
typedef typename BlockImpl::Index Index;
public:
inline InnerIterator(const BlockType& xpr, Index outer)
: XprType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
{}
inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
protected:
Index m_outer;
};
class ReverseInnerIterator: public XprType::ReverseInnerIterator
{
typedef typename BlockImpl::Index Index;
public:
inline ReverseInnerIterator(const BlockType& xpr, Index outer)
: XprType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
{}
inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
protected:
Index m_outer;
};
#endif // EIGEN_TEST_EVALUATORS
inline BlockImpl(const XprType& xpr, Index i)
: m_matrix(xpr), m_outerStart(i), m_outerSize(OuterSize)
@@ -66,14 +39,6 @@ public:
Index nonZeros() const
{
#ifndef EIGEN_TEST_EVALUATORS
Index nnz = 0;
Index end = m_outerStart + m_outerSize.value();
for(Index j=m_outerStart; j<end; ++j)
for(typename XprType::InnerIterator it(m_matrix, j); it; ++it)
++nnz;
return nnz;
#else // EIGEN_TEST_EVALUATORS
typedef typename internal::evaluator<XprType>::type EvaluatorType;
EvaluatorType matEval(m_matrix);
Index nnz = 0;
@@ -82,7 +47,6 @@ public:
for(typename EvaluatorType::InnerIterator it(matEval, j); it; ++it)
++nnz;
return nnz;
#endif // EIGEN_TEST_EVALUATORS
}
inline const _MatrixTypeNested& nestedExpression() const { return m_matrix; }
@@ -120,31 +84,6 @@ public:
protected:
enum { OuterSize = IsRowMajor ? BlockRows : BlockCols };
public:
#ifndef EIGEN_TEST_EVALUATORS
class InnerIterator: public SparseMatrixType::InnerIterator
{
public:
inline InnerIterator(const BlockType& xpr, Index outer)
: SparseMatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
{}
inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
protected:
Index m_outer;
};
class ReverseInnerIterator: public SparseMatrixType::ReverseInnerIterator
{
public:
inline ReverseInnerIterator(const BlockType& xpr, Index outer)
: SparseMatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
{}
inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
protected:
Index m_outer;
};
#endif // EIGEN_TEST_EVALUATORS
inline sparse_matrix_block_impl(const SparseMatrixType& xpr, Index i)
: m_matrix(xpr), m_outerStart(i), m_outerSize(OuterSize)
@@ -434,34 +373,6 @@ public:
m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
}
#ifndef EIGEN_TEST_EVALUATORS
typedef internal::GenericSparseBlockInnerIteratorImpl<XprType,BlockRows,BlockCols,InnerPanel> InnerIterator;
class ReverseInnerIterator : public _MatrixTypeNested::ReverseInnerIterator
{
typedef typename _MatrixTypeNested::ReverseInnerIterator Base;
const BlockType& m_block;
Index m_begin;
public:
EIGEN_STRONG_INLINE ReverseInnerIterator(const BlockType& block, Index outer)
: Base(block.derived().nestedExpression(), outer + (IsRowMajor ? block.m_startRow.value() : block.m_startCol.value())),
m_block(block),
m_begin(IsRowMajor ? block.m_startCol.value() : block.m_startRow.value())
{
while( (Base::operator bool()) && (Base::index() >= (IsRowMajor ? m_block.m_startCol.value()+block.m_blockCols.value() : m_block.m_startRow.value()+block.m_blockRows.value())) )
Base::operator--();
}
inline Index index() const { return Base::index() - (IsRowMajor ? m_block.m_startCol.value() : m_block.m_startRow.value()); }
inline Index outer() const { return Base::outer() - (IsRowMajor ? m_block.m_startRow.value() : m_block.m_startCol.value()); }
inline Index row() const { return Base::row() - m_block.m_startRow.value(); }
inline Index col() const { return Base::col() - m_block.m_startCol.value(); }
inline operator bool() const { return Base::operator bool() && Base::index() >= m_begin; }
};
#endif // EIGEN_TEST_EVALUATORS
inline const _MatrixTypeNested& nestedExpression() const { return m_matrix; }
Index startRow() const { return m_startRow.value(); }
Index startCol() const { return m_startCol.value(); }
@@ -574,9 +485,6 @@ namespace internal {
inline operator bool() const { return m_outerPos < m_end; }
};
#ifdef EIGEN_TEST_EVALUATORS
//
template<typename ArgType, int BlockRows, int BlockCols, bool InnerPanel>
struct unary_evaluator<Block<ArgType,BlockRows,BlockCols,InnerPanel>, IteratorBased >
: public evaluator_base<Block<ArgType,BlockRows,BlockCols,InnerPanel> >
@@ -690,9 +598,6 @@ public:
inline operator bool() const { return m_outerPos < m_end; }
};
#endif // EIGEN_TEST_EVALUATORS
} // end namespace internal

View File

@@ -38,256 +38,6 @@ class sparse_cwise_binary_op_inner_iterator_selector;
} // end namespace internal
#ifndef EIGEN_TEST_EVALUATORS
template<typename BinaryOp, typename Lhs, typename Rhs>
class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Sparse>
: public SparseMatrixBase<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
{
public:
class InnerIterator;
class ReverseInnerIterator;
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived;
EIGEN_SPARSE_PUBLIC_INTERFACE(Derived)
CwiseBinaryOpImpl()
{
typedef typename internal::traits<Lhs>::StorageKind LhsStorageKind;
typedef typename internal::traits<Rhs>::StorageKind RhsStorageKind;
EIGEN_STATIC_ASSERT((
(!internal::is_same<LhsStorageKind,RhsStorageKind>::value)
|| ((Lhs::Flags&RowMajorBit) == (Rhs::Flags&RowMajorBit))),
THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH);
}
};
template<typename BinaryOp, typename Lhs, typename Rhs>
class CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator
: public internal::sparse_cwise_binary_op_inner_iterator_selector<BinaryOp,Lhs,Rhs,typename CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator>
{
public:
typedef internal::sparse_cwise_binary_op_inner_iterator_selector<
BinaryOp,Lhs,Rhs, InnerIterator> Base;
EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, Index outer)
: Base(binOp.derived(),outer)
{}
};
/***************************************************************************
* Implementation of inner-iterators
***************************************************************************/
// template<typename T> struct internal::func_is_conjunction { enum { ret = false }; };
// template<typename T> struct internal::func_is_conjunction<internal::scalar_product_op<T> > { enum { ret = true }; };
// TODO generalize the internal::scalar_product_op specialization to all conjunctions if any !
namespace internal {
// sparse - sparse (generic)
template<typename BinaryOp, typename Lhs, typename Rhs, typename Derived>
class sparse_cwise_binary_op_inner_iterator_selector<BinaryOp, Lhs, Rhs, Derived, Sparse, Sparse>
{
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> CwiseBinaryXpr;
typedef typename traits<CwiseBinaryXpr>::Scalar Scalar;
typedef typename traits<CwiseBinaryXpr>::Index Index;
typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
typedef typename _LhsNested::InnerIterator LhsIterator;
typedef typename _RhsNested::InnerIterator RhsIterator;
public:
EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
: m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor())
{
this->operator++();
}
EIGEN_STRONG_INLINE Derived& operator++()
{
if (m_lhsIter && m_rhsIter && (m_lhsIter.index() == m_rhsIter.index()))
{
m_id = m_lhsIter.index();
m_value = m_functor(m_lhsIter.value(), m_rhsIter.value());
++m_lhsIter;
++m_rhsIter;
}
else if (m_lhsIter && (!m_rhsIter || (m_lhsIter.index() < m_rhsIter.index())))
{
m_id = m_lhsIter.index();
m_value = m_functor(m_lhsIter.value(), Scalar(0));
++m_lhsIter;
}
else if (m_rhsIter && (!m_lhsIter || (m_lhsIter.index() > m_rhsIter.index())))
{
m_id = m_rhsIter.index();
m_value = m_functor(Scalar(0), m_rhsIter.value());
++m_rhsIter;
}
else
{
m_value = 0; // this is to avoid a compilation warning
m_id = -1;
}
return *static_cast<Derived*>(this);
}
EIGEN_STRONG_INLINE Scalar value() const { return m_value; }
EIGEN_STRONG_INLINE Index index() const { return m_id; }
EIGEN_STRONG_INLINE Index row() const { return Lhs::IsRowMajor ? m_lhsIter.row() : index(); }
EIGEN_STRONG_INLINE Index col() const { return Lhs::IsRowMajor ? index() : m_lhsIter.col(); }
EIGEN_STRONG_INLINE operator bool() const { return m_id>=0; }
protected:
LhsIterator m_lhsIter;
RhsIterator m_rhsIter;
const BinaryOp& m_functor;
Scalar m_value;
Index m_id;
};
// sparse - sparse (product)
template<typename T, typename Lhs, typename Rhs, typename Derived>
class sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Sparse, Sparse>
{
typedef scalar_product_op<T> BinaryFunc;
typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
typedef typename CwiseBinaryXpr::Scalar Scalar;
typedef typename CwiseBinaryXpr::Index Index;
typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
typedef typename _LhsNested::InnerIterator LhsIterator;
typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
typedef typename _RhsNested::InnerIterator RhsIterator;
public:
EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
: m_lhsIter(xpr.lhs(),outer), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor())
{
while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
{
if (m_lhsIter.index() < m_rhsIter.index())
++m_lhsIter;
else
++m_rhsIter;
}
}
EIGEN_STRONG_INLINE Derived& operator++()
{
++m_lhsIter;
++m_rhsIter;
while (m_lhsIter && m_rhsIter && (m_lhsIter.index() != m_rhsIter.index()))
{
if (m_lhsIter.index() < m_rhsIter.index())
++m_lhsIter;
else
++m_rhsIter;
}
return *static_cast<Derived*>(this);
}
EIGEN_STRONG_INLINE Scalar value() const { return m_functor(m_lhsIter.value(), m_rhsIter.value()); }
EIGEN_STRONG_INLINE Index index() const { return m_lhsIter.index(); }
EIGEN_STRONG_INLINE Index row() const { return m_lhsIter.row(); }
EIGEN_STRONG_INLINE Index col() const { return m_lhsIter.col(); }
EIGEN_STRONG_INLINE operator bool() const { return (m_lhsIter && m_rhsIter); }
protected:
LhsIterator m_lhsIter;
RhsIterator m_rhsIter;
const BinaryFunc& m_functor;
};
// sparse - dense (product)
template<typename T, typename Lhs, typename Rhs, typename Derived>
class sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Sparse, Dense>
{
typedef scalar_product_op<T> BinaryFunc;
typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
typedef typename CwiseBinaryXpr::Scalar Scalar;
typedef typename CwiseBinaryXpr::Index Index;
typedef typename traits<CwiseBinaryXpr>::_LhsNested _LhsNested;
typedef typename traits<CwiseBinaryXpr>::RhsNested RhsNested;
typedef typename _LhsNested::InnerIterator LhsIterator;
enum { IsRowMajor = (int(Lhs::Flags)&RowMajorBit)==RowMajorBit };
public:
EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
: m_rhs(xpr.rhs()), m_lhsIter(xpr.lhs(),typename _LhsNested::Index(outer)), m_functor(xpr.functor()), m_outer(outer)
{}
EIGEN_STRONG_INLINE Derived& operator++()
{
++m_lhsIter;
return *static_cast<Derived*>(this);
}
EIGEN_STRONG_INLINE Scalar value() const
{ return m_functor(m_lhsIter.value(),
m_rhs.coeff(IsRowMajor?m_outer:m_lhsIter.index(),IsRowMajor?m_lhsIter.index():m_outer)); }
EIGEN_STRONG_INLINE Index index() const { return m_lhsIter.index(); }
EIGEN_STRONG_INLINE Index row() const { return m_lhsIter.row(); }
EIGEN_STRONG_INLINE Index col() const { return m_lhsIter.col(); }
EIGEN_STRONG_INLINE operator bool() const { return m_lhsIter; }
protected:
RhsNested m_rhs;
LhsIterator m_lhsIter;
const BinaryFunc m_functor;
const Index m_outer;
};
// sparse - dense (product)
template<typename T, typename Lhs, typename Rhs, typename Derived>
class sparse_cwise_binary_op_inner_iterator_selector<scalar_product_op<T>, Lhs, Rhs, Derived, Dense, Sparse>
{
typedef scalar_product_op<T> BinaryFunc;
typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr;
typedef typename CwiseBinaryXpr::Scalar Scalar;
typedef typename CwiseBinaryXpr::Index Index;
typedef typename traits<CwiseBinaryXpr>::_RhsNested _RhsNested;
typedef typename _RhsNested::InnerIterator RhsIterator;
enum { IsRowMajor = (int(Rhs::Flags)&RowMajorBit)==RowMajorBit };
public:
EIGEN_STRONG_INLINE sparse_cwise_binary_op_inner_iterator_selector(const CwiseBinaryXpr& xpr, Index outer)
: m_xpr(xpr), m_rhsIter(xpr.rhs(),outer), m_functor(xpr.functor()), m_outer(outer)
{}
EIGEN_STRONG_INLINE Derived& operator++()
{
++m_rhsIter;
return *static_cast<Derived*>(this);
}
EIGEN_STRONG_INLINE Scalar value() const
{ return m_functor(m_xpr.lhs().coeff(IsRowMajor?m_outer:m_rhsIter.index(),IsRowMajor?m_rhsIter.index():m_outer), m_rhsIter.value()); }
EIGEN_STRONG_INLINE Index index() const { return m_rhsIter.index(); }
EIGEN_STRONG_INLINE Index row() const { return m_rhsIter.row(); }
EIGEN_STRONG_INLINE Index col() const { return m_rhsIter.col(); }
EIGEN_STRONG_INLINE operator bool() const { return m_rhsIter; }
protected:
const CwiseBinaryXpr& m_xpr;
RhsIterator m_rhsIter;
const BinaryFunc& m_functor;
const Index m_outer;
};
} // end namespace internal
#else // EIGEN_TEST_EVALUATORS
namespace internal {
@@ -590,10 +340,6 @@ protected:
}
#endif
/***************************************************************************
* Implementation of SparseMatrixBase and SparseCwise functions/operators
***************************************************************************/

View File

@@ -11,136 +11,6 @@
#define EIGEN_SPARSE_CWISE_UNARY_OP_H
namespace Eigen {
#ifndef EIGEN_TEST_EVALUATORS
template<typename UnaryOp, typename MatrixType>
class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>
: public SparseMatrixBase<CwiseUnaryOp<UnaryOp, MatrixType> >
{
public:
typedef CwiseUnaryOp<UnaryOp, MatrixType> Derived;
EIGEN_SPARSE_PUBLIC_INTERFACE(Derived)
class InnerIterator;
class ReverseInnerIterator;
protected:
typedef typename internal::traits<Derived>::_XprTypeNested _MatrixTypeNested;
typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator;
typedef typename _MatrixTypeNested::ReverseInnerIterator MatrixTypeReverseIterator;
};
template<typename UnaryOp, typename MatrixType>
class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::InnerIterator
: public CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::MatrixTypeIterator
{
typedef typename CwiseUnaryOpImpl::Scalar Scalar;
typedef typename CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::MatrixTypeIterator Base;
public:
EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryOpImpl& unaryOp, typename CwiseUnaryOpImpl::Index outer)
: Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor())
{}
EIGEN_STRONG_INLINE InnerIterator& operator++()
{ Base::operator++(); return *this; }
EIGEN_STRONG_INLINE typename CwiseUnaryOpImpl::Scalar value() const { return m_functor(Base::value()); }
protected:
const UnaryOp m_functor;
private:
typename CwiseUnaryOpImpl::Scalar& valueRef();
};
template<typename UnaryOp, typename MatrixType>
class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::ReverseInnerIterator
: public CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::MatrixTypeReverseIterator
{
typedef typename CwiseUnaryOpImpl::Scalar Scalar;
typedef typename CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::MatrixTypeReverseIterator Base;
public:
EIGEN_STRONG_INLINE ReverseInnerIterator(const CwiseUnaryOpImpl& unaryOp, typename CwiseUnaryOpImpl::Index outer)
: Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor())
{}
EIGEN_STRONG_INLINE ReverseInnerIterator& operator--()
{ Base::operator--(); return *this; }
EIGEN_STRONG_INLINE typename CwiseUnaryOpImpl::Scalar value() const { return m_functor(Base::value()); }
protected:
const UnaryOp m_functor;
private:
typename CwiseUnaryOpImpl::Scalar& valueRef();
};
template<typename ViewOp, typename MatrixType>
class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>
: public SparseMatrixBase<CwiseUnaryView<ViewOp, MatrixType> >
{
public:
class InnerIterator;
class ReverseInnerIterator;
typedef CwiseUnaryView<ViewOp, MatrixType> Derived;
EIGEN_SPARSE_PUBLIC_INTERFACE(Derived)
protected:
typedef typename internal::traits<Derived>::_MatrixTypeNested _MatrixTypeNested;
typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator;
typedef typename _MatrixTypeNested::ReverseInnerIterator MatrixTypeReverseIterator;
};
template<typename ViewOp, typename MatrixType>
class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::InnerIterator
: public CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeIterator
{
typedef typename CwiseUnaryViewImpl::Scalar Scalar;
typedef typename CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeIterator Base;
public:
EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryViewImpl& unaryOp, typename CwiseUnaryViewImpl::Index outer)
: Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor())
{}
EIGEN_STRONG_INLINE InnerIterator& operator++()
{ Base::operator++(); return *this; }
EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar value() const { return m_functor(Base::value()); }
EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar& valueRef() { return m_functor(Base::valueRef()); }
protected:
const ViewOp m_functor;
};
template<typename ViewOp, typename MatrixType>
class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::ReverseInnerIterator
: public CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeReverseIterator
{
typedef typename CwiseUnaryViewImpl::Scalar Scalar;
typedef typename CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeReverseIterator Base;
public:
EIGEN_STRONG_INLINE ReverseInnerIterator(const CwiseUnaryViewImpl& unaryOp, typename CwiseUnaryViewImpl::Index outer)
: Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor())
{}
EIGEN_STRONG_INLINE ReverseInnerIterator& operator--()
{ Base::operator--(); return *this; }
EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar value() const { return m_functor(Base::value()); }
EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar& valueRef() { return m_functor(Base::valueRef()); }
protected:
const ViewOp m_functor;
};
#else // EIGEN_TEST_EVALUATORS
namespace internal {
@@ -291,8 +161,6 @@ class unary_evaluator<CwiseUnaryView<ViewOp,ArgType>, IteratorBased>::InnerItera
} // end namespace internal
#endif // EIGEN_TEST_EVALUATORS
template<typename Derived>
EIGEN_STRONG_INLINE Derived&
SparseMatrixBase<Derived>::operator*=(const Scalar& other)

View File

@@ -30,18 +30,10 @@ struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, t
typedef typename internal::remove_all<DenseRhsType>::type Rhs;
typedef typename internal::remove_all<DenseResType>::type Res;
typedef typename Lhs::Index Index;
#ifndef EIGEN_TEST_EVALUATORS
typedef typename Lhs::InnerIterator LhsInnerIterator;
#else
typedef typename evaluator<Lhs>::InnerIterator LhsInnerIterator;
#endif
static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const typename Res::Scalar& alpha)
{
#ifndef EIGEN_TEST_EVALUATORS
const Lhs &lhsEval(lhs);
#else
typename evaluator<Lhs>::type lhsEval(lhs);
#endif
typename evaluator<Lhs>::type lhsEval(lhs);
for(Index c=0; c<rhs.cols(); ++c)
{
Index n = lhs.outerSize();
@@ -71,18 +63,10 @@ struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, A
typedef typename internal::remove_all<DenseRhsType>::type Rhs;
typedef typename internal::remove_all<DenseResType>::type Res;
typedef typename Lhs::Index Index;
#ifndef EIGEN_TEST_EVALUATORS
typedef typename Lhs::InnerIterator LhsInnerIterator;
#else
typedef typename evaluator<Lhs>::InnerIterator LhsInnerIterator;
#endif
static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const AlphaType& alpha)
{
#ifndef EIGEN_TEST_EVALUATORS
const Lhs &lhsEval(lhs);
#else
typename evaluator<Lhs>::type lhsEval(lhs);
#endif
typename evaluator<Lhs>::type lhsEval(lhs);
for(Index c=0; c<rhs.cols(); ++c)
{
for(Index j=0; j<lhs.outerSize(); ++j)
@@ -103,18 +87,10 @@ struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, t
typedef typename internal::remove_all<DenseRhsType>::type Rhs;
typedef typename internal::remove_all<DenseResType>::type Res;
typedef typename Lhs::Index Index;
#ifndef EIGEN_TEST_EVALUATORS
typedef typename Lhs::InnerIterator LhsInnerIterator;
#else
typedef typename evaluator<Lhs>::InnerIterator LhsInnerIterator;
#endif
static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const typename Res::Scalar& alpha)
{
#ifndef EIGEN_TEST_EVALUATORS
const Lhs &lhsEval(lhs);
#else
typename evaluator<Lhs>::type lhsEval(lhs);
#endif
typename evaluator<Lhs>::type lhsEval(lhs);
for(Index j=0; j<lhs.outerSize(); ++j)
{
typename Res::RowXpr res_j(res.row(j));
@@ -131,18 +107,10 @@ struct sparse_time_dense_product_impl<SparseLhsType,DenseRhsType,DenseResType, t
typedef typename internal::remove_all<DenseRhsType>::type Rhs;
typedef typename internal::remove_all<DenseResType>::type Res;
typedef typename Lhs::Index Index;
#ifndef EIGEN_TEST_EVALUATORS
typedef typename Lhs::InnerIterator LhsInnerIterator;
#else
typedef typename evaluator<Lhs>::InnerIterator LhsInnerIterator;
#endif
static void run(const SparseLhsType& lhs, const DenseRhsType& rhs, DenseResType& res, const typename Res::Scalar& alpha)
{
#ifndef EIGEN_TEST_EVALUATORS
const Lhs &lhsEval(lhs);
#else
typename evaluator<Lhs>::type lhsEval(lhs);
#endif
typename evaluator<Lhs>::type lhsEval(lhs);
for(Index j=0; j<lhs.outerSize(); ++j)
{
typename Rhs::ConstRowXpr rhs_j(rhs.row(j));
@@ -160,212 +128,6 @@ inline void sparse_time_dense_product(const SparseLhsType& lhs, const DenseRhsTy
} // end namespace internal
#ifndef EIGEN_TEST_EVALUATORS
template<typename Lhs, typename Rhs, int InnerSize> struct SparseDenseProductReturnType
{
typedef SparseTimeDenseProduct<Lhs,Rhs> Type;
};
template<typename Lhs, typename Rhs> struct SparseDenseProductReturnType<Lhs,Rhs,1>
{
typedef typename internal::conditional<
Lhs::IsRowMajor,
SparseDenseOuterProduct<Rhs,Lhs,true>,
SparseDenseOuterProduct<Lhs,Rhs,false> >::type Type;
};
template<typename Lhs, typename Rhs, int InnerSize> struct DenseSparseProductReturnType
{
typedef DenseTimeSparseProduct<Lhs,Rhs> Type;
};
template<typename Lhs, typename Rhs> struct DenseSparseProductReturnType<Lhs,Rhs,1>
{
typedef typename internal::conditional<
Rhs::IsRowMajor,
SparseDenseOuterProduct<Rhs,Lhs,true>,
SparseDenseOuterProduct<Lhs,Rhs,false> >::type Type;
};
namespace internal {
template<typename Lhs, typename Rhs, bool Tr>
struct traits<SparseDenseOuterProduct<Lhs,Rhs,Tr> >
{
typedef Sparse StorageKind;
typedef typename scalar_product_traits<typename traits<Lhs>::Scalar,
typename traits<Rhs>::Scalar>::ReturnType Scalar;
typedef typename Lhs::Index Index;
typedef typename Lhs::Nested LhsNested;
typedef typename Rhs::Nested RhsNested;
typedef typename remove_all<LhsNested>::type _LhsNested;
typedef typename remove_all<RhsNested>::type _RhsNested;
enum {
LhsCoeffReadCost = traits<_LhsNested>::CoeffReadCost,
RhsCoeffReadCost = traits<_RhsNested>::CoeffReadCost,
RowsAtCompileTime = Tr ? int(traits<Rhs>::RowsAtCompileTime) : int(traits<Lhs>::RowsAtCompileTime),
ColsAtCompileTime = Tr ? int(traits<Lhs>::ColsAtCompileTime) : int(traits<Rhs>::ColsAtCompileTime),
MaxRowsAtCompileTime = Tr ? int(traits<Rhs>::MaxRowsAtCompileTime) : int(traits<Lhs>::MaxRowsAtCompileTime),
MaxColsAtCompileTime = Tr ? int(traits<Lhs>::MaxColsAtCompileTime) : int(traits<Rhs>::MaxColsAtCompileTime),
Flags = Tr ? RowMajorBit : 0,
CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + NumTraits<Scalar>::MulCost
};
};
} // end namespace internal
template<typename Lhs, typename Rhs, bool Tr>
class SparseDenseOuterProduct
: public SparseMatrixBase<SparseDenseOuterProduct<Lhs,Rhs,Tr> >
{
public:
typedef SparseMatrixBase<SparseDenseOuterProduct> Base;
EIGEN_DENSE_PUBLIC_INTERFACE(SparseDenseOuterProduct)
typedef internal::traits<SparseDenseOuterProduct> Traits;
private:
typedef typename Traits::LhsNested LhsNested;
typedef typename Traits::RhsNested RhsNested;
typedef typename Traits::_LhsNested _LhsNested;
typedef typename Traits::_RhsNested _RhsNested;
public:
class InnerIterator;
EIGEN_STRONG_INLINE SparseDenseOuterProduct(const Lhs& lhs, const Rhs& rhs)
: m_lhs(lhs), m_rhs(rhs)
{
EIGEN_STATIC_ASSERT(!Tr,YOU_MADE_A_PROGRAMMING_MISTAKE);
}
EIGEN_STRONG_INLINE SparseDenseOuterProduct(const Rhs& rhs, const Lhs& lhs)
: m_lhs(lhs), m_rhs(rhs)
{
EIGEN_STATIC_ASSERT(Tr,YOU_MADE_A_PROGRAMMING_MISTAKE);
}
EIGEN_STRONG_INLINE Index rows() const { return Tr ? Index(m_rhs.rows()) : m_lhs.rows(); }
EIGEN_STRONG_INLINE Index cols() const { return Tr ? m_lhs.cols() : Index(m_rhs.cols()); }
EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; }
EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; }
protected:
LhsNested m_lhs;
RhsNested m_rhs;
};
template<typename Lhs, typename Rhs, bool Transpose>
class SparseDenseOuterProduct<Lhs,Rhs,Transpose>::InnerIterator : public _LhsNested::InnerIterator
{
typedef typename _LhsNested::InnerIterator Base;
typedef typename SparseDenseOuterProduct::Index Index;
public:
EIGEN_STRONG_INLINE InnerIterator(const SparseDenseOuterProduct& prod, Index outer)
: Base(prod.lhs(), 0), m_outer(outer), m_empty(false), m_factor(get(prod.rhs(), outer, typename internal::traits<Rhs>::StorageKind() ))
{}
inline Index outer() const { return m_outer; }
inline Index row() const { return Transpose ? m_outer : Base::index(); }
inline Index col() const { return Transpose ? Base::index() : m_outer; }
inline Scalar value() const { return Base::value() * m_factor; }
inline operator bool() const { return Base::operator bool() && !m_empty; }
protected:
Scalar get(const _RhsNested &rhs, Index outer, Dense = Dense()) const
{
return rhs.coeff(outer);
}
Scalar get(const _RhsNested &rhs, Index outer, Sparse = Sparse())
{
typename Traits::_RhsNested::InnerIterator it(rhs, outer);
if (it && it.index()==0 && it.value()!=Scalar(0))
return it.value();
m_empty = true;
return Scalar(0);
}
Index m_outer;
bool m_empty;
Scalar m_factor;
};
namespace internal {
template<typename Lhs, typename Rhs>
struct traits<SparseTimeDenseProduct<Lhs,Rhs> >
: traits<ProductBase<SparseTimeDenseProduct<Lhs,Rhs>, Lhs, Rhs> >
{
typedef Dense StorageKind;
typedef MatrixXpr XprKind;
};
} // end namespace internal
template<typename Lhs, typename Rhs>
class SparseTimeDenseProduct
: public ProductBase<SparseTimeDenseProduct<Lhs,Rhs>, Lhs, Rhs>
{
public:
EIGEN_PRODUCT_PUBLIC_INTERFACE(SparseTimeDenseProduct)
SparseTimeDenseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
{}
template<typename Dest> void scaleAndAddTo(Dest& dest, const Scalar& alpha) const
{
internal::sparse_time_dense_product(m_lhs, m_rhs, dest, alpha);
}
private:
SparseTimeDenseProduct& operator=(const SparseTimeDenseProduct&);
};
// dense = dense * sparse
namespace internal {
template<typename Lhs, typename Rhs>
struct traits<DenseTimeSparseProduct<Lhs,Rhs> >
: traits<ProductBase<DenseTimeSparseProduct<Lhs,Rhs>, Lhs, Rhs> >
{
typedef Dense StorageKind;
};
} // end namespace internal
template<typename Lhs, typename Rhs>
class DenseTimeSparseProduct
: public ProductBase<DenseTimeSparseProduct<Lhs,Rhs>, Lhs, Rhs>
{
public:
EIGEN_PRODUCT_PUBLIC_INTERFACE(DenseTimeSparseProduct)
DenseTimeSparseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
{}
template<typename Dest> void scaleAndAddTo(Dest& dest, const Scalar& alpha) const
{
Transpose<const _LhsNested> lhs_t(m_lhs);
Transpose<const _RhsNested> rhs_t(m_rhs);
Transpose<Dest> dest_t(dest);
internal::sparse_time_dense_product(rhs_t, lhs_t, dest_t, alpha);
}
private:
DenseTimeSparseProduct& operator=(const DenseTimeSparseProduct&);
};
#endif // EIGEN_TEST_EVALUATORS
#ifdef EIGEN_TEST_EVALUATORS
namespace internal {
template<typename Lhs, typename Rhs, int ProductType>
@@ -514,8 +276,6 @@ struct product_evaluator<Product<Lhs, Rhs, DefaultProduct>, OuterProduct, DenseS
} // end namespace internal
#endif // EIGEN_TEST_EVALUATORS
} // end namespace Eigen
#endif // EIGEN_SPARSEDENSEPRODUCT_H

View File

@@ -24,171 +24,8 @@ namespace Eigen {
// for that particular case
// The two other cases are symmetric.
#ifndef EIGEN_TEST_EVALUATORS
namespace internal {
template<typename Lhs, typename Rhs>
struct traits<SparseDiagonalProduct<Lhs, Rhs> >
{
typedef typename remove_all<Lhs>::type _Lhs;
typedef typename remove_all<Rhs>::type _Rhs;
typedef typename _Lhs::Scalar Scalar;
// propagate the index type of the sparse matrix
typedef typename conditional< is_diagonal<_Lhs>::ret,
typename traits<Rhs>::Index,
typename traits<Lhs>::Index>::type Index;
typedef Sparse StorageKind;
typedef MatrixXpr XprKind;
enum {
RowsAtCompileTime = _Lhs::RowsAtCompileTime,
ColsAtCompileTime = _Rhs::ColsAtCompileTime,
MaxRowsAtCompileTime = _Lhs::MaxRowsAtCompileTime,
MaxColsAtCompileTime = _Rhs::MaxColsAtCompileTime,
SparseFlags = is_diagonal<_Lhs>::ret ? int(_Rhs::Flags) : int(_Lhs::Flags),
Flags = (SparseFlags&RowMajorBit),
CoeffReadCost = Dynamic
};
};
enum {SDP_IsDiagonal, SDP_IsSparseRowMajor, SDP_IsSparseColMajor};
template<typename Lhs, typename Rhs, typename SparseDiagonalProductType, int RhsMode, int LhsMode>
class sparse_diagonal_product_inner_iterator_selector;
} // end namespace internal
template<typename Lhs, typename Rhs>
class SparseDiagonalProduct
: public SparseMatrixBase<SparseDiagonalProduct<Lhs,Rhs> >,
internal::no_assignment_operator
{
typedef typename Lhs::Nested LhsNested;
typedef typename Rhs::Nested RhsNested;
typedef typename internal::remove_all<LhsNested>::type _LhsNested;
typedef typename internal::remove_all<RhsNested>::type _RhsNested;
enum {
LhsMode = internal::is_diagonal<_LhsNested>::ret ? internal::SDP_IsDiagonal
: (_LhsNested::Flags&RowMajorBit) ? internal::SDP_IsSparseRowMajor : internal::SDP_IsSparseColMajor,
RhsMode = internal::is_diagonal<_RhsNested>::ret ? internal::SDP_IsDiagonal
: (_RhsNested::Flags&RowMajorBit) ? internal::SDP_IsSparseRowMajor : internal::SDP_IsSparseColMajor
};
public:
EIGEN_SPARSE_PUBLIC_INTERFACE(SparseDiagonalProduct)
typedef internal::sparse_diagonal_product_inner_iterator_selector
<_LhsNested,_RhsNested,SparseDiagonalProduct,LhsMode,RhsMode> InnerIterator;
// We do not want ReverseInnerIterator for diagonal-sparse products,
// but this dummy declaration is needed to make diag * sparse * diag compile.
class ReverseInnerIterator;
EIGEN_STRONG_INLINE SparseDiagonalProduct(const Lhs& lhs, const Rhs& rhs)
: m_lhs(lhs), m_rhs(rhs)
{
eigen_assert(lhs.cols() == rhs.rows() && "invalid sparse matrix * diagonal matrix product");
}
EIGEN_STRONG_INLINE Index rows() const { return Index(m_lhs.rows()); }
EIGEN_STRONG_INLINE Index cols() const { return Index(m_rhs.cols()); }
EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; }
EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; }
protected:
LhsNested m_lhs;
RhsNested m_rhs;
};
#endif
namespace internal {
#ifndef EIGEN_TEST_EVALUATORS
template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
class sparse_diagonal_product_inner_iterator_selector
<Lhs,Rhs,SparseDiagonalProductType,SDP_IsDiagonal,SDP_IsSparseRowMajor>
: public CwiseUnaryOp<scalar_multiple_op<typename Lhs::Scalar>,const Rhs>::InnerIterator
{
typedef typename CwiseUnaryOp<scalar_multiple_op<typename Lhs::Scalar>,const Rhs>::InnerIterator Base;
typedef typename Rhs::Index Index;
public:
inline sparse_diagonal_product_inner_iterator_selector(
const SparseDiagonalProductType& expr, Index outer)
: Base(expr.rhs()*(expr.lhs().diagonal().coeff(outer)), outer)
{}
};
template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
class sparse_diagonal_product_inner_iterator_selector
<Lhs,Rhs,SparseDiagonalProductType,SDP_IsDiagonal,SDP_IsSparseColMajor>
: public CwiseBinaryOp<
scalar_product_op<typename Lhs::Scalar>,
const typename Rhs::ConstInnerVectorReturnType,
const typename Lhs::DiagonalVectorType>::InnerIterator
{
typedef typename CwiseBinaryOp<
scalar_product_op<typename Lhs::Scalar>,
const typename Rhs::ConstInnerVectorReturnType,
const typename Lhs::DiagonalVectorType>::InnerIterator Base;
typedef typename Rhs::Index Index;
Index m_outer;
public:
inline sparse_diagonal_product_inner_iterator_selector(
const SparseDiagonalProductType& expr, Index outer)
: Base(expr.rhs().innerVector(outer) .cwiseProduct(expr.lhs().diagonal()), 0), m_outer(outer)
{}
inline Index outer() const { return m_outer; }
inline Index col() const { return m_outer; }
};
template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
class sparse_diagonal_product_inner_iterator_selector
<Lhs,Rhs,SparseDiagonalProductType,SDP_IsSparseColMajor,SDP_IsDiagonal>
: public CwiseUnaryOp<scalar_multiple_op<typename Rhs::Scalar>,const Lhs>::InnerIterator
{
typedef typename CwiseUnaryOp<scalar_multiple_op<typename Rhs::Scalar>,const Lhs>::InnerIterator Base;
typedef typename Lhs::Index Index;
public:
inline sparse_diagonal_product_inner_iterator_selector(
const SparseDiagonalProductType& expr, Index outer)
: Base(expr.lhs()*expr.rhs().diagonal().coeff(outer), outer)
{}
};
template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
class sparse_diagonal_product_inner_iterator_selector
<Lhs,Rhs,SparseDiagonalProductType,SDP_IsSparseRowMajor,SDP_IsDiagonal>
: public CwiseBinaryOp<
scalar_product_op<typename Rhs::Scalar>,
const typename Lhs::ConstInnerVectorReturnType,
const Transpose<const typename Rhs::DiagonalVectorType> >::InnerIterator
{
typedef typename CwiseBinaryOp<
scalar_product_op<typename Rhs::Scalar>,
const typename Lhs::ConstInnerVectorReturnType,
const Transpose<const typename Rhs::DiagonalVectorType> >::InnerIterator Base;
typedef typename Lhs::Index Index;
Index m_outer;
public:
inline sparse_diagonal_product_inner_iterator_selector(
const SparseDiagonalProductType& expr, Index outer)
: Base(expr.lhs().innerVector(outer) .cwiseProduct(expr.rhs().diagonal().transpose()), 0), m_outer(outer)
{}
inline Index outer() const { return m_outer; }
inline Index row() const { return m_outer; }
};
#else // EIGEN_TEST_EVALUATORS
enum {
SDP_AsScalarProduct,
SDP_AsCwiseProduct
@@ -303,23 +140,8 @@ protected:
: SparseXprType::ColsAtCompileTime>::type m_diagCoeffNested;
};
#endif // EIGEN_TEST_EVALUATORS
} // end namespace internal
#ifndef EIGEN_TEST_EVALUATORS
// SparseMatrixBase functions
template<typename Derived>
template<typename OtherDerived>
const SparseDiagonalProduct<Derived,OtherDerived>
SparseMatrixBase<Derived>::operator*(const DiagonalBase<OtherDerived> &other) const
{
return SparseDiagonalProduct<Derived,OtherDerived>(this->derived(), other.derived());
}
#endif // EIGEN_TEST_EVALUATORS
} // end namespace Eigen
#endif // EIGEN_SPARSE_DIAGONAL_PRODUCT_H

View File

@@ -26,12 +26,8 @@ SparseMatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
eigen_assert(size() == other.size());
eigen_assert(other.size()>0 && "you are using a non initialized vector");
#ifndef EIGEN_TEST_EVALUATORS
typename Derived::InnerIterator i(derived(),0);
#else
typename internal::evaluator<Derived>::type thisEval(derived());
typename internal::evaluator<Derived>::InnerIterator i(thisEval, 0);
#endif
Scalar res(0);
while (i)
{
@@ -54,24 +50,12 @@ SparseMatrixBase<Derived>::dot(const SparseMatrixBase<OtherDerived>& other) cons
eigen_assert(size() == other.size());
#ifndef EIGEN_TEST_EVALUATORS
typedef typename Derived::Nested Nested;
typedef typename OtherDerived::Nested OtherNested;
typedef typename internal::remove_all<Nested>::type NestedCleaned;
typedef typename internal::remove_all<OtherNested>::type OtherNestedCleaned;
Nested nthis(derived());
OtherNested nother(other.derived());
typename NestedCleaned::InnerIterator i(nthis,0);
typename OtherNestedCleaned::InnerIterator j(nother,0);
#else
typename internal::evaluator<Derived>::type thisEval(derived());
typename internal::evaluator<Derived>::InnerIterator i(thisEval, 0);
typename internal::evaluator<OtherDerived>::type otherEval(other.derived());
typename internal::evaluator<OtherDerived>::InnerIterator j(otherEval, 0);
#endif
Scalar res(0);
while (i && j)
{

View File

@@ -52,9 +52,6 @@ struct traits<SparseMatrix<_Scalar, _Options, _Index> >
MaxRowsAtCompileTime = Dynamic,
MaxColsAtCompileTime = Dynamic,
Flags = _Options | NestByRefBit | LvalueBit,
#ifndef EIGEN_TEST_EVALUATORS
CoeffReadCost = NumTraits<Scalar>::ReadCost,
#endif
SupportedAccessPatterns = InnerRandomAccessPattern
};
};
@@ -77,9 +74,6 @@ struct traits<Diagonal<const SparseMatrix<_Scalar, _Options, _Index>, DiagIndex>
MaxRowsAtCompileTime = Dynamic,
MaxColsAtCompileTime = 1,
Flags = 0
#ifndef EIGEN_TEST_EVALUATORS
, CoeffReadCost = _MatrixTypeNested::CoeffReadCost*10
#endif
};
};
@@ -653,13 +647,9 @@ class SparseMatrix
EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
check_template_parameters();
#ifndef EIGEN_TEST_EVALUATORS
*this = other.derived();
#else
const bool needToTranspose = (Flags & RowMajorBit) != (internal::evaluator<OtherDerived>::Flags & RowMajorBit);
if (needToTranspose) *this = other.derived();
else internal::call_assignment_no_alias(*this, other.derived());
#endif
}
/** Constructs a sparse matrix from the sparse selfadjoint view \a other */
@@ -668,11 +658,7 @@ class SparseMatrix
: m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0)
{
check_template_parameters();
#ifndef EIGEN_TEST_EVALUATORS
*this = other;
#else
Base::operator=(other);
#endif
}
/** Copy constructor (it performs a deep copy) */
@@ -737,19 +723,6 @@ class SparseMatrix
}
#ifndef EIGEN_PARSED_BY_DOXYGEN
#ifndef EIGEN_TEST_EVALUATORS
template<typename Lhs, typename Rhs>
inline SparseMatrix& operator=(const SparseSparseProduct<Lhs,Rhs>& product)
{ return Base::operator=(product); }
template<typename OtherDerived>
inline SparseMatrix& operator=(const ReturnByValue<OtherDerived>& other)
{
initAssignment(other);
return Base::operator=(other.derived());
}
#endif // EIGEN_TEST_EVALUATORS
template<typename OtherDerived>
inline SparseMatrix& operator=(const EigenBase<OtherDerived>& other)
{ return Base::operator=(other.derived()); }
@@ -1071,69 +1044,6 @@ void SparseMatrix<Scalar,_Options,_Index>::sumupDuplicates()
m_data.resize(m_outerIndex[m_outerSize]);
}
#ifndef EIGEN_TEST_EVALUATORS
template<typename Scalar, int _Options, typename _Index>
template<typename OtherDerived>
EIGEN_DONT_INLINE SparseMatrix<Scalar,_Options,_Index>& SparseMatrix<Scalar,_Options,_Index>::operator=(const SparseMatrixBase<OtherDerived>& other)
{
EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
if (needToTranspose)
{
// two passes algorithm:
// 1 - compute the number of coeffs per dest inner vector
// 2 - do the actual copy/eval
// Since each coeff of the rhs has to be evaluated twice, let's evaluate it if needed
typedef typename internal::nested<OtherDerived,2>::type OtherCopy;
typedef typename internal::remove_all<OtherCopy>::type _OtherCopy;
OtherCopy otherCopy(other.derived());
SparseMatrix dest(other.rows(),other.cols());
Eigen::Map<Matrix<Index, Dynamic, 1> > (dest.m_outerIndex,dest.outerSize()).setZero();
// pass 1
// FIXME the above copy could be merged with that pass
for (Index j=0; j<otherCopy.outerSize(); ++j)
for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it)
++dest.m_outerIndex[it.index()];
// prefix sum
Index count = 0;
Matrix<Index,Dynamic,1> positions(dest.outerSize());
for (Index j=0; j<dest.outerSize(); ++j)
{
Index tmp = dest.m_outerIndex[j];
dest.m_outerIndex[j] = count;
positions[j] = count;
count += tmp;
}
dest.m_outerIndex[dest.outerSize()] = count;
// alloc
dest.m_data.resize(count);
// pass 2
for (Index j=0; j<otherCopy.outerSize(); ++j)
{
for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it)
{
Index pos = positions[it.index()]++;
dest.m_data.index(pos) = j;
dest.m_data.value(pos) = it.value();
}
}
this->swap(dest);
return *this;
}
else
{
if(other.isRValue())
initAssignment(other.derived());
// there is no special optimization
return Base::operator=(other.derived());
}
}
#else
template<typename Scalar, int _Options, typename _Index>
template<typename OtherDerived>
EIGEN_DONT_INLINE SparseMatrix<Scalar,_Options,_Index>& SparseMatrix<Scalar,_Options,_Index>::operator=(const SparseMatrixBase<OtherDerived>& other)
@@ -1199,7 +1109,6 @@ EIGEN_DONT_INLINE SparseMatrix<Scalar,_Options,_Index>& SparseMatrix<Scalar,_Opt
return Base::operator=(other.derived());
}
}
#endif
template<typename _Scalar, int _Options, typename _Index>
EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& SparseMatrix<_Scalar,_Options,_Index>::insertUncompressed(Index row, Index col)
@@ -1340,7 +1249,6 @@ EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& Sparse
return (m_data.value(p) = 0);
}
#ifdef EIGEN_ENABLE_EVALUATORS
namespace internal {
template<typename _Scalar, int _Options, typename _Index>
@@ -1370,7 +1278,6 @@ struct evaluator<SparseMatrix<_Scalar,_Options,_Index> >
};
}
#endif
} // end namespace Eigen

View File

@@ -79,13 +79,6 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
* constructed from this one. See the \ref flags "list of flags".
*/
#ifndef EIGEN_TEST_EVALUATORS
CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
/**< This is a rough measure of how expensive it is to read one coefficient from
* this expression.
*/
#endif
IsRowMajor = Flags&RowMajorBit ? 1 : 0,
InnerSizeAtCompileTime = int(IsVectorAtCompileTime) ? int(SizeAtCompileTime)
@@ -189,11 +182,6 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
public:
#ifndef EIGEN_TEST_EVALUATORS
template<typename Lhs, typename Rhs>
inline Derived& operator=(const SparseSparseProduct<Lhs,Rhs>& product);
#endif
friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m)
{
typedef typename Derived::Nested Nested;
@@ -265,36 +253,6 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE
cwiseProduct(const MatrixBase<OtherDerived> &other) const;
#ifndef EIGEN_TEST_EVALUATORS
// sparse * sparse
template<typename OtherDerived>
const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type
operator*(const SparseMatrixBase<OtherDerived> &other) const;
// sparse * diagonal
template<typename OtherDerived>
const SparseDiagonalProduct<Derived,OtherDerived>
operator*(const DiagonalBase<OtherDerived> &other) const;
// diagonal * sparse
template<typename OtherDerived> friend
const SparseDiagonalProduct<OtherDerived,Derived>
operator*(const DiagonalBase<OtherDerived> &lhs, const SparseMatrixBase& rhs)
{ return SparseDiagonalProduct<OtherDerived,Derived>(lhs.derived(), rhs.derived()); }
/** dense * sparse (return a dense object unless it is an outer product) */
template<typename OtherDerived> friend
const typename DenseSparseProductReturnType<OtherDerived,Derived>::Type
operator*(const MatrixBase<OtherDerived>& lhs, const Derived& rhs)
{ return typename DenseSparseProductReturnType<OtherDerived,Derived>::Type(lhs.derived(),rhs); }
/** sparse * dense (returns a dense object unless it is an outer product) */
template<typename OtherDerived>
const typename SparseDenseProductReturnType<Derived,OtherDerived>::Type
operator*(const MatrixBase<OtherDerived> &other) const
{ return typename SparseDenseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); }
#else // EIGEN_TEST_EVALUATORS
// sparse * diagonal
template<typename OtherDerived>
const Product<Derived,OtherDerived>
@@ -323,7 +281,6 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
const Product<OtherDerived,Derived>
operator*(const MatrixBase<OtherDerived> &lhs, const SparseMatrixBase& rhs)
{ return Product<OtherDerived,Derived>(lhs.derived(), rhs.derived()); }
#endif // EIGEN_TEST_EVALUATORS
/** \returns an expression of P H P^-1 where H is the matrix represented by \c *this */
SparseSymmetricPermutationProduct<Derived,Upper|Lower> twistedBy(const PermutationMatrix<Dynamic,Dynamic,Index>& perm) const
@@ -360,18 +317,6 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived>
Block<Derived,Dynamic,Dynamic,true> innerVectors(Index outerStart, Index outerSize);
const Block<const Derived,Dynamic,Dynamic,true> innerVectors(Index outerStart, Index outerSize) const;
#ifndef EIGEN_TEST_EVALUATORS
/** \internal use operator= */
template<typename DenseDerived>
void evalTo(MatrixBase<DenseDerived>& dst) const
{
dst.setZero();
for (Index j=0; j<outerSize(); ++j)
for (typename Derived::InnerIterator i(derived(),typename Derived::Index(j)); i; ++i)
dst.coeffRef(i.row(),i.col()) = i.value();
}
#endif
Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> toDense() const
{
return derived();

View File

@@ -103,48 +103,6 @@ struct permut_sparsematrix_product_retval
}
#ifndef EIGEN_TEST_EVALUATORS
/** \returns the matrix with the permutation applied to the columns
*/
template<typename SparseDerived, typename PermDerived>
inline const internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheRight, false>
operator*(const SparseMatrixBase<SparseDerived>& matrix, const PermutationBase<PermDerived>& perm)
{
return internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheRight, false>(perm, matrix.derived());
}
/** \returns the matrix with the permutation applied to the rows
*/
template<typename SparseDerived, typename PermDerived>
inline const internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheLeft, false>
operator*( const PermutationBase<PermDerived>& perm, const SparseMatrixBase<SparseDerived>& matrix)
{
return internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheLeft, false>(perm, matrix.derived());
}
/** \returns the matrix with the inverse permutation applied to the columns.
*/
template<typename SparseDerived, typename PermDerived>
inline const internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheRight, true>
operator*(const SparseMatrixBase<SparseDerived>& matrix, const Transpose<PermutationBase<PermDerived> >& tperm)
{
return internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheRight, true>(tperm.nestedPermutation(), matrix.derived());
}
/** \returns the matrix with the inverse permutation applied to the rows.
*/
template<typename SparseDerived, typename PermDerived>
inline const internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheLeft, true>
operator*(const Transpose<PermutationBase<PermDerived> >& tperm, const SparseMatrixBase<SparseDerived>& matrix)
{
return internal::permut_sparsematrix_product_retval<PermutationBase<PermDerived>, SparseDerived, OnTheLeft, true>(tperm.nestedPermutation(), matrix.derived());
}
#else // EIGEN_TEST_EVALUATORS
namespace internal {
template <int ProductTag> struct product_promote_storage_type<Sparse, PermutationStorage, ProductTag> { typedef Sparse ret; };
@@ -274,8 +232,6 @@ operator*(const Transpose<PermutationBase<PermDerived> >& tperm, const SparseMat
return Product<Transpose<PermutationBase<PermDerived> >, SparseDerived>(tperm, matrix.derived());
}
#endif // EIGEN_TEST_EVALUATORS
} // end namespace Eigen
#endif // EIGEN_SPARSE_SELFADJOINTVIEW_H

View File

@@ -12,182 +12,6 @@
namespace Eigen {
#ifndef EIGEN_TEST_EVALUATORS
template<typename Lhs, typename Rhs>
struct SparseSparseProductReturnType
{
typedef typename internal::traits<Lhs>::Scalar Scalar;
typedef typename internal::traits<Lhs>::Index Index;
enum {
LhsRowMajor = internal::traits<Lhs>::Flags & RowMajorBit,
RhsRowMajor = internal::traits<Rhs>::Flags & RowMajorBit,
TransposeRhs = (!LhsRowMajor) && RhsRowMajor,
TransposeLhs = LhsRowMajor && (!RhsRowMajor)
};
typedef typename internal::conditional<TransposeLhs,
SparseMatrix<Scalar,0,Index>,
typename internal::nested<Lhs,Rhs::RowsAtCompileTime>::type>::type LhsNested;
typedef typename internal::conditional<TransposeRhs,
SparseMatrix<Scalar,0,Index>,
typename internal::nested<Rhs,Lhs::RowsAtCompileTime>::type>::type RhsNested;
typedef SparseSparseProduct<LhsNested, RhsNested> Type;
};
namespace internal {
template<typename LhsNested, typename RhsNested>
struct traits<SparseSparseProduct<LhsNested, RhsNested> >
{
typedef MatrixXpr XprKind;
// clean the nested types:
typedef typename remove_all<LhsNested>::type _LhsNested;
typedef typename remove_all<RhsNested>::type _RhsNested;
typedef typename _LhsNested::Scalar Scalar;
typedef typename promote_index_type<typename traits<_LhsNested>::Index,
typename traits<_RhsNested>::Index>::type Index;
enum {
LhsCoeffReadCost = _LhsNested::CoeffReadCost,
RhsCoeffReadCost = _RhsNested::CoeffReadCost,
LhsFlags = _LhsNested::Flags,
RhsFlags = _RhsNested::Flags,
RowsAtCompileTime = _LhsNested::RowsAtCompileTime,
ColsAtCompileTime = _RhsNested::ColsAtCompileTime,
MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime,
MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime,
InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime),
EvalToRowMajor = (RhsFlags & LhsFlags & RowMajorBit),
RemovedBits = ~(EvalToRowMajor ? 0 : RowMajorBit),
Flags = (int(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits)
| EvalBeforeAssigningBit
| EvalBeforeNestingBit,
CoeffReadCost = Dynamic
};
typedef Sparse StorageKind;
};
} // end namespace internal
template<typename LhsNested, typename RhsNested>
class SparseSparseProduct : internal::no_assignment_operator,
public SparseMatrixBase<SparseSparseProduct<LhsNested, RhsNested> >
{
public:
typedef SparseMatrixBase<SparseSparseProduct> Base;
EIGEN_DENSE_PUBLIC_INTERFACE(SparseSparseProduct)
private:
typedef typename internal::traits<SparseSparseProduct>::_LhsNested _LhsNested;
typedef typename internal::traits<SparseSparseProduct>::_RhsNested _RhsNested;
public:
template<typename Lhs, typename Rhs>
EIGEN_STRONG_INLINE SparseSparseProduct(const Lhs& lhs, const Rhs& rhs)
: m_lhs(lhs), m_rhs(rhs), m_tolerance(0), m_conservative(true)
{
init();
}
template<typename Lhs, typename Rhs>
EIGEN_STRONG_INLINE SparseSparseProduct(const Lhs& lhs, const Rhs& rhs, const RealScalar& tolerance)
: m_lhs(lhs), m_rhs(rhs), m_tolerance(tolerance), m_conservative(false)
{
init();
}
SparseSparseProduct pruned(const Scalar& reference = 0, const RealScalar& epsilon = NumTraits<RealScalar>::dummy_precision()) const
{
using std::abs;
return SparseSparseProduct(m_lhs,m_rhs,abs(reference)*epsilon);
}
template<typename Dest>
void evalTo(Dest& result) const
{
if(m_conservative)
internal::conservative_sparse_sparse_product_selector<_LhsNested, _RhsNested, Dest>::run(lhs(),rhs(),result);
else
internal::sparse_sparse_product_with_pruning_selector<_LhsNested, _RhsNested, Dest>::run(lhs(),rhs(),result,m_tolerance);
}
EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); }
EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); }
EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; }
EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; }
protected:
void init()
{
eigen_assert(m_lhs.cols() == m_rhs.rows());
enum {
ProductIsValid = _LhsNested::ColsAtCompileTime==Dynamic
|| _RhsNested::RowsAtCompileTime==Dynamic
|| int(_LhsNested::ColsAtCompileTime)==int(_RhsNested::RowsAtCompileTime),
AreVectors = _LhsNested::IsVectorAtCompileTime && _RhsNested::IsVectorAtCompileTime,
SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(_LhsNested,_RhsNested)
};
// note to the lost user:
// * for a dot product use: v1.dot(v2)
// * for a coeff-wise product use: v1.cwise()*v2
EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
}
LhsNested m_lhs;
RhsNested m_rhs;
RealScalar m_tolerance;
bool m_conservative;
};
// sparse = sparse * sparse
template<typename Derived>
template<typename Lhs, typename Rhs>
inline Derived& SparseMatrixBase<Derived>::operator=(const SparseSparseProduct<Lhs,Rhs>& product)
{
product.evalTo(derived());
return derived();
}
/** \returns an expression of the product of two sparse matrices.
* By default a conservative product preserving the symbolic non zeros is performed.
* The automatic pruning of the small values can be achieved by calling the pruned() function
* in which case a totally different product algorithm is employed:
* \code
* C = (A*B).pruned(); // supress numerical zeros (exact)
* C = (A*B).pruned(ref);
* C = (A*B).pruned(ref,epsilon);
* \endcode
* where \c ref is a meaningful non zero reference value.
* */
template<typename Derived>
template<typename OtherDerived>
inline const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type
SparseMatrixBase<Derived>::operator*(const SparseMatrixBase<OtherDerived> &other) const
{
return typename SparseSparseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
}
#else // EIGEN_TEST_EVALUATORS
/** \returns an expression of the product of two sparse matrices.
* By default a conservative product preserving the symbolic non zeros is performed.
* The automatic pruning of the small values can be achieved by calling the pruned() function
@@ -256,8 +80,6 @@ protected:
} // end namespace internal
#endif // EIGEN_TEST_EVALUATORS
} // end namespace Eigen
#endif // EIGEN_SPARSEPRODUCT_H

View File

@@ -18,14 +18,9 @@ SparseMatrixBase<Derived>::sum() const
{
eigen_assert(rows()>0 && cols()>0 && "you are using a non initialized matrix");
Scalar res(0);
#ifndef EIGEN_TEST_EVALUATORS
for (Index j=0; j<outerSize(); ++j)
for (typename Derived::InnerIterator iter(derived(),j); iter; ++iter)
#else
typename internal::evaluator<Derived>::type thisEval(derived());
for (Index j=0; j<outerSize(); ++j)
for (typename internal::evaluator<Derived>::InnerIterator iter(thisEval,j); iter; ++iter)
#endif
res += iter.value();
return res;
}

View File

@@ -11,16 +11,6 @@
#define EIGEN_SPARSE_SELFADJOINTVIEW_H
namespace Eigen {
#ifndef EIGEN_TEST_EVALUATORS
template<typename Lhs, typename Rhs, int Mode>
class SparseSelfAdjointTimeDenseProduct;
template<typename Lhs, typename Rhs, int Mode>
class DenseTimeSparseSelfAdjointProduct;
#endif // EIGEN_TEST_EVALUATORS
/** \ingroup SparseCore_Module
* \class SparseSelfAdjointView
@@ -80,76 +70,40 @@ template<typename MatrixType, unsigned int _Mode> class SparseSelfAdjointView
* Note that there is no algorithmic advantage of performing such a product compared to a general sparse-sparse matrix product.
* Indeed, the SparseSelfadjointView operand is first copied into a temporary SparseMatrix before computing the product.
*/
#ifndef EIGEN_TEST_EVALUATORS
template<typename OtherDerived>
SparseSparseProduct<typename OtherDerived::PlainObject, OtherDerived>
operator*(const SparseMatrixBase<OtherDerived>& rhs) const
{
return SparseSparseProduct<typename OtherDerived::PlainObject, OtherDerived>(*this, rhs.derived());
}
#else
template<typename OtherDerived>
Product<SparseSelfAdjointView, OtherDerived>
operator*(const SparseMatrixBase<OtherDerived>& rhs) const
{
return Product<SparseSelfAdjointView, OtherDerived>(*this, rhs.derived());
}
#endif
/** \returns an expression of the matrix product between a sparse matrix \a lhs and a sparse self-adjoint matrix \a rhs.
*
* Note that there is no algorithmic advantage of performing such a product compared to a general sparse-sparse matrix product.
* Indeed, the SparseSelfadjointView operand is first copied into a temporary SparseMatrix before computing the product.
*/
#ifndef EIGEN_TEST_EVALUATORS
template<typename OtherDerived> friend
SparseSparseProduct<OtherDerived, typename OtherDerived::PlainObject >
operator*(const SparseMatrixBase<OtherDerived>& lhs, const SparseSelfAdjointView& rhs)
{
return SparseSparseProduct<OtherDerived, typename OtherDerived::PlainObject>(lhs.derived(), rhs);
}
#else // EIGEN_TEST_EVALUATORS
template<typename OtherDerived> friend
Product<OtherDerived, SparseSelfAdjointView>
operator*(const SparseMatrixBase<OtherDerived>& lhs, const SparseSelfAdjointView& rhs)
{
return Product<OtherDerived, SparseSelfAdjointView>(lhs.derived(), rhs);
}
#endif // EIGEN_TEST_EVALUATORS
/** Efficient sparse self-adjoint matrix times dense vector/matrix product */
#ifndef EIGEN_TEST_EVALUATORS
template<typename OtherDerived>
SparseSelfAdjointTimeDenseProduct<MatrixType,OtherDerived,Mode>
operator*(const MatrixBase<OtherDerived>& rhs) const
{
return SparseSelfAdjointTimeDenseProduct<MatrixType,OtherDerived,Mode>(m_matrix, rhs.derived());
}
#else
template<typename OtherDerived>
Product<SparseSelfAdjointView,OtherDerived>
operator*(const MatrixBase<OtherDerived>& rhs) const
{
return Product<SparseSelfAdjointView,OtherDerived>(*this, rhs.derived());
}
#endif
/** Efficient dense vector/matrix times sparse self-adjoint matrix product */
#ifndef EIGEN_TEST_EVALUATORS
template<typename OtherDerived> friend
DenseTimeSparseSelfAdjointProduct<OtherDerived,MatrixType,Mode>
operator*(const MatrixBase<OtherDerived>& lhs, const SparseSelfAdjointView& rhs)
{
return DenseTimeSparseSelfAdjointProduct<OtherDerived,_MatrixTypeNested,Mode>(lhs.derived(), rhs.m_matrix);
}
#else
template<typename OtherDerived> friend
Product<OtherDerived,SparseSelfAdjointView>
operator*(const MatrixBase<OtherDerived>& lhs, const SparseSelfAdjointView& rhs)
{
return Product<OtherDerived,SparseSelfAdjointView>(lhs.derived(), rhs);
}
#endif
/** Perform a symmetric rank K update of the selfadjoint matrix \c *this:
* \f$ this = this + \alpha ( u u^* ) \f$ where \a u is a vector or matrix.
@@ -177,7 +131,7 @@ template<typename MatrixType, unsigned int _Mode> class SparseSelfAdjointView
}
/** \returns an expression of P H P^-1 */
// #ifndef EIGEN_TEST_EVALUATORS
// TODO implement twists in a more evaluator friendly fashion
SparseSymmetricPermutationProduct<_MatrixTypeNested,Mode> twistedBy(const PermutationMatrix<Dynamic,Dynamic,Index>& perm) const
{
return SparseSymmetricPermutationProduct<_MatrixTypeNested,Mode>(m_matrix, perm);
@@ -189,7 +143,6 @@ template<typename MatrixType, unsigned int _Mode> class SparseSelfAdjointView
permutedMatrix.evalTo(*this);
return *this;
}
// #endif // EIGEN_TEST_EVALUATORS
SparseSelfAdjointView& operator=(const SparseSelfAdjointView& src)
{
@@ -251,98 +204,6 @@ SparseSelfAdjointView<MatrixType,Mode>::rankUpdate(const SparseMatrixBase<Derive
* Implementation of sparse self-adjoint time dense matrix
***************************************************************************/
#ifndef EIGEN_TEST_EVALUATORS
namespace internal {
template<typename Lhs, typename Rhs, int Mode>
struct traits<SparseSelfAdjointTimeDenseProduct<Lhs,Rhs,Mode> >
: traits<ProductBase<SparseSelfAdjointTimeDenseProduct<Lhs,Rhs,Mode>, Lhs, Rhs> >
{
typedef Dense StorageKind;
};
}
template<typename Lhs, typename Rhs, int Mode>
class SparseSelfAdjointTimeDenseProduct
: public ProductBase<SparseSelfAdjointTimeDenseProduct<Lhs,Rhs,Mode>, Lhs, Rhs>
{
public:
EIGEN_PRODUCT_PUBLIC_INTERFACE(SparseSelfAdjointTimeDenseProduct)
SparseSelfAdjointTimeDenseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
{}
template<typename Dest> void scaleAndAddTo(Dest& dest, const Scalar& alpha) const
{
EIGEN_ONLY_USED_FOR_DEBUG(alpha);
// TODO use alpha
eigen_assert(alpha==Scalar(1) && "alpha != 1 is not implemented yet, sorry");
typedef typename internal::remove_all<Lhs>::type _Lhs;
typedef typename _Lhs::InnerIterator LhsInnerIterator;
enum {
LhsIsRowMajor = (_Lhs::Flags&RowMajorBit)==RowMajorBit,
ProcessFirstHalf =
((Mode&(Upper|Lower))==(Upper|Lower))
|| ( (Mode&Upper) && !LhsIsRowMajor)
|| ( (Mode&Lower) && LhsIsRowMajor),
ProcessSecondHalf = !ProcessFirstHalf
};
for (typename _Lhs::Index j=0; j<m_lhs.outerSize(); ++j)
{
LhsInnerIterator i(m_lhs,j);
if (ProcessSecondHalf)
{
while (i && i.index()<j) ++i;
if(i && i.index()==j)
{
dest.row(j) += i.value() * m_rhs.row(j);
++i;
}
}
for(; (ProcessFirstHalf ? i && i.index() < j : i) ; ++i)
{
Index a = LhsIsRowMajor ? j : i.index();
Index b = LhsIsRowMajor ? i.index() : j;
typename Lhs::Scalar v = i.value();
dest.row(a) += (v) * m_rhs.row(b);
dest.row(b) += numext::conj(v) * m_rhs.row(a);
}
if (ProcessFirstHalf && i && (i.index()==j))
dest.row(j) += i.value() * m_rhs.row(j);
}
}
private:
SparseSelfAdjointTimeDenseProduct& operator=(const SparseSelfAdjointTimeDenseProduct&);
};
namespace internal {
template<typename Lhs, typename Rhs, int Mode>
struct traits<DenseTimeSparseSelfAdjointProduct<Lhs,Rhs,Mode> >
: traits<ProductBase<DenseTimeSparseSelfAdjointProduct<Lhs,Rhs,Mode>, Lhs, Rhs> >
{};
}
template<typename Lhs, typename Rhs, int Mode>
class DenseTimeSparseSelfAdjointProduct
: public ProductBase<DenseTimeSparseSelfAdjointProduct<Lhs,Rhs,Mode>, Lhs, Rhs>
{
public:
EIGEN_PRODUCT_PUBLIC_INTERFACE(DenseTimeSparseSelfAdjointProduct)
DenseTimeSparseSelfAdjointProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs)
{}
template<typename Dest> void scaleAndAddTo(Dest& /*dest*/, const Scalar& /*alpha*/) const
{
// TODO
}
private:
DenseTimeSparseSelfAdjointProduct& operator=(const DenseTimeSparseSelfAdjointProduct&);
};
#else // EIGEN_TEST_EVALUATORS
namespace internal {
template<int Mode, typename SparseLhsType, typename DenseRhsType, typename DenseResType, typename AlphaType>
@@ -486,8 +347,6 @@ protected:
} // namespace internal
#endif // EIGEN_TEST_EVALUATORS
/***************************************************************************
* Implementation of symmetric copies and permutations
***************************************************************************/
@@ -644,7 +503,7 @@ void permute_symm_to_symm(const MatrixType& mat, SparseMatrix<typename MatrixTyp
}
// #ifndef EIGEN_TEST_EVALUATORS
// TODO implement twists in a more evaluator friendly fashion
namespace internal {
@@ -695,10 +554,6 @@ class SparseSymmetricPermutationProduct
};
// #else // EIGEN_TEST_EVALUATORS
// #endif // EIGEN_TEST_EVALUATORS
} // end namespace Eigen
#endif // EIGEN_SPARSE_SELFADJOINTVIEW_H

View File

@@ -65,7 +65,6 @@ class SparseSolverBase : internal::noncopyable
Derived& derived() { return *static_cast<Derived*>(this); }
const Derived& derived() const { return *static_cast<const Derived*>(this); }
#ifdef EIGEN_TEST_EVALUATORS
/** \returns an expression of the solution x of \f$ A x = b \f$ using the current decomposition of A.
*
* \sa compute()
@@ -91,17 +90,15 @@ class SparseSolverBase : internal::noncopyable
eigen_assert(derived().rows()==b.rows() && "solve(): invalid number of rows of the right hand side matrix b");
return Solve<Derived, Rhs>(derived(), b.derived());
}
#endif
#ifndef EIGEN_PARSED_BY_DOXYGEN
#ifndef EIGEN_PARSED_BY_DOXYGEN
/** \internal default implementation of solving with a sparse rhs */
template<typename Rhs,typename Dest>
void _solve_impl(const SparseMatrixBase<Rhs> &b, SparseMatrixBase<Dest> &dest) const
{
internal::solve_sparse_through_dense_panels(derived(), b.derived(), dest.derived());
}
#endif // EIGEN_PARSED_BY_DOXYGEN
#endif // EIGEN_PARSED_BY_DOXYGEN
protected:

View File

@@ -47,10 +47,8 @@ static void sparse_sparse_product_with_pruning_impl(const Lhs& lhs, const Rhs& r
else
res.resize(rows, cols);
#ifdef EIGEN_TEST_EVALUATORS
typename evaluator<Lhs>::type lhsEval(lhs);
typename evaluator<Rhs>::type rhsEval(rhs);
#endif
res.reserve(estimated_nnz_prod);
double ratioColRes = double(estimated_nnz_prod)/double(lhs.rows()*rhs.cols());
@@ -61,20 +59,12 @@ static void sparse_sparse_product_with_pruning_impl(const Lhs& lhs, const Rhs& r
// let's do a more accurate determination of the nnz ratio for the current column j of res
tempVector.init(ratioColRes);
tempVector.setZero();
#ifndef EIGEN_TEST_EVALUATORS
for (typename Rhs::InnerIterator rhsIt(rhs, j); rhsIt; ++rhsIt)
#else
for (typename evaluator<Rhs>::InnerIterator rhsIt(rhsEval, j); rhsIt; ++rhsIt)
#endif
{
// FIXME should be written like this: tmp += rhsIt.value() * lhs.col(rhsIt.index())
tempVector.restart();
Scalar x = rhsIt.value();
#ifndef EIGEN_TEST_EVALUATORS
for (typename Lhs::InnerIterator lhsIt(lhs, rhsIt.index()); lhsIt; ++lhsIt)
#else
for (typename evaluator<Lhs>::InnerIterator lhsIt(lhsEval, rhsIt.index()); lhsIt; ++lhsIt)
#endif
{
tempVector.coeffRef(lhsIt.index()) += lhsIt.value() * x;
}
@@ -153,10 +143,6 @@ struct sparse_sparse_product_with_pruning_selector<Lhs,Rhs,ResultType,RowMajor,R
}
};
#ifndef EIGEN_TEST_EVALUATORS
// NOTE the 2 others cases (col row *) must never occur since they are caught
// by ProductReturnType which transforms it to (col col *) by evaluating rhs.
#else
template<typename Lhs, typename Rhs, typename ResultType>
struct sparse_sparse_product_with_pruning_selector<Lhs,Rhs,ResultType,ColMajor,RowMajor,RowMajor>
{
@@ -204,7 +190,6 @@ struct sparse_sparse_product_with_pruning_selector<Lhs,Rhs,ResultType,RowMajor,C
internal::sparse_sparse_product_with_pruning_impl<ColMajorMatrixLhs,Rhs,ResultType>(colLhs, rhs, res, tolerance);
}
};
#endif
} // end namespace internal

View File

@@ -12,55 +12,6 @@
namespace Eigen {
#ifndef EIGEN_TEST_EVALUATORS
template<typename MatrixType> class TransposeImpl<MatrixType,Sparse>
: public SparseMatrixBase<Transpose<MatrixType> >
{
typedef typename internal::remove_all<typename MatrixType::Nested>::type _MatrixTypeNested;
public:
EIGEN_SPARSE_PUBLIC_INTERFACE(Transpose<MatrixType> )
class InnerIterator;
class ReverseInnerIterator;
inline Index nonZeros() const { return derived().nestedExpression().nonZeros(); }
};
// NOTE: VC10 trigger an ICE if don't put typename TransposeImpl<MatrixType,Sparse>:: in front of Index,
// a typedef typename TransposeImpl<MatrixType,Sparse>::Index Index;
// does not fix the issue.
// An alternative is to define the nested class in the parent class itself.
template<typename MatrixType> class TransposeImpl<MatrixType,Sparse>::InnerIterator
: public _MatrixTypeNested::InnerIterator
{
typedef typename _MatrixTypeNested::InnerIterator Base;
typedef typename TransposeImpl::Index Index;
public:
EIGEN_STRONG_INLINE InnerIterator(const TransposeImpl& trans, typename TransposeImpl<MatrixType,Sparse>::Index outer)
: Base(trans.derived().nestedExpression(), outer)
{}
Index row() const { return Base::col(); }
Index col() const { return Base::row(); }
};
template<typename MatrixType> class TransposeImpl<MatrixType,Sparse>::ReverseInnerIterator
: public _MatrixTypeNested::ReverseInnerIterator
{
typedef typename _MatrixTypeNested::ReverseInnerIterator Base;
typedef typename TransposeImpl::Index Index;
public:
EIGEN_STRONG_INLINE ReverseInnerIterator(const TransposeImpl& xpr, typename TransposeImpl<MatrixType,Sparse>::Index outer)
: Base(xpr.derived().nestedExpression(), outer)
{}
Index row() const { return Base::col(); }
Index col() const { return Base::row(); }
};
#else // EIGEN_TEST_EVALUATORS
// Implement nonZeros() for transpose. I'm not sure that's the best approach for that.
// Perhaps it should be implemented in Transpose<> itself.
template<typename MatrixType> class TransposeImpl<MatrixType,Sparse>
@@ -119,8 +70,6 @@ struct unary_evaluator<Transpose<ArgType>, IteratorBased>
} // end namespace internal
#endif // EIGEN_TEST_EVALUATORS
} // end namespace Eigen
#endif // EIGEN_SPARSETRANSPOSE_H

View File

@@ -40,11 +40,6 @@ protected:
typedef typename internal::remove_reference<MatrixTypeNested>::type MatrixTypeNestedNonRef;
typedef typename internal::remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned;
#ifndef EIGEN_TEST_EVALUATORS
template<typename OtherDerived>
typename internal::plain_matrix_type_column_major<OtherDerived>::type
solve(const MatrixBase<OtherDerived>& other) const;
#else // EIGEN_TEST_EVALUATORS
template<typename RhsType, typename DstType>
EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE void _solve_impl(const RhsType &rhs, DstType &dst) const {
@@ -52,7 +47,6 @@ protected:
dst = rhs;
this->solveInPlace(dst);
}
#endif // EIGEN_TEST_EVALUATORS
template<typename OtherDerived> void solveInPlace(MatrixBase<OtherDerived>& other) const;
template<typename OtherDerived> void solveInPlace(SparseMatrixBase<OtherDerived>& other) const;
@@ -163,7 +157,6 @@ class TriangularViewImpl<MatrixType,Mode,Sparse>::ReverseInnerIterator : public
}
};
#ifdef EIGEN_TEST_EVALUATORS
namespace internal {
template<typename ArgType, unsigned int Mode>
@@ -270,7 +263,6 @@ protected:
};
} // end namespace internal
#endif
template<typename Derived>
template<int Mode>

View File

@@ -43,26 +43,6 @@ EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(Derived, -=) \
EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, *=) \
EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, /=)
#ifndef EIGEN_TEST_EVALUATORS
#define _EIGEN_SPARSE_PUBLIC_INTERFACE(Derived, BaseClass) \
typedef BaseClass Base; \
typedef typename Eigen::internal::traits<Derived >::Scalar Scalar; \
typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; \
typedef typename Eigen::internal::nested<Derived >::type Nested; \
typedef typename Eigen::internal::traits<Derived >::StorageKind StorageKind; \
typedef typename Eigen::internal::traits<Derived >::Index Index; \
enum { RowsAtCompileTime = Eigen::internal::traits<Derived >::RowsAtCompileTime, \
ColsAtCompileTime = Eigen::internal::traits<Derived >::ColsAtCompileTime, \
Flags = Eigen::internal::traits<Derived>::Flags, \
CoeffReadCost = Eigen::internal::traits<Derived >::CoeffReadCost, \
SizeAtCompileTime = Base::SizeAtCompileTime, \
IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; \
using Base::derived; \
using Base::const_cast_derived;
#else // EIGEN_TEST_EVALUATORS
#define _EIGEN_SPARSE_PUBLIC_INTERFACE(Derived, BaseClass) \
typedef BaseClass Base; \
typedef typename Eigen::internal::traits<Derived >::Scalar Scalar; \
@@ -78,8 +58,6 @@ EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, /=)
using Base::derived; \
using Base::const_cast_derived;
#endif // EIGEN_TEST_EVALUATORS
#define EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) \
_EIGEN_SPARSE_PUBLIC_INTERFACE(Derived, Eigen::SparseMatrixBase<Derived >)
@@ -156,13 +134,11 @@ template<typename T> struct plain_matrix_type<T,Sparse>
typedef SparseMatrix<_Scalar, _Options, _Index> type;
};
#ifdef EIGEN_TEST_EVALUATORS
template<typename Decomposition, typename RhsType>
struct solve_traits<Decomposition,RhsType,Sparse>
{
typedef typename sparse_eval<RhsType, RhsType::RowsAtCompileTime, RhsType::ColsAtCompileTime>::type PlainObject;
};
#endif
template<typename Derived>
struct generic_xpr_base<Derived, MatrixXpr, Sparse>

View File

@@ -422,30 +422,6 @@ class SparseVector<Scalar,_Options,_Index>::ReverseInnerIterator
namespace internal {
#ifndef EIGEN_TEST_EVALUATORS
template< typename Dest, typename Src>
struct sparse_vector_assign_selector<Dest,Src,SVA_Inner> {
static void run(Dest& dst, const Src& src) {
eigen_internal_assert(src.innerSize()==src.size());
for(typename Src::InnerIterator it(src, 0); it; ++it)
dst.insert(it.index()) = it.value();
}
};
template< typename Dest, typename Src>
struct sparse_vector_assign_selector<Dest,Src,SVA_Outer> {
static void run(Dest& dst, const Src& src) {
eigen_internal_assert(src.outerSize()==src.size());
for(typename Dest::Index i=0; i<src.size(); ++i)
{
typename Src::InnerIterator it(src, i);
if(it)
dst.insert(i) = it.value();
}
}
};
#else // EIGEN_TEST_EVALUATORS
template<typename _Scalar, int _Options, typename _Index>
struct evaluator<SparseVector<_Scalar,_Options,_Index> >
: evaluator_base<SparseVector<_Scalar,_Options,_Index> >
@@ -492,7 +468,6 @@ struct sparse_vector_assign_selector<Dest,Src,SVA_Outer> {
}
}
};
#endif // EIGEN_TEST_EVALUATORS
template< typename Dest, typename Src>
struct sparse_vector_assign_selector<Dest,Src,SVA_RuntimeSwitch> {

View File

@@ -40,10 +40,6 @@ public:
RealScalar m_epsilon = NumTraits<Scalar>::dummy_precision()) :
m_matrix(mat), m_reference(m_reference), m_epsilon(m_epsilon) {}
#ifndef EIGEN_TEST_EVALUATORS
class InnerIterator;
#endif // EIGEN_TEST_EVALUATORS
inline Index rows() const { return m_matrix.rows(); }
inline Index cols() const { return m_matrix.cols(); }
@@ -63,43 +59,6 @@ protected:
RealScalar m_epsilon;
};
#ifndef EIGEN_TEST_EVALUATORS
template<typename MatrixType>
class SparseView<MatrixType>::InnerIterator : public _MatrixTypeNested::InnerIterator
{
typedef typename SparseView::Index Index;
public:
typedef typename _MatrixTypeNested::InnerIterator IterBase;
InnerIterator(const SparseView& view, Index outer) :
IterBase(view.m_matrix, outer), m_view(view)
{
incrementToNonZero();
}
EIGEN_STRONG_INLINE InnerIterator& operator++()
{
IterBase::operator++();
incrementToNonZero();
return *this;
}
using IterBase::value;
protected:
const SparseView& m_view;
private:
void incrementToNonZero()
{
while((bool(*this)) && internal::isMuchSmallerThan(value(), m_view.reference(), m_view.epsilon()))
{
IterBase::operator++();
}
}
};
#else // EIGEN_TEST_EVALUATORS
namespace internal {
// TODO find a way to unify the two following variants
@@ -230,8 +189,6 @@ struct unary_evaluator<SparseView<ArgType>, IndexBased>
} // end namespace internal
#endif // EIGEN_TEST_EVALUATORS
template<typename Derived>
const SparseView<Derived> MatrixBase<Derived>::sparseView(const Scalar& reference,
const typename NumTraits<Scalar>::Real& epsilon) const

View File

@@ -23,149 +23,6 @@ template<typename Lhs, typename Rhs, int Mode,
int StorageOrder = int(traits<Lhs>::Flags) & RowMajorBit>
struct sparse_solve_triangular_selector;
#ifndef EIGEN_TEST_EVALUATORS
// forward substitution, row-major
template<typename Lhs, typename Rhs, int Mode>
struct sparse_solve_triangular_selector<Lhs,Rhs,Mode,Lower,RowMajor>
{
typedef typename Rhs::Scalar Scalar;
typedef typename Lhs::Index Index;
static void run(const Lhs& lhs, Rhs& other)
{
for(Index col=0 ; col<other.cols() ; ++col)
{
for(Index i=0; i<lhs.rows(); ++i)
{
Scalar tmp = other.coeff(i,col);
Scalar lastVal(0);
Index lastIndex = 0;
for(typename Lhs::InnerIterator it(lhs, i); it; ++it)
{
lastVal = it.value();
lastIndex = it.index();
if(lastIndex==i)
break;
tmp -= lastVal * other.coeff(lastIndex,col);
}
if (Mode & UnitDiag)
other.coeffRef(i,col) = tmp;
else
{
eigen_assert(lastIndex==i);
other.coeffRef(i,col) = tmp/lastVal;
}
}
}
}
};
// backward substitution, row-major
template<typename Lhs, typename Rhs, int Mode>
struct sparse_solve_triangular_selector<Lhs,Rhs,Mode,Upper,RowMajor>
{
typedef typename Rhs::Scalar Scalar;
typedef typename Lhs::Index Index;
static void run(const Lhs& lhs, Rhs& other)
{
for(Index col=0 ; col<other.cols() ; ++col)
{
for(Index i=lhs.rows()-1 ; i>=0 ; --i)
{
Scalar tmp = other.coeff(i,col);
Scalar l_ii = 0;
typename Lhs::InnerIterator it(lhs, i);
while(it && it.index()<i)
++it;
if(!(Mode & UnitDiag))
{
eigen_assert(it && it.index()==i);
l_ii = it.value();
++it;
}
else if (it && it.index() == i)
++it;
for(; it; ++it)
{
tmp -= it.value() * other.coeff(it.index(),col);
}
if (Mode & UnitDiag)
other.coeffRef(i,col) = tmp;
else
other.coeffRef(i,col) = tmp/l_ii;
}
}
}
};
// forward substitution, col-major
template<typename Lhs, typename Rhs, int Mode>
struct sparse_solve_triangular_selector<Lhs,Rhs,Mode,Lower,ColMajor>
{
typedef typename Rhs::Scalar Scalar;
typedef typename Lhs::Index Index;
static void run(const Lhs& lhs, Rhs& other)
{
for(Index col=0 ; col<other.cols() ; ++col)
{
for(Index i=0; i<lhs.cols(); ++i)
{
Scalar& tmp = other.coeffRef(i,col);
if (tmp!=Scalar(0)) // optimization when other is actually sparse
{
typename Lhs::InnerIterator it(lhs, i);
while(it && it.index()<i)
++it;
if(!(Mode & UnitDiag))
{
eigen_assert(it && it.index()==i);
tmp /= it.value();
}
if (it && it.index()==i)
++it;
for(; it; ++it)
other.coeffRef(it.index(), col) -= tmp * it.value();
}
}
}
}
};
// backward substitution, col-major
template<typename Lhs, typename Rhs, int Mode>
struct sparse_solve_triangular_selector<Lhs,Rhs,Mode,Upper,ColMajor>
{
typedef typename Rhs::Scalar Scalar;
typedef typename Lhs::Index Index;
static void run(const Lhs& lhs, Rhs& other)
{
for(Index col=0 ; col<other.cols() ; ++col)
{
for(Index i=lhs.cols()-1; i>=0; --i)
{
Scalar& tmp = other.coeffRef(i,col);
if (tmp!=Scalar(0)) // optimization when other is actually sparse
{
if(!(Mode & UnitDiag))
{
// TODO replace this by a binary search. make sure the binary search is safe for partially sorted elements
typename Lhs::ReverseInnerIterator it(lhs, i);
while(it && it.index()!=i)
--it;
eigen_assert(it && it.index()==i);
other.coeffRef(i,col) /= it.value();
}
typename Lhs::InnerIterator it(lhs, i);
for(; it && it.index()<i; ++it)
other.coeffRef(it.index(), col) -= tmp * it.value();
}
}
}
}
};
#else // EIGEN_TEST_EVALUATORS
// forward substitution, row-major
template<typename Lhs, typename Rhs, int Mode>
struct sparse_solve_triangular_selector<Lhs,Rhs,Mode,Lower,RowMajor>
@@ -316,7 +173,6 @@ struct sparse_solve_triangular_selector<Lhs,Rhs,Mode,Upper,ColMajor>
}
};
#endif // EIGEN_TEST_EVALUATORS
} // end namespace internal
template<typename ExpressionType,unsigned int Mode>
@@ -338,18 +194,6 @@ void TriangularViewImpl<ExpressionType,Mode,Sparse>::solveInPlace(MatrixBase<Oth
other = otherCopy;
}
#ifndef EIGEN_TEST_EVALUATORS
template<typename ExpressionType,unsigned int Mode>
template<typename OtherDerived>
typename internal::plain_matrix_type_column_major<OtherDerived>::type
TriangularViewImpl<ExpressionType,Mode,Sparse>::solve(const MatrixBase<OtherDerived>& other) const
{
typename internal::plain_matrix_type_column_major<OtherDerived>::type res(other);
solveInPlace(res);
return res;
}
#endif
// pure sparse path
namespace internal {