diff options
-rw-r--r-- | Eigen/src/Core/GeneralProduct.h | 53 | ||||
-rw-r--r-- | Eigen/src/Core/Product.h | 2 | ||||
-rw-r--r-- | Eigen/src/Core/ProductEvaluators.h | 72 | ||||
-rw-r--r-- | Eigen/src/Core/SelfAdjointView.h | 2 |
4 files changed, 98 insertions, 31 deletions
diff --git a/Eigen/src/Core/GeneralProduct.h b/Eigen/src/Core/GeneralProduct.h index 675f6ee8d..f823ff251 100644 --- a/Eigen/src/Core/GeneralProduct.h +++ b/Eigen/src/Core/GeneralProduct.h @@ -82,7 +82,8 @@ private: public: enum { - value = selector::ret + value = selector::ret, + ret = selector::ret }; #ifdef EIGEN_DEBUG_PRODUCT static void debug() @@ -98,31 +99,31 @@ public: #endif }; -template<typename Lhs, typename Rhs> struct product_tag -{ -private: - - typedef typename remove_all<Lhs>::type _Lhs; - typedef typename remove_all<Rhs>::type _Rhs; - enum { - Rows = _Lhs::RowsAtCompileTime, - Cols = _Rhs::ColsAtCompileTime, - Depth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::ColsAtCompileTime, _Rhs::RowsAtCompileTime) - }; - - enum { - rows_select = Rows==1 ? int(Rows) : int(Large), - cols_select = Cols==1 ? int(Cols) : int(Large), - depth_select = Depth==1 ? int(Depth) : int(Large) - }; - typedef product_type_selector<rows_select, cols_select, depth_select> selector; - -public: - enum { - ret = selector::ret - }; - -}; +// template<typename Lhs, typename Rhs> struct product_tag +// { +// private: +// +// typedef typename remove_all<Lhs>::type _Lhs; +// typedef typename remove_all<Rhs>::type _Rhs; +// enum { +// Rows = _Lhs::RowsAtCompileTime, +// Cols = _Rhs::ColsAtCompileTime, +// Depth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::ColsAtCompileTime, _Rhs::RowsAtCompileTime) +// }; +// +// enum { +// rows_select = Rows==1 ? int(Rows) : int(Large), +// cols_select = Cols==1 ? int(Cols) : int(Large), +// depth_select = Depth==1 ? int(Depth) : int(Large) +// }; +// typedef product_type_selector<rows_select, cols_select, depth_select> selector; +// +// public: +// enum { +// ret = selector::ret +// }; +// +// }; /* The following allows to select the kind of product at compile time * based on the three dimensions of the product. diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index 79d09fbb6..d64fbae35 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -88,7 +88,7 @@ class Product : public ProductImpl<_Lhs,_Rhs,Option, namespace internal { -template<typename Lhs, typename Rhs, int Option, int ProductTab = internal::product_tag<Lhs,Rhs>::ret> +template<typename Lhs, typename Rhs, int Option, int ProductTag = internal::product_type<Lhs,Rhs>::ret> class dense_product_base : public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type {}; diff --git a/Eigen/src/Core/ProductEvaluators.h b/Eigen/src/Core/ProductEvaluators.h index f0eb57d67..46048882b 100644 --- a/Eigen/src/Core/ProductEvaluators.h +++ b/Eigen/src/Core/ProductEvaluators.h @@ -19,7 +19,7 @@ namespace internal { // Like more general binary expressions, products need their own evaluator: template< typename T, - int ProductTag = internal::product_tag<typename T::Lhs,typename T::Rhs>::ret, + int ProductTag = internal::product_type<typename T::Lhs,typename T::Rhs>::ret, typename LhsShape = typename evaluator_traits<typename T::Lhs>::Shape, typename RhsShape = typename evaluator_traits<typename T::Rhs>::Shape, typename LhsScalar = typename T::Lhs::Scalar, @@ -38,7 +38,43 @@ struct evaluator<Product<Lhs, Rhs, Options> > evaluator(const XprType& xpr) : Base(xpr) {} }; + +// Catch scalar * ( A * B ) and transform it to (A*scalar) * B +// TODO we should apply that rule if that's really helpful +template<typename Lhs, typename Rhs, typename Scalar> +struct evaluator<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const Product<Lhs, Rhs, DefaultProduct> > > + : public evaluator<Product<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,const Lhs>, Rhs, DefaultProduct> > +{ + typedef CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const Product<Lhs, Rhs, DefaultProduct> > XprType; + typedef evaluator<Product<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,const Lhs>, Rhs, DefaultProduct> > Base; + + typedef evaluator type; + typedef evaluator nestedType; + + evaluator(const XprType& xpr) + : Base(xpr.functor().m_other * xpr.nestedExpression().lhs() * xpr.nestedExpression().rhs()) + {} +}; + + +template<typename Lhs, typename Rhs, int DiagIndex> +struct evaluator<Diagonal<const Product<Lhs, Rhs, DefaultProduct>, DiagIndex> > + : public evaluator<Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex> > +{ + typedef Diagonal<const Product<Lhs, Rhs, DefaultProduct>, DiagIndex> XprType; + typedef evaluator<Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex> > Base; + typedef evaluator type; + typedef evaluator nestedType; +// + evaluator(const XprType& xpr) + : Base(Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex>( + Product<Lhs, Rhs, LazyProduct>(xpr.nestedExpression().lhs(), xpr.nestedExpression().rhs()), + xpr.index() )) + {} +}; + + // Helper class to perform a matrix product with the destination at hand. // Depending on the sizes of the factors, there are different evaluation strategies // as controlled by internal::product_type. @@ -108,6 +144,23 @@ struct Assignment<DstXprType, Product<Lhs,Rhs,DefaultProduct>, internal::sub_ass } }; + +// Dense ?= scalar * Product +// TODO we should apply that rule if that's really helpful +// for instance, this is not good for inner products +template< typename DstXprType, typename Lhs, typename Rhs, typename AssignFunc, typename Scalar, typename ScalarBis> +struct Assignment<DstXprType, CwiseUnaryOp<internal::scalar_multiple_op<ScalarBis>, + const Product<Lhs,Rhs,DefaultProduct> >, AssignFunc, Dense2Dense, Scalar> +{ + typedef CwiseUnaryOp<internal::scalar_multiple_op<ScalarBis>, + const Product<Lhs,Rhs,DefaultProduct> > SrcXprType; + static void run(DstXprType &dst, const SrcXprType &src, const AssignFunc& func) + { + call_assignment(dst.noalias(), (src.functor().m_other * src.nestedExpression().lhs()) * src.nestedExpression().rhs(), func); + } +}; + + template<typename Lhs, typename Rhs> struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,InnerProduct> { @@ -255,9 +308,9 @@ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,CoeffBasedProductMode> }; // This specialization enforces the use of a coefficient-based evaluation strategy -template<typename Lhs, typename Rhs> -struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,LazyCoeffBasedProductMode> - : generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,CoeffBasedProductMode> {}; +// template<typename Lhs, typename Rhs> +// struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,LazyCoeffBasedProductMode> +// : generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,CoeffBasedProductMode> {}; // Case 2: Evaluate coeff by coeff // @@ -347,6 +400,17 @@ protected: Index m_innerDim; }; +template<typename Lhs, typename Rhs> +struct product_evaluator<Product<Lhs, Rhs, DefaultProduct>, LazyCoeffBasedProductMode, DenseShape, DenseShape, typename Lhs::Scalar, typename Rhs::Scalar > + : product_evaluator<Product<Lhs, Rhs, LazyProduct>, CoeffBasedProductMode, DenseShape, DenseShape, typename Lhs::Scalar, typename Rhs::Scalar > +{ + typedef Product<Lhs, Rhs, DefaultProduct> XprType; + typedef Product<Lhs, Rhs, LazyProduct> BaseProduct; + typedef product_evaluator<BaseProduct, CoeffBasedProductMode, DenseShape, DenseShape, typename Lhs::Scalar, typename Rhs::Scalar > Base; + product_evaluator(const XprType& xpr) + : Base(BaseProduct(xpr.lhs(),xpr.rhs())) + {} +}; /*************************************************************************** * Normal product .coeff() implementation (with meta-unrolling) diff --git a/Eigen/src/Core/SelfAdjointView.h b/Eigen/src/Core/SelfAdjointView.h index 079b987f8..a5c6d5ceb 100644 --- a/Eigen/src/Core/SelfAdjointView.h +++ b/Eigen/src/Core/SelfAdjointView.h @@ -336,6 +336,7 @@ struct triangular_assignment_selector<Derived1, Derived2, SelfAdjoint|Lower, Dyn } }; +#ifdef EIGEN_ENABLE_EVALUATORS // TODO currently a selfadjoint expression has the form SelfAdjointView<.,.> // in the future selfadjoint-ness should be defined by the expression traits // such that Transpose<SelfAdjointView<.,.> > is valid. (currently TriangularBase::transpose() is overloaded to make it work) @@ -347,6 +348,7 @@ struct evaluator_traits<SelfAdjointView<MatrixType,Mode> > static const int AssumeAliasing = 0; }; +#endif // EIGEN_ENABLE_EVALUATORS } // end namespace internal |