mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-04-12 19:20:36 +08:00
unfuck v.cwise()*w where v is real and w is complex
This commit is contained in:
parent
9e00d94543
commit
f5a05e7ed1
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user