Big 279: enable mixing types for comparisons, min, and max.

This commit is contained in:
Gael Guennebaud 2016-06-10 15:05:43 +02:00
parent 2c462f4201
commit 2e238bafb6
8 changed files with 113 additions and 88 deletions

View File

@ -425,7 +425,7 @@ template<typename Derived>
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
DenseBase<Derived>::minCoeff() const DenseBase<Derived>::minCoeff() const
{ {
return derived().redux(Eigen::internal::scalar_min_op<Scalar>()); return derived().redux(Eigen::internal::scalar_min_op<Scalar,Scalar>());
} }
/** \returns the maximum of all coefficients of \c *this. /** \returns the maximum of all coefficients of \c *this.
@ -435,7 +435,7 @@ template<typename Derived>
EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar EIGEN_STRONG_INLINE typename internal::traits<Derived>::Scalar
DenseBase<Derived>::maxCoeff() const DenseBase<Derived>::maxCoeff() const
{ {
return derived().redux(Eigen::internal::scalar_max_op<Scalar>()); return derived().redux(Eigen::internal::scalar_max_op<Scalar,Scalar>());
} }
/** \returns the sum of all coefficients of \c *this /** \returns the sum of all coefficients of \c *this

View File

@ -111,21 +111,22 @@ struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > {
* *
* \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff() * \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff()
*/ */
template<typename Scalar> struct scalar_min_op { template<typename LhsScalar,typename RhsScalar> struct scalar_min_op {
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_min_op>::ReturnType result_type;
EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op) EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return numext::mini(a, b); } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return numext::mini(a, b); }
template<typename Packet> template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
{ return internal::pmin(a,b); } { return internal::pmin(a,b); }
template<typename Packet> template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const
{ return internal::predux_min(a); } { return internal::predux_min(a); }
}; };
template<typename Scalar> template<typename LhsScalar,typename RhsScalar>
struct functor_traits<scalar_min_op<Scalar> > { struct functor_traits<scalar_min_op<LhsScalar,RhsScalar> > {
enum { enum {
Cost = NumTraits<Scalar>::AddCost, Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
PacketAccess = packet_traits<Scalar>::HasMin PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMin
}; };
}; };
@ -134,21 +135,22 @@ struct functor_traits<scalar_min_op<Scalar> > {
* *
* \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff() * \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff()
*/ */
template<typename Scalar> struct scalar_max_op { template<typename LhsScalar,typename RhsScalar> struct scalar_max_op {
typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_max_op>::ReturnType result_type;
EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op) EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return numext::maxi(a, b); } EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return numext::maxi(a, b); }
template<typename Packet> template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
{ return internal::pmax(a,b); } { return internal::pmax(a,b); }
template<typename Packet> template<typename Packet>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const
{ return internal::predux_max(a); } { return internal::predux_max(a); }
}; };
template<typename Scalar> template<typename LhsScalar,typename RhsScalar>
struct functor_traits<scalar_max_op<Scalar> > { struct functor_traits<scalar_max_op<LhsScalar,RhsScalar> > {
enum { enum {
Cost = NumTraits<Scalar>::AddCost, Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
PacketAccess = packet_traits<Scalar>::HasMax PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMax
}; };
}; };
@ -156,56 +158,56 @@ struct functor_traits<scalar_max_op<Scalar> > {
* \brief Template functors for comparison of two scalars * \brief Template functors for comparison of two scalars
* \todo Implement packet-comparisons * \todo Implement packet-comparisons
*/ */
template<typename Scalar, ComparisonName cmp> struct scalar_cmp_op; template<typename LhsScalar, typename RhsScalar, ComparisonName cmp> struct scalar_cmp_op;
template<typename Scalar, ComparisonName cmp> template<typename LhsScalar, typename RhsScalar, ComparisonName cmp>
struct functor_traits<scalar_cmp_op<Scalar, cmp> > { struct functor_traits<scalar_cmp_op<LhsScalar,RhsScalar, cmp> > {
enum { enum {
Cost = NumTraits<Scalar>::AddCost, Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
PacketAccess = false PacketAccess = false
}; };
}; };
template<ComparisonName Cmp, typename Scalar> template<ComparisonName Cmp, typename LhsScalar, typename RhsScalar>
struct result_of<scalar_cmp_op<Scalar, Cmp>(Scalar,Scalar)> { struct result_of<scalar_cmp_op<LhsScalar, RhsScalar, Cmp>(LhsScalar,RhsScalar)> {
typedef bool type; typedef bool type;
}; };
template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_EQ> { template<typename LhsScalar, typename RhsScalar> struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_EQ> {
typedef bool result_type; typedef bool result_type;
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a==b;} EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a==b;}
}; };
template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_LT> { template<typename LhsScalar, typename RhsScalar> struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_LT> {
typedef bool result_type; typedef bool result_type;
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a<b;} EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a<b;}
}; };
template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_LE> { template<typename LhsScalar, typename RhsScalar> struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_LE> {
typedef bool result_type; typedef bool result_type;
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a<=b;} EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a<=b;}
}; };
template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_GT> { template<typename LhsScalar, typename RhsScalar> struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_GT> {
typedef bool result_type; typedef bool result_type;
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a>b;} EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a>b;}
}; };
template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_GE> { template<typename LhsScalar, typename RhsScalar> struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_GE> {
typedef bool result_type; typedef bool result_type;
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a>=b;} EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a>=b;}
}; };
template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_UNORD> { template<typename LhsScalar, typename RhsScalar> struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_UNORD> {
typedef bool result_type; typedef bool result_type;
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return !(a<=b || b<=a);} EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return !(a<=b || b<=a);}
}; };
template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_NEQ> { template<typename LhsScalar, typename RhsScalar> struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_NEQ> {
typedef bool result_type; typedef bool result_type;
EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a!=b;} EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a!=b;}
}; };
@ -214,7 +216,7 @@ template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_NEQ> {
* *
* \sa MatrixBase::stableNorm(), class Redux * \sa MatrixBase::stableNorm(), class Redux
*/ */
template<typename Scalar> struct scalar_hypot_op { template<typename Scalar> struct scalar_hypot_op<Scalar,Scalar> {
EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op) EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op)
// typedef typename NumTraits<Scalar>::Real result_type; // typedef typename NumTraits<Scalar>::Real result_type;
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const
@ -235,7 +237,7 @@ template<typename Scalar> struct scalar_hypot_op {
} }
}; };
template<typename Scalar> template<typename Scalar>
struct functor_traits<scalar_hypot_op<Scalar> > { struct functor_traits<scalar_hypot_op<Scalar,Scalar> > {
enum enum
{ {
Cost = 3 * NumTraits<Scalar>::AddCost + Cost = 3 * NumTraits<Scalar>::AddCost +

View File

@ -179,6 +179,8 @@ template<typename LhsScalar, typename RhsScalar, bool ConjLhs=false, bool ConjRh
template<typename LhsScalar,typename RhsScalar> struct scalar_sum_op; template<typename LhsScalar,typename RhsScalar> struct scalar_sum_op;
template<typename LhsScalar,typename RhsScalar> struct scalar_difference_op; template<typename LhsScalar,typename RhsScalar> struct scalar_difference_op;
template<typename LhsScalar,typename RhsScalar> struct scalar_conj_product_op; template<typename LhsScalar,typename RhsScalar> struct scalar_conj_product_op;
template<typename LhsScalar,typename RhsScalar> struct scalar_min_op;
template<typename LhsScalar,typename RhsScalar> struct scalar_max_op;
template<typename Scalar> struct scalar_opposite_op; template<typename Scalar> struct scalar_opposite_op;
template<typename Scalar> struct scalar_conjugate_op; template<typename Scalar> struct scalar_conjugate_op;
template<typename Scalar> struct scalar_real_op; template<typename Scalar> struct scalar_real_op;
@ -201,8 +203,6 @@ template<typename Scalar> struct scalar_cube_op;
template<typename Scalar, typename NewType> struct scalar_cast_op; template<typename Scalar, typename NewType> struct scalar_cast_op;
template<typename Scalar> struct scalar_multiple_op; template<typename Scalar> struct scalar_multiple_op;
template<typename Scalar> struct scalar_quotient1_op; template<typename Scalar> struct scalar_quotient1_op;
template<typename Scalar> struct scalar_min_op;
template<typename Scalar> struct scalar_max_op;
template<typename Scalar> struct scalar_random_op; template<typename Scalar> struct scalar_random_op;
template<typename Scalar> struct scalar_add_op; template<typename Scalar> struct scalar_add_op;
template<typename Scalar> struct scalar_constant_op; template<typename Scalar> struct scalar_constant_op;
@ -212,9 +212,10 @@ template<typename Scalar> struct scalar_igamma_op;
template<typename Scalar> struct scalar_igammac_op; template<typename Scalar> struct scalar_igammac_op;
template<typename Scalar> struct scalar_betainc_op; template<typename Scalar> struct scalar_betainc_op;
template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_hypot_op;
template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_product_op; template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_product_op;
template<typename LhsScalar,typename RhsScalar> struct scalar_multiple2_op;
template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_quotient_op; template<typename LhsScalar,typename RhsScalar=LhsScalar> struct scalar_quotient_op;
template<typename LhsScalar,typename RhsScalar> struct scalar_multiple2_op;
template<typename LhsScalar,typename RhsScalar> struct scalar_quotient2_op; template<typename LhsScalar,typename RhsScalar> struct scalar_quotient2_op;
} // end namespace internal } // end namespace internal

View File

@ -876,15 +876,7 @@ namespace Eigen {
#define EIGEN_IMPLIES(a,b) (!(a) || (b)) #define EIGEN_IMPLIES(a,b) (!(a) || (b))
#define EIGEN_MAKE_CWISE_BINARY_OP(METHOD,FUNCTOR) \ // the expression type of a standard coefficient wise binary operation
template<typename OtherDerived> \
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseBinaryOp<FUNCTOR<Scalar>, const Derived, const OtherDerived> \
(METHOD)(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \
{ \
return CwiseBinaryOp<FUNCTOR<Scalar>, const Derived, const OtherDerived>(derived(), other.derived()); \
}
// the expression type of a cwise product
#define EIGEN_CWISE_BINARY_RETURN_TYPE(LHS,RHS,OPNAME) \ #define EIGEN_CWISE_BINARY_RETURN_TYPE(LHS,RHS,OPNAME) \
CwiseBinaryOp< \ CwiseBinaryOp< \
EIGEN_CAT(EIGEN_CAT(internal::scalar_,OPNAME),_op)< \ EIGEN_CAT(EIGEN_CAT(internal::scalar_,OPNAME),_op)< \
@ -895,6 +887,14 @@ namespace Eigen {
const RHS \ const RHS \
> >
#define EIGEN_MAKE_CWISE_BINARY_OP(METHOD,OPNAME) \
template<typename OtherDerived> \
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,OPNAME) \
(METHOD)(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \
{ \
return EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,OPNAME)(derived(), other.derived()); \
}
#ifdef EIGEN_EXCEPTIONS #ifdef EIGEN_EXCEPTIONS
# define EIGEN_THROW_X(X) throw X # define EIGEN_THROW_X(X) throw X
# define EIGEN_THROW throw # define EIGEN_THROW throw

View File

@ -327,13 +327,33 @@ GeneralizedEigenSolver<MatrixType>::compute(const MatrixType& A, const MatrixTyp
} }
else else
{ {
Scalar p = Scalar(0.5) * (m_matS.coeff(i, i) - m_matS.coeff(i+1, i+1)); // We need to extract the generalized eigenvalues of the pair of a general 2x2 block S and a triangular 2x2 block T
Scalar z = sqrt(abs(p * p + m_matS.coeff(i+1, i) * m_matS.coeff(i, i+1))); // From the eigen decomposition of T = U * E * U^-1,
m_alphas.coeffRef(i) = ComplexScalar(m_matS.coeff(i+1, i+1) + p, z); // we can extract the eigenvalues of (U^-1 * S * U) / E
m_alphas.coeffRef(i+1) = ComplexScalar(m_matS.coeff(i+1, i+1) + p, -z); // Here, we can take advantage that E = diag(T), and U = [ 1 T_01 ; 0 T_11-T_00], and U^-1 = [1 -T_11/(T_11-T_00) ; 0 1/(T_11-T_00)].
// Then taking beta=T_00*T_11*(T_11-T_00), we can avoid any division, and alpha is the eigenvalues of A = (U^-1 * S * U) * diag(T_11,T_00) * (T_11-T_00):
// T = [a b ; 0 c]
// S = [e f ; g h]
RealScalar a = m_realQZ.matrixT().coeff(i, i), b = m_realQZ.matrixT().coeff(i, i+1), c = m_realQZ.matrixT().coeff(i+1, i+1);
RealScalar e = m_matS.coeff(i, i), f = m_matS.coeff(i, i+1), g = m_matS.coeff(i+1, i), h = m_matS.coeff(i+1, i+1);
RealScalar d = c-a;
RealScalar gb = g*b;
Matrix<RealScalar,2,2> A;
A << (e*d-gb)*c, ((e*b+f*d-h*b)*d-gb*b)*a,
g*c , (gb+h*d)*a;
// NOTE, we could also compute the SVD of T's block during the QZ factorization so that the respective T block is guaranteed to be diagonal,
// and then we could directly apply the formula below (while taking care of scaling S columns by T11,T00):
Scalar p = Scalar(0.5) * (A.coeff(i, i) - A.coeff(i+1, i+1));
Scalar z = sqrt(abs(p * p + A.coeff(i+1, i) * A.coeff(i, i+1)));
m_alphas.coeffRef(i) = ComplexScalar(A.coeff(i+1, i+1) + p, z);
m_alphas.coeffRef(i+1) = ComplexScalar(A.coeff(i+1, i+1) + p, -z);
m_betas.coeffRef(i) =
m_betas.coeffRef(i+1) = a*c*d;
m_betas.coeffRef(i) = m_realQZ.matrixT().coeff(i,i);
m_betas.coeffRef(i+1) = m_realQZ.matrixT().coeff(i,i);
i += 2; i += 2;
} }
} }

View File

@ -29,14 +29,14 @@ operator/(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
* *
* \sa max() * \sa max()
*/ */
EIGEN_MAKE_CWISE_BINARY_OP(min,internal::scalar_min_op) EIGEN_MAKE_CWISE_BINARY_OP(min,min)
/** \returns an expression of the coefficient-wise min of \c *this and scalar \a other /** \returns an expression of the coefficient-wise min of \c *this and scalar \a other
* *
* \sa max() * \sa max()
*/ */
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_min_op<Scalar>, const Derived, EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_min_op<Scalar,Scalar>, const Derived,
const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject> > const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject> >
#ifdef EIGEN_PARSED_BY_DOXYGEN #ifdef EIGEN_PARSED_BY_DOXYGEN
min min
@ -55,14 +55,14 @@ min
* *
* \sa min() * \sa min()
*/ */
EIGEN_MAKE_CWISE_BINARY_OP(max,internal::scalar_max_op) EIGEN_MAKE_CWISE_BINARY_OP(max,max)
/** \returns an expression of the coefficient-wise max of \c *this and scalar \a other /** \returns an expression of the coefficient-wise max of \c *this and scalar \a other
* *
* \sa min() * \sa min()
*/ */
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar,Scalar>, const Derived,
const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject> > const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject> >
#ifdef EIGEN_PARSED_BY_DOXYGEN #ifdef EIGEN_PARSED_BY_DOXYGEN
max max
@ -95,13 +95,13 @@ pow(const ArrayBase<ExponentDerived>& exponents) const
// TODO code generating macros could be moved to Macros.h and could include generation of documentation // TODO code generating macros could be moved to Macros.h and could include generation of documentation
#define EIGEN_MAKE_CWISE_COMP_OP(OP, COMPARATOR) \ #define EIGEN_MAKE_CWISE_COMP_OP(OP, COMPARATOR) \
template<typename OtherDerived> \ template<typename OtherDerived> \
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const OtherDerived> \ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_cmp_op<Scalar, typename OtherDerived::Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const OtherDerived> \
OP(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \ OP(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \
{ \ { \
return CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const OtherDerived>(derived(), other.derived()); \ return CwiseBinaryOp<internal::scalar_cmp_op<Scalar, typename OtherDerived::Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const OtherDerived>(derived(), other.derived()); \
}\ }\
typedef CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject> > Cmp ## COMPARATOR ## ReturnType; \ typedef CwiseBinaryOp<internal::scalar_cmp_op<Scalar,Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject> > Cmp ## COMPARATOR ## ReturnType; \
typedef CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_ ## COMPARATOR>, const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject>, const Derived > RCmp ## COMPARATOR ## ReturnType; \ typedef CwiseBinaryOp<internal::scalar_cmp_op<Scalar,Scalar, internal::cmp_ ## COMPARATOR>, const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject>, const Derived > RCmp ## COMPARATOR ## ReturnType; \
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Cmp ## COMPARATOR ## ReturnType \ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Cmp ## COMPARATOR ## ReturnType \
OP(const Scalar& s) const { \ OP(const Scalar& s) const { \
return this->OP(Derived::PlainObject::Constant(rows(), cols(), s)); \ return this->OP(Derived::PlainObject::Constant(rows(), cols(), s)); \
@ -113,10 +113,10 @@ OP(const Scalar& s, const Derived& d) { \
#define EIGEN_MAKE_CWISE_COMP_R_OP(OP, R_OP, RCOMPARATOR) \ #define EIGEN_MAKE_CWISE_COMP_R_OP(OP, R_OP, RCOMPARATOR) \
template<typename OtherDerived> \ template<typename OtherDerived> \
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_##RCOMPARATOR>, const OtherDerived, const Derived> \ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_cmp_op<typename OtherDerived::Scalar, Scalar, internal::cmp_##RCOMPARATOR>, const OtherDerived, const Derived> \
OP(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \ OP(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \
{ \ { \
return CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_##RCOMPARATOR>, const OtherDerived, const Derived>(other.derived(), derived()); \ return CwiseBinaryOp<internal::scalar_cmp_op<typename OtherDerived::Scalar, Scalar, internal::cmp_##RCOMPARATOR>, const OtherDerived, const Derived>(other.derived(), derived()); \
} \ } \
EIGEN_DEVICE_FUNC \ EIGEN_DEVICE_FUNC \
inline const RCmp ## RCOMPARATOR ## ReturnType \ inline const RCmp ## RCOMPARATOR ## ReturnType \

View File

@ -16,13 +16,14 @@
* *
* \sa class CwiseBinaryOp, operator-=() * \sa class CwiseBinaryOp, operator-=()
*/ */
template<typename OtherDerived> EIGEN_MAKE_CWISE_BINARY_OP(operator-,difference)
EIGEN_DEVICE_FUNC // template<typename OtherDerived>
EIGEN_STRONG_INLINE const EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,difference) // EIGEN_DEVICE_FUNC
operator-(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const // EIGEN_STRONG_INLINE const EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,difference)
{ // operator-(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
return EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,difference)(derived(), other.derived()); // {
} // return EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,difference)(derived(), other.derived());
// }
/** \returns an expression of the sum of \c *this and \a other /** \returns an expression of the sum of \c *this and \a other
* *
@ -30,13 +31,14 @@ operator-(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
* *
* \sa class CwiseBinaryOp, operator+=() * \sa class CwiseBinaryOp, operator+=()
*/ */
template<typename OtherDerived> EIGEN_MAKE_CWISE_BINARY_OP(operator+,sum)
EIGEN_DEVICE_FUNC // template<typename OtherDerived>
EIGEN_STRONG_INLINE const EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,sum) // EIGEN_DEVICE_FUNC
operator+(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const // EIGEN_STRONG_INLINE const EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,sum)
{ // operator+(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
return EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,sum)(derived(), other.derived()); // {
} // return EIGEN_CWISE_BINARY_RETURN_TYPE(Derived,OtherDerived,sum)(derived(), other.derived());
// }
/** \returns an expression of a custom coefficient-wise operator \a func of *this and \a other /** \returns an expression of a custom coefficient-wise operator \a func of *this and \a other
* *

View File

@ -74,10 +74,10 @@ cwiseNotEqual(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
*/ */
template<typename OtherDerived> template<typename OtherDerived>
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_min_op<Scalar>, const Derived, const OtherDerived> EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_min_op<Scalar,Scalar>, const Derived, const OtherDerived>
cwiseMin(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const cwiseMin(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
{ {
return CwiseBinaryOp<internal::scalar_min_op<Scalar>, const Derived, const OtherDerived>(derived(), other.derived()); return CwiseBinaryOp<internal::scalar_min_op<Scalar,Scalar>, const Derived, const OtherDerived>(derived(), other.derived());
} }
/** \returns an expression of the coefficient-wise min of *this and scalar \a other /** \returns an expression of the coefficient-wise min of *this and scalar \a other
@ -85,7 +85,7 @@ cwiseMin(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
* \sa class CwiseBinaryOp, min() * \sa class CwiseBinaryOp, min()
*/ */
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_min_op<Scalar>, const Derived, const ConstantReturnType> EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_min_op<Scalar,Scalar>, const Derived, const ConstantReturnType>
cwiseMin(const Scalar &other) const cwiseMin(const Scalar &other) const
{ {
return cwiseMin(Derived::Constant(rows(), cols(), other)); return cwiseMin(Derived::Constant(rows(), cols(), other));
@ -100,10 +100,10 @@ cwiseMin(const Scalar &other) const
*/ */
template<typename OtherDerived> template<typename OtherDerived>
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const OtherDerived> EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar,Scalar>, const Derived, const OtherDerived>
cwiseMax(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const cwiseMax(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
{ {
return CwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const OtherDerived>(derived(), other.derived()); return CwiseBinaryOp<internal::scalar_max_op<Scalar,Scalar>, const Derived, const OtherDerived>(derived(), other.derived());
} }
/** \returns an expression of the coefficient-wise max of *this and scalar \a other /** \returns an expression of the coefficient-wise max of *this and scalar \a other
@ -111,7 +111,7 @@ cwiseMax(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
* \sa class CwiseBinaryOp, min() * \sa class CwiseBinaryOp, min()
*/ */
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar>, const Derived, const ConstantReturnType> EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_max_op<Scalar,Scalar>, const Derived, const ConstantReturnType>
cwiseMax(const Scalar &other) const cwiseMax(const Scalar &other) const
{ {
return cwiseMax(Derived::Constant(rows(), cols(), other)); return cwiseMax(Derived::Constant(rows(), cols(), other));
@ -133,7 +133,7 @@ cwiseQuotient(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const
return CwiseBinaryOp<internal::scalar_quotient_op<Scalar>, const Derived, const OtherDerived>(derived(), other.derived()); return CwiseBinaryOp<internal::scalar_quotient_op<Scalar>, const Derived, const OtherDerived>(derived(), other.derived());
} }
typedef CwiseBinaryOp<internal::scalar_cmp_op<Scalar,internal::cmp_EQ>, const Derived, const ConstantReturnType> CwiseScalarEqualReturnType; typedef CwiseBinaryOp<internal::scalar_cmp_op<Scalar,Scalar,internal::cmp_EQ>, const Derived, const ConstantReturnType> CwiseScalarEqualReturnType;
/** \returns an expression of the coefficient-wise == operator of \c *this and a scalar \a s /** \returns an expression of the coefficient-wise == operator of \c *this and a scalar \a s
* *
@ -148,5 +148,5 @@ EIGEN_DEVICE_FUNC
inline const CwiseScalarEqualReturnType inline const CwiseScalarEqualReturnType
cwiseEqual(const Scalar& s) const cwiseEqual(const Scalar& s) const
{ {
return CwiseScalarEqualReturnType(derived(), Derived::Constant(rows(), cols(), s), internal::scalar_cmp_op<Scalar,internal::cmp_EQ>()); return CwiseScalarEqualReturnType(derived(), Derived::Constant(rows(), cols(), s), internal::scalar_cmp_op<Scalar,Scalar,internal::cmp_EQ>());
} }