diff options
author | Gael Guennebaud <g.gael@free.fr> | 2013-12-03 17:17:53 +0100 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2013-12-03 17:17:53 +0100 |
commit | 6c5e915e9a6c79550e7e2db2b53648f163a1411d (patch) | |
tree | aab5c0a07616fcd028d2839f402edcadc0e53d81 /Eigen/src/Core | |
parent | f0b82c3ab972a1eafd6aa4f08f4eaffa0d6f1e55 (diff) |
Enable use of evaluators for noalias and lazyProduct, add conversion to scalar for inner products
Diffstat (limited to 'Eigen/src/Core')
-rw-r--r-- | Eigen/src/Core/CoreEvaluators.h | 4 | ||||
-rw-r--r-- | Eigen/src/Core/GeneralProduct.h | 33 | ||||
-rw-r--r-- | Eigen/src/Core/MatrixBase.h | 4 | ||||
-rw-r--r-- | Eigen/src/Core/NoAlias.h | 29 | ||||
-rw-r--r-- | Eigen/src/Core/Product.h | 6 | ||||
-rw-r--r-- | Eigen/src/Core/ProductEvaluators.h | 32 | ||||
-rw-r--r-- | Eigen/src/Core/products/CoeffBasedProduct.h | 6 | ||||
-rw-r--r-- | Eigen/src/Core/util/ForwardDeclarations.h | 6 | ||||
-rw-r--r-- | Eigen/src/Core/util/StaticAssert.h | 3 |
9 files changed, 101 insertions, 22 deletions
diff --git a/Eigen/src/Core/CoreEvaluators.h b/Eigen/src/Core/CoreEvaluators.h index 961b56e55..faf5aedb5 100644 --- a/Eigen/src/Core/CoreEvaluators.h +++ b/Eigen/src/Core/CoreEvaluators.h @@ -53,11 +53,7 @@ struct storage_kind_to_shape<Sparse> { }; */ -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, typename LhsKind = typename evaluator_traits<typename T::Lhs>::Kind, diff --git a/Eigen/src/Core/GeneralProduct.h b/Eigen/src/Core/GeneralProduct.h index c9ab63782..675f6ee8d 100644 --- a/Eigen/src/Core/GeneralProduct.h +++ b/Eigen/src/Core/GeneralProduct.h @@ -623,7 +623,7 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const return Product<Derived, OtherDerived>(derived(), other.derived()); } -#else +#else // EIGEN_TEST_EVALUATORS template<typename Derived> template<typename OtherDerived> inline const typename ProductReturnType<Derived, OtherDerived>::Type @@ -653,9 +653,10 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const #endif return typename ProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); } -#endif +#endif // EIGEN_TEST_EVALUATORS + +#endif // __CUDACC__ -#endif /** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation. * * The returned product will behave like any other expressions: the coefficients of the product will be @@ -667,6 +668,31 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const * * \sa operator*(const MatrixBase&) */ +#ifdef EIGEN_TEST_EVALUATORS +template<typename Derived> +template<typename OtherDerived> +const Product<Derived,OtherDerived,LazyProduct> +MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const +{ + enum { + ProductIsValid = Derived::ColsAtCompileTime==Dynamic + || OtherDerived::RowsAtCompileTime==Dynamic + || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime), + AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime, + SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived) + }; + // note to the lost user: + // * for a dot product use: v1.dot(v2) + // * for a coeff-wise product use: v1.cwiseProduct(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) + + return Product<Derived,OtherDerived,LazyProduct>(derived(), other.derived()); +} +#else // EIGEN_TEST_EVALUATORS template<typename Derived> template<typename OtherDerived> const typename LazyProductReturnType<Derived,OtherDerived>::Type @@ -690,6 +716,7 @@ MatrixBase<Derived>::lazyProduct(const MatrixBase<OtherDerived> &other) const return typename LazyProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); } +#endif // EIGEN_TEST_EVALUATORS } // end namespace Eigen diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 61798317e..37e7408a4 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -199,7 +199,11 @@ template<typename Derived> class MatrixBase template<typename OtherDerived> EIGEN_DEVICE_FUNC +#ifdef EIGEN_TEST_EVALUATORS + const Product<Derived,OtherDerived,LazyProduct> +#else const typename LazyProductReturnType<Derived,OtherDerived>::Type +#endif lazyProduct(const MatrixBase<OtherDerived> &other) const; template<typename OtherDerived> diff --git a/Eigen/src/Core/NoAlias.h b/Eigen/src/Core/NoAlias.h index 65117a806..6ac525336 100644 --- a/Eigen/src/Core/NoAlias.h +++ b/Eigen/src/Core/NoAlias.h @@ -34,6 +34,33 @@ class NoAlias typedef typename ExpressionType::Scalar Scalar; NoAlias(ExpressionType& expression) : m_expression(expression) {} + +#ifdef EIGEN_TEST_EVALUATORS + template<typename OtherDerived> + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other) + { + call_assignment(*this, other.derived(), internal::assign_op<Scalar>()); + return m_expression; + } + + template<typename OtherDerived> + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other) + { + call_assignment(*this, other.derived(), internal::add_assign_op<Scalar>()); + return m_expression; + } + + template<typename OtherDerived> + EIGEN_DEVICE_FUNC + EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase<OtherDerived>& other) + { + call_assignment(*this, other.derived(), internal::sub_assign_op<Scalar>()); + return m_expression; + } + +#else /** Behaves like MatrixBase::lazyAssign(other) * \sa MatrixBase::lazyAssign() */ @@ -93,6 +120,8 @@ class NoAlias { return m_expression = func; } #endif +#endif + EIGEN_DEVICE_FUNC ExpressionType& expression() const { diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index 3b8fd7d9a..b37fd2ff7 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -79,6 +79,12 @@ class Product : public ProductImpl<_Lhs,_Rhs,Option, const LhsNestedCleaned& lhs() const { return m_lhs; } const RhsNestedCleaned& rhs() const { return m_rhs; } + + /** Convertion to scalar for inner-products */ + operator const Scalar() const { + EIGEN_STATIC_ASSERT(SizeAtCompileTime==1, IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY); + return typename internal::evaluator<Product>::type(*this).coeff(0,0); + } protected: diff --git a/Eigen/src/Core/ProductEvaluators.h b/Eigen/src/Core/ProductEvaluators.h index d0dba1644..5dd480cad 100644 --- a/Eigen/src/Core/ProductEvaluators.h +++ b/Eigen/src/Core/ProductEvaluators.h @@ -209,12 +209,12 @@ struct dense_product_impl<Lhs,Rhs,GemmProduct> : dense_product_impl_base<Lhs,Rhs { typedef typename Product<Lhs,Rhs>::Scalar Scalar; - template<typename Dest> - static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) - { - // TODO bypass GeneralProduct class - GeneralProduct<Lhs, Rhs, GemmProduct>(lhs,rhs).scaleAndAddTo(dst, alpha); - } +// template<typename Dest> +// static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) +// { +// // TODO bypass GeneralProduct class +// GeneralProduct<Lhs, Rhs, GemmProduct>(lhs,rhs).scaleAndAddTo(dst, alpha); +// } }; template<typename Lhs, typename Rhs> @@ -225,22 +225,28 @@ struct dense_product_impl<Lhs,Rhs,CoeffBasedProductMode> template<typename Dst> static inline void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) { - // TODO: use the following instead of calling call_assignment + // TODO: use the following instead of calling call_assignment, same for the other methods // dst = lazyprod(lhs,rhs); call_assignment(dst, lazyprod(lhs,rhs), internal::assign_op<Scalar>()); } template<typename Dst> static inline void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) - { dst += lazyprod(lhs,rhs); } + { + // dst += lazyprod(lhs,rhs); + call_assignment(dst, lazyprod(lhs,rhs), internal::add_assign_op<Scalar>()); + } template<typename Dst> static inline void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) - { dst -= lazyprod(lhs,rhs); } + { + // dst -= lazyprod(lhs,rhs); + call_assignment(dst, lazyprod(lhs,rhs), internal::sub_assign_op<Scalar>()); + } - template<typename Dst> - static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) - { dst += alpha * lazyprod(lhs,rhs); } +// template<typename Dst> +// static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) +// { dst += alpha * lazyprod(lhs,rhs); } }; template<typename Lhs, typename Rhs> @@ -286,7 +292,7 @@ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape, CoeffReadCost = traits<CoeffBasedProductType>::CoeffReadCost, Unroll = CoeffReadCost != Dynamic && CoeffReadCost <= EIGEN_UNROLLING_LIMIT, CanVectorizeInner = traits<CoeffBasedProductType>::CanVectorizeInner, - Flags = CoeffBasedProductType::Flags + Flags = traits<CoeffBasedProductType>::Flags }; typedef typename evaluator<Lhs>::type LhsEtorType; diff --git a/Eigen/src/Core/products/CoeffBasedProduct.h b/Eigen/src/Core/products/CoeffBasedProduct.h index 637513132..c987a30b0 100644 --- a/Eigen/src/Core/products/CoeffBasedProduct.h +++ b/Eigen/src/Core/products/CoeffBasedProduct.h @@ -14,7 +14,7 @@ namespace Eigen { namespace internal { - + /********************************************************************************* * Coefficient based product implementation. * It is designed for the following use cases: @@ -110,6 +110,8 @@ struct traits<CoeffBasedProduct<LhsNested,RhsNested,NestingFlags> > } // end namespace internal +#ifndef EIGEN_TEST_EVALUATORS + template<typename LhsNested, typename RhsNested, int NestingFlags> class CoeffBasedProduct : internal::no_assignment_operator, @@ -447,6 +449,8 @@ struct product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, Packet, LoadMode> } // end namespace internal +#endif // EIGEN_TEST_EVALUATORS + } // end namespace Eigen #endif // EIGEN_COEFFBASED_PRODUCT_H diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index 776eac587..3bc151229 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -36,6 +36,12 @@ 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; + } // end namespace internal template<typename T> struct NumTraits; diff --git a/Eigen/src/Core/util/StaticAssert.h b/Eigen/src/Core/util/StaticAssert.h index 8872c5b64..b9b1ee02a 100644 --- a/Eigen/src/Core/util/StaticAssert.h +++ b/Eigen/src/Core/util/StaticAssert.h @@ -90,7 +90,8 @@ YOU_PASSED_A_COLUMN_VECTOR_BUT_A_ROW_VECTOR_WAS_EXPECTED, THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE, THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH, - OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG + OBJECT_ALLOCATED_ON_STACK_IS_TOO_BIG, + IMPLICIT_CONVERSION_TO_SCALAR_IS_FOR_INNER_PRODUCT_ONLY }; }; |