diff options
author | Deanna Hood <deanna.m.hood@gmail.com> | 2015-03-11 06:39:23 +1000 |
---|---|---|
committer | Deanna Hood <deanna.m.hood@gmail.com> | 2015-03-11 06:39:23 +1000 |
commit | 31fdd67756630de05f2464ef620bc62185a53bee (patch) | |
tree | 9700728b8ad190ef9b94035c15360c078f0204bd /Eigen | |
parent | fd788748889f50536f590b68dfa98db0044e5115 (diff) |
Additional unary coeff-wise functors (isnan, round, arg, e.g.)
Diffstat (limited to 'Eigen')
-rw-r--r-- | Eigen/src/Core/Assign_MKL.h | 24 | ||||
-rw-r--r-- | Eigen/src/Core/GenericPacketMath.h | 33 | ||||
-rw-r--r-- | Eigen/src/Core/GlobalFunctions.h | 6 | ||||
-rw-r--r-- | Eigen/src/Core/MathFunctions.h | 133 | ||||
-rw-r--r-- | Eigen/src/Core/functors/UnaryFunctors.h | 118 | ||||
-rw-r--r-- | Eigen/src/plugins/ArrayCwiseUnaryOps.h | 85 |
6 files changed, 388 insertions, 11 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<typename Packet> EIGEN_DEVICE_FUNC inline Packet pabs(const Packet& a) { using std::abs; return abs(a); } +/** \internal \returns the phase angle of \a a */ +template<typename Packet> 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<typename Packet> 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<typename Packet> 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<typename Packet> 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<typename Packet> 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<typename Packet> 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<typename Packet> 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<typename Packet> 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<typename Derived> inline const Eigen::CwiseUnaryOp<Eigen::internal::scalar_pow_op<typename Derived::Scalar>, 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 @@ -134,6 +134,41 @@ struct imag_retval }; /**************************************************************************** +* Implementation of arg * +****************************************************************************/ + +template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex> +struct arg_default_impl +{ + typedef typename NumTraits<Scalar>::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<typename Scalar> +struct arg_default_impl<Scalar,true> +{ + typedef typename NumTraits<Scalar>::Real RealScalar; + EIGEN_DEVICE_FUNC + static inline RealScalar run(const Scalar& x) + { + using std::arg; + return arg(x); + } +}; + +template<typename Scalar> struct arg_impl : arg_default_impl<Scalar> {}; + +template<typename Scalar> +struct arg_retval +{ + typedef typename NumTraits<Scalar>::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 { @@ -625,6 +660,13 @@ inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x) template<typename Scalar> EIGEN_DEVICE_FUNC +inline EIGEN_MATHFUNC_RETVAL(arg, Scalar) arg(const Scalar& x) +{ + return EIGEN_MATHFUNC_IMPL(arg, Scalar)::run(x); +} + +template<typename Scalar> +EIGEN_DEVICE_FUNC inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x) { return internal::imag_ref_impl<Scalar>::run(x); @@ -697,6 +739,95 @@ bool (isfinite)(const std::complex<T>& x) return isfinite(real(x)) && isfinite(imag(x)); } +template<typename T> +EIGEN_DEVICE_FUNC +bool (isnan)(const T& x) +{ + using std::isnan; + return isnan(x); +} + +template<typename T> +EIGEN_DEVICE_FUNC +bool (isnan)(const std::complex<T>& x) +{ + using std::real; + using std::imag; + using std::isnan; + return isnan(real(x)) || isnan(imag(x)); +} + +template<typename T> +EIGEN_DEVICE_FUNC +bool (isinf)(const T& x) +{ + using std::isinf; + return isinf(x); +} + +template<typename T> +EIGEN_DEVICE_FUNC +bool (isinf)(const std::complex<T>& x) +{ + using std::real; + using std::imag; + using std::isinf; + return isinf(real(x)) || isinf(imag(x)); +} + +template<typename T> +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<typename T> +EIGEN_DEVICE_FUNC +std::complex<T> (round)(const std::complex<T>& x) +{ + using numext::round; + return std::complex<T>(round(real(x)), round(imag(x))); +} + +template<typename T> +EIGEN_DEVICE_FUNC +T (floor)(const T& x) +{ + using std::floor; + return floor(x); +} + +template<typename T> +EIGEN_DEVICE_FUNC +std::complex<T> (floor)(const std::complex<T>& x) +{ + using std::real; + using std::imag; + using std::floor; + return std::complex<T>(floor(real(x)), floor(imag(x))); +} + +template<typename T> +EIGEN_DEVICE_FUNC +T (ceil)(const T& x) +{ + using std::ceil; + return ceil(x); +} + +template<typename T> +EIGEN_DEVICE_FUNC +std::complex<T> (ceil)(const std::complex<T>& x) +{ + using std::real; + using std::imag; + using std::ceil; + return std::complex<T>(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 @@ -123,6 +123,27 @@ struct functor_traits<scalar_conjugate_op<Scalar> > }; /** \internal + * \brief Template functor to compute the phase angle of a complex + * + * \sa class CwiseUnaryOp, Cwise::arg + */ +template<typename Scalar> struct scalar_arg_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_arg_op) + typedef typename NumTraits<Scalar>::Real result_type; + EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { using numext::arg; return arg(a); } + template<typename Packet> + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const + { return internal::parg(a); } +}; +template<typename Scalar> +struct functor_traits<scalar_arg_op<Scalar> > +{ + enum { + Cost = NumTraits<Scalar>::AddCost, + PacketAccess = packet_traits<Scalar>::HasArg + }; +}; +/** \internal * \brief Template functor to cast a scalar to another type * * \sa class CwiseUnaryOp, MatrixBase::cast() @@ -416,6 +437,103 @@ template<typename Scalar> struct functor_traits<scalar_cube_op<Scalar> > { enum { Cost = 2*NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; }; +/** \internal + * \brief Template functor to compute the rounded value of a scalar + * \sa class CwiseUnaryOp, ArrayBase::round() + */ +template<typename Scalar> 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<Scalar>::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pround(a); } +}; +template<typename Scalar> +struct functor_traits<scalar_round_op<Scalar> > +{ + enum { + Cost = NumTraits<Scalar>::MulCost, + PacketAccess = packet_traits<Scalar>::HasRound + }; +}; + +/** \internal + * \brief Template functor to compute the floor of a scalar + * \sa class CwiseUnaryOp, ArrayBase::floor() + */ +template<typename Scalar> 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<Scalar>::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pfloor(a); } +}; +template<typename Scalar> +struct functor_traits<scalar_floor_op<Scalar> > +{ + enum { + Cost = NumTraits<Scalar>::MulCost, + PacketAccess = packet_traits<Scalar>::HasFloor + }; +}; + +/** \internal + * \brief Template functor to compute the ceil of a scalar + * \sa class CwiseUnaryOp, ArrayBase::ceil() + */ +template<typename Scalar> 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<Scalar>::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pceil(a); } +}; +template<typename Scalar> +struct functor_traits<scalar_ceil_op<Scalar> > +{ + enum { + Cost = NumTraits<Scalar>::MulCost, + PacketAccess = packet_traits<Scalar>::HasCeil + }; +}; + +/** \internal + * \brief Template functor to compute the isnan of a scalar + * \sa class CwiseUnaryOp, ArrayBase::isnan() + */ +template<typename Scalar> 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<typename Packet> + EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const + { return internal::pisnan(a); } +}; +template<typename Scalar> +struct functor_traits<scalar_isnan_op<Scalar> > +{ + enum { + Cost = NumTraits<Scalar>::MulCost, + PacketAccess = packet_traits<Scalar>::HasIsnan + }; +}; + +/** \internal + * \brief Template functor to compute the isinf of a scalar + * \sa class CwiseUnaryOp, ArrayBase::isinf() + */ +template<typename Scalar> 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<Scalar>::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pisinf(a); } +}; +template<typename Scalar> +struct functor_traits<scalar_isinf_op<Scalar> > +{ + enum { + Cost = NumTraits<Scalar>::MulCost, + PacketAccess = packet_traits<Scalar>::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<internal::scalar_abs_op<Scalar>, const Derived> AbsReturnType; +typedef CwiseUnaryOp<internal::scalar_arg_op<Scalar>, const Derived> ArgReturnType; typedef CwiseUnaryOp<internal::scalar_abs2_op<Scalar>, const Derived> Abs2ReturnType; typedef CwiseUnaryOp<internal::scalar_sqrt_op<Scalar>, const Derived> SqrtReturnType; typedef CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const Derived> InverseReturnType; @@ -16,6 +17,11 @@ typedef CwiseUnaryOp<internal::scalar_atan_op<Scalar>, const Derived> AtanReturn typedef CwiseUnaryOp<internal::scalar_pow_op<Scalar>, const Derived> PowReturnType; typedef CwiseUnaryOp<internal::scalar_square_op<Scalar>, const Derived> SquareReturnType; typedef CwiseUnaryOp<internal::scalar_cube_op<Scalar>, const Derived> CubeReturnType; +typedef CwiseUnaryOp<internal::scalar_round_op<Scalar>, const Derived> RoundReturnType; +typedef CwiseUnaryOp<internal::scalar_floor_op<Scalar>, const Derived> FloorReturnType; +typedef CwiseUnaryOp<internal::scalar_ceil_op<Scalar>, const Derived> CeilReturnType; +typedef CwiseUnaryOp<internal::scalar_isnan_op<Scalar>, const Derived> IsnanReturnType; +typedef CwiseUnaryOp<internal::scalar_isinf_op<Scalar>, 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<std::binder2nd<FUNCTOR<Scalar> >, const Derived> \ |