diff options
author | Gael Guennebaud <g.gael@free.fr> | 2014-06-20 15:39:38 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2014-06-20 15:39:38 +0200 |
commit | 78bb80833708615c330659d9b64870b19185df37 (patch) | |
tree | 15976a9b6efcf2e9a63b8ed9136737a2006fc527 | |
parent | 0a6c472335b593a227c3adbcf1d770187449a30f (diff) |
1- Introduce sub-evaluator types for unary, binary, product, and map expressions to ease specializing them.
2- Remove a lot of code which should not be there with evaluators, in particular coeff/packet methods implemented in the expressions.
-rw-r--r-- | Eigen/src/Core/ArrayBase.h | 4 | ||||
-rw-r--r-- | Eigen/src/Core/ArrayWrapper.h | 2 | ||||
-rw-r--r-- | Eigen/src/Core/Block.h | 13 | ||||
-rw-r--r-- | Eigen/src/Core/CoreEvaluators.h | 247 | ||||
-rw-r--r-- | Eigen/src/Core/CwiseBinaryOp.h | 30 | ||||
-rw-r--r-- | Eigen/src/Core/CwiseUnaryOp.h | 14 | ||||
-rw-r--r-- | Eigen/src/Core/CwiseUnaryView.h | 9 | ||||
-rw-r--r-- | Eigen/src/Core/DenseBase.h | 5 | ||||
-rw-r--r-- | Eigen/src/Core/DenseCoeffsBase.h | 45 | ||||
-rw-r--r-- | Eigen/src/Core/Inverse.h | 9 | ||||
-rw-r--r-- | Eigen/src/Core/Replicate.h | 1 | ||||
-rw-r--r-- | Eigen/src/Core/ReturnByValue.h | 28 | ||||
-rw-r--r-- | Eigen/src/Core/Reverse.h | 1 | ||||
-rw-r--r-- | Eigen/src/Core/Transpose.h | 30 | ||||
-rw-r--r-- | Eigen/src/Core/TriangularMatrix.h | 4 | ||||
-rw-r--r-- | Eigen/src/Core/products/GeneralMatrixMatrix.h | 4 | ||||
-rw-r--r-- | Eigen/src/Core/util/ForwardDeclarations.h | 4 | ||||
-rw-r--r-- | Eigen/src/Core/util/XprHelper.h | 9 |
18 files changed, 300 insertions, 159 deletions
diff --git a/Eigen/src/Core/ArrayBase.h b/Eigen/src/Core/ArrayBase.h index d1c422836..f5bae6357 100644 --- a/Eigen/src/Core/ArrayBase.h +++ b/Eigen/src/Core/ArrayBase.h @@ -123,7 +123,11 @@ template<typename Derived> class ArrayBase EIGEN_DEVICE_FUNC Derived& operator=(const ArrayBase& other) { +#ifndef EIGEN_TEST_EVALUATORS return internal::assign_selector<Derived,Derived>::run(derived(), other.derived()); +#else + internal::call_assignment(derived(), other.derived()); +#endif } EIGEN_DEVICE_FUNC diff --git a/Eigen/src/Core/ArrayWrapper.h b/Eigen/src/Core/ArrayWrapper.h index 4bb648024..599d87f64 100644 --- a/Eigen/src/Core/ArrayWrapper.h +++ b/Eigen/src/Core/ArrayWrapper.h @@ -39,6 +39,7 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> > typedef ArrayBase<ArrayWrapper> Base; EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper) EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper) + typedef typename internal::remove_all<ExpressionType>::type NestedExpression; typedef typename internal::conditional< internal::is_lvalue<ExpressionType>::value, @@ -176,6 +177,7 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> > typedef MatrixBase<MatrixWrapper<ExpressionType> > Base; EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper) EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper) + typedef typename internal::remove_all<ExpressionType>::type NestedExpression; typedef typename internal::conditional< internal::is_lvalue<ExpressionType>::value, diff --git a/Eigen/src/Core/Block.h b/Eigen/src/Core/Block.h index e0b24e199..ef6c143d3 100644 --- a/Eigen/src/Core/Block.h +++ b/Eigen/src/Core/Block.h @@ -344,6 +344,9 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true> : public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel> > { typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType; + enum { + XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0 + }; public: typedef MapBase<BlockType> Base; @@ -354,9 +357,8 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true> */ EIGEN_DEVICE_FUNC inline BlockImpl_dense(XprType& xpr, Index i) - : Base(internal::const_cast_ptr(&xpr.coeffRef( - (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0, - (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)), + : Base(xpr.data() + i * ( ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor)) + || ((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && ( XprTypeIsRowMajor)) ? xpr.innerStride() : xpr.outerStride()), BlockRows==1 ? 1 : xpr.rows(), BlockCols==1 ? 1 : xpr.cols()), m_xpr(xpr) @@ -368,7 +370,8 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true> */ EIGEN_DEVICE_FUNC inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol) - : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol))), m_xpr(xpr) + : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol)), + m_xpr(xpr) { init(); } @@ -379,7 +382,7 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true> inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols) - : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol)), blockRows, blockCols), + : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol), blockRows, blockCols), m_xpr(xpr) { init(); diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h index 47f50d548..f872b41e1 100644 --- a/Eigen/src/Core/CoreEvaluators.h +++ b/Eigen/src/Core/CoreEvaluators.h @@ -27,14 +27,6 @@ struct storage_kind_to_evaluator_kind { typedef IndexBased Kind; }; -// TODO to be moved to SparseCore: -/* -template<> -struct storage_kind_to_evaluator_kind<Sparse> { - typedef IteratorBased Kind -}; -*/ - // This class returns the evaluator shape from the expression storage kind. // It can be Dense, Sparse, Triangular, Diagonal, SelfAdjoint, Band, etc. template<typename StorageKind> struct storage_kind_to_shape; @@ -45,22 +37,28 @@ struct storage_kind_to_shape<Dense> { typedef DenseShape Shape; }; -// TODO to be moved to SparseCore: -/* -template<> -struct storage_kind_to_shape<Sparse> { - typedef SparseSpape Shape; -}; -*/ - +// Evaluators have to be specialized with respect to various criteria such as: +// - storage/structure/shape +// - scalar type +// - etc. +// Therefore, we need specialization of evaluator providing additional template arguments for each kind of evaluators. +// We currently distinguish the following kind of evaluators: +// - unary_evaluator for expressions taking only one arguments (CwiseUnaryOp, CwiseUnaryView, Transpose, MatrixWrapper, ArrayWrapper, Reverse, Replicate) +// - binary_evaluator for expression taking two arguments (CwiseBinaryOp) +// - product_evaluator for linear algebra products (Product); special case of binary_evaluator because it requires additional tags for dispatching. +// - mapbase_evaluator for Map, Block, Ref +// - block_evaluator for Block (special dispatching to a mapbase_evaluator or unary_evaluator) - template< typename T, - typename LhsKind = typename evaluator_traits<typename T::Lhs>::Kind, - typename RhsKind = typename evaluator_traits<typename T::Rhs>::Kind, + typename LhsKind = typename evaluator_traits<typename T::Lhs>::Kind, + typename RhsKind = typename evaluator_traits<typename T::Rhs>::Kind, typename LhsScalar = typename T::Lhs::Scalar, typename RhsScalar = typename T::Rhs::Scalar> struct binary_evaluator; +template< typename T, + typename Kind = typename evaluator_traits<typename T::NestedExpression>::Kind, + typename Scalar = typename T::Scalar> struct unary_evaluator; + // evaluator_traits<T> contains traits for evaluator<T> template<typename T> @@ -80,15 +78,20 @@ struct evaluator_traits_base static const int AssumeAliasing = 0; }; +// Default evaluator traits template<typename T> struct evaluator_traits : public evaluator_traits_base<T> { }; -// expression class for evaluating nested expression to a temporary - -template<typename ArgType> -class EvalToTemp; + +// By default, we assume a unary expression: +template<typename T> +struct evaluator : public unary_evaluator<T> +{ + typedef unary_evaluator<T> Base; + evaluator(const T& xpr) : Base(xpr) {} +}; // TODO: Think about const-correctness @@ -118,6 +121,8 @@ struct evaluator_base // // evaluator<PlainObjectBase> is a common base class for the // Matrix and Array evaluators. +// Here we directly specialize evaluator. This is not really a unary expression, and it is, by definition, dense, +// so no need for more sophisticated dispatching. template<typename Derived> struct evaluator<PlainObjectBase<Derived> > @@ -245,81 +250,10 @@ struct evaluator<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > { } }; -// -------------------- EvalToTemp -------------------- - -template<typename ArgType> -struct traits<EvalToTemp<ArgType> > - : public traits<ArgType> -{ }; - -template<typename ArgType> -class EvalToTemp - : public dense_xpr_base<EvalToTemp<ArgType> >::type -{ - public: - - typedef typename dense_xpr_base<EvalToTemp>::type Base; - EIGEN_GENERIC_PUBLIC_INTERFACE(EvalToTemp) - - EvalToTemp(const ArgType& arg) - : m_arg(arg) - { } - - const ArgType& arg() const - { - return m_arg; - } - - Index rows() const - { - return m_arg.rows(); - } - - Index cols() const - { - return m_arg.cols(); - } - - private: - const ArgType& m_arg; -}; - -template<typename ArgType> -struct evaluator<EvalToTemp<ArgType> > - : public evaluator<typename ArgType::PlainObject>::type -{ - typedef EvalToTemp<ArgType> XprType; - typedef typename ArgType::PlainObject PlainObject; - typedef typename evaluator<PlainObject>::type Base; - - typedef evaluator type; - typedef evaluator nestedType; - - evaluator(const XprType& xpr) - : m_result(xpr.rows(), xpr.cols()) - { - ::new (static_cast<Base*>(this)) Base(m_result); - // TODO we should simply do m_result(xpr.arg()); - call_dense_assignment_loop(m_result, xpr.arg()); - } - - // This constructor is used when nesting an EvalTo evaluator in another evaluator - evaluator(const ArgType& arg) - : m_result(arg.rows(), arg.cols()) - { - ::new (static_cast<Base*>(this)) Base(m_result); - // TODO we should simply do m_result(xpr.arg()); - call_dense_assignment_loop(m_result, arg); - } - -protected: - PlainObject m_result; -}; - // -------------------- Transpose -------------------- template<typename ArgType> -struct evaluator<Transpose<ArgType> > +struct unary_evaluator<Transpose<ArgType> > : evaluator_base<Transpose<ArgType> > { typedef Transpose<ArgType> XprType; @@ -329,7 +263,7 @@ struct evaluator<Transpose<ArgType> > Flags = evaluator<ArgType>::Flags ^ RowMajorBit }; - evaluator(const XprType& t) : m_argImpl(t.nestedExpression()) {} + unary_evaluator(const XprType& t) : m_argImpl(t.nestedExpression()) {} typedef typename XprType::Index Index; typedef typename XprType::Scalar Scalar; @@ -386,6 +320,8 @@ protected: }; // -------------------- CwiseNullaryOp -------------------- +// Like Matrix and Array, this is not really a unary expression, so we directly specialize evaluator. +// Likewise, there is not need to more sophisticated dispatching here. template<typename NullaryOp, typename PlainObjectType> struct evaluator<CwiseNullaryOp<NullaryOp,PlainObjectType> > @@ -441,7 +377,7 @@ protected: // -------------------- CwiseUnaryOp -------------------- template<typename UnaryOp, typename ArgType> -struct evaluator<CwiseUnaryOp<UnaryOp, ArgType> > +struct unary_evaluator<CwiseUnaryOp<UnaryOp, ArgType>, IndexBased > : evaluator_base<CwiseUnaryOp<UnaryOp, ArgType> > { typedef CwiseUnaryOp<UnaryOp, ArgType> XprType; @@ -454,7 +390,7 @@ struct evaluator<CwiseUnaryOp<UnaryOp, ArgType> > | (functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0)) }; - evaluator(const XprType& op) + unary_evaluator(const XprType& op) : m_functor(op.functor()), m_argImpl(op.nestedExpression()) { } @@ -492,8 +428,19 @@ protected: // -------------------- CwiseBinaryOp -------------------- +// this is a binary expression template<typename BinaryOp, typename Lhs, typename Rhs> struct evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > + : public binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > +{ + typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType; + typedef binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > Base; + + evaluator(const XprType& xpr) : Base(xpr) {} +}; + +template<typename BinaryOp, typename Lhs, typename Rhs> +struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > : evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > { typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType; @@ -517,7 +464,7 @@ struct evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > Flags = (Flags0 & ~RowMajorBit) | (LhsFlags & RowMajorBit) }; - evaluator(const XprType& xpr) + binary_evaluator(const XprType& xpr) : m_functor(xpr.functor()), m_lhsImpl(xpr.lhs()), m_rhsImpl(xpr.rhs()) @@ -560,7 +507,7 @@ protected: // -------------------- CwiseUnaryView -------------------- template<typename UnaryOp, typename ArgType> -struct evaluator<CwiseUnaryView<UnaryOp, ArgType> > +struct unary_evaluator<CwiseUnaryView<UnaryOp, ArgType> > : evaluator_base<CwiseUnaryView<UnaryOp, ArgType> > { typedef CwiseUnaryView<UnaryOp, ArgType> XprType; @@ -571,7 +518,7 @@ struct evaluator<CwiseUnaryView<UnaryOp, ArgType> > Flags = (evaluator<ArgType>::Flags & (HereditaryBits | LinearAccessBit | DirectAccessBit)) }; - evaluator(const XprType& op) + unary_evaluator(const XprType& op) : m_unaryOp(op.functor()), m_argImpl(op.nestedExpression()) { } @@ -884,6 +831,7 @@ struct block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel, /* HasDirectAc // -------------------- Select -------------------- +// TODO shall we introduce a ternary_evaluator? // TODO enable vectorization for Select template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType> @@ -934,7 +882,7 @@ protected: // -------------------- Replicate -------------------- template<typename ArgType, int RowFactor, int ColFactor> -struct evaluator<Replicate<ArgType, RowFactor, ColFactor> > +struct unary_evaluator<Replicate<ArgType, RowFactor, ColFactor> > : evaluator_base<Replicate<ArgType, RowFactor, ColFactor> > { typedef Replicate<ArgType, RowFactor, ColFactor> XprType; @@ -953,7 +901,7 @@ struct evaluator<Replicate<ArgType, RowFactor, ColFactor> > Flags = (evaluator<ArgTypeNestedCleaned>::Flags & HereditaryBits & ~RowMajorBit) | (traits<XprType>::Flags & RowMajorBit) }; - evaluator(const XprType& replicate) + unary_evaluator(const XprType& replicate) : m_arg(replicate.nestedExpression()), m_argImpl(m_arg), m_rows(replicate.nestedExpression().rows()), @@ -1111,23 +1059,23 @@ protected: }; template<typename TArgType> -struct evaluator<MatrixWrapper<TArgType> > +struct unary_evaluator<MatrixWrapper<TArgType> > : evaluator_wrapper_base<MatrixWrapper<TArgType> > { typedef MatrixWrapper<TArgType> XprType; - evaluator(const XprType& wrapper) + unary_evaluator(const XprType& wrapper) : evaluator_wrapper_base<MatrixWrapper<TArgType> >(wrapper.nestedExpression()) { } }; template<typename TArgType> -struct evaluator<ArrayWrapper<TArgType> > +struct unary_evaluator<ArrayWrapper<TArgType> > : evaluator_wrapper_base<ArrayWrapper<TArgType> > { typedef ArrayWrapper<TArgType> XprType; - evaluator(const XprType& wrapper) + unary_evaluator(const XprType& wrapper) : evaluator_wrapper_base<ArrayWrapper<TArgType> >(wrapper.nestedExpression()) { } }; @@ -1139,7 +1087,7 @@ struct evaluator<ArrayWrapper<TArgType> > template<typename PacketScalar, bool ReversePacket> struct reverse_packet_cond; template<typename ArgType, int Direction> -struct evaluator<Reverse<ArgType, Direction> > +struct unary_evaluator<Reverse<ArgType, Direction> > : evaluator_base<Reverse<ArgType, Direction> > { typedef Reverse<ArgType, Direction> XprType; @@ -1173,7 +1121,7 @@ struct evaluator<Reverse<ArgType, Direction> > }; typedef internal::reverse_packet_cond<PacketScalar,ReversePacket> reverse_packet; - evaluator(const XprType& reverse) + unary_evaluator(const XprType& reverse) : m_argImpl(reverse.nestedExpression()), m_rows(ReverseRow ? reverse.nestedExpression().rows() : 0), m_cols(ReverseCol ? reverse.nestedExpression().cols() : 0) @@ -1292,6 +1240,87 @@ private: EIGEN_STRONG_INLINE Index colOffset() const { return m_index.value() > 0 ? m_index.value() : 0; } }; + + +//---------------------------------------------------------------------- +// deprecated code +//---------------------------------------------------------------------- + +// -------------------- EvalToTemp -------------------- + +// expression class for evaluating nested expression to a temporary + +template<typename ArgType> class EvalToTemp; + +template<typename ArgType> +struct traits<EvalToTemp<ArgType> > + : public traits<ArgType> +{ }; + +template<typename ArgType> +class EvalToTemp + : public dense_xpr_base<EvalToTemp<ArgType> >::type +{ + public: + + typedef typename dense_xpr_base<EvalToTemp>::type Base; + EIGEN_GENERIC_PUBLIC_INTERFACE(EvalToTemp) + + EvalToTemp(const ArgType& arg) + : m_arg(arg) + { } + + const ArgType& arg() const + { + return m_arg; + } + + Index rows() const + { + return m_arg.rows(); + } + + Index cols() const + { + return m_arg.cols(); + } + + private: + const ArgType& m_arg; +}; + +template<typename ArgType> +struct evaluator<EvalToTemp<ArgType> > + : public evaluator<typename ArgType::PlainObject>::type +{ + typedef EvalToTemp<ArgType> XprType; + typedef typename ArgType::PlainObject PlainObject; + typedef typename evaluator<PlainObject>::type Base; + + typedef evaluator type; + typedef evaluator nestedType; + + evaluator(const XprType& xpr) + : m_result(xpr.rows(), xpr.cols()) + { + ::new (static_cast<Base*>(this)) Base(m_result); + // TODO we should simply do m_result(xpr.arg()); + call_dense_assignment_loop(m_result, xpr.arg()); + } + + // This constructor is used when nesting an EvalTo evaluator in another evaluator + evaluator(const ArgType& arg) + : m_result(arg.rows(), arg.cols()) + { + ::new (static_cast<Base*>(this)) Base(m_result); + // TODO we should simply do m_result(xpr.arg()); + call_dense_assignment_loop(m_result, arg); + } + +protected: + PlainObject m_result; +}; + } // namespace internal } // end namespace Eigen diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h index 07861dbc9..5e4fb147b 100644 --- a/Eigen/src/Core/CwiseBinaryOp.h +++ b/Eigen/src/Core/CwiseBinaryOp.h @@ -94,23 +94,26 @@ struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind> class CwiseBinaryOpImpl; -template<typename BinaryOp, typename Lhs, typename Rhs> +template<typename BinaryOp, typename LhsType, typename RhsType> class CwiseBinaryOp : internal::no_assignment_operator, public CwiseBinaryOpImpl< - BinaryOp, Lhs, Rhs, - typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind, - typename internal::traits<Rhs>::StorageKind>::ret> + BinaryOp, LhsType, RhsType, + typename internal::promote_storage_type<typename internal::traits<LhsType>::StorageKind, + typename internal::traits<RhsType>::StorageKind>::ret> { public: + + typedef typename internal::remove_all<LhsType>::type Lhs; + typedef typename internal::remove_all<RhsType>::type Rhs; typedef typename CwiseBinaryOpImpl< - BinaryOp, Lhs, Rhs, - typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind, + BinaryOp, LhsType, RhsType, + typename internal::promote_storage_type<typename internal::traits<LhsType>::StorageKind, typename internal::traits<Rhs>::StorageKind>::ret>::Base Base; EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp) - typedef typename internal::nested<Lhs>::type LhsNested; - typedef typename internal::nested<Rhs>::type RhsNested; + typedef typename internal::nested<LhsType>::type LhsNested; + typedef typename internal::nested<RhsType>::type RhsNested; typedef typename internal::remove_reference<LhsNested>::type _LhsNested; typedef typename internal::remove_reference<RhsNested>::type _RhsNested; @@ -157,6 +160,7 @@ class CwiseBinaryOp : internal::no_assignment_operator, const BinaryOp m_functor; }; +#ifndef EIGEN_TEST_EVALUATORS template<typename BinaryOp, typename Lhs, typename Rhs> class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense> : public internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type @@ -195,6 +199,16 @@ class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense> derived().rhs().template packet<LoadMode>(index)); } }; +#else +// Generic API dispatcher +template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind> +class CwiseBinaryOpImpl + : public internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type +{ +public: + typedef typename internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type Base; +}; +#endif /** replaces \c *this by \c *this - \a other. * diff --git a/Eigen/src/Core/CwiseUnaryOp.h b/Eigen/src/Core/CwiseUnaryOp.h index af05a9108..098034a1e 100644 --- a/Eigen/src/Core/CwiseUnaryOp.h +++ b/Eigen/src/Core/CwiseUnaryOp.h @@ -67,6 +67,7 @@ class CwiseUnaryOp : internal::no_assignment_operator, typedef typename CwiseUnaryOpImpl<UnaryOp, XprType,typename internal::traits<XprType>::StorageKind>::Base Base; EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryOp) + typedef typename internal::remove_all<XprType>::type NestedExpression; EIGEN_DEVICE_FUNC inline CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp()) @@ -96,6 +97,7 @@ class CwiseUnaryOp : internal::no_assignment_operator, const UnaryOp m_functor; }; +#ifndef EIGEN_TEST_EVALUATORS // This is the generic implementation for dense storage. // It can be used for any expression types implementing the dense concept. template<typename UnaryOp, typename XprType> @@ -107,7 +109,7 @@ class CwiseUnaryOpImpl<UnaryOp,XprType,Dense> typedef CwiseUnaryOp<UnaryOp, XprType> Derived; typedef typename internal::dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base; EIGEN_DENSE_PUBLIC_INTERFACE(Derived) - + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const { @@ -133,6 +135,16 @@ class CwiseUnaryOpImpl<UnaryOp,XprType,Dense> return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(index)); } }; +#else +// Generic API dispatcher +template<typename UnaryOp, typename XprType, typename StorageKind> +class CwiseUnaryOpImpl + : public internal::generic_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type +{ +public: + typedef typename internal::generic_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base; +}; +#endif } // end namespace Eigen diff --git a/Eigen/src/Core/CwiseUnaryView.h b/Eigen/src/Core/CwiseUnaryView.h index 9cdebb8e7..92b031e19 100644 --- a/Eigen/src/Core/CwiseUnaryView.h +++ b/Eigen/src/Core/CwiseUnaryView.h @@ -66,6 +66,7 @@ class CwiseUnaryView : public CwiseUnaryViewImpl<ViewOp, MatrixType, typename in typedef typename CwiseUnaryViewImpl<ViewOp, MatrixType,typename internal::traits<MatrixType>::StorageKind>::Base Base; EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryView) + typedef typename internal::remove_all<MatrixType>::type NestedExpression; inline CwiseUnaryView(const MatrixType& mat, const ViewOp& func = ViewOp()) : m_matrix(mat), m_functor(func) {} @@ -104,8 +105,8 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense> EIGEN_DENSE_PUBLIC_INTERFACE(Derived) EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryViewImpl) - inline Scalar* data() { return &coeffRef(0); } - inline const Scalar* data() const { return &coeff(0); } + inline Scalar* data() { return &(this->coeffRef(0)); } + inline const Scalar* data() const { return &(this->coeff(0)); } inline Index innerStride() const { @@ -116,6 +117,8 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense> { return derived().nestedExpression().outerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar); } + +#ifndef EIGEN_TEST_EVALUATORS EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const { @@ -136,6 +139,8 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense> { return derived().functor()(const_cast_derived().nestedExpression().coeffRef(index)); } + +#endif }; } // end namespace Eigen diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h index f3c79aa31..624276240 100644 --- a/Eigen/src/Core/DenseBase.h +++ b/Eigen/src/Core/DenseBase.h @@ -74,6 +74,7 @@ template<typename Derived> class DenseBase using Base::colIndexByOuterInner; using Base::coeff; using Base::coeffByOuterInner; +#ifndef EIGEN_TEST_EVALUATORS using Base::packet; using Base::packetByOuterInner; using Base::writePacket; @@ -84,6 +85,7 @@ template<typename Derived> class DenseBase using Base::copyCoeffByOuterInner; using Base::copyPacket; using Base::copyPacketByOuterInner; +#endif using Base::operator(); using Base::operator[]; using Base::x; @@ -280,7 +282,8 @@ template<typename Derived> class DenseBase Derived& operator=(const ReturnByValue<OtherDerived>& func); #ifndef EIGEN_PARSED_BY_DOXYGEN - /** Copies \a other into *this without evaluating other. \returns a reference to *this. */ + /** Copies \a other into *this without evaluating other. \returns a reference to *this. + * \deprecated */ template<typename OtherDerived> EIGEN_DEVICE_FUNC Derived& lazyAssign(const DenseBase<OtherDerived>& other); diff --git a/Eigen/src/Core/DenseCoeffsBase.h b/Eigen/src/Core/DenseCoeffsBase.h index efabb5e67..6f35a67ca 100644 --- a/Eigen/src/Core/DenseCoeffsBase.h +++ b/Eigen/src/Core/DenseCoeffsBase.h @@ -97,8 +97,12 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived> EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const { eigen_internal_assert(row >= 0 && row < rows() - && col >= 0 && col < cols()); + && col >= 0 && col < cols()); +#ifndef EIGEN_TEST_EVALUATORS return derived().coeff(row, col); +#else + return typename internal::evaluator<Derived>::type(derived()).coeff(row,col); +#endif } EIGEN_DEVICE_FUNC @@ -117,7 +121,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived> { eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols()); - return derived().coeff(row, col); + return coeff(row, col); } /** Short version: don't use this function, use @@ -140,7 +144,11 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived> coeff(Index index) const { eigen_internal_assert(index >= 0 && index < size()); +#ifndef EIGEN_TEST_EVALUATORS return derived().coeff(index); +#else + return typename internal::evaluator<Derived>::type(derived()).coeff(index); +#endif } @@ -161,7 +169,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived> THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD) #endif eigen_assert(index >= 0 && index < size()); - return derived().coeff(index); + return coeff(index); } /** \returns the coefficient at given index. @@ -179,7 +187,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived> operator()(Index index) const { eigen_assert(index >= 0 && index < size()); - return derived().coeff(index); + return coeff(index); } /** equivalent to operator[](0). */ @@ -219,9 +227,12 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived> template<int LoadMode> EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const { - eigen_internal_assert(row >= 0 && row < rows() - && col >= 0 && col < cols()); + eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols()); +#ifndef EIGEN_TEST_EVALUATORS return derived().template packet<LoadMode>(row,col); +#else + return typename internal::evaluator<Derived>::type(derived()).template packet<LoadMode>(row,col); +#endif } @@ -247,7 +258,11 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived> EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const { eigen_internal_assert(index >= 0 && index < size()); +#ifndef EIGEN_TEST_EVALUATORS return derived().template packet<LoadMode>(index); +#else + return typename internal::evaluator<Derived>::type(derived()).template packet<LoadMode>(index); +#endif } protected: @@ -327,8 +342,12 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col) { eigen_internal_assert(row >= 0 && row < rows() - && col >= 0 && col < cols()); + && col >= 0 && col < cols()); +#ifndef EIGEN_TEST_EVALUATORS return derived().coeffRef(row, col); +#else + return typename internal::evaluator<Derived>::type(derived()).coeffRef(row,col); +#endif } EIGEN_DEVICE_FUNC @@ -350,7 +369,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, { eigen_assert(row >= 0 && row < rows() && col >= 0 && col < cols()); - return derived().coeffRef(row, col); + return coeffRef(row, col); } @@ -374,7 +393,11 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, coeffRef(Index index) { eigen_internal_assert(index >= 0 && index < size()); +#ifndef EIGEN_TEST_EVALUATORS return derived().coeffRef(index); +#else + return typename internal::evaluator<Derived>::type(derived()).coeffRef(index); +#endif } /** \returns a reference to the coefficient at given index. @@ -393,7 +416,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD) #endif eigen_assert(index >= 0 && index < size()); - return derived().coeffRef(index); + return coeffRef(index); } /** \returns a reference to the coefficient at given index. @@ -410,7 +433,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, operator()(Index index) { eigen_assert(index >= 0 && index < size()); - return derived().coeffRef(index); + return coeffRef(index); } /** equivalent to operator[](0). */ @@ -437,6 +460,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, EIGEN_STRONG_INLINE Scalar& w() { return (*this)[3]; } +#ifndef EIGEN_TEST_EVALUATORS /** \internal * Stores the given packet of coefficients, at the given row and column of this expression. It is your responsibility * to ensure that a packet really starts there. This method is only available on expressions having the @@ -573,6 +597,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, derived().template copyPacket< OtherDerived, StoreMode, LoadMode>(row, col, other); } #endif +#endif // EIGEN_TEST_EVALUATORS }; diff --git a/Eigen/src/Core/Inverse.h b/Eigen/src/Core/Inverse.h index 57eaf99f1..788d0664d 100644 --- a/Eigen/src/Core/Inverse.h +++ b/Eigen/src/Core/Inverse.h @@ -81,6 +81,7 @@ public: typedef MatrixBase<Derived> Base; EIGEN_DENSE_PUBLIC_INTERFACE(Derived) + typedef typename internal::remove_all<XprType>::type NestedExpression; private: @@ -101,19 +102,19 @@ namespace internal { * \sa class Inverse */ template<typename XprType> -struct evaluator<Inverse<XprType> > +struct unary_evaluator<Inverse<XprType> > : public evaluator<typename Inverse<XprType>::PlainObject>::type { typedef Inverse<XprType> InverseType; typedef typename InverseType::PlainObject PlainObject; typedef typename evaluator<PlainObject>::type Base; - typedef evaluator type; - typedef evaluator nestedType; + typedef evaluator<XprType> type; + typedef evaluator<XprType> nestedType; enum { Flags = Base::Flags | EvalBeforeNestingBit }; - evaluator(const InverseType& inv_xpr) + unary_evaluator(const InverseType& inv_xpr) : m_result(inv_xpr.rows(), inv_xpr.cols()) { ::new (static_cast<Base*>(this)) Base(m_result); diff --git a/Eigen/src/Core/Replicate.h b/Eigen/src/Core/Replicate.h index 2dff03ea3..e63f0d421 100644 --- a/Eigen/src/Core/Replicate.h +++ b/Eigen/src/Core/Replicate.h @@ -74,6 +74,7 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate typedef typename internal::dense_xpr_base<Replicate>::type Base; EIGEN_DENSE_PUBLIC_INTERFACE(Replicate) + typedef typename internal::remove_all<MatrixType>::type NestedExpression; template<typename OriginalMatrixType> inline explicit Replicate(const OriginalMatrixType& a_matrix) diff --git a/Eigen/src/Core/ReturnByValue.h b/Eigen/src/Core/ReturnByValue.h index d63b96138..30ade1b75 100644 --- a/Eigen/src/Core/ReturnByValue.h +++ b/Eigen/src/Core/ReturnByValue.h @@ -92,6 +92,34 @@ Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other) return derived(); } +#ifdef EIGEN_TEST_EVALUATORS +namespace internal { + +template<typename Derived> +struct evaluator<ReturnByValue<Derived> > + : public evaluator<typename internal::traits<Derived>::ReturnType>::type +{ + typedef ReturnByValue<Derived> XprType; + typedef typename internal::traits<Derived>::ReturnType PlainObject; + typedef typename evaluator<PlainObject>::type Base; + + typedef evaluator type; + typedef evaluator nestedType; + + evaluator(const XprType& xpr) + : m_result(xpr.rows(), xpr.cols()) + { + ::new (static_cast<Base*>(this)) Base(m_result); + xpr.evalTo(m_result); + } + +protected: + PlainObject m_result; +}; + +} // end namespace internal +#endif + } // end namespace Eigen #endif // EIGEN_RETURNBYVALUE_H diff --git a/Eigen/src/Core/Reverse.h b/Eigen/src/Core/Reverse.h index 4969bb4fc..ceb6e4701 100644 --- a/Eigen/src/Core/Reverse.h +++ b/Eigen/src/Core/Reverse.h @@ -77,6 +77,7 @@ template<typename MatrixType, int Direction> class Reverse typedef typename internal::dense_xpr_base<Reverse>::type Base; EIGEN_DENSE_PUBLIC_INTERFACE(Reverse) + typedef typename internal::remove_all<MatrixType>::type NestedExpression; using Base::IsRowMajor; // next line is necessary because otherwise const version of operator() diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h index 079f21fd9..4b605dfd6 100644 --- a/Eigen/src/Core/Transpose.h +++ b/Eigen/src/Core/Transpose.h @@ -68,6 +68,7 @@ template<typename MatrixType> class Transpose typedef typename TransposeImpl<MatrixType,typename internal::traits<MatrixType>::StorageKind>::Base Base; EIGEN_GENERIC_PUBLIC_INTERFACE(Transpose) + typedef typename internal::remove_all<MatrixType>::type NestedExpression; EIGEN_DEVICE_FUNC inline Transpose(MatrixType& a_matrix) : m_matrix(a_matrix) {} @@ -113,6 +114,7 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense> public: typedef typename internal::TransposeImpl_base<MatrixType>::type Base; + using Base::coeffRef; EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>) EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TransposeImpl) @@ -127,6 +129,8 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense> inline ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); } inline const Scalar* data() const { return derived().nestedExpression().data(); } + +#ifndef EIGEN_TEST_EVALUATORS EIGEN_DEVICE_FUNC inline ScalarWithConstIfNotLvalue& coeffRef(Index rowId, Index colId) @@ -143,18 +147,6 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense> } EIGEN_DEVICE_FUNC - inline const Scalar& coeffRef(Index rowId, Index colId) const - { - return derived().nestedExpression().coeffRef(colId, rowId); - } - - EIGEN_DEVICE_FUNC - inline const Scalar& coeffRef(Index index) const - { - return derived().nestedExpression().coeffRef(index); - } - - EIGEN_DEVICE_FUNC inline CoeffReturnType coeff(Index rowId, Index colId) const { return derived().nestedExpression().coeff(colId, rowId); @@ -189,6 +181,20 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense> { derived().nestedExpression().const_cast_derived().template writePacket<LoadMode>(index, x); } +#endif + + // FIXME: shall we keep the const version of coeffRef? + EIGEN_DEVICE_FUNC + inline const Scalar& coeffRef(Index rowId, Index colId) const + { + return derived().nestedExpression().coeffRef(colId, rowId); + } + + EIGEN_DEVICE_FUNC + inline const Scalar& coeffRef(Index index) const + { + return derived().nestedExpression().coeffRef(index); + } }; /** \returns an expression of the transpose of *this. diff --git a/Eigen/src/Core/TriangularMatrix.h b/Eigen/src/Core/TriangularMatrix.h index 064e0e10d..180efdd62 100644 --- a/Eigen/src/Core/TriangularMatrix.h +++ b/Eigen/src/Core/TriangularMatrix.h @@ -1071,8 +1071,8 @@ struct evaluator_traits<TriangularView<MatrixType,Mode> > static const int AssumeAliasing = 0; }; -template<typename MatrixType, unsigned int Mode, typename Kind> -struct evaluator<TriangularView<MatrixType,Mode>, Kind, typename MatrixType::Scalar> +template<typename MatrixType, unsigned int Mode> +struct evaluator<TriangularView<MatrixType,Mode> > : evaluator<typename internal::remove_all<MatrixType>::type> { typedef TriangularView<MatrixType,Mode> XprType; diff --git a/Eigen/src/Core/products/GeneralMatrixMatrix.h b/Eigen/src/Core/products/GeneralMatrixMatrix.h index 1726f98ed..b0a09216d 100644 --- a/Eigen/src/Core/products/GeneralMatrixMatrix.h +++ b/Eigen/src/Core/products/GeneralMatrixMatrix.h @@ -219,8 +219,8 @@ struct gemm_functor cols = m_rhs.cols(); Gemm::run(rows, cols, m_lhs.cols(), - /*(const Scalar*)*/&m_lhs.coeffRef(row,0), m_lhs.outerStride(), - /*(const Scalar*)*/&m_rhs.coeffRef(0,col), m_rhs.outerStride(), + &m_lhs.coeffRef(row,0), m_lhs.outerStride(), + &m_rhs.coeffRef(0,col), m_rhs.outerStride(), (Scalar*)&(m_dest.coeffRef(row,col)), m_dest.outerStride(), m_actualAlpha, m_blocking, info); } diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index 092ba758e..ead5de650 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -38,9 +38,7 @@ template<typename Derived> struct accessors_level template<typename T> struct evaluator_traits; -template< typename T, - typename Kind = typename evaluator_traits<T>::Kind, - typename Scalar = typename T::Scalar> struct evaluator; +template< typename T> struct evaluator; } // end namespace internal diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h index 0be5029c9..5407645c9 100644 --- a/Eigen/src/Core/util/XprHelper.h +++ b/Eigen/src/Core/util/XprHelper.h @@ -465,6 +465,15 @@ struct dense_xpr_base<Derived, ArrayXpr> typedef ArrayBase<Derived> type; }; +template<typename Derived, typename XprKind = typename traits<Derived>::XprKind, typename StorageKind = typename traits<Derived>::StorageKind> +struct generic_xpr_base; + +template<typename Derived, typename XprKind> +struct generic_xpr_base<Derived, XprKind, Dense> +{ + typedef typename dense_xpr_base<Derived,XprKind>::type type; +}; + /** \internal Helper base class to add a scalar multiple operator * overloads for complex types */ template<typename Derived,typename Scalar,typename OtherScalar, |