mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-08-12 11:49:02 +08:00
Implement evaluator for sparse views.
This commit is contained in:
parent
54607665ab
commit
f0648f8860
@ -47,6 +47,7 @@ struct Sparse {};
|
|||||||
#include "src/SparseCore/SparseBlock.h"
|
#include "src/SparseCore/SparseBlock.h"
|
||||||
#include "src/SparseCore/SparseDot.h"
|
#include "src/SparseCore/SparseDot.h"
|
||||||
#include "src/SparseCore/SparseRedux.h"
|
#include "src/SparseCore/SparseRedux.h"
|
||||||
|
#include "src/SparseCore/SparseView.h"
|
||||||
#ifndef EIGEN_TEST_EVALUATORS
|
#ifndef EIGEN_TEST_EVALUATORS
|
||||||
#include "src/SparseCore/SparsePermutation.h"
|
#include "src/SparseCore/SparsePermutation.h"
|
||||||
#include "src/SparseCore/SparseFuzzy.h"
|
#include "src/SparseCore/SparseFuzzy.h"
|
||||||
@ -58,7 +59,6 @@ struct Sparse {};
|
|||||||
#include "src/SparseCore/SparseTriangularView.h"
|
#include "src/SparseCore/SparseTriangularView.h"
|
||||||
#include "src/SparseCore/SparseSelfAdjointView.h"
|
#include "src/SparseCore/SparseSelfAdjointView.h"
|
||||||
#include "src/SparseCore/TriangularSolver.h"
|
#include "src/SparseCore/TriangularSolver.h"
|
||||||
#include "src/SparseCore/SparseView.h"
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "src/Core/util/ReenableStupidWarnings.h"
|
#include "src/Core/util/ReenableStupidWarnings.h"
|
||||||
|
@ -43,6 +43,8 @@ EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(Derived, -=) \
|
|||||||
EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, *=) \
|
EIGEN_SPARSE_INHERIT_SCALAR_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) \
|
#define _EIGEN_SPARSE_PUBLIC_INTERFACE(Derived, BaseClass) \
|
||||||
typedef BaseClass Base; \
|
typedef BaseClass Base; \
|
||||||
typedef typename Eigen::internal::traits<Derived >::Scalar Scalar; \
|
typedef typename Eigen::internal::traits<Derived >::Scalar Scalar; \
|
||||||
@ -59,6 +61,25 @@ EIGEN_SPARSE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, /=)
|
|||||||
using Base::derived; \
|
using Base::derived; \
|
||||||
using Base::const_cast_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; \
|
||||||
|
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, \
|
||||||
|
SizeAtCompileTime = Base::SizeAtCompileTime, \
|
||||||
|
IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; \
|
||||||
|
using Base::derived; \
|
||||||
|
using Base::const_cast_derived;
|
||||||
|
|
||||||
|
#endif // EIGEN_TEST_EVALUATORS
|
||||||
|
|
||||||
#define EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) \
|
#define EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) \
|
||||||
_EIGEN_SPARSE_PUBLIC_INTERFACE(Derived, Eigen::SparseMatrixBase<Derived >)
|
_EIGEN_SPARSE_PUBLIC_INTERFACE(Derived, Eigen::SparseMatrixBase<Derived >)
|
||||||
|
|
||||||
|
@ -34,25 +34,36 @@ class SparseView : public SparseMatrixBase<SparseView<MatrixType> >
|
|||||||
typedef typename internal::remove_all<MatrixTypeNested>::type _MatrixTypeNested;
|
typedef typename internal::remove_all<MatrixTypeNested>::type _MatrixTypeNested;
|
||||||
public:
|
public:
|
||||||
EIGEN_SPARSE_PUBLIC_INTERFACE(SparseView)
|
EIGEN_SPARSE_PUBLIC_INTERFACE(SparseView)
|
||||||
|
typedef typename internal::remove_all<MatrixType>::type NestedExpression;
|
||||||
|
|
||||||
SparseView(const MatrixType& mat, const Scalar& m_reference = Scalar(0),
|
SparseView(const MatrixType& mat, const Scalar& m_reference = Scalar(0),
|
||||||
typename NumTraits<Scalar>::Real m_epsilon = NumTraits<Scalar>::dummy_precision()) :
|
RealScalar m_epsilon = NumTraits<Scalar>::dummy_precision()) :
|
||||||
m_matrix(mat), m_reference(m_reference), m_epsilon(m_epsilon) {}
|
m_matrix(mat), m_reference(m_reference), m_epsilon(m_epsilon) {}
|
||||||
|
|
||||||
|
#ifndef EIGEN_TEST_EVALUATORS
|
||||||
class InnerIterator;
|
class InnerIterator;
|
||||||
|
#endif // EIGEN_TEST_EVALUATORS
|
||||||
|
|
||||||
inline Index rows() const { return m_matrix.rows(); }
|
inline Index rows() const { return m_matrix.rows(); }
|
||||||
inline Index cols() const { return m_matrix.cols(); }
|
inline Index cols() const { return m_matrix.cols(); }
|
||||||
|
|
||||||
inline Index innerSize() const { return m_matrix.innerSize(); }
|
inline Index innerSize() const { return m_matrix.innerSize(); }
|
||||||
inline Index outerSize() const { return m_matrix.outerSize(); }
|
inline Index outerSize() const { return m_matrix.outerSize(); }
|
||||||
|
|
||||||
|
/** \returns the nested expression */
|
||||||
|
const typename internal::remove_all<MatrixTypeNested>::type&
|
||||||
|
nestedExpression() const { return m_matrix; }
|
||||||
|
|
||||||
|
Scalar reference() const { return m_reference; }
|
||||||
|
RealScalar epsilon() const { return m_epsilon; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MatrixTypeNested m_matrix;
|
MatrixTypeNested m_matrix;
|
||||||
Scalar m_reference;
|
Scalar m_reference;
|
||||||
typename NumTraits<Scalar>::Real m_epsilon;
|
RealScalar m_epsilon;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef EIGEN_TEST_EVALUATORS
|
||||||
template<typename MatrixType>
|
template<typename MatrixType>
|
||||||
class SparseView<MatrixType>::InnerIterator : public _MatrixTypeNested::InnerIterator
|
class SparseView<MatrixType>::InnerIterator : public _MatrixTypeNested::InnerIterator
|
||||||
{
|
{
|
||||||
@ -80,13 +91,147 @@ protected:
|
|||||||
private:
|
private:
|
||||||
void incrementToNonZero()
|
void incrementToNonZero()
|
||||||
{
|
{
|
||||||
while((bool(*this)) && internal::isMuchSmallerThan(value(), m_view.m_reference, m_view.m_epsilon))
|
while((bool(*this)) && internal::isMuchSmallerThan(value(), m_view.reference(), m_view.epsilon()))
|
||||||
{
|
{
|
||||||
IterBase::operator++();
|
IterBase::operator++();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#else // EIGEN_TEST_EVALUATORS
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
// TODO find a way to unify the two following variants
|
||||||
|
// This is tricky because implementing an inner iterator on top of an IndexBased evaluator is
|
||||||
|
// not easy because the evaluators do not expose the sizes of the underlying expression.
|
||||||
|
|
||||||
|
template<typename ArgType>
|
||||||
|
struct unary_evaluator<SparseView<ArgType>, IteratorBased>
|
||||||
|
: public evaluator_base<SparseView<ArgType> >
|
||||||
|
{
|
||||||
|
typedef typename evaluator<ArgType>::InnerIterator EvalIterator;
|
||||||
|
public:
|
||||||
|
typedef SparseView<ArgType> XprType;
|
||||||
|
|
||||||
|
class InnerIterator : public EvalIterator
|
||||||
|
{
|
||||||
|
typedef typename XprType::Scalar Scalar;
|
||||||
|
public:
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& sve, typename XprType::Index outer)
|
||||||
|
: EvalIterator(sve.m_argImpl,outer), m_view(sve.m_view)
|
||||||
|
{
|
||||||
|
incrementToNonZero();
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE InnerIterator& operator++()
|
||||||
|
{
|
||||||
|
EvalIterator::operator++();
|
||||||
|
incrementToNonZero();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
using EvalIterator::value;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const XprType &m_view;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void incrementToNonZero()
|
||||||
|
{
|
||||||
|
while((bool(*this)) && internal::isMuchSmallerThan(value(), m_view.reference(), m_view.epsilon()))
|
||||||
|
{
|
||||||
|
EvalIterator::operator++();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
|
||||||
|
Flags = XprType::Flags
|
||||||
|
};
|
||||||
|
|
||||||
|
unary_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_view(xpr) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
typename evaluator<ArgType>::nestedType m_argImpl;
|
||||||
|
const XprType &m_view;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename ArgType>
|
||||||
|
struct unary_evaluator<SparseView<ArgType>, IndexBased>
|
||||||
|
: public evaluator_base<SparseView<ArgType> >
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef SparseView<ArgType> XprType;
|
||||||
|
protected:
|
||||||
|
enum { IsRowMajor = (XprType::Flags&RowMajorBit)==RowMajorBit };
|
||||||
|
typedef typename XprType::Index Index;
|
||||||
|
typedef typename XprType::Scalar Scalar;
|
||||||
|
public:
|
||||||
|
|
||||||
|
class InnerIterator
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& sve, typename XprType::Index outer)
|
||||||
|
: m_sve(sve), m_inner(0), m_outer(outer), m_end(sve.m_view.innerSize())
|
||||||
|
{
|
||||||
|
incrementToNonZero();
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE InnerIterator& operator++()
|
||||||
|
{
|
||||||
|
m_inner++;
|
||||||
|
incrementToNonZero();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE Scalar value() const
|
||||||
|
{
|
||||||
|
return (IsRowMajor) ? m_sve.m_argImpl.coeff(m_outer, m_inner)
|
||||||
|
: m_sve.m_argImpl.coeff(m_inner, m_outer);
|
||||||
|
}
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE Index index() const { return m_inner; }
|
||||||
|
inline Index row() const { return IsRowMajor ? m_outer : index(); }
|
||||||
|
inline Index col() const { return IsRowMajor ? index() : m_outer; }
|
||||||
|
|
||||||
|
EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
const unary_evaluator &m_sve;
|
||||||
|
Index m_inner;
|
||||||
|
const Index m_outer;
|
||||||
|
const Index m_end;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void incrementToNonZero()
|
||||||
|
{
|
||||||
|
while((bool(*this)) && internal::isMuchSmallerThan(value(), m_sve.m_view.reference(), m_sve.m_view.epsilon()))
|
||||||
|
{
|
||||||
|
m_inner++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
|
||||||
|
Flags = XprType::Flags
|
||||||
|
};
|
||||||
|
|
||||||
|
unary_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_view(xpr) {}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
typename evaluator<ArgType>::nestedType m_argImpl;
|
||||||
|
const XprType &m_view;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end namespace internal
|
||||||
|
|
||||||
|
#endif // EIGEN_TEST_EVALUATORS
|
||||||
|
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
const SparseView<Derived> MatrixBase<Derived>::sparseView(const Scalar& m_reference,
|
const SparseView<Derived> MatrixBase<Derived>::sparseView(const Scalar& m_reference,
|
||||||
const typename NumTraits<Scalar>::Real& m_epsilon) const
|
const typename NumTraits<Scalar>::Real& m_epsilon) const
|
||||||
|
Loading…
x
Reference in New Issue
Block a user