mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Remove deprecated code not used by evaluators
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
***************************************************************************/
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user