diff options
author | 2008-12-21 20:55:46 +0000 | |
---|---|---|
committer | 2008-12-21 20:55:46 +0000 | |
commit | f5a05e7ed159d771545767c430d12263e205ec87 (patch) | |
tree | 15bd4c04bdabfcb7efe5c60787a60b6e77f42587 /Eigen/src | |
parent | 9e00d945439d801d3f4e33ed1ce57545e3310723 (diff) |
unfuck v.cwise()*w where v is real and w is complex
Diffstat (limited to 'Eigen/src')
-rw-r--r-- | Eigen/src/Core/Cwise.h | 14 | ||||
-rw-r--r-- | Eigen/src/Core/CwiseBinaryOp.h | 9 | ||||
-rw-r--r-- | Eigen/src/Core/Functors.h | 6 | ||||
-rw-r--r-- | Eigen/src/Core/util/Meta.h | 36 |
4 files changed, 58 insertions, 7 deletions
diff --git a/Eigen/src/Core/Cwise.h b/Eigen/src/Core/Cwise.h index 7c935a9ac..a04fff3db 100644 --- a/Eigen/src/Core/Cwise.h +++ b/Eigen/src/Core/Cwise.h @@ -31,6 +31,18 @@ #define EIGEN_CWISE_BINOP_RETURN_TYPE(OP) \ CwiseBinaryOp<OP<typename ei_traits<ExpressionType>::Scalar>, ExpressionType, OtherDerived> +#define EIGEN_CWISE_PRODUCT_RETURN_TYPE \ + CwiseBinaryOp< \ + ei_scalar_product_op< \ + typename ei_scalar_product_traits< \ + typename ei_traits<ExpressionType>::Scalar, \ + typename ei_traits<OtherDerived>::Scalar \ + >::ReturnType \ + >, \ + ExpressionType, \ + OtherDerived \ + > + /** \internal * convenient macro to defined the return type of a cwise unary operation */ #define EIGEN_CWISE_UNOP_RETURN_TYPE(OP) \ @@ -74,7 +86,7 @@ template<typename ExpressionType> class Cwise inline const ExpressionType& _expression() const { return m_matrix; } template<typename OtherDerived> - const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_product_op) + const EIGEN_CWISE_PRODUCT_RETURN_TYPE operator*(const MatrixBase<OtherDerived> &other) const; template<typename OtherDerived> diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h index 834a9b820..87d7123dd 100644 --- a/Eigen/src/Core/CwiseBinaryOp.h +++ b/Eigen/src/Core/CwiseBinaryOp.h @@ -54,7 +54,6 @@ struct ei_traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > typename Rhs::Scalar ) >::type Scalar; - typedef typename Lhs::Nested LhsNested; typedef typename Rhs::Nested RhsNested; typedef typename ei_unref<LhsNested>::type _LhsNested; @@ -99,7 +98,9 @@ class CwiseBinaryOp : ei_no_assignment_operator, // It is tempting to always allow mixing different types but remember that this is often impossible in the vectorized paths. // 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. - EIGEN_STATIC_ASSERT((ei_is_same_type<typename Lhs::Scalar, typename Rhs::Scalar>::ret), + EIGEN_STATIC_ASSERT((ei_functor_allows_mixing_real_and_complex<BinaryOp>::ret + ? int(ei_is_same_type<typename Lhs::RealScalar, typename Rhs::RealScalar>::ret) + : int(ei_is_same_type<typename Lhs::Scalar, typename Rhs::Scalar>::ret)), YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) // require the sizes to match EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs) @@ -202,10 +203,10 @@ MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other) */ template<typename ExpressionType> template<typename OtherDerived> -EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_product_op) +EIGEN_STRONG_INLINE const EIGEN_CWISE_PRODUCT_RETURN_TYPE Cwise<ExpressionType>::operator*(const MatrixBase<OtherDerived> &other) const { - return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_product_op)(_expression(), other.derived()); + return EIGEN_CWISE_PRODUCT_RETURN_TYPE(_expression(), other.derived()); } /** \returns an expression of the coefficient-wise quotient of *this and \a other diff --git a/Eigen/src/Core/Functors.h b/Eigen/src/Core/Functors.h index 6784ea946..347f1b252 100644 --- a/Eigen/src/Core/Functors.h +++ b/Eigen/src/Core/Functors.h @@ -348,11 +348,15 @@ template<typename Scalar> struct ei_functor_traits<ei_scalar_identity_op<Scalar> > { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; }; -// FIXME quick hack: // all functors allow linear access, except ei_scalar_identity_op. So we fix here a quick meta // to indicate whether a functor allows linear access, just always answering 'yes' except for // ei_scalar_identity_op. template<typename Functor> struct ei_functor_has_linear_access { enum { ret = 1 }; }; template<typename Scalar> struct ei_functor_has_linear_access<ei_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>. +template<typename Functor> struct ei_functor_allows_mixing_real_and_complex { enum { ret = 0 }; }; +template<typename Scalar> struct ei_functor_allows_mixing_real_and_complex<ei_scalar_product_op<Scalar> > { enum { ret = 1 }; }; + #endif // EIGEN_FUNCTORS_H diff --git a/Eigen/src/Core/util/Meta.h b/Eigen/src/Core/util/Meta.h index 97535caa1..c65c52ef4 100644 --- a/Eigen/src/Core/util/Meta.h +++ b/Eigen/src/Core/util/Meta.h @@ -69,7 +69,7 @@ template<typename T> struct ei_cleantype<T*> { typedef typename ei_cleant * * It supports both the current STL mechanism (using the result_type member) as well as * upcoming next STL generation (using a templated result member). - * If none of these members is provided, then the type of the first argument is returned. + * If none of these members is provided, then the type of the first argument is returned. FIXME, that behavior is a pretty bad hack. */ template<typename T> struct ei_result_of {}; @@ -146,4 +146,38 @@ class ei_meta_sqrt template<int Y, int InfX, int SupX> class ei_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 ei_scalar_product_traits +{ + // dummy general case where T and U aren't compatible -- not allowed anyway but we catch it elsewhere + //enum { Cost = NumTraits<T>::MulCost }; + typedef T ReturnType; +}; + +template<typename T> struct ei_scalar_product_traits<T,T> +{ + //enum { Cost = NumTraits<T>::MulCost }; + typedef T ReturnType; +}; + +template<typename T> struct ei_scalar_product_traits<T,std::complex<T> > +{ + //enum { Cost = 2*NumTraits<T>::MulCost }; + typedef std::complex<T> ReturnType; +}; + +template<typename T> struct ei_scalar_product_traits<std::complex<T>, T> +{ + //enum { Cost = 2*NumTraits<T>::MulCost }; + typedef std::complex<T> ReturnType; +}; + +// FIXME quick workaround around current limitation of ei_result_of +template<typename Scalar, typename ArgType0, typename ArgType1> +struct ei_result_of<ei_scalar_product_op<Scalar>(ArgType0,ArgType1)> { +typedef typename ei_scalar_product_traits<typename ei_cleantype<ArgType0>::type, typename ei_cleantype<ArgType1>::type>::ReturnType type; +}; + + + #endif // EIGEN_META_H |