diff options
author | Gael Guennebaud <g.gael@free.fr> | 2013-03-20 21:19:16 +0100 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2013-03-20 21:19:16 +0100 |
commit | c519be2bac43aa8ccaa8d568c3bfafd311286a9f (patch) | |
tree | 8711d8dd2c05ce3f8d31d1e409b917aa639c13e0 /Eigen | |
parent | f350f34560d1cc67a8c220d973b003226ff58892 (diff) |
Allow multiplication like binary operators to be applied on type couples supported by scalar_product_traits
Diffstat (limited to 'Eigen')
-rw-r--r-- | Eigen/src/Core/CwiseBinaryOp.h | 4 | ||||
-rw-r--r-- | Eigen/src/Core/Functors.h | 13 | ||||
-rw-r--r-- | Eigen/src/Core/products/CoeffBasedProduct.h | 2 | ||||
-rw-r--r-- | Eigen/src/Core/util/Meta.h | 20 |
4 files changed, 26 insertions, 13 deletions
diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h index 686c2afa3..586f77aaf 100644 --- a/Eigen/src/Core/CwiseBinaryOp.h +++ b/Eigen/src/Core/CwiseBinaryOp.h @@ -94,8 +94,8 @@ struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > // So allowing mixing different types gives very unexpected errors when enabling vectorization, when the user tries to // add together a float matrix and a double matrix. #define EIGEN_CHECK_BINARY_COMPATIBILIY(BINOP,LHS,RHS) \ - EIGEN_STATIC_ASSERT((internal::functor_allows_mixing_real_and_complex<BINOP>::ret \ - ? int(internal::is_same<typename NumTraits<LHS>::Real, typename NumTraits<RHS>::Real>::value) \ + EIGEN_STATIC_ASSERT((internal::functor_is_product_like<BINOP>::ret \ + ? int(internal::scalar_product_traits<LHS, RHS>::Defined) \ : int(internal::is_same<LHS, RHS>::value)), \ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) diff --git a/Eigen/src/Core/Functors.h b/Eigen/src/Core/Functors.h index 147df3a50..0ab767f30 100644 --- a/Eigen/src/Core/Functors.h +++ b/Eigen/src/Core/Functors.h @@ -648,13 +648,14 @@ template <typename Scalar, bool RandomAccess> struct linspaced_op template<typename Functor> struct functor_has_linear_access { enum { ret = 1 }; }; template<typename Scalar> struct functor_has_linear_access<scalar_identity_op<Scalar> > { enum { ret = 0 }; }; -// in CwiseBinaryOp, we require the Lhs and Rhs to have the same scalar type, except for multiplication -// where we only require them to have the same _real_ scalar type so one may multiply, say, float by complex<float>. +// In Eigen, any binary op (Product, CwiseBinaryOp) require the Lhs and Rhs to have the same scalar type, except for multiplication +// where the mixing of different types is handled by scalar_product_traits +// In particular, real * complex<real> is allowed. // FIXME move this to functor_traits adding a functor_default -template<typename Functor> struct functor_allows_mixing_real_and_complex { enum { ret = 0 }; }; -template<typename LhsScalar,typename RhsScalar> struct functor_allows_mixing_real_and_complex<scalar_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; }; -template<typename LhsScalar,typename RhsScalar> struct functor_allows_mixing_real_and_complex<scalar_conj_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; }; -template<typename LhsScalar,typename RhsScalar> struct functor_allows_mixing_real_and_complex<scalar_quotient_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; }; +template<typename Functor> struct functor_is_product_like { enum { ret = 0 }; }; +template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; }; +template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_conj_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; }; +template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_quotient_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; }; /** \internal diff --git a/Eigen/src/Core/products/CoeffBasedProduct.h b/Eigen/src/Core/products/CoeffBasedProduct.h index 403d25fa9..c06a0df1c 100644 --- a/Eigen/src/Core/products/CoeffBasedProduct.h +++ b/Eigen/src/Core/products/CoeffBasedProduct.h @@ -150,7 +150,7 @@ class CoeffBasedProduct { // we don't allow taking products of matrices of different real types, as that wouldn't be vectorizable. // We still allow to mix T and complex<T>. - EIGEN_STATIC_ASSERT((internal::is_same<typename Lhs::RealScalar, typename Rhs::RealScalar>::value), + EIGEN_STATIC_ASSERT((internal::scalar_product_traits<typename Lhs::RealScalar, typename Rhs::RealScalar>::Defined), YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) eigen_assert(lhs.cols() == rhs.rows() && "invalid matrix product" diff --git a/Eigen/src/Core/util/Meta.h b/Eigen/src/Core/util/Meta.h index a5f31164d..71d587108 100644 --- a/Eigen/src/Core/util/Meta.h +++ b/Eigen/src/Core/util/Meta.h @@ -186,23 +186,35 @@ template<int Y, int InfX, int SupX> class meta_sqrt<Y, InfX, SupX, true> { public: enum { ret = (SupX*SupX <= Y) ? SupX : InfX }; }; /** \internal determines whether the product of two numeric types is allowed and what the return type is */ -template<typename T, typename U> struct scalar_product_traits; +template<typename T, typename U> struct scalar_product_traits +{ + enum { Defined = 0 }; +}; template<typename T> struct scalar_product_traits<T,T> { - //enum { Cost = NumTraits<T>::MulCost }; + enum { + // Cost = NumTraits<T>::MulCost, + Defined = 1 + }; typedef T ReturnType; }; template<typename T> struct scalar_product_traits<T,std::complex<T> > { - //enum { Cost = 2*NumTraits<T>::MulCost }; + enum { + // Cost = 2*NumTraits<T>::MulCost, + Defined = 1 + }; typedef std::complex<T> ReturnType; }; template<typename T> struct scalar_product_traits<std::complex<T>, T> { - //enum { Cost = 2*NumTraits<T>::MulCost }; + enum { + // Cost = 2*NumTraits<T>::MulCost, + Defined = 1 + }; typedef std::complex<T> ReturnType; }; |