From 31fdd67756630de05f2464ef620bc62185a53bee Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Wed, 11 Mar 2015 06:39:23 +1000 Subject: Additional unary coeff-wise functors (isnan, round, arg, e.g.) --- Eigen/src/Core/Assign_MKL.h | 24 +++--- Eigen/src/Core/GenericPacketMath.h | 33 +++++++- Eigen/src/Core/GlobalFunctions.h | 6 ++ Eigen/src/Core/MathFunctions.h | 133 +++++++++++++++++++++++++++++++- Eigen/src/Core/functors/UnaryFunctors.h | 118 ++++++++++++++++++++++++++++ Eigen/src/plugins/ArrayCwiseUnaryOps.h | 85 ++++++++++++++++++++ test/array.cpp | 14 +++- 7 files changed, 401 insertions(+), 12 deletions(-) diff --git a/Eigen/src/Core/Assign_MKL.h b/Eigen/src/Core/Assign_MKL.h index a7b9e9293..3e9db616d 100644 --- a/Eigen/src/Core/Assign_MKL.h +++ b/Eigen/src/Core/Assign_MKL.h @@ -196,16 +196,22 @@ EIGEN_MKL_VML_SPECIALIZE_ASSIGN(SliceVectorizedTraversal,NoUnrolling) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX_LA(EIGENOP, VMLOP) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sin, Sin) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(asin, Asin) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(cos, Cos) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(acos, Acos) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(tan, Tan) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sin, Sin) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(asin, Asin) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(cos, Cos) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(acos, Acos) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(tan, Tan) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(atan, Atan) -//EIGEN_MKL_VML_DECLARE_UNARY_CALLS(abs, Abs) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(exp, Exp) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(log, Ln) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sqrt, Sqrt) +//EIGEN_MKL_VML_DECLARE_UNARY_CALLS(abs, Abs) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(arg, Arg) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(exp, Exp) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(log, Ln) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sqrt, Sqrt) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(round, Round) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(floor, Floor) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(ceil, Ceil) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(isnan, Isnan) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(isinf, Isinf) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr) diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h index e48c064ce..31b4d699a 100644 --- a/Eigen/src/Core/GenericPacketMath.h +++ b/Eigen/src/Core/GenericPacketMath.h @@ -49,6 +49,7 @@ struct default_packet_traits HasMul = 1, HasNegate = 1, HasAbs = 1, + HasArg = 0, HasAbs2 = 1, HasMin = 1, HasMax = 1, @@ -67,7 +68,13 @@ struct default_packet_traits HasTan = 0, HasASin = 0, HasACos = 0, - HasATan = 0 + HasATan = 0, + + HasRound = 0, + HasFloor = 0, + HasCeil = 0, + HasIsnan = 0, + HasIsinf = 0 }; }; @@ -140,6 +147,10 @@ pmax(const Packet& a, template EIGEN_DEVICE_FUNC inline Packet pabs(const Packet& a) { using std::abs; return abs(a); } +/** \internal \returns the phase angle of \a a */ +template EIGEN_DEVICE_FUNC inline Packet +parg(const Packet& a) { using numext::arg; return arg(a); } + /** \internal \returns the bitwise and of \a a and \a b */ template EIGEN_DEVICE_FUNC inline Packet pand(const Packet& a, const Packet& b) { return a & b; } @@ -352,6 +363,26 @@ Packet plog(const Packet& a) { using std::log; return log(a); } template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet psqrt(const Packet& a) { using std::sqrt; return sqrt(a); } +/** \internal \returns the rounded value of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet pround(const Packet& a) { using numext::round; return round(a); } + +/** \internal \returns the floor of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet pfloor(const Packet& a) { using numext::floor; return floor(a); } + +/** \internal \returns the ceil of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet pceil(const Packet& a) { using numext::ceil; return ceil(a); } + +/** \internal \returns the isnan of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet pisnan(const Packet& a) { using numext::isnan; return isnan(a); } + +/** \internal \returns the isinf of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet pisinf(const Packet& a) { using numext::isinf; return isinf(a); } + /*************************************************************************** * The following functions might not have to be overwritten for vectorized types ***************************************************************************/ diff --git a/Eigen/src/Core/GlobalFunctions.h b/Eigen/src/Core/GlobalFunctions.h index ee67b7d3c..72450662f 100644 --- a/Eigen/src/Core/GlobalFunctions.h +++ b/Eigen/src/Core/GlobalFunctions.h @@ -49,7 +49,13 @@ namespace Eigen EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp,scalar_exp_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs,scalar_abs_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(arg,scalar_arg_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sqrt,scalar_sqrt_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(round,scalar_round_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(floor,scalar_floor_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(ceil,scalar_ceil_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isnan,scalar_isnan_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isinf,scalar_isinf_op) template inline const Eigen::CwiseUnaryOp, const Derived> diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index 878f38e92..e98160ce3 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -133,6 +133,41 @@ struct imag_retval typedef typename NumTraits::Real type; }; +/**************************************************************************** +* Implementation of arg * +****************************************************************************/ + +template::IsComplex> +struct arg_default_impl +{ + typedef typename NumTraits::Real RealScalar; + EIGEN_DEVICE_FUNC + static inline RealScalar run(const Scalar& x) + { + const double pi = std::acos(-1.0); + return (x < 0.0) ? pi : 0.0; } +}; + +template +struct arg_default_impl +{ + typedef typename NumTraits::Real RealScalar; + EIGEN_DEVICE_FUNC + static inline RealScalar run(const Scalar& x) + { + using std::arg; + return arg(x); + } +}; + +template struct arg_impl : arg_default_impl {}; + +template +struct arg_retval +{ + typedef typename NumTraits::Real type; +}; + /**************************************************************************** * Implementation of real_ref * ****************************************************************************/ @@ -574,7 +609,7 @@ inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random() } // end namespace internal /**************************************************************************** -* Generic math function * +* Generic math functions * ****************************************************************************/ namespace numext { @@ -623,6 +658,13 @@ inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x) return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x); } +template +EIGEN_DEVICE_FUNC +inline EIGEN_MATHFUNC_RETVAL(arg, Scalar) arg(const Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(arg, Scalar)::run(x); +} + template EIGEN_DEVICE_FUNC inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x) @@ -697,6 +739,95 @@ bool (isfinite)(const std::complex& x) return isfinite(real(x)) && isfinite(imag(x)); } +template +EIGEN_DEVICE_FUNC +bool (isnan)(const T& x) +{ + using std::isnan; + return isnan(x); +} + +template +EIGEN_DEVICE_FUNC +bool (isnan)(const std::complex& x) +{ + using std::real; + using std::imag; + using std::isnan; + return isnan(real(x)) || isnan(imag(x)); +} + +template +EIGEN_DEVICE_FUNC +bool (isinf)(const T& x) +{ + using std::isinf; + return isinf(x); +} + +template +EIGEN_DEVICE_FUNC +bool (isinf)(const std::complex& x) +{ + using std::real; + using std::imag; + using std::isinf; + return isinf(real(x)) || isinf(imag(x)); +} + +template +EIGEN_DEVICE_FUNC +T (round)(const T& x) +{ + using std::floor; + using std::ceil; + return (x > 0.0) ? floor(x + 0.5) : ceil(x - 0.5); +} + +template +EIGEN_DEVICE_FUNC +std::complex (round)(const std::complex& x) +{ + using numext::round; + return std::complex(round(real(x)), round(imag(x))); +} + +template +EIGEN_DEVICE_FUNC +T (floor)(const T& x) +{ + using std::floor; + return floor(x); +} + +template +EIGEN_DEVICE_FUNC +std::complex (floor)(const std::complex& x) +{ + using std::real; + using std::imag; + using std::floor; + return std::complex(floor(real(x)), floor(imag(x))); +} + +template +EIGEN_DEVICE_FUNC +T (ceil)(const T& x) +{ + using std::ceil; + return ceil(x); +} + +template +EIGEN_DEVICE_FUNC +std::complex (ceil)(const std::complex& x) +{ + using std::real; + using std::imag; + using std::ceil; + return std::complex(ceil(real(x)), ceil(imag(x))); +} + // Log base 2 for 32 bits positive integers. // Conveniently returns 0 for x==0. inline int log2(int x) diff --git a/Eigen/src/Core/functors/UnaryFunctors.h b/Eigen/src/Core/functors/UnaryFunctors.h index f32f0f113..0aadcdaea 100644 --- a/Eigen/src/Core/functors/UnaryFunctors.h +++ b/Eigen/src/Core/functors/UnaryFunctors.h @@ -122,6 +122,27 @@ struct functor_traits > }; }; +/** \internal + * \brief Template functor to compute the phase angle of a complex + * + * \sa class CwiseUnaryOp, Cwise::arg + */ +template struct scalar_arg_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_arg_op) + typedef typename NumTraits::Real result_type; + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { using numext::arg; return arg(a); } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const + { return internal::parg(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = NumTraits::AddCost, + PacketAccess = packet_traits::HasArg + }; +}; /** \internal * \brief Template functor to cast a scalar to another type * @@ -416,6 +437,103 @@ template struct functor_traits > { enum { Cost = 2*NumTraits::MulCost, PacketAccess = packet_traits::HasMul }; }; +/** \internal + * \brief Template functor to compute the rounded value of a scalar + * \sa class CwiseUnaryOp, ArrayBase::round() + */ +template struct scalar_round_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_round_op) + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { using numext::round; return round(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pround(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = NumTraits::MulCost, + PacketAccess = packet_traits::HasRound + }; +}; + +/** \internal + * \brief Template functor to compute the floor of a scalar + * \sa class CwiseUnaryOp, ArrayBase::floor() + */ +template struct scalar_floor_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_floor_op) + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return numext::floor(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pfloor(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = NumTraits::MulCost, + PacketAccess = packet_traits::HasFloor + }; +}; + +/** \internal + * \brief Template functor to compute the ceil of a scalar + * \sa class CwiseUnaryOp, ArrayBase::ceil() + */ +template struct scalar_ceil_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_ceil_op) + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return numext::ceil(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pceil(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = NumTraits::MulCost, + PacketAccess = packet_traits::HasCeil + }; +}; + +/** \internal + * \brief Template functor to compute the isnan of a scalar + * \sa class CwiseUnaryOp, ArrayBase::isnan() + */ +template struct scalar_isnan_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_isnan_op) + typedef bool result_type; + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::isnan(a); } + template + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const + { return internal::pisnan(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = NumTraits::MulCost, + PacketAccess = packet_traits::HasIsnan + }; +}; + +/** \internal + * \brief Template functor to compute the isinf of a scalar + * \sa class CwiseUnaryOp, ArrayBase::isinf() + */ +template struct scalar_isinf_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_isinf_op) + typedef bool result_type; + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::isinf(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pisinf(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = NumTraits::MulCost, + PacketAccess = packet_traits::HasIsinf + }; +}; } // end namespace internal diff --git a/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/Eigen/src/plugins/ArrayCwiseUnaryOps.h index f6f526d2b..b5f66e181 100644 --- a/Eigen/src/plugins/ArrayCwiseUnaryOps.h +++ b/Eigen/src/plugins/ArrayCwiseUnaryOps.h @@ -1,6 +1,7 @@ typedef CwiseUnaryOp, const Derived> AbsReturnType; +typedef CwiseUnaryOp, const Derived> ArgReturnType; typedef CwiseUnaryOp, const Derived> Abs2ReturnType; typedef CwiseUnaryOp, const Derived> SqrtReturnType; typedef CwiseUnaryOp, const Derived> InverseReturnType; @@ -16,6 +17,11 @@ typedef CwiseUnaryOp, const Derived> AtanReturn typedef CwiseUnaryOp, const Derived> PowReturnType; typedef CwiseUnaryOp, const Derived> SquareReturnType; typedef CwiseUnaryOp, const Derived> CubeReturnType; +typedef CwiseUnaryOp, const Derived> RoundReturnType; +typedef CwiseUnaryOp, const Derived> FloorReturnType; +typedef CwiseUnaryOp, const Derived> CeilReturnType; +typedef CwiseUnaryOp, const Derived> IsnanReturnType; +typedef CwiseUnaryOp, const Derived> IsinfReturnType; /** \returns an expression of the coefficient-wise absolute value of \c *this * @@ -31,6 +37,20 @@ abs() const return AbsReturnType(derived()); } +/** \returns an expression of the coefficient-wise phase angle of \c *this + * + * Example: \include Cwise_arg.cpp + * Output: \verbinclude Cwise_arg.out + * + * \sa abs() + */ +EIGEN_DEVICE_FUNC +EIGEN_STRONG_INLINE const ArgReturnType +arg() const +{ + return ArgReturnType(derived()); +} + /** \returns an expression of the coefficient-wise squared absolute value of \c *this * * Example: \include Cwise_abs2.cpp @@ -246,6 +266,71 @@ cube() const return CubeReturnType(derived()); } +/** \returns an expression of the coefficient-wise round of *this. + * + * Example: \include Cwise_round.cpp + * Output: \verbinclude Cwise_round.out + * + * \sa ceil(), floor() + */ +inline const RoundReturnType +round() const +{ + return RoundReturnType(derived()); +} + +/** \returns an expression of the coefficient-wise floor of *this. + * + * Example: \include Cwise_floor.cpp + * Output: \verbinclude Cwise_floor.out + * + * \sa ceil(), round() + */ +inline const FloorReturnType +floor() const +{ + return FloorReturnType(derived()); +} + +/** \returns an expression of the coefficient-wise ceil of *this. + * + * Example: \include Cwise_ceil.cpp + * Output: \verbinclude Cwise_ceil.out + * + * \sa floor(), round() + */ +inline const CeilReturnType +ceil() const +{ + return CeilReturnType(derived()); +} + +/** \returns an expression of the coefficient-wise isnan of *this. + * + * Example: \include Cwise_isnan.cpp + * Output: \verbinclude Cwise_isnan.out + * + * \sa isinf() + */ +inline const IsnanReturnType +isnan() const +{ + return IsnanReturnType(derived()); +} + +/** \returns an expression of the coefficient-wise isinf of *this. + * + * Example: \include Cwise_isinf.cpp + * Output: \verbinclude Cwise_isinf.out + * + * \sa isnan() + */ +inline const IsinfReturnType +isinf() const +{ + return IsinfReturnType(derived()); +} + #define EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(METHOD_NAME,FUNCTOR) \ EIGEN_DEVICE_FUNC \ inline const CwiseUnaryOp >, const Derived> \ diff --git a/test/array.cpp b/test/array.cpp index ad0182e10..5bcca3b04 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -204,7 +204,12 @@ template void array_real(const ArrayType& m) VERIFY_IS_APPROX(m1.acos(), acos(m1)); VERIFY_IS_APPROX(m1.tan(), tan(m1)); VERIFY_IS_APPROX(m1.atan(), atan(m1)); - + VERIFY_IS_APPROX(m1.round(), round(m1)); + VERIFY_IS_APPROX(m1.floor(), floor(m1)); + VERIFY_IS_APPROX(m1.ceil(), ceil(m1)); + VERIFY_IS_APPROX(m1.isnan(), isnan(m1)); + VERIFY_IS_APPROX(m1.isinf(), isinf(m1)); + VERIFY_IS_APPROX(cos(m1+RealScalar(3)*m2), cos((m1+RealScalar(3)*m2).eval())); VERIFY_IS_APPROX(m1.abs().sqrt(), sqrt(abs(m1))); @@ -263,6 +268,13 @@ template void array_complex(const ArrayType& m) VERIFY_IS_APPROX(m1.sqrt(), m2); VERIFY_IS_APPROX(m1.sqrt(), Eigen::sqrt(m1)); + VERIFY_IS_APPROX(m1.arg(), arg(m1)); + VERIFY_IS_APPROX(m1.round(), round(m1)); + VERIFY_IS_APPROX(m1.floor(), floor(m1)); + VERIFY_IS_APPROX(m1.ceil(), ceil(m1)); + VERIFY_IS_APPROX(m1.isnan(), isnan(m1)); + VERIFY_IS_APPROX(m1.isinf(), isinf(m1)); + } template void min_max(const ArrayType& m) -- cgit v1.2.3 From 19a71056ae12f78b2d90828be83c84f9966a0837 Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Wed, 11 Mar 2015 06:59:28 +1000 Subject: Allow calling of square(array) in addition to array.square() --- Eigen/src/Core/GlobalFunctions.h | 1 + test/array.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/Eigen/src/Core/GlobalFunctions.h b/Eigen/src/Core/GlobalFunctions.h index 72450662f..5ef57c229 100644 --- a/Eigen/src/Core/GlobalFunctions.h +++ b/Eigen/src/Core/GlobalFunctions.h @@ -51,6 +51,7 @@ namespace Eigen EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs,scalar_abs_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(arg,scalar_arg_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sqrt,scalar_sqrt_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(square,scalar_square_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(round,scalar_round_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(floor,scalar_floor_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(ceil,scalar_ceil_op) diff --git a/test/array.cpp b/test/array.cpp index 5bcca3b04..2d49a29fd 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -209,6 +209,7 @@ template void array_real(const ArrayType& m) VERIFY_IS_APPROX(m1.ceil(), ceil(m1)); VERIFY_IS_APPROX(m1.isnan(), isnan(m1)); VERIFY_IS_APPROX(m1.isinf(), isinf(m1)); + VERIFY_IS_APPROX(m1.square(), square(m1)); VERIFY_IS_APPROX(cos(m1+RealScalar(3)*m2), cos((m1+RealScalar(3)*m2).eval())); @@ -274,6 +275,7 @@ template void array_complex(const ArrayType& m) VERIFY_IS_APPROX(m1.ceil(), ceil(m1)); VERIFY_IS_APPROX(m1.isnan(), isnan(m1)); VERIFY_IS_APPROX(m1.isinf(), isinf(m1)); + VERIFY_IS_APPROX(m1.square(), square(m1)); } -- cgit v1.2.3 From a5e49976f5534aa1acd84eb6a375a1fbb0eac87c Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Wed, 11 Mar 2015 08:56:42 +1000 Subject: Add log10 array support --- Eigen/src/Core/Assign_MKL.h | 1 + Eigen/src/Core/GenericPacketMath.h | 5 +++++ Eigen/src/Core/GlobalFunctions.h | 1 + Eigen/src/Core/functors/UnaryFunctors.h | 15 +++++++++++++++ Eigen/src/plugins/ArrayCwiseUnaryOps.h | 17 +++++++++++++++++ test/array.cpp | 5 +++++ 6 files changed, 44 insertions(+) diff --git a/Eigen/src/Core/Assign_MKL.h b/Eigen/src/Core/Assign_MKL.h index 3e9db616d..e5d9850fa 100644 --- a/Eigen/src/Core/Assign_MKL.h +++ b/Eigen/src/Core/Assign_MKL.h @@ -206,6 +206,7 @@ EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(atan, Atan) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(arg, Arg) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(exp, Exp) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(log, Ln) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(log10, Log10) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sqrt, Sqrt) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(round, Round) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(floor, Floor) diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h index 31b4d699a..0ecd6fc2d 100644 --- a/Eigen/src/Core/GenericPacketMath.h +++ b/Eigen/src/Core/GenericPacketMath.h @@ -61,6 +61,7 @@ struct default_packet_traits HasSqrt = 0, HasExp = 0, HasLog = 0, + HasLog10 = 0, HasPow = 0, HasSin = 0, @@ -359,6 +360,10 @@ Packet pexp(const Packet& a) { using std::exp; return exp(a); } template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet plog(const Packet& a) { using std::log; return log(a); } +/** \internal \returns the log10 of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet plog10(const Packet& a) { using std::log10; return log10(a); } + /** \internal \returns the square-root of \a a (coeff-wise) */ template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet psqrt(const Packet& a) { using std::sqrt; return sqrt(a); } diff --git a/Eigen/src/Core/GlobalFunctions.h b/Eigen/src/Core/GlobalFunctions.h index 5ef57c229..4db0a906e 100644 --- a/Eigen/src/Core/GlobalFunctions.h +++ b/Eigen/src/Core/GlobalFunctions.h @@ -48,6 +48,7 @@ namespace Eigen EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(atan,scalar_atan_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp,scalar_exp_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log10,scalar_log10_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs,scalar_abs_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(arg,scalar_arg_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sqrt,scalar_sqrt_op) diff --git a/Eigen/src/Core/functors/UnaryFunctors.h b/Eigen/src/Core/functors/UnaryFunctors.h index 0aadcdaea..c3901029d 100644 --- a/Eigen/src/Core/functors/UnaryFunctors.h +++ b/Eigen/src/Core/functors/UnaryFunctors.h @@ -254,6 +254,21 @@ template struct functor_traits > { enum { Cost = 5 * NumTraits::MulCost, PacketAccess = packet_traits::HasLog }; }; +/** \internal + * + * \brief Template functor to compute the base-10 logarithm of a scalar + * + * \sa class CwiseUnaryOp, Cwise::log10() + */ +template struct scalar_log10_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_log10_op) + EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { using std::log10; return log10(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::plog10(a); } +}; +template +struct functor_traits > +{ enum { Cost = 5 * NumTraits::MulCost, PacketAccess = packet_traits::HasLog10 }; }; /** \internal * \brief Template functor to compute the square root of a scalar diff --git a/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/Eigen/src/plugins/ArrayCwiseUnaryOps.h index b5f66e181..eae5de9f6 100644 --- a/Eigen/src/plugins/ArrayCwiseUnaryOps.h +++ b/Eigen/src/plugins/ArrayCwiseUnaryOps.h @@ -8,6 +8,7 @@ typedef CwiseUnaryOp, const Derived> Inverse typedef CwiseUnaryOp, const Derived> ExpReturnType; typedef CwiseUnaryOp, const Derived> LogReturnType; +typedef CwiseUnaryOp, const Derived> Log10ReturnType; typedef CwiseUnaryOp, const Derived> CosReturnType; typedef CwiseUnaryOp, const Derived> SinReturnType; typedef CwiseUnaryOp, const Derived> AcosReturnType; @@ -99,6 +100,22 @@ log() const return LogReturnType(derived()); } +/** \returns an expression of the coefficient-wise base-10 logarithm of *this. + * + * This function computes the coefficient-wise base-10 logarithm. + * + * Example: \include Cwise_log10.cpp + * Output: \verbinclude Cwise_log10.out + * + * \sa log() + */ +EIGEN_DEVICE_FUNC +inline const Log10ReturnType +log10() const +{ + return Log10ReturnType(derived()); +} + /** \returns an expression of the coefficient-wise square root of *this. * * This function computes the coefficient-wise square root. The function MatrixBase::sqrt() in the diff --git a/test/array.cpp b/test/array.cpp index 2d49a29fd..1a6c7987e 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -204,6 +204,9 @@ template void array_real(const ArrayType& m) VERIFY_IS_APPROX(m1.acos(), acos(m1)); VERIFY_IS_APPROX(m1.tan(), tan(m1)); VERIFY_IS_APPROX(m1.atan(), atan(m1)); + VERIFY_IS_APPROX(m1.log(), log(m1)); + VERIFY_IS_APPROX(m1.log10(), log10(m1)); + VERIFY_IS_APPROX(m1.arg(), arg(m1)); VERIFY_IS_APPROX(m1.round(), round(m1)); VERIFY_IS_APPROX(m1.floor(), floor(m1)); VERIFY_IS_APPROX(m1.ceil(), ceil(m1)); @@ -269,6 +272,8 @@ template void array_complex(const ArrayType& m) VERIFY_IS_APPROX(m1.sqrt(), m2); VERIFY_IS_APPROX(m1.sqrt(), Eigen::sqrt(m1)); + VERIFY_IS_APPROX(m1.log(), log(m1)); + VERIFY_IS_APPROX(m1.log10(), log10(m1)); VERIFY_IS_APPROX(m1.arg(), arg(m1)); VERIFY_IS_APPROX(m1.round(), round(m1)); VERIFY_IS_APPROX(m1.floor(), floor(m1)); -- cgit v1.2.3 From f89fcefa79382f5a93c38927b79f40973b2e71f2 Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Wed, 11 Mar 2015 13:13:30 +1000 Subject: Add hyperbolic trigonometric functions from std array support --- Eigen/src/Core/Assign_MKL.h | 3 ++ Eigen/src/Core/GenericPacketMath.h | 17 +++++++- Eigen/src/Core/GlobalFunctions.h | 7 +++- Eigen/src/Core/functors/UnaryFunctors.h | 58 +++++++++++++++++++++++++- Eigen/src/plugins/ArrayCwiseUnaryOps.h | 74 ++++++++++++++++++++++++++------- test/array.cpp | 11 ++++- 6 files changed, 149 insertions(+), 21 deletions(-) diff --git a/Eigen/src/Core/Assign_MKL.h b/Eigen/src/Core/Assign_MKL.h index e5d9850fa..fd1f391e3 100644 --- a/Eigen/src/Core/Assign_MKL.h +++ b/Eigen/src/Core/Assign_MKL.h @@ -198,10 +198,13 @@ EIGEN_MKL_VML_SPECIALIZE_ASSIGN(SliceVectorizedTraversal,NoUnrolling) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sin, Sin) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(asin, Asin) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sinh, Sinh) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(cos, Cos) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(acos, Acos) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(cosh, Cosh) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(tan, Tan) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(atan, Atan) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(tanh, Tanh) //EIGEN_MKL_VML_DECLARE_UNARY_CALLS(abs, Abs) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(arg, Arg) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(exp, Exp) diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h index 0ecd6fc2d..35701cce4 100644 --- a/Eigen/src/Core/GenericPacketMath.h +++ b/Eigen/src/Core/GenericPacketMath.h @@ -70,6 +70,9 @@ struct default_packet_traits HasASin = 0, HasACos = 0, HasATan = 0, + HasSinh = 0, + HasCosh = 0, + HasTanh = 0, HasRound = 0, HasFloor = 0, @@ -348,10 +351,22 @@ Packet pasin(const Packet& a) { using std::asin; return asin(a); } template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pacos(const Packet& a) { using std::acos; return acos(a); } -/** \internal \returns the atan of \a a (coeff-wise) */ +/** \internal \returns the arc tangent of \a a (coeff-wise) */ template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet patan(const Packet& a) { using std::atan; return atan(a); } +/** \internal \returns the hyperbolic sine of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet psinh(const Packet& a) { using std::sinh; return sinh(a); } + +/** \internal \returns the hyperbolic cosine of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet pcosh(const Packet& a) { using std::cosh; return cosh(a); } + +/** \internal \returns the hyperbolic tan of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet ptanh(const Packet& a) { using std::tanh; return tanh(a); } + /** \internal \returns the exp of \a a (coeff-wise) */ template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pexp(const Packet& a) { using std::exp; return exp(a); } diff --git a/Eigen/src/Core/GlobalFunctions.h b/Eigen/src/Core/GlobalFunctions.h index 4db0a906e..44f9c7790 100644 --- a/Eigen/src/Core/GlobalFunctions.h +++ b/Eigen/src/Core/GlobalFunctions.h @@ -42,10 +42,13 @@ namespace Eigen EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(conj,scalar_conjugate_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sin,scalar_sin_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cos,scalar_cos_op) - EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(asin,scalar_asin_op) - EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(acos,scalar_acos_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(tan,scalar_tan_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(atan,scalar_atan_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(asin,scalar_asin_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(acos,scalar_acos_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sinh,scalar_sinh_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cosh,scalar_cosh_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(tanh,scalar_tanh_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp,scalar_exp_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log10,scalar_log10_op) diff --git a/Eigen/src/Core/functors/UnaryFunctors.h b/Eigen/src/Core/functors/UnaryFunctors.h index c3901029d..bf1bc47a8 100644 --- a/Eigen/src/Core/functors/UnaryFunctors.h +++ b/Eigen/src/Core/functors/UnaryFunctors.h @@ -384,7 +384,6 @@ struct functor_traits > }; }; - /** \internal * \brief Template functor to compute the atan of a scalar * \sa class CwiseUnaryOp, ArrayBase::atan() @@ -404,6 +403,63 @@ struct functor_traits > }; }; +/** \internal + * \brief Template functor to compute the tanh of a scalar + * \sa class CwiseUnaryOp, ArrayBase::tanh() + */ +template struct scalar_tanh_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_tanh_op) + inline const Scalar operator() (const Scalar& a) const { using std::tanh; return tanh(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::ptanh(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = 5 * NumTraits::MulCost, + PacketAccess = packet_traits::HasTanh + }; +}; + +/** \internal + * \brief Template functor to compute the sinh of a scalar + * \sa class CwiseUnaryOp, ArrayBase::sinh() + */ +template struct scalar_sinh_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_sinh_op) + inline const Scalar operator() (const Scalar& a) const { using std::sinh; return sinh(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::psinh(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = 5 * NumTraits::MulCost, + PacketAccess = packet_traits::HasSinh + }; +}; + +/** \internal + * \brief Template functor to compute the cosh of a scalar + * \sa class CwiseUnaryOp, ArrayBase::cosh() + */ +template struct scalar_cosh_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_cosh_op) + inline const Scalar operator() (const Scalar& a) const { using std::cosh; return cosh(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pcosh(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = 5 * NumTraits::MulCost, + PacketAccess = packet_traits::HasCosh + }; +}; + /** \internal * \brief Template functor to compute the inverse of a scalar * \sa class CwiseUnaryOp, Cwise::inverse() diff --git a/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/Eigen/src/plugins/ArrayCwiseUnaryOps.h index eae5de9f6..032f5c31c 100644 --- a/Eigen/src/plugins/ArrayCwiseUnaryOps.h +++ b/Eigen/src/plugins/ArrayCwiseUnaryOps.h @@ -11,10 +11,13 @@ typedef CwiseUnaryOp, const Derived> LogReturnTy typedef CwiseUnaryOp, const Derived> Log10ReturnType; typedef CwiseUnaryOp, const Derived> CosReturnType; typedef CwiseUnaryOp, const Derived> SinReturnType; +typedef CwiseUnaryOp, const Derived> TanReturnType; typedef CwiseUnaryOp, const Derived> AcosReturnType; typedef CwiseUnaryOp, const Derived> AsinReturnType; -typedef CwiseUnaryOp, const Derived> TanReturnType; typedef CwiseUnaryOp, const Derived> AtanReturnType; +typedef CwiseUnaryOp, const Derived> TanhReturnType; +typedef CwiseUnaryOp, const Derived> SinhReturnType; +typedef CwiseUnaryOp, const Derived> CoshReturnType; typedef CwiseUnaryOp, const Derived> PowReturnType; typedef CwiseUnaryOp, const Derived> SquareReturnType; typedef CwiseUnaryOp, const Derived> CubeReturnType; @@ -168,6 +171,33 @@ sin() const return SinReturnType(derived()); } +/** \returns an expression of the coefficient-wise tan of *this. + * + * Example: \include Cwise_tan.cpp + * Output: \verbinclude Cwise_tan.out + * + * \sa cos(), sin() + */ +EIGEN_DEVICE_FUNC +inline const TanReturnType +tan() const +{ + return TanReturnType(derived()); +} + +/** \returns an expression of the coefficient-wise arc tan of *this. + * + * Example: \include Cwise_atan.cpp + * Output: \verbinclude Cwise_atan.out + * + * \sa tan(), asin(), acos() + */ +inline const AtanReturnType +atan() const +{ + return AtanReturnType(derived()); +} + /** \returns an expression of the coefficient-wise arc cosine of *this. * * Example: \include Cwise_acos.cpp @@ -196,31 +226,43 @@ asin() const return AsinReturnType(derived()); } -/** \returns an expression of the coefficient-wise tan of *this. +/** \returns an expression of the coefficient-wise hyperbolic tan of *this. * - * Example: \include Cwise_tan.cpp - * Output: \verbinclude Cwise_tan.out + * Example: \include Cwise_tanh.cpp + * Output: \verbinclude Cwise_tanh.out * - * \sa cos(), sin() + * \sa tan(), sinh(), cosh() */ -EIGEN_DEVICE_FUNC -inline const TanReturnType -tan() const +inline const TanhReturnType +tanh() const { - return TanReturnType(derived()); + return TanhReturnType(derived()); } -/** \returns an expression of the coefficient-wise arc tan of *this. +/** \returns an expression of the coefficient-wise hyperbolic sin of *this. * - * Example: \include Cwise_atan.cpp - * Output: \verbinclude Cwise_atan.out + * Example: \include Cwise_sinh.cpp + * Output: \verbinclude Cwise_sinh.out * - * \sa cos(), sin(), tan() + * \sa sin(), tanh(), cosh() */ -inline const AtanReturnType -atan() const +inline const SinhReturnType +sinh() const { - return AtanReturnType(derived()); + return SinhReturnType(derived()); +} + +/** \returns an expression of the coefficient-wise hyperbolic cos of *this. + * + * Example: \include Cwise_cosh.cpp + * Output: \verbinclude Cwise_cosh.out + * + * \sa tan(), sinh(), cosh() + */ +inline const CoshReturnType +cosh() const +{ + return CoshReturnType(derived()); } /** \returns an expression of the coefficient-wise power of *this to the given exponent. diff --git a/test/array.cpp b/test/array.cpp index 1a6c7987e..a8b6a3afc 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -200,10 +200,13 @@ template void array_real(const ArrayType& m) // these tests are mostly to check possible compilation issues. VERIFY_IS_APPROX(m1.sin(), sin(m1)); VERIFY_IS_APPROX(m1.cos(), cos(m1)); + VERIFY_IS_APPROX(m1.tan(), tan(m1)); VERIFY_IS_APPROX(m1.asin(), asin(m1)); VERIFY_IS_APPROX(m1.acos(), acos(m1)); - VERIFY_IS_APPROX(m1.tan(), tan(m1)); VERIFY_IS_APPROX(m1.atan(), atan(m1)); + VERIFY_IS_APPROX(m1.sinh(), sinh(m1)); + VERIFY_IS_APPROX(m1.cosh(), cosh(m1)); + VERIFY_IS_APPROX(m1.tanh(), tanh(m1)); VERIFY_IS_APPROX(m1.log(), log(m1)); VERIFY_IS_APPROX(m1.log10(), log10(m1)); VERIFY_IS_APPROX(m1.arg(), arg(m1)); @@ -281,6 +284,12 @@ template void array_complex(const ArrayType& m) VERIFY_IS_APPROX(m1.isnan(), isnan(m1)); VERIFY_IS_APPROX(m1.isinf(), isinf(m1)); VERIFY_IS_APPROX(m1.square(), square(m1)); + VERIFY_IS_APPROX(m1.sin(), sin(m1)); + VERIFY_IS_APPROX(m1.cos(), cos(m1)); + VERIFY_IS_APPROX(m1.tan(), tan(m1)); + VERIFY_IS_APPROX(m1.sinh(), sinh(m1)); + VERIFY_IS_APPROX(m1.cosh(), cosh(m1)); + VERIFY_IS_APPROX(m1.tanh(), tanh(m1)); } -- cgit v1.2.3 From fb68b149cb499baf1007b0f0b8cf1784eed185fe Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Tue, 17 Mar 2015 02:04:42 +1000 Subject: Rename isnan to isNaN --- Eigen/src/Core/Assign_MKL.h | 2 +- Eigen/src/Core/GenericPacketMath.h | 6 +++--- Eigen/src/Core/GlobalFunctions.h | 2 +- Eigen/src/Core/MathFunctions.h | 4 ++-- Eigen/src/Core/functors/UnaryFunctors.h | 16 ++++++++-------- Eigen/src/plugins/ArrayCwiseUnaryOps.h | 16 ++++++++-------- test/array.cpp | 4 ++-- 7 files changed, 25 insertions(+), 25 deletions(-) diff --git a/Eigen/src/Core/Assign_MKL.h b/Eigen/src/Core/Assign_MKL.h index fd1f391e3..25cfec25a 100644 --- a/Eigen/src/Core/Assign_MKL.h +++ b/Eigen/src/Core/Assign_MKL.h @@ -214,7 +214,7 @@ EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sqrt, Sqrt) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(round, Round) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(floor, Floor) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(ceil, Ceil) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(isnan, Isnan) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(isNaN, IsNaN) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(isinf, Isinf) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr) diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h index 35701cce4..5c217f4f0 100644 --- a/Eigen/src/Core/GenericPacketMath.h +++ b/Eigen/src/Core/GenericPacketMath.h @@ -77,7 +77,7 @@ struct default_packet_traits HasRound = 0, HasFloor = 0, HasCeil = 0, - HasIsnan = 0, + HasIsNaN = 0, HasIsinf = 0 }; }; @@ -395,9 +395,9 @@ Packet pfloor(const Packet& a) { using numext::floor; return floor(a); } template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pceil(const Packet& a) { using numext::ceil; return ceil(a); } -/** \internal \returns the isnan of \a a (coeff-wise) */ +/** \internal \returns whether \a a is NaN (coeff-wise) */ template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS -Packet pisnan(const Packet& a) { using numext::isnan; return isnan(a); } +Packet pisNaN(const Packet& a) { using numext::isNaN; return isNaN(a); } /** \internal \returns the isinf of \a a (coeff-wise) */ template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS diff --git a/Eigen/src/Core/GlobalFunctions.h b/Eigen/src/Core/GlobalFunctions.h index 44f9c7790..f7a8b06f4 100644 --- a/Eigen/src/Core/GlobalFunctions.h +++ b/Eigen/src/Core/GlobalFunctions.h @@ -59,7 +59,7 @@ namespace Eigen EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(round,scalar_round_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(floor,scalar_floor_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(ceil,scalar_ceil_op) - EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isnan,scalar_isnan_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isNaN,scalar_isNaN_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isinf,scalar_isinf_op) template diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index e98160ce3..a2c9d16f9 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -741,7 +741,7 @@ bool (isfinite)(const std::complex& x) template EIGEN_DEVICE_FUNC -bool (isnan)(const T& x) +bool (isNaN)(const T& x) { using std::isnan; return isnan(x); @@ -749,7 +749,7 @@ bool (isnan)(const T& x) template EIGEN_DEVICE_FUNC -bool (isnan)(const std::complex& x) +bool (isNaN)(const std::complex& x) { using std::real; using std::imag; diff --git a/Eigen/src/Core/functors/UnaryFunctors.h b/Eigen/src/Core/functors/UnaryFunctors.h index bf1bc47a8..e0ceb1b2b 100644 --- a/Eigen/src/Core/functors/UnaryFunctors.h +++ b/Eigen/src/Core/functors/UnaryFunctors.h @@ -566,23 +566,23 @@ struct functor_traits > }; /** \internal - * \brief Template functor to compute the isnan of a scalar - * \sa class CwiseUnaryOp, ArrayBase::isnan() + * \brief Template functor to compute whether a scalar is NaN + * \sa class CwiseUnaryOp, ArrayBase::isNaN() */ -template struct scalar_isnan_op { - EIGEN_EMPTY_STRUCT_CTOR(scalar_isnan_op) +template struct scalar_isNaN_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_isNaN_op) typedef bool result_type; - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::isnan(a); } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::isNaN(a); } template EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const - { return internal::pisnan(a); } + { return internal::pisNaN(a); } }; template -struct functor_traits > +struct functor_traits > { enum { Cost = NumTraits::MulCost, - PacketAccess = packet_traits::HasIsnan + PacketAccess = packet_traits::HasIsNaN }; }; diff --git a/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/Eigen/src/plugins/ArrayCwiseUnaryOps.h index 032f5c31c..5e5c8a857 100644 --- a/Eigen/src/plugins/ArrayCwiseUnaryOps.h +++ b/Eigen/src/plugins/ArrayCwiseUnaryOps.h @@ -24,7 +24,7 @@ typedef CwiseUnaryOp, const Derived> CubeReturn typedef CwiseUnaryOp, const Derived> RoundReturnType; typedef CwiseUnaryOp, const Derived> FloorReturnType; typedef CwiseUnaryOp, const Derived> CeilReturnType; -typedef CwiseUnaryOp, const Derived> IsnanReturnType; +typedef CwiseUnaryOp, const Derived> IsNaNReturnType; typedef CwiseUnaryOp, const Derived> IsinfReturnType; /** \returns an expression of the coefficient-wise absolute value of \c *this @@ -364,17 +364,17 @@ ceil() const return CeilReturnType(derived()); } -/** \returns an expression of the coefficient-wise isnan of *this. +/** \returns an expression of the coefficient-wise isNaN of *this. * - * Example: \include Cwise_isnan.cpp - * Output: \verbinclude Cwise_isnan.out + * Example: \include Cwise_isNaN.cpp + * Output: \verbinclude Cwise_isNaN.out * * \sa isinf() */ -inline const IsnanReturnType -isnan() const +inline const IsNaNReturnType +isNaN() const { - return IsnanReturnType(derived()); + return IsNaNReturnType(derived()); } /** \returns an expression of the coefficient-wise isinf of *this. @@ -382,7 +382,7 @@ isnan() const * Example: \include Cwise_isinf.cpp * Output: \verbinclude Cwise_isinf.out * - * \sa isnan() + * \sa isNaN() */ inline const IsinfReturnType isinf() const diff --git a/test/array.cpp b/test/array.cpp index a8b6a3afc..9686a7445 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -213,7 +213,7 @@ template void array_real(const ArrayType& m) VERIFY_IS_APPROX(m1.round(), round(m1)); VERIFY_IS_APPROX(m1.floor(), floor(m1)); VERIFY_IS_APPROX(m1.ceil(), ceil(m1)); - VERIFY_IS_APPROX(m1.isnan(), isnan(m1)); + VERIFY_IS_APPROX(m1.isNaN(), isNaN(m1)); VERIFY_IS_APPROX(m1.isinf(), isinf(m1)); VERIFY_IS_APPROX(m1.square(), square(m1)); @@ -281,7 +281,7 @@ template void array_complex(const ArrayType& m) VERIFY_IS_APPROX(m1.round(), round(m1)); VERIFY_IS_APPROX(m1.floor(), floor(m1)); VERIFY_IS_APPROX(m1.ceil(), ceil(m1)); - VERIFY_IS_APPROX(m1.isnan(), isnan(m1)); + VERIFY_IS_APPROX(m1.isNaN(), isNaN(m1)); VERIFY_IS_APPROX(m1.isinf(), isinf(m1)); VERIFY_IS_APPROX(m1.square(), square(m1)); VERIFY_IS_APPROX(m1.sin(), sin(m1)); -- cgit v1.2.3 From 717b7954cec7b1004dbb329fd33443f73aac5c80 Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Tue, 17 Mar 2015 02:11:57 +1000 Subject: Update cost of coeff-wise arg call --- Eigen/src/Core/functors/UnaryFunctors.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Eigen/src/Core/functors/UnaryFunctors.h b/Eigen/src/Core/functors/UnaryFunctors.h index e0ceb1b2b..1745d8b55 100644 --- a/Eigen/src/Core/functors/UnaryFunctors.h +++ b/Eigen/src/Core/functors/UnaryFunctors.h @@ -139,7 +139,7 @@ template struct functor_traits > { enum { - Cost = NumTraits::AddCost, + Cost = 5 * NumTraits::MulCost + NumTraits::AddCost, PacketAccess = packet_traits::HasArg }; }; -- cgit v1.2.3 From 1d76ceab551e1918bb049f473fc9a57f90dee028 Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Tue, 17 Mar 2015 02:36:07 +1000 Subject: Remove floor, ceil, round for complex numbers --- Eigen/src/Core/MathFunctions.h | 28 ---------------------------- 1 file changed, 28 deletions(-) diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index a2c9d16f9..fceb29e1a 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -784,14 +784,6 @@ T (round)(const T& x) return (x > 0.0) ? floor(x + 0.5) : ceil(x - 0.5); } -template -EIGEN_DEVICE_FUNC -std::complex (round)(const std::complex& x) -{ - using numext::round; - return std::complex(round(real(x)), round(imag(x))); -} - template EIGEN_DEVICE_FUNC T (floor)(const T& x) @@ -800,16 +792,6 @@ T (floor)(const T& x) return floor(x); } -template -EIGEN_DEVICE_FUNC -std::complex (floor)(const std::complex& x) -{ - using std::real; - using std::imag; - using std::floor; - return std::complex(floor(real(x)), floor(imag(x))); -} - template EIGEN_DEVICE_FUNC T (ceil)(const T& x) @@ -818,16 +800,6 @@ T (ceil)(const T& x) return ceil(x); } -template -EIGEN_DEVICE_FUNC -std::complex (ceil)(const std::complex& x) -{ - using std::real; - using std::imag; - using std::ceil; - return std::complex(ceil(real(x)), ceil(imag(x))); -} - // Log base 2 for 32 bits positive integers. // Conveniently returns 0 for x==0. inline int log2(int x) -- cgit v1.2.3 From 7b829940d1ce106f9b83aba63782cb7be689ba5d Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Tue, 17 Mar 2015 03:40:28 +1000 Subject: Add code snippets for new methods --- doc/snippets/Cwise_arg.cpp | 3 +++ doc/snippets/Cwise_ceil.cpp | 3 +++ doc/snippets/Cwise_cosh.cpp | 2 ++ doc/snippets/Cwise_floor.cpp | 3 +++ doc/snippets/Cwise_isNaN.cpp | 5 +++++ doc/snippets/Cwise_isinf.cpp | 5 +++++ doc/snippets/Cwise_log10.cpp | 2 ++ doc/snippets/Cwise_round.cpp | 3 +++ doc/snippets/Cwise_sinh.cpp | 2 ++ doc/snippets/Cwise_tanh.cpp | 2 ++ 10 files changed, 30 insertions(+) create mode 100644 doc/snippets/Cwise_arg.cpp create mode 100644 doc/snippets/Cwise_ceil.cpp create mode 100644 doc/snippets/Cwise_cosh.cpp create mode 100644 doc/snippets/Cwise_floor.cpp create mode 100644 doc/snippets/Cwise_isNaN.cpp create mode 100644 doc/snippets/Cwise_isinf.cpp create mode 100644 doc/snippets/Cwise_log10.cpp create mode 100644 doc/snippets/Cwise_round.cpp create mode 100644 doc/snippets/Cwise_sinh.cpp create mode 100644 doc/snippets/Cwise_tanh.cpp diff --git a/doc/snippets/Cwise_arg.cpp b/doc/snippets/Cwise_arg.cpp new file mode 100644 index 000000000..3f45133b6 --- /dev/null +++ b/doc/snippets/Cwise_arg.cpp @@ -0,0 +1,3 @@ +ArrayXcf v = ArrayXcf::Random(3); +cout << v << endl << endl; +cout << arg(v) << endl; diff --git a/doc/snippets/Cwise_ceil.cpp b/doc/snippets/Cwise_ceil.cpp new file mode 100644 index 000000000..76cf661f4 --- /dev/null +++ b/doc/snippets/Cwise_ceil.cpp @@ -0,0 +1,3 @@ +ArrayXd v = ArrayXd::LinSpaced(7,-2,2); +cout << v << endl << endl; +cout << ceil(v) << endl; diff --git a/doc/snippets/Cwise_cosh.cpp b/doc/snippets/Cwise_cosh.cpp new file mode 100644 index 000000000..80ee75da5 --- /dev/null +++ b/doc/snippets/Cwise_cosh.cpp @@ -0,0 +1,2 @@ +ArrayXd v = ArrayXd::LinSpaced(5,0,1); +cout << cosh(v) << endl; diff --git a/doc/snippets/Cwise_floor.cpp b/doc/snippets/Cwise_floor.cpp new file mode 100644 index 000000000..73756b41c --- /dev/null +++ b/doc/snippets/Cwise_floor.cpp @@ -0,0 +1,3 @@ +ArrayXd v = ArrayXd::LinSpaced(7,-2,2); +cout << v << endl << endl; +cout << floor(v) << endl; diff --git a/doc/snippets/Cwise_isNaN.cpp b/doc/snippets/Cwise_isNaN.cpp new file mode 100644 index 000000000..cc1e7fe6a --- /dev/null +++ b/doc/snippets/Cwise_isNaN.cpp @@ -0,0 +1,5 @@ +Array3d v(1,2,3); +v(1) *= 0.0/0.0; +v(2) /= 0.0; +cout << v << endl << endl; +cout << isNaN(v) << endl; diff --git a/doc/snippets/Cwise_isinf.cpp b/doc/snippets/Cwise_isinf.cpp new file mode 100644 index 000000000..be793081c --- /dev/null +++ b/doc/snippets/Cwise_isinf.cpp @@ -0,0 +1,5 @@ +Array3d v(1,2,3); +v(1) *= 0.0/0.0; +v(2) /= 0.0; +cout << v << endl << endl; +cout << isinf(v) << endl; diff --git a/doc/snippets/Cwise_log10.cpp b/doc/snippets/Cwise_log10.cpp new file mode 100644 index 000000000..b7ae4a834 --- /dev/null +++ b/doc/snippets/Cwise_log10.cpp @@ -0,0 +1,2 @@ +Array4d v(-1,0,1,2); +cout << log10(v) << endl; diff --git a/doc/snippets/Cwise_round.cpp b/doc/snippets/Cwise_round.cpp new file mode 100644 index 000000000..e5c88230b --- /dev/null +++ b/doc/snippets/Cwise_round.cpp @@ -0,0 +1,3 @@ +ArrayXd v = ArrayXd::LinSpaced(7,-2,2); +cout << v << endl << endl; +cout << round(v) << endl; diff --git a/doc/snippets/Cwise_sinh.cpp b/doc/snippets/Cwise_sinh.cpp new file mode 100644 index 000000000..fac9b19a8 --- /dev/null +++ b/doc/snippets/Cwise_sinh.cpp @@ -0,0 +1,2 @@ +ArrayXd v = ArrayXd::LinSpaced(5,0,1); +cout << sinh(v) << endl; diff --git a/doc/snippets/Cwise_tanh.cpp b/doc/snippets/Cwise_tanh.cpp new file mode 100644 index 000000000..30cd0450d --- /dev/null +++ b/doc/snippets/Cwise_tanh.cpp @@ -0,0 +1,2 @@ +ArrayXd v = ArrayXd::LinSpaced(5,0,1); +cout << tanh(v) << endl; -- cgit v1.2.3 From 46cf9cda32be99fcd658a926c14088e087d91b7e Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Tue, 17 Mar 2015 04:33:12 +1000 Subject: Add isfinite array support as isFinite --- Eigen/src/Core/Assign_MKL.h | 1 + Eigen/src/Core/GenericPacketMath.h | 7 ++++++- Eigen/src/Core/GlobalFunctions.h | 1 + Eigen/src/Core/functors/UnaryFunctors.h | 20 ++++++++++++++++++++ Eigen/src/plugins/ArrayCwiseUnaryOps.h | 16 +++++++++++++++- doc/snippets/Cwise_isFinite.cpp | 5 +++++ test/array.cpp | 2 ++ 7 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 doc/snippets/Cwise_isFinite.cpp diff --git a/Eigen/src/Core/Assign_MKL.h b/Eigen/src/Core/Assign_MKL.h index 25cfec25a..ec333e4a1 100644 --- a/Eigen/src/Core/Assign_MKL.h +++ b/Eigen/src/Core/Assign_MKL.h @@ -216,6 +216,7 @@ EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(floor, Floor) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(ceil, Ceil) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(isNaN, IsNaN) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(isinf, Isinf) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(isFinite, IsFinite) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr) diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h index 5c217f4f0..c0c3ba1c9 100644 --- a/Eigen/src/Core/GenericPacketMath.h +++ b/Eigen/src/Core/GenericPacketMath.h @@ -78,7 +78,8 @@ struct default_packet_traits HasFloor = 0, HasCeil = 0, HasIsNaN = 0, - HasIsinf = 0 + HasIsinf = 0, + HasIsFinite = 0 }; }; @@ -403,6 +404,10 @@ Packet pisNaN(const Packet& a) { using numext::isNaN; return isNaN(a); } template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pisinf(const Packet& a) { using numext::isinf; return isinf(a); } +/** \internal \returns the isFinite of \a a (coeff-wise) */ +template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet pisFinite(const Packet& a) { using numext::isfinite; return isfinite(a); } + /*************************************************************************** * The following functions might not have to be overwritten for vectorized types ***************************************************************************/ diff --git a/Eigen/src/Core/GlobalFunctions.h b/Eigen/src/Core/GlobalFunctions.h index f7a8b06f4..03627c759 100644 --- a/Eigen/src/Core/GlobalFunctions.h +++ b/Eigen/src/Core/GlobalFunctions.h @@ -61,6 +61,7 @@ namespace Eigen EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(ceil,scalar_ceil_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isNaN,scalar_isNaN_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isinf,scalar_isinf_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isFinite,scalar_isFinite_op) template inline const Eigen::CwiseUnaryOp, const Derived> diff --git a/Eigen/src/Core/functors/UnaryFunctors.h b/Eigen/src/Core/functors/UnaryFunctors.h index 1745d8b55..a340963c2 100644 --- a/Eigen/src/Core/functors/UnaryFunctors.h +++ b/Eigen/src/Core/functors/UnaryFunctors.h @@ -606,6 +606,26 @@ struct functor_traits > }; }; +/** \internal + * \brief Template functor to compute the isFinite of a scalar + * \sa class CwiseUnaryOp, ArrayBase::isFinite() + */ +template struct scalar_isFinite_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_isFinite_op) + typedef bool result_type; + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::isfinite(a); } + typedef typename packet_traits::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pisFinite(a); } +}; +template +struct functor_traits > +{ + enum { + Cost = NumTraits::MulCost, + PacketAccess = packet_traits::HasIsFinite + }; +}; + } // end namespace internal } // end namespace Eigen diff --git a/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/Eigen/src/plugins/ArrayCwiseUnaryOps.h index 5e5c8a857..32f2afc00 100644 --- a/Eigen/src/plugins/ArrayCwiseUnaryOps.h +++ b/Eigen/src/plugins/ArrayCwiseUnaryOps.h @@ -26,6 +26,7 @@ typedef CwiseUnaryOp, const Derived> FloorRetu typedef CwiseUnaryOp, const Derived> CeilReturnType; typedef CwiseUnaryOp, const Derived> IsNaNReturnType; typedef CwiseUnaryOp, const Derived> IsinfReturnType; +typedef CwiseUnaryOp, const Derived> IsFiniteReturnType; /** \returns an expression of the coefficient-wise absolute value of \c *this * @@ -369,7 +370,7 @@ ceil() const * Example: \include Cwise_isNaN.cpp * Output: \verbinclude Cwise_isNaN.out * - * \sa isinf() + * \sa isFinite(), isinf() */ inline const IsNaNReturnType isNaN() const @@ -390,6 +391,19 @@ isinf() const return IsinfReturnType(derived()); } +/** \returns an expression of the coefficient-wise isFinite of *this. + * + * Example: \include Cwise_isFinite.cpp + * Output: \verbinclude Cwise_isFinite.out + * + * \sa isNaN() + */ +inline const IsFiniteReturnType +isFinite() const +{ + return IsFiniteReturnType(derived()); +} + #define EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(METHOD_NAME,FUNCTOR) \ EIGEN_DEVICE_FUNC \ inline const CwiseUnaryOp >, const Derived> \ diff --git a/doc/snippets/Cwise_isFinite.cpp b/doc/snippets/Cwise_isFinite.cpp new file mode 100644 index 000000000..7e59456bf --- /dev/null +++ b/doc/snippets/Cwise_isFinite.cpp @@ -0,0 +1,5 @@ +Array3d v(1,2,3); +v(1) *= 0.0/0.0; +v(2) /= 0.0; +cout << v << endl << endl; +cout << isFinite(v) << endl; diff --git a/test/array.cpp b/test/array.cpp index 9686a7445..cc0aed0a6 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -215,6 +215,7 @@ template void array_real(const ArrayType& m) VERIFY_IS_APPROX(m1.ceil(), ceil(m1)); VERIFY_IS_APPROX(m1.isNaN(), isNaN(m1)); VERIFY_IS_APPROX(m1.isinf(), isinf(m1)); + VERIFY_IS_APPROX(m1.isFinite(), isFinite(m1)); VERIFY_IS_APPROX(m1.square(), square(m1)); VERIFY_IS_APPROX(cos(m1+RealScalar(3)*m2), cos((m1+RealScalar(3)*m2).eval())); @@ -283,6 +284,7 @@ template void array_complex(const ArrayType& m) VERIFY_IS_APPROX(m1.ceil(), ceil(m1)); VERIFY_IS_APPROX(m1.isNaN(), isNaN(m1)); VERIFY_IS_APPROX(m1.isinf(), isinf(m1)); + VERIFY_IS_APPROX(m1.isFinite(), isFinite(m1)); VERIFY_IS_APPROX(m1.square(), square(m1)); VERIFY_IS_APPROX(m1.sin(), sin(m1)); VERIFY_IS_APPROX(m1.cos(), cos(m1)); -- cgit v1.2.3 From fef4e071d70870e91aba68b0a34e53bb20f9303f Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Tue, 17 Mar 2015 05:58:47 +1000 Subject: Rename isinf to isInf --- Eigen/src/Core/Assign_MKL.h | 2 +- Eigen/src/Core/GenericPacketMath.h | 6 +++--- Eigen/src/Core/GlobalFunctions.h | 2 +- Eigen/src/Core/MathFunctions.h | 4 ++-- Eigen/src/Core/functors/UnaryFunctors.h | 16 ++++++++-------- Eigen/src/plugins/ArrayCwiseUnaryOps.h | 16 ++++++++-------- doc/snippets/Cwise_isInf.cpp | 5 +++++ doc/snippets/Cwise_isinf.cpp | 5 ----- test/array.cpp | 4 ++-- 9 files changed, 30 insertions(+), 30 deletions(-) create mode 100644 doc/snippets/Cwise_isInf.cpp delete mode 100644 doc/snippets/Cwise_isinf.cpp diff --git a/Eigen/src/Core/Assign_MKL.h b/Eigen/src/Core/Assign_MKL.h index ec333e4a1..60d8df2de 100644 --- a/Eigen/src/Core/Assign_MKL.h +++ b/Eigen/src/Core/Assign_MKL.h @@ -215,7 +215,7 @@ EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(round, Round) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(floor, Floor) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(ceil, Ceil) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(isNaN, IsNaN) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(isinf, Isinf) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(isInf, IsInf) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(isFinite, IsFinite) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr) diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h index c0c3ba1c9..7a467e8db 100644 --- a/Eigen/src/Core/GenericPacketMath.h +++ b/Eigen/src/Core/GenericPacketMath.h @@ -78,7 +78,7 @@ struct default_packet_traits HasFloor = 0, HasCeil = 0, HasIsNaN = 0, - HasIsinf = 0, + HasIsInf = 0, HasIsFinite = 0 }; }; @@ -400,9 +400,9 @@ Packet pceil(const Packet& a) { using numext::ceil; return ceil(a); } template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pisNaN(const Packet& a) { using numext::isNaN; return isNaN(a); } -/** \internal \returns the isinf of \a a (coeff-wise) */ +/** \internal \returns the isInf of \a a (coeff-wise) */ template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS -Packet pisinf(const Packet& a) { using numext::isinf; return isinf(a); } +Packet pisInf(const Packet& a) { using numext::isInf; return isInf(a); } /** \internal \returns the isFinite of \a a (coeff-wise) */ template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS diff --git a/Eigen/src/Core/GlobalFunctions.h b/Eigen/src/Core/GlobalFunctions.h index 03627c759..b99bc7533 100644 --- a/Eigen/src/Core/GlobalFunctions.h +++ b/Eigen/src/Core/GlobalFunctions.h @@ -60,7 +60,7 @@ namespace Eigen EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(floor,scalar_floor_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(ceil,scalar_ceil_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isNaN,scalar_isNaN_op) - EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isinf,scalar_isinf_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isInf,scalar_isInf_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(isFinite,scalar_isFinite_op) template diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index fceb29e1a..36a6eb650 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -759,7 +759,7 @@ bool (isNaN)(const std::complex& x) template EIGEN_DEVICE_FUNC -bool (isinf)(const T& x) +bool (isInf)(const T& x) { using std::isinf; return isinf(x); @@ -767,7 +767,7 @@ bool (isinf)(const T& x) template EIGEN_DEVICE_FUNC -bool (isinf)(const std::complex& x) +bool (isInf)(const std::complex& x) { using std::real; using std::imag; diff --git a/Eigen/src/Core/functors/UnaryFunctors.h b/Eigen/src/Core/functors/UnaryFunctors.h index a340963c2..fa74aeae0 100644 --- a/Eigen/src/Core/functors/UnaryFunctors.h +++ b/Eigen/src/Core/functors/UnaryFunctors.h @@ -587,22 +587,22 @@ struct functor_traits > }; /** \internal - * \brief Template functor to compute the isinf of a scalar - * \sa class CwiseUnaryOp, ArrayBase::isinf() + * \brief Template functor to compute the isInf of a scalar + * \sa class CwiseUnaryOp, ArrayBase::isInf() */ -template struct scalar_isinf_op { - EIGEN_EMPTY_STRUCT_CTOR(scalar_isinf_op) +template struct scalar_isInf_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_isInf_op) typedef bool result_type; - EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::isinf(a); } + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::isInf(a); } typedef typename packet_traits::type Packet; - inline Packet packetOp(const Packet& a) const { return internal::pisinf(a); } + inline Packet packetOp(const Packet& a) const { return internal::pisInf(a); } }; template -struct functor_traits > +struct functor_traits > { enum { Cost = NumTraits::MulCost, - PacketAccess = packet_traits::HasIsinf + PacketAccess = packet_traits::HasIsInf }; }; diff --git a/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/Eigen/src/plugins/ArrayCwiseUnaryOps.h index 32f2afc00..6e6c86401 100644 --- a/Eigen/src/plugins/ArrayCwiseUnaryOps.h +++ b/Eigen/src/plugins/ArrayCwiseUnaryOps.h @@ -25,7 +25,7 @@ typedef CwiseUnaryOp, const Derived> RoundRetu typedef CwiseUnaryOp, const Derived> FloorReturnType; typedef CwiseUnaryOp, const Derived> CeilReturnType; typedef CwiseUnaryOp, const Derived> IsNaNReturnType; -typedef CwiseUnaryOp, const Derived> IsinfReturnType; +typedef CwiseUnaryOp, const Derived> IsInfReturnType; typedef CwiseUnaryOp, const Derived> IsFiniteReturnType; /** \returns an expression of the coefficient-wise absolute value of \c *this @@ -370,7 +370,7 @@ ceil() const * Example: \include Cwise_isNaN.cpp * Output: \verbinclude Cwise_isNaN.out * - * \sa isFinite(), isinf() + * \sa isFinite(), isInf() */ inline const IsNaNReturnType isNaN() const @@ -378,17 +378,17 @@ isNaN() const return IsNaNReturnType(derived()); } -/** \returns an expression of the coefficient-wise isinf of *this. +/** \returns an expression of the coefficient-wise isInf of *this. * - * Example: \include Cwise_isinf.cpp - * Output: \verbinclude Cwise_isinf.out + * Example: \include Cwise_isInf.cpp + * Output: \verbinclude Cwise_isInf.out * * \sa isNaN() */ -inline const IsinfReturnType -isinf() const +inline const IsInfReturnType +isInf() const { - return IsinfReturnType(derived()); + return IsInfReturnType(derived()); } /** \returns an expression of the coefficient-wise isFinite of *this. diff --git a/doc/snippets/Cwise_isInf.cpp b/doc/snippets/Cwise_isInf.cpp new file mode 100644 index 000000000..beb6746d0 --- /dev/null +++ b/doc/snippets/Cwise_isInf.cpp @@ -0,0 +1,5 @@ +Array3d v(1,2,3); +v(1) *= 0.0/0.0; +v(2) /= 0.0; +cout << v << endl << endl; +cout << isInf(v) << endl; diff --git a/doc/snippets/Cwise_isinf.cpp b/doc/snippets/Cwise_isinf.cpp deleted file mode 100644 index be793081c..000000000 --- a/doc/snippets/Cwise_isinf.cpp +++ /dev/null @@ -1,5 +0,0 @@ -Array3d v(1,2,3); -v(1) *= 0.0/0.0; -v(2) /= 0.0; -cout << v << endl << endl; -cout << isinf(v) << endl; diff --git a/test/array.cpp b/test/array.cpp index cc0aed0a6..5729e8eed 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -214,7 +214,7 @@ template void array_real(const ArrayType& m) VERIFY_IS_APPROX(m1.floor(), floor(m1)); VERIFY_IS_APPROX(m1.ceil(), ceil(m1)); VERIFY_IS_APPROX(m1.isNaN(), isNaN(m1)); - VERIFY_IS_APPROX(m1.isinf(), isinf(m1)); + VERIFY_IS_APPROX(m1.isInf(), isInf(m1)); VERIFY_IS_APPROX(m1.isFinite(), isFinite(m1)); VERIFY_IS_APPROX(m1.square(), square(m1)); @@ -283,7 +283,7 @@ template void array_complex(const ArrayType& m) VERIFY_IS_APPROX(m1.floor(), floor(m1)); VERIFY_IS_APPROX(m1.ceil(), ceil(m1)); VERIFY_IS_APPROX(m1.isNaN(), isNaN(m1)); - VERIFY_IS_APPROX(m1.isinf(), isinf(m1)); + VERIFY_IS_APPROX(m1.isInf(), isInf(m1)); VERIFY_IS_APPROX(m1.isFinite(), isFinite(m1)); VERIFY_IS_APPROX(m1.square(), square(m1)); VERIFY_IS_APPROX(m1.sin(), sin(m1)); -- cgit v1.2.3 From e1d6e6c972e378a0a97212a5fced6166c6a5b722 Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Tue, 17 Mar 2015 06:25:24 +1000 Subject: Make cube, inverse and abs2 free-functions --- Eigen/src/Core/GlobalFunctions.h | 3 +++ test/array.cpp | 11 +++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Eigen/src/Core/GlobalFunctions.h b/Eigen/src/Core/GlobalFunctions.h index b99bc7533..1924c8e5f 100644 --- a/Eigen/src/Core/GlobalFunctions.h +++ b/Eigen/src/Core/GlobalFunctions.h @@ -40,6 +40,7 @@ namespace Eigen EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(real,scalar_real_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(imag,scalar_imag_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(conj,scalar_conjugate_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(inverse,scalar_inverse_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sin,scalar_sin_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cos,scalar_cos_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(tan,scalar_tan_op) @@ -53,9 +54,11 @@ namespace Eigen EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log10,scalar_log10_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs,scalar_abs_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs2,scalar_abs2_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(arg,scalar_arg_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(sqrt,scalar_sqrt_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(square,scalar_square_op) + EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(cube,scalar_cube_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(round,scalar_round_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(floor,scalar_floor_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(ceil,scalar_ceil_op) diff --git a/test/array.cpp b/test/array.cpp index 5729e8eed..590a1a74e 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -216,7 +216,10 @@ template void array_real(const ArrayType& m) VERIFY_IS_APPROX(m1.isNaN(), isNaN(m1)); VERIFY_IS_APPROX(m1.isInf(), isInf(m1)); VERIFY_IS_APPROX(m1.isFinite(), isFinite(m1)); - VERIFY_IS_APPROX(m1.square(), square(m1)); + VERIFY_IS_APPROX(inverse(m1.inverse()), m1); + VERIFY_IS_APPROX(abs2(m1.abs2()), pow(abs(m1),2*2)); + VERIFY_IS_APPROX(m1.square().sqrt(), sqrt(square(m1))); + VERIFY_IS_APPROX(cube(m1.cube()), pow((m1),3*3)); VERIFY_IS_APPROX(cos(m1+RealScalar(3)*m2), cos((m1+RealScalar(3)*m2).eval())); @@ -279,13 +282,17 @@ template void array_complex(const ArrayType& m) VERIFY_IS_APPROX(m1.log(), log(m1)); VERIFY_IS_APPROX(m1.log10(), log10(m1)); VERIFY_IS_APPROX(m1.arg(), arg(m1)); + VERIFY_IS_APPROX(abs2(m1.abs2()), pow(abs(m1),2*2)); VERIFY_IS_APPROX(m1.round(), round(m1)); VERIFY_IS_APPROX(m1.floor(), floor(m1)); VERIFY_IS_APPROX(m1.ceil(), ceil(m1)); VERIFY_IS_APPROX(m1.isNaN(), isNaN(m1)); VERIFY_IS_APPROX(m1.isInf(), isInf(m1)); VERIFY_IS_APPROX(m1.isFinite(), isFinite(m1)); - VERIFY_IS_APPROX(m1.square(), square(m1)); + VERIFY_IS_APPROX(m1.square().sqrt(), sqrt(square(m1))); + VERIFY_IS_APPROX(cube(m1.cube()), pow((m1),3*3)); + VERIFY_IS_APPROX(conj(m1.conjugate()), m1); + VERIFY_IS_APPROX(inverse(m1.inverse()), m1); VERIFY_IS_APPROX(m1.sin(), sin(m1)); VERIFY_IS_APPROX(m1.cos(), cos(m1)); VERIFY_IS_APPROX(m1.tan(), tan(m1)); -- cgit v1.2.3 From 85da0c22819dcab2b7d50802e4e40e1e781e2e8b Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Tue, 17 Mar 2015 06:56:47 +1000 Subject: Remove test of now-missing floor, ceil, round complex implementations --- test/array.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/array.cpp b/test/array.cpp index 590a1a74e..a17fe9b4a 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -283,9 +283,6 @@ template void array_complex(const ArrayType& m) VERIFY_IS_APPROX(m1.log10(), log10(m1)); VERIFY_IS_APPROX(m1.arg(), arg(m1)); VERIFY_IS_APPROX(abs2(m1.abs2()), pow(abs(m1),2*2)); - VERIFY_IS_APPROX(m1.round(), round(m1)); - VERIFY_IS_APPROX(m1.floor(), floor(m1)); - VERIFY_IS_APPROX(m1.ceil(), ceil(m1)); VERIFY_IS_APPROX(m1.isNaN(), isNaN(m1)); VERIFY_IS_APPROX(m1.isInf(), isInf(m1)); VERIFY_IS_APPROX(m1.isFinite(), isFinite(m1)); -- cgit v1.2.3 From 1c78d6f2a6c7be509c1a190e1cfe42bce1916230 Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Tue, 17 Mar 2015 08:29:57 +1000 Subject: Add boolean not operator (!) array support --- Eigen/src/Core/functors/UnaryFunctors.h | 18 ++++++++++++++++++ Eigen/src/plugins/ArrayCwiseUnaryOps.h | 20 ++++++++++++++++++++ doc/snippets/Cwise_boolean_not.cpp | 5 +++++ test/array.cpp | 2 ++ 4 files changed, 45 insertions(+) create mode 100644 doc/snippets/Cwise_boolean_not.cpp diff --git a/Eigen/src/Core/functors/UnaryFunctors.h b/Eigen/src/Core/functors/UnaryFunctors.h index fa74aeae0..a7cd3b7ca 100644 --- a/Eigen/src/Core/functors/UnaryFunctors.h +++ b/Eigen/src/Core/functors/UnaryFunctors.h @@ -626,6 +626,24 @@ struct functor_traits > }; }; +/** \internal + * \brief Template functor to compute the logical not of a boolean + * + * \sa class CwiseUnaryOp, ArrayBase::operator! + */ +template struct scalar_boolean_not_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_not_op) + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a) const { return !a; } +}; +template +struct functor_traits > { + enum { + Cost = NumTraits::AddCost, + PacketAccess = false + }; +}; + + } // end namespace internal } // end namespace Eigen diff --git a/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/Eigen/src/plugins/ArrayCwiseUnaryOps.h index 6e6c86401..1d5c9a6c1 100644 --- a/Eigen/src/plugins/ArrayCwiseUnaryOps.h +++ b/Eigen/src/plugins/ArrayCwiseUnaryOps.h @@ -5,6 +5,7 @@ typedef CwiseUnaryOp, const Derived> ArgReturnTy typedef CwiseUnaryOp, const Derived> Abs2ReturnType; typedef CwiseUnaryOp, const Derived> SqrtReturnType; typedef CwiseUnaryOp, const Derived> InverseReturnType; +typedef CwiseUnaryOp, const Derived> BooleanNotReturnType; typedef CwiseUnaryOp, const Derived> ExpReturnType; typedef CwiseUnaryOp, const Derived> LogReturnType; @@ -404,6 +405,25 @@ isFinite() const return IsFiniteReturnType(derived()); } +/** \returns an expression of the coefficient-wise ! operator of *this + * + * \warning this operator is for expression of bool only. + * + * Example: \include Cwise_boolean_not.cpp + * Output: \verbinclude Cwise_boolean_not.out + * + * \sa operator!=() + */ +EIGEN_DEVICE_FUNC +inline const BooleanNotReturnType +operator!() const +{ + EIGEN_STATIC_ASSERT((internal::is_same::value), + THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL); + return BooleanNotReturnType(derived()); +} + + #define EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(METHOD_NAME,FUNCTOR) \ EIGEN_DEVICE_FUNC \ inline const CwiseUnaryOp >, const Derived> \ diff --git a/doc/snippets/Cwise_boolean_not.cpp b/doc/snippets/Cwise_boolean_not.cpp new file mode 100644 index 000000000..8b8e6fc95 --- /dev/null +++ b/doc/snippets/Cwise_boolean_not.cpp @@ -0,0 +1,5 @@ +Array3d v(1,2,3); +v(1) *= 0.0/0.0; +v(2) /= 0.0; +cout << v << endl << endl; +cout << !isFinite(v) << endl; diff --git a/test/array.cpp b/test/array.cpp index a17fe9b4a..254af2ee9 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -221,6 +221,8 @@ template void array_real(const ArrayType& m) VERIFY_IS_APPROX(m1.square().sqrt(), sqrt(square(m1))); VERIFY_IS_APPROX(cube(m1.cube()), pow((m1),3*3)); + VERIFY(!(m1>m2),(m1<=m2)); + VERIFY_IS_APPROX(cos(m1+RealScalar(3)*m2), cos((m1+RealScalar(3)*m2).eval())); VERIFY_IS_APPROX(m1.abs().sqrt(), sqrt(abs(m1))); -- cgit v1.2.3 From f52b78491c9a3a0c3e021be3e947d65190cf6833 Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Tue, 17 Mar 2015 09:26:24 +1000 Subject: Remove packet isNaN, isInf, isFinite --- Eigen/src/Core/Assign_MKL.h | 3 --- Eigen/src/Core/GenericPacketMath.h | 17 +---------------- Eigen/src/Core/functors/UnaryFunctors.h | 13 +++---------- 3 files changed, 4 insertions(+), 29 deletions(-) diff --git a/Eigen/src/Core/Assign_MKL.h b/Eigen/src/Core/Assign_MKL.h index 60d8df2de..6f08ece7d 100644 --- a/Eigen/src/Core/Assign_MKL.h +++ b/Eigen/src/Core/Assign_MKL.h @@ -214,9 +214,6 @@ EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sqrt, Sqrt) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(round, Round) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(floor, Floor) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(ceil, Ceil) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(isNaN, IsNaN) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(isInf, IsInf) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(isFinite, IsFinite) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr) diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h index 7a467e8db..85c0cb4ba 100644 --- a/Eigen/src/Core/GenericPacketMath.h +++ b/Eigen/src/Core/GenericPacketMath.h @@ -76,10 +76,7 @@ struct default_packet_traits HasRound = 0, HasFloor = 0, - HasCeil = 0, - HasIsNaN = 0, - HasIsInf = 0, - HasIsFinite = 0 + HasCeil = 0 }; }; @@ -396,18 +393,6 @@ Packet pfloor(const Packet& a) { using numext::floor; return floor(a); } template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pceil(const Packet& a) { using numext::ceil; return ceil(a); } -/** \internal \returns whether \a a is NaN (coeff-wise) */ -template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS -Packet pisNaN(const Packet& a) { using numext::isNaN; return isNaN(a); } - -/** \internal \returns the isInf of \a a (coeff-wise) */ -template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS -Packet pisInf(const Packet& a) { using numext::isInf; return isInf(a); } - -/** \internal \returns the isFinite of \a a (coeff-wise) */ -template EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS -Packet pisFinite(const Packet& a) { using numext::isfinite; return isfinite(a); } - /*************************************************************************** * The following functions might not have to be overwritten for vectorized types ***************************************************************************/ diff --git a/Eigen/src/Core/functors/UnaryFunctors.h b/Eigen/src/Core/functors/UnaryFunctors.h index a7cd3b7ca..01fef88f2 100644 --- a/Eigen/src/Core/functors/UnaryFunctors.h +++ b/Eigen/src/Core/functors/UnaryFunctors.h @@ -573,16 +573,13 @@ template struct scalar_isNaN_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_isNaN_op) typedef bool result_type; EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::isNaN(a); } - template - EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const - { return internal::pisNaN(a); } }; template struct functor_traits > { enum { Cost = NumTraits::MulCost, - PacketAccess = packet_traits::HasIsNaN + PacketAccess = false }; }; @@ -594,15 +591,13 @@ template struct scalar_isInf_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_isInf_op) typedef bool result_type; EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::isInf(a); } - typedef typename packet_traits::type Packet; - inline Packet packetOp(const Packet& a) const { return internal::pisInf(a); } }; template struct functor_traits > { enum { Cost = NumTraits::MulCost, - PacketAccess = packet_traits::HasIsInf + PacketAccess = false }; }; @@ -614,15 +609,13 @@ template struct scalar_isFinite_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_isFinite_op) typedef bool result_type; EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::isfinite(a); } - typedef typename packet_traits::type Packet; - inline Packet packetOp(const Packet& a) const { return internal::pisFinite(a); } }; template struct functor_traits > { enum { Cost = NumTraits::MulCost, - PacketAccess = packet_traits::HasIsFinite + PacketAccess = false }; }; -- cgit v1.2.3 From 447a5a6b0147b95bf3d377927df5b1b2b0a7e5d7 Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Tue, 17 Mar 2015 13:33:31 +1000 Subject: Fix VML declarations to only be for real/complex as appropriate --- Eigen/src/Core/Assign_MKL.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Eigen/src/Core/Assign_MKL.h b/Eigen/src/Core/Assign_MKL.h index 6f08ece7d..d4ef1d3a4 100644 --- a/Eigen/src/Core/Assign_MKL.h +++ b/Eigen/src/Core/Assign_MKL.h @@ -206,16 +206,16 @@ EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(tan, Tan) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(atan, Atan) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(tanh, Tanh) //EIGEN_MKL_VML_DECLARE_UNARY_CALLS(abs, Abs) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(arg, Arg) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(exp, Exp) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(log, Ln) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(log10, Log10) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sqrt, Sqrt) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(round, Round) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(floor, Floor) -EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(ceil, Ceil) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS(sqrt, Sqrt) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_COMPLEX(arg, Arg) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(round, Round) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(floor, Floor) +EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(ceil, Ceil) // The vm*powx functions are not avaibale in the windows version of MKL. #ifndef _WIN32 -- cgit v1.2.3 From e21e29a08850e43402824c9cc6a29a59420e3701 Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Tue, 17 Mar 2015 14:04:33 +1000 Subject: Update cost of arg call to depend on if the scalar is complex or not --- Eigen/src/Core/functors/UnaryFunctors.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Eigen/src/Core/functors/UnaryFunctors.h b/Eigen/src/Core/functors/UnaryFunctors.h index 01fef88f2..c92692e53 100644 --- a/Eigen/src/Core/functors/UnaryFunctors.h +++ b/Eigen/src/Core/functors/UnaryFunctors.h @@ -139,7 +139,7 @@ template struct functor_traits > { enum { - Cost = 5 * NumTraits::MulCost + NumTraits::AddCost, + Cost = NumTraits::IsComplex ? 5 * NumTraits::MulCost : NumTraits::AddCost, PacketAccess = packet_traits::HasArg }; }; -- cgit v1.2.3 From e26134ed62082adb9c382631d8afab03c855de60 Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Tue, 17 Mar 2015 14:55:14 +1000 Subject: Use std::round when c++11 is used, custom implementation otherwise --- Eigen/src/Core/MathFunctions.h | 47 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index 36a6eb650..a7e75b4a9 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -395,7 +395,44 @@ inline NewType cast(const OldType& x) } /**************************************************************************** -* Implementation of logp1 * +* Implementation of round * +****************************************************************************/ +// In C++11 we can specialize round_impl for real Scalars +// Let's be conservative and enable the default C++11 implementation only if we are sure it exists +#if (__cplusplus >= 201103L) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_MSVC || EIGEN_COMP_ICC) \ + && (EIGEN_ARCH_i386_OR_x86_64) && (EIGEN_OS_GNULINUX || EIGEN_OS_WIN_STRICT || EIGEN_OS_MAC) + template + struct round_impl { + static inline Scalar run(const Scalar& x) + { + EIGEN_STATIC_ASSERT((!NumTraits::IsComplex), NUMERIC_TYPE_MUST_BE_REAL) + using std::round; + return round(x); + } + }; +// No C++11, use our own implementation +#else + template + struct round_impl + { + static inline Scalar run(const Scalar& x) + { + EIGEN_STATIC_ASSERT((!NumTraits::IsComplex), NUMERIC_TYPE_MUST_BE_REAL) + using std::floor; + using std::ceil; + return (x > 0.0) ? floor(x + 0.5) : ceil(x - 0.5); + } + }; +#endif + +template +struct round_retval +{ + typedef Scalar type; +}; + +/**************************************************************************** +* Implementation of log1p * ****************************************************************************/ template::IsComplex > struct log1p_impl @@ -775,13 +812,11 @@ bool (isInf)(const std::complex& x) return isinf(real(x)) || isinf(imag(x)); } -template +template EIGEN_DEVICE_FUNC -T (round)(const T& x) +inline EIGEN_MATHFUNC_RETVAL(round, Scalar) round(const Scalar& x) { - using std::floor; - using std::ceil; - return (x > 0.0) ? floor(x + 0.5) : ceil(x - 0.5); + return EIGEN_MATHFUNC_IMPL(round, Scalar)::run(x); } template -- cgit v1.2.3 From 596be3cd86ad976c7e03a871fc44a95f377bfe0f Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Tue, 17 Mar 2015 15:28:12 +1000 Subject: Use std::arg for real numbers when c++11 is used, custom implementation otherwise --- Eigen/src/Core/MathFunctions.h | 85 +++++++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 35 deletions(-) diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index a7e75b4a9..734a5e373 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -133,41 +133,6 @@ struct imag_retval typedef typename NumTraits::Real type; }; -/**************************************************************************** -* Implementation of arg * -****************************************************************************/ - -template::IsComplex> -struct arg_default_impl -{ - typedef typename NumTraits::Real RealScalar; - EIGEN_DEVICE_FUNC - static inline RealScalar run(const Scalar& x) - { - const double pi = std::acos(-1.0); - return (x < 0.0) ? pi : 0.0; } -}; - -template -struct arg_default_impl -{ - typedef typename NumTraits::Real RealScalar; - EIGEN_DEVICE_FUNC - static inline RealScalar run(const Scalar& x) - { - using std::arg; - return arg(x); - } -}; - -template struct arg_impl : arg_default_impl {}; - -template -struct arg_retval -{ - typedef typename NumTraits::Real type; -}; - /**************************************************************************** * Implementation of real_ref * ****************************************************************************/ @@ -431,6 +396,56 @@ struct round_retval typedef Scalar type; }; +/**************************************************************************** +* Implementation of arg * +****************************************************************************/ +// In C++11 we can specialize arg_impl for all Scalars +// Let's be conservative and enable the default C++11 implementation only if we are sure it exists +#if (__cplusplus >= 201103L) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_MSVC || EIGEN_COMP_ICC) \ + && (EIGEN_ARCH_i386_OR_x86_64) && (EIGEN_OS_GNULINUX || EIGEN_OS_WIN_STRICT || EIGEN_OS_MAC) + template + struct arg_impl { + static inline Scalar run(const Scalar& x) + { + using std::arg; + return arg(x); + } + }; + +// No C++11, use our own implementation for real Scalars +#else + template::IsComplex> + struct arg_default_impl + { + typedef typename NumTraits::Real RealScalar; + EIGEN_DEVICE_FUNC + static inline RealScalar run(const Scalar& x) + { + const double pi = std::acos(-1.0); + return (x < 0.0) ? pi : 0.0; } + }; + + template + struct arg_default_impl + { + typedef typename NumTraits::Real RealScalar; + EIGEN_DEVICE_FUNC + static inline RealScalar run(const Scalar& x) + { + using std::arg; + return arg(x); + } + }; + + template struct arg_impl : arg_default_impl {}; +#endif + +template +struct arg_retval +{ + typedef typename NumTraits::Real type; +}; + /**************************************************************************** * Implementation of log1p * ****************************************************************************/ -- cgit v1.2.3 From 8878e1c1de73bddbcbd5d801d647ae6dcbc4e778 Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Tue, 17 Mar 2015 22:39:51 +1000 Subject: Remove ambiguity with recent numext methods isNaN and isInf --- test/main.h | 7 +------ test/packetmath.cpp | 10 +++++----- test/stable_norm.cpp | 40 ++++++++++++++++++++-------------------- 3 files changed, 26 insertions(+), 31 deletions(-) diff --git a/test/main.h b/test/main.h index ecf0c6924..5849cedd9 100644 --- a/test/main.h +++ b/test/main.h @@ -442,12 +442,7 @@ template bool isNotNaN(const T& x) return x==x; } -template bool isNaN(const T& x) -{ - return x!=x; -} - -template bool isInf(const T& x) +template bool isPlusInf(const T& x) { return x > NumTraits::highest(); } diff --git a/test/packetmath.cpp b/test/packetmath.cpp index 49f601907..e3a754627 100644 --- a/test/packetmath.cpp +++ b/test/packetmath.cpp @@ -317,7 +317,7 @@ template void packetmath_real() data1[0] = std::numeric_limits::quiet_NaN(); packet_helper::HasExp,Packet> h; h.store(data2, internal::pexp(h.load(data1))); - VERIFY(isNaN(data2[0])); + VERIFY(numext::isNaN(data2[0])); } for (int i=0; i void packetmath_real() data1[0] = std::numeric_limits::quiet_NaN(); packet_helper::HasLog,Packet> h; h.store(data2, internal::plog(h.load(data1))); - VERIFY(isNaN(data2[0])); + VERIFY(numext::isNaN(data2[0])); data1[0] = -1.0f; h.store(data2, internal::plog(h.load(data1))); - VERIFY(isNaN(data2[0])); + VERIFY(numext::isNaN(data2[0])); #if !EIGEN_FAST_MATH h.store(data2, internal::psqrt(h.load(data1))); - VERIFY(isNaN(data2[0])); - VERIFY(isNaN(data2[1])); + VERIFY(numext::isNaN(data2[0])); + VERIFY(numext::isNaN(data2[1])); #endif } } diff --git a/test/stable_norm.cpp b/test/stable_norm.cpp index 650f62a8a..0674006de 100644 --- a/test/stable_norm.cpp +++ b/test/stable_norm.cpp @@ -111,33 +111,33 @@ template void stable_norm(const MatrixType& m) { v = vrand; v(i,j) = std::numeric_limits::quiet_NaN(); - VERIFY(!isFinite(v.squaredNorm())); VERIFY(isNaN(v.squaredNorm())); - VERIFY(!isFinite(v.norm())); VERIFY(isNaN(v.norm())); - VERIFY(!isFinite(v.stableNorm())); VERIFY(isNaN(v.stableNorm())); - VERIFY(!isFinite(v.blueNorm())); VERIFY(isNaN(v.blueNorm())); - VERIFY(!isFinite(v.hypotNorm())); VERIFY(isNaN(v.hypotNorm())); + VERIFY(!isFinite(v.squaredNorm())); VERIFY(numext::isNaN(v.squaredNorm())); + VERIFY(!isFinite(v.norm())); VERIFY(numext::isNaN(v.norm())); + VERIFY(!isFinite(v.stableNorm())); VERIFY(numext::isNaN(v.stableNorm())); + VERIFY(!isFinite(v.blueNorm())); VERIFY(numext::isNaN(v.blueNorm())); + VERIFY(!isFinite(v.hypotNorm())); VERIFY(numext::isNaN(v.hypotNorm())); } // +inf { v = vrand; v(i,j) = std::numeric_limits::infinity(); - VERIFY(!isFinite(v.squaredNorm())); VERIFY(isInf(v.squaredNorm())); - VERIFY(!isFinite(v.norm())); VERIFY(isInf(v.norm())); - VERIFY(!isFinite(v.stableNorm())); VERIFY(isInf(v.stableNorm())); - VERIFY(!isFinite(v.blueNorm())); VERIFY(isInf(v.blueNorm())); - VERIFY(!isFinite(v.hypotNorm())); VERIFY(isInf(v.hypotNorm())); + VERIFY(!isFinite(v.squaredNorm())); VERIFY(isPlusInf(v.squaredNorm())); + VERIFY(!isFinite(v.norm())); VERIFY(isPlusInf(v.norm())); + VERIFY(!isFinite(v.stableNorm())); VERIFY(isPlusInf(v.stableNorm())); + VERIFY(!isFinite(v.blueNorm())); VERIFY(isPlusInf(v.blueNorm())); + VERIFY(!isFinite(v.hypotNorm())); VERIFY(isPlusInf(v.hypotNorm())); } // -inf { v = vrand; v(i,j) = -std::numeric_limits::infinity(); - VERIFY(!isFinite(v.squaredNorm())); VERIFY(isInf(v.squaredNorm())); - VERIFY(!isFinite(v.norm())); VERIFY(isInf(v.norm())); - VERIFY(!isFinite(v.stableNorm())); VERIFY(isInf(v.stableNorm())); - VERIFY(!isFinite(v.blueNorm())); VERIFY(isInf(v.blueNorm())); - VERIFY(!isFinite(v.hypotNorm())); VERIFY(isInf(v.hypotNorm())); + VERIFY(!isFinite(v.squaredNorm())); VERIFY(isPlusInf(v.squaredNorm())); + VERIFY(!isFinite(v.norm())); VERIFY(isPlusInf(v.norm())); + VERIFY(!isFinite(v.stableNorm())); VERIFY(isPlusInf(v.stableNorm())); + VERIFY(!isFinite(v.blueNorm())); VERIFY(isPlusInf(v.blueNorm())); + VERIFY(!isFinite(v.hypotNorm())); VERIFY(isPlusInf(v.hypotNorm())); } // mix @@ -147,11 +147,11 @@ template void stable_norm(const MatrixType& m) v = vrand; v(i,j) = -std::numeric_limits::infinity(); v(i2,j2) = std::numeric_limits::quiet_NaN(); - VERIFY(!isFinite(v.squaredNorm())); VERIFY(isNaN(v.squaredNorm())); - VERIFY(!isFinite(v.norm())); VERIFY(isNaN(v.norm())); - VERIFY(!isFinite(v.stableNorm())); VERIFY(isNaN(v.stableNorm())); - VERIFY(!isFinite(v.blueNorm())); VERIFY(isNaN(v.blueNorm())); - VERIFY(!isFinite(v.hypotNorm())); VERIFY(isNaN(v.hypotNorm())); + VERIFY(!isFinite(v.squaredNorm())); VERIFY(numext::isNaN(v.squaredNorm())); + VERIFY(!isFinite(v.norm())); VERIFY(numext::isNaN(v.norm())); + VERIFY(!isFinite(v.stableNorm())); VERIFY(numext::isNaN(v.stableNorm())); + VERIFY(!isFinite(v.blueNorm())); VERIFY(numext::isNaN(v.blueNorm())); + VERIFY(!isFinite(v.hypotNorm())); VERIFY(numext::isNaN(v.hypotNorm())); } } -- cgit v1.2.3 From 41b717de255c5091ece9e21a321e6149c6b1b4af Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Wed, 18 Mar 2015 03:11:03 +1000 Subject: More extensive unit tests for recent array-wise functors --- test/array.cpp | 129 +++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 97 insertions(+), 32 deletions(-) diff --git a/test/array.cpp b/test/array.cpp index 254af2ee9..0208ba7c9 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -197,7 +197,7 @@ template void array_real(const ArrayType& m) Scalar s1 = internal::random(); - // these tests are mostly to check possible compilation issues. + // these tests are mostly to check possible compilation issues with free-functions. VERIFY_IS_APPROX(m1.sin(), sin(m1)); VERIFY_IS_APPROX(m1.cos(), cos(m1)); VERIFY_IS_APPROX(m1.tan(), tan(m1)); @@ -207,26 +207,44 @@ template void array_real(const ArrayType& m) VERIFY_IS_APPROX(m1.sinh(), sinh(m1)); VERIFY_IS_APPROX(m1.cosh(), cosh(m1)); VERIFY_IS_APPROX(m1.tanh(), tanh(m1)); - VERIFY_IS_APPROX(m1.log(), log(m1)); - VERIFY_IS_APPROX(m1.log10(), log10(m1)); VERIFY_IS_APPROX(m1.arg(), arg(m1)); VERIFY_IS_APPROX(m1.round(), round(m1)); VERIFY_IS_APPROX(m1.floor(), floor(m1)); VERIFY_IS_APPROX(m1.ceil(), ceil(m1)); - VERIFY_IS_APPROX(m1.isNaN(), isNaN(m1)); - VERIFY_IS_APPROX(m1.isInf(), isInf(m1)); - VERIFY_IS_APPROX(m1.isFinite(), isFinite(m1)); - VERIFY_IS_APPROX(inverse(m1.inverse()), m1); - VERIFY_IS_APPROX(abs2(m1.abs2()), pow(abs(m1),2*2)); - VERIFY_IS_APPROX(m1.square().sqrt(), sqrt(square(m1))); - VERIFY_IS_APPROX(cube(m1.cube()), pow((m1),3*3)); - - VERIFY(!(m1>m2),(m1<=m2)); - + VERIFY((m1.isNaN() == isNaN(m1)).all()); + VERIFY((m1.isInf() == isInf(m1)).all()); + VERIFY((m1.isFinite() == isFinite(m1)).all()); + VERIFY_IS_APPROX(m1.inverse(), inverse(m1)); + VERIFY_IS_APPROX(m1.abs(), abs(m1)); + VERIFY_IS_APPROX(m1.abs2(), abs2(m1)); + VERIFY_IS_APPROX(m1.square(), square(m1)); + VERIFY_IS_APPROX(m1.cube(), cube(m1)); VERIFY_IS_APPROX(cos(m1+RealScalar(3)*m2), cos((m1+RealScalar(3)*m2).eval())); - VERIFY_IS_APPROX(m1.abs().sqrt(), sqrt(abs(m1))); - VERIFY_IS_APPROX(m1.abs(), sqrt(numext::abs2(m1))); + + // avoid NaNs with abs() so verification doesn't fail + m3 = m1.abs(); + VERIFY_IS_APPROX(m3.sqrt(), sqrt(abs(m1))); + VERIFY_IS_APPROX(m3.log(), log(m3)); + VERIFY_IS_APPROX(m3.log10(), log10(m3)); + + + VERIFY((!(m1>m2) == (m1<=m2)).all()); + + VERIFY_IS_APPROX(sin(m1.asin()), m1); + VERIFY_IS_APPROX(cos(m1.acos()), m1); + VERIFY_IS_APPROX(tan(m1.atan()), m1); + VERIFY_IS_APPROX(sinh(m1), 0.5*(exp(m1)-exp(-m1))); + VERIFY_IS_APPROX(cosh(m1), 0.5*(exp(m1)+exp(-m1))); + VERIFY_IS_APPROX(tanh(m1), (0.5*(exp(m1)-exp(-m1)))/(0.5*(exp(m1)+exp(-m1)))); + VERIFY_IS_APPROX(arg(m1), ((ArrayType)(m1<0))*std::acos(-1.0)); + VERIFY((round(m1) <= ceil(m1) && round(m1) >= floor(m1)).all()); + VERIFY(isNaN(m1*0.0/0.0).all()); + VERIFY(isInf(m1/0.0).all()); + VERIFY((isFinite(m1) && !isFinite(m1*0.0/0.0) && !isFinite(m1/0.0)).all()); + VERIFY_IS_APPROX(inverse(inverse(m1)),m1); + VERIFY((abs(m1) == m1 || abs(m1) == -m1).all()); + VERIFY_IS_APPROX(m3, sqrt(abs2(m1))); VERIFY_IS_APPROX(numext::abs2(numext::real(m1)) + numext::abs2(numext::imag(m1)), numext::abs2(m1)); VERIFY_IS_APPROX(numext::abs2(real(m1)) + numext::abs2(imag(m1)), numext::abs2(m1)); @@ -235,7 +253,7 @@ template void array_real(const ArrayType& m) // shift argument of logarithm so that it is not zero Scalar smallNumber = NumTraits::dummy_precision(); - VERIFY_IS_APPROX((m1.abs() + smallNumber).log() , log(abs(m1) + smallNumber)); + VERIFY_IS_APPROX((m3 + smallNumber).log() , log(abs(m1) + smallNumber)); VERIFY_IS_APPROX(m1.exp() * m2.exp(), exp(m1+m2)); VERIFY_IS_APPROX(m1.exp(), exp(m1)); @@ -243,13 +261,15 @@ template void array_real(const ArrayType& m) VERIFY_IS_APPROX(m1.pow(2), m1.square()); VERIFY_IS_APPROX(pow(m1,2), m1.square()); + VERIFY_IS_APPROX(m1.pow(3), m1.cube()); + VERIFY_IS_APPROX(pow(m1,3), m1.cube()); ArrayType exponents = ArrayType::Constant(rows, cols, RealScalar(2)); VERIFY_IS_APPROX(Eigen::pow(m1,exponents), m1.square()); - m3 = m1.abs(); VERIFY_IS_APPROX(m3.pow(RealScalar(0.5)), m3.sqrt()); VERIFY_IS_APPROX(pow(m3,RealScalar(0.5)), m3.sqrt()); + VERIFY_IS_APPROX(log10(m3), log(m3)/log(10)); // scalar by array division const RealScalar tiny = sqrt(std::numeric_limits::epsilon()); @@ -260,14 +280,16 @@ template void array_real(const ArrayType& m) // check inplace transpose m3 = m1; m3.transposeInPlace(); - VERIFY_IS_APPROX(m3,m1.transpose()); + VERIFY_IS_APPROX(m3, m1.transpose()); m3.transposeInPlace(); - VERIFY_IS_APPROX(m3,m1); + VERIFY_IS_APPROX(m3, m1); } template void array_complex(const ArrayType& m) { typedef typename ArrayType::Index Index; + typedef typename ArrayType::Scalar Scalar; + typedef typename NumTraits::Real RealScalar; Index rows = m.rows(); Index cols = m.cols(); @@ -275,29 +297,72 @@ template void array_complex(const ArrayType& m) ArrayType m1 = ArrayType::Random(rows, cols), m2(rows, cols); + Array m3(rows, cols); + + Scalar s1 = internal::random(); + for (Index i = 0; i < m.rows(); ++i) for (Index j = 0; j < m.cols(); ++j) m2(i,j) = sqrt(m1(i,j)); - VERIFY_IS_APPROX(m1.sqrt(), m2); - VERIFY_IS_APPROX(m1.sqrt(), Eigen::sqrt(m1)); - VERIFY_IS_APPROX(m1.log(), log(m1)); - VERIFY_IS_APPROX(m1.log10(), log10(m1)); - VERIFY_IS_APPROX(m1.arg(), arg(m1)); - VERIFY_IS_APPROX(abs2(m1.abs2()), pow(abs(m1),2*2)); - VERIFY_IS_APPROX(m1.isNaN(), isNaN(m1)); - VERIFY_IS_APPROX(m1.isInf(), isInf(m1)); - VERIFY_IS_APPROX(m1.isFinite(), isFinite(m1)); - VERIFY_IS_APPROX(m1.square().sqrt(), sqrt(square(m1))); - VERIFY_IS_APPROX(cube(m1.cube()), pow((m1),3*3)); - VERIFY_IS_APPROX(conj(m1.conjugate()), m1); - VERIFY_IS_APPROX(inverse(m1.inverse()), m1); + // these tests are mostly to check possible compilation issues with free-functions. VERIFY_IS_APPROX(m1.sin(), sin(m1)); VERIFY_IS_APPROX(m1.cos(), cos(m1)); VERIFY_IS_APPROX(m1.tan(), tan(m1)); VERIFY_IS_APPROX(m1.sinh(), sinh(m1)); VERIFY_IS_APPROX(m1.cosh(), cosh(m1)); VERIFY_IS_APPROX(m1.tanh(), tanh(m1)); + VERIFY_IS_APPROX(m1.arg(), arg(m1)); + VERIFY((m1.isNaN() == isNaN(m1)).all()); + VERIFY((m1.isInf() == isInf(m1)).all()); + VERIFY((m1.isFinite() == isFinite(m1)).all()); + VERIFY_IS_APPROX(m1.inverse(), inverse(m1)); + VERIFY_IS_APPROX(m1.log(), log(m1)); + VERIFY_IS_APPROX(m1.log10(), log10(m1)); + VERIFY_IS_APPROX(m1.abs(), abs(m1)); + VERIFY_IS_APPROX(m1.abs2(), abs2(m1)); + VERIFY_IS_APPROX(m1.sqrt(), sqrt(m1)); + VERIFY_IS_APPROX(m1.square(), square(m1)); + VERIFY_IS_APPROX(m1.cube(), cube(m1)); + VERIFY_IS_APPROX(cos(m1+RealScalar(3)*m2), cos((m1+RealScalar(3)*m2).eval())); + + + VERIFY_IS_APPROX(m1.exp() * m2.exp(), exp(m1+m2)); + VERIFY_IS_APPROX(m1.exp(), exp(m1)); + VERIFY_IS_APPROX(m1.exp() / m2.exp(),(m1-m2).exp()); + + VERIFY_IS_APPROX(sinh(m1), 0.5*(exp(m1)-exp(-m1))); + VERIFY_IS_APPROX(cosh(m1), 0.5*(exp(m1)+exp(-m1))); + VERIFY_IS_APPROX(tanh(m1), (0.5*(exp(m1)-exp(-m1)))/(0.5*(exp(m1)+exp(-m1)))); + + for (Index i = 0; i < m.rows(); ++i) + for (Index j = 0; j < m.cols(); ++j) + m3(i,j) = std::atan2(imag(m1(i,j)), real(m1(i,j))); + VERIFY_IS_APPROX(arg(m1), m3); + + std::complex zero(0.0,0.0); + VERIFY(isNaN(m1*zero/zero).all()); + VERIFY(isInf(m1/zero).all()); + VERIFY((isFinite(m1) && !isFinite(m1*zero/zero) && !isFinite(m1/zero)).all()); + + VERIFY_IS_APPROX(inverse(inverse(m1)),m1); + VERIFY_IS_APPROX(conj(m1.conjugate()), m1); + VERIFY_IS_APPROX(abs(m1), sqrt(square(real(m1))+square(imag(m1)))); + VERIFY_IS_APPROX(abs(m1), sqrt(abs2(m1))); + VERIFY_IS_APPROX(log10(m1), log(m1)/log(10)); + + // scalar by array division + const RealScalar tiny = sqrt(std::numeric_limits::epsilon()); + s1 += Scalar(tiny); + m1 += ArrayType::Constant(rows,cols,Scalar(tiny)); + VERIFY_IS_APPROX(s1/m1, s1 * m1.inverse()); + + // check inplace transpose + m2 = m1; + m2.transposeInPlace(); + VERIFY_IS_APPROX(m2, m1.transpose()); + m2.transposeInPlace(); + VERIFY_IS_APPROX(m2, m1); } -- cgit v1.2.3 From 4bab4790c0b0fd12d1ef1f5e200962e59d49552c Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Sun, 22 Mar 2015 05:39:08 +1000 Subject: Add \sa tags of isFinite/isInf for each other --- Eigen/src/plugins/ArrayCwiseUnaryOps.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/Eigen/src/plugins/ArrayCwiseUnaryOps.h index 1d5c9a6c1..9843c2a58 100644 --- a/Eigen/src/plugins/ArrayCwiseUnaryOps.h +++ b/Eigen/src/plugins/ArrayCwiseUnaryOps.h @@ -384,7 +384,7 @@ isNaN() const * Example: \include Cwise_isInf.cpp * Output: \verbinclude Cwise_isInf.out * - * \sa isNaN() + * \sa isNaN(), isFinite() */ inline const IsInfReturnType isInf() const @@ -397,7 +397,7 @@ isInf() const * Example: \include Cwise_isFinite.cpp * Output: \verbinclude Cwise_isFinite.out * - * \sa isNaN() + * \sa isNaN(), isInf() */ inline const IsFiniteReturnType isFinite() const -- cgit v1.2.3 From 83e5b7656b6e3d68539584baf703ad30e96fa0de Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Sun, 22 Mar 2015 06:04:31 +1000 Subject: Use M_PI instead of acos(-1) for pi --- Eigen/src/Core/MathFunctions.h | 3 +-- test/array.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index 734a5e373..787634081 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -421,8 +421,7 @@ struct round_retval EIGEN_DEVICE_FUNC static inline RealScalar run(const Scalar& x) { - const double pi = std::acos(-1.0); - return (x < 0.0) ? pi : 0.0; } + return (x < 0.0) ? M_PI : 0.0; } }; template diff --git a/test/array.cpp b/test/array.cpp index 0208ba7c9..efccd2b0c 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -237,7 +237,7 @@ template void array_real(const ArrayType& m) VERIFY_IS_APPROX(sinh(m1), 0.5*(exp(m1)-exp(-m1))); VERIFY_IS_APPROX(cosh(m1), 0.5*(exp(m1)+exp(-m1))); VERIFY_IS_APPROX(tanh(m1), (0.5*(exp(m1)-exp(-m1)))/(0.5*(exp(m1)+exp(-m1)))); - VERIFY_IS_APPROX(arg(m1), ((ArrayType)(m1<0))*std::acos(-1.0)); + VERIFY_IS_APPROX(arg(m1), ((ArrayType)(m1<0))*M_PI); VERIFY((round(m1) <= ceil(m1) && round(m1) >= floor(m1)).all()); VERIFY(isNaN(m1*0.0/0.0).all()); VERIFY(isInf(m1/0.0).all()); -- cgit v1.2.3 From 085aa8e6019f7ff8edc3108cc851c09c5213f8ee Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Wed, 8 Apr 2015 13:59:18 -0500 Subject: Don't use M_PI since it's only guaranteed to be defined in Eigen/Geometry --- Eigen/src/Core/MathFunctions.h | 3 ++- test/array.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index 787634081..734a5e373 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -421,7 +421,8 @@ struct round_retval EIGEN_DEVICE_FUNC static inline RealScalar run(const Scalar& x) { - return (x < 0.0) ? M_PI : 0.0; } + const double pi = std::acos(-1.0); + return (x < 0.0) ? pi : 0.0; } }; template diff --git a/test/array.cpp b/test/array.cpp index efccd2b0c..0208ba7c9 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -237,7 +237,7 @@ template void array_real(const ArrayType& m) VERIFY_IS_APPROX(sinh(m1), 0.5*(exp(m1)-exp(-m1))); VERIFY_IS_APPROX(cosh(m1), 0.5*(exp(m1)+exp(-m1))); VERIFY_IS_APPROX(tanh(m1), (0.5*(exp(m1)-exp(-m1)))/(0.5*(exp(m1)+exp(-m1)))); - VERIFY_IS_APPROX(arg(m1), ((ArrayType)(m1<0))*M_PI); + VERIFY_IS_APPROX(arg(m1), ((ArrayType)(m1<0))*std::acos(-1.0)); VERIFY((round(m1) <= ceil(m1) && round(m1) >= floor(m1)).all()); VERIFY(isNaN(m1*0.0/0.0).all()); VERIFY(isInf(m1/0.0).all()); -- cgit v1.2.3 From 0339502a4feb6340f1e9f6f6ca8b3ef4d263f366 Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Mon, 20 Apr 2015 13:14:06 -0400 Subject: Only use std::isnan and std::isinf if they are available --- Eigen/src/Core/MathFunctions.h | 54 ++++++++++++++++++++++++++++++------------ Eigen/src/Core/util/Macros.h | 8 +++++++ 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index 734a5e373..3bbebb345 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -790,14 +790,26 @@ bool (isfinite)(const std::complex& x) using std::imag; return isfinite(real(x)) && isfinite(imag(x)); } - -template -EIGEN_DEVICE_FUNC -bool (isNaN)(const T& x) -{ - using std::isnan; - return isnan(x); -} +#import +// Let's be conservative and enable the std::isnan implementation only if we are sure it exists +#if (__cplusplus >= 201103L) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_MSVC || EIGEN_COMP_ICC) \ +&& (EIGEN_ARCH_i386_OR_x86_64) && (EIGEN_OS_GNULINUX || EIGEN_OS_WIN_STRICT || EIGEN_OS_MAC) \ +|| defined(EIGEN_HAS_C99_MATH) + template + EIGEN_DEVICE_FUNC + bool (isNaN)(const T& x) + { + using std::isnan; + return isnan(x); + } +#else + template + EIGEN_DEVICE_FUNC + bool (isNaN)(const T& x) + { + return x == x; + } +#endif template EIGEN_DEVICE_FUNC @@ -809,13 +821,25 @@ bool (isNaN)(const std::complex& x) return isnan(real(x)) || isnan(imag(x)); } -template -EIGEN_DEVICE_FUNC -bool (isInf)(const T& x) -{ - using std::isinf; - return isinf(x); -} +// Let's be conservative and enable the std::isinf implementation only if we are sure it exists +#if (__cplusplus >= 201103L) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_MSVC || EIGEN_COMP_ICC) \ +&& (EIGEN_ARCH_i386_OR_x86_64) && (EIGEN_OS_GNULINUX || EIGEN_OS_WIN_STRICT || EIGEN_OS_MAC) \ +|| defined(EIGEN_HAS_C99_MATH) + template + EIGEN_DEVICE_FUNC + bool (isInf)(const T& x) + { + using std::isinf; + return isinf(x); + } +#else + template + EIGEN_DEVICE_FUNC + bool (isInf)(const T& x) + { + return x>NumTraits::highest() || x::lowest(); + } +#endif template EIGEN_DEVICE_FUNC diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h index aaea9f035..754e2c7cc 100644 --- a/Eigen/src/Core/util/Macros.h +++ b/Eigen/src/Core/util/Macros.h @@ -398,6 +398,14 @@ #define EIGEN_HAS_CONSTEXPR 1 #endif +// Does the compiler support C99 math? +#if (EIGEN_COMP_GNUC_STRICT || \ + (EIGEN_COMP_ICC && EIGEN_COMP_GNUC) || \ + (EIGEN_COMP_CLANG) || \ + (EIGEN_COMP_MSVC >= 1800)) +#define EIGEN_HAS_C99_MATH 1 +#endif + /** Allows to disable some optimizations which might affect the accuracy of the result. * Such optimization are enabled by default, and set EIGEN_FAST_MATH to 0 to disable them. * They currently include: -- cgit v1.2.3 From 249c48ba001f83978f84bf1befdf4867550ff6ea Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Mon, 20 Apr 2015 14:57:04 -0400 Subject: Incorporate C++11 check into EIGEN_HAS_C99_MATH macro --- Eigen/src/Core/MathFunctions.h | 52 +++++++++++++++--------------------------- Eigen/src/Core/util/Macros.h | 10 ++++---- 2 files changed, 24 insertions(+), 38 deletions(-) diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index 944ed9417..a1ea059b7 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -804,26 +804,18 @@ bool (isfinite)(const std::complex& x) using std::imag; return isfinite(real(x)) && isfinite(imag(x)); } -#import -// Let's be conservative and enable the std::isnan implementation only if we are sure it exists -#if (__cplusplus >= 201103L) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_MSVC || EIGEN_COMP_ICC) \ -&& (EIGEN_ARCH_i386_OR_x86_64) && (EIGEN_OS_GNULINUX || EIGEN_OS_WIN_STRICT || EIGEN_OS_MAC) \ -|| defined(EIGEN_HAS_C99_MATH) - template - EIGEN_DEVICE_FUNC - bool (isNaN)(const T& x) - { + +template +EIGEN_DEVICE_FUNC +bool (isNaN)(const T& x) +{ + #ifdef EIGEN_HAS_C99_MATH using std::isnan; return isnan(x); - } -#else - template - EIGEN_DEVICE_FUNC - bool (isNaN)(const T& x) - { - return x == x; - } -#endif + #else + return x != x; + #endif +} template EIGEN_DEVICE_FUNC @@ -835,25 +827,17 @@ bool (isNaN)(const std::complex& x) return isnan(real(x)) || isnan(imag(x)); } -// Let's be conservative and enable the std::isinf implementation only if we are sure it exists -#if (__cplusplus >= 201103L) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_MSVC || EIGEN_COMP_ICC) \ -&& (EIGEN_ARCH_i386_OR_x86_64) && (EIGEN_OS_GNULINUX || EIGEN_OS_WIN_STRICT || EIGEN_OS_MAC) \ -|| defined(EIGEN_HAS_C99_MATH) - template - EIGEN_DEVICE_FUNC - bool (isInf)(const T& x) - { +template +EIGEN_DEVICE_FUNC +bool (isInf)(const T& x) +{ + #ifdef EIGEN_HAS_C99_MATH using std::isinf; return isinf(x); - } -#else - template - EIGEN_DEVICE_FUNC - bool (isInf)(const T& x) - { + #else return x>NumTraits::highest() || x::lowest(); - } -#endif + #endif +} template EIGEN_DEVICE_FUNC diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h index 414f688ad..7c7a3b8e7 100644 --- a/Eigen/src/Core/util/Macros.h +++ b/Eigen/src/Core/util/Macros.h @@ -403,10 +403,12 @@ #endif // Does the compiler support C99 math? -#if (EIGEN_COMP_GNUC_STRICT || \ - (EIGEN_COMP_ICC && EIGEN_COMP_GNUC) || \ - (EIGEN_COMP_CLANG) || \ - (EIGEN_COMP_MSVC >= 1800)) +#if (__cplusplus >= 201103L) && (EIGEN_COMP_GNUC_STRICT || EIGEN_COMP_CLANG || EIGEN_COMP_MSVC || EIGEN_COMP_ICC) \ + && (EIGEN_ARCH_i386_OR_x86_64) && (EIGEN_OS_GNULINUX || EIGEN_OS_WIN_STRICT || EIGEN_OS_MAC) || \ + (EIGEN_COMP_GNUC_STRICT || \ + (EIGEN_COMP_ICC && EIGEN_COMP_GNUC) || \ + (EIGEN_COMP_CLANG) || \ + (EIGEN_COMP_MSVC >= 1800)) #define EIGEN_HAS_C99_MATH 1 #endif -- cgit v1.2.3 From e5048b5501a4c2cd86fa3f92ad214938eb3f9b3f Mon Sep 17 00:00:00 2001 From: Deanna Hood Date: Mon, 20 Apr 2015 14:59:57 -0400 Subject: Use std::isfinite when available --- Eigen/src/Core/MathFunctions.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index a1ea059b7..1ce935909 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -787,13 +787,16 @@ inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y) return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y); } -// std::isfinite is non standard, so let's define our own version, -// even though it is not very efficient. template EIGEN_DEVICE_FUNC bool (isfinite)(const T& x) { - return x::highest() && x>NumTraits::lowest(); + #ifdef EIGEN_HAS_C99_MATH + using std::isfinite; + return isfinite(x); + #else + return x::highest() && x>NumTraits::lowest(); + #endif } template -- cgit v1.2.3