diff options
author | Gael Guennebaud <g.gael@free.fr> | 2011-02-17 17:37:11 +0100 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2011-02-17 17:37:11 +0100 |
commit | aea630a98a39a523bfb008e884262d69ee473b8d (patch) | |
tree | 9af0e1ae346bc2e07568fd8c155013986dcfe34a | |
parent | 2ba55e90db84d33c83fd9aaaa42004d211779a1d (diff) |
factorize implementation of standard real unary math functions, and add acos, asin
-rw-r--r-- | Eigen/src/Core/Functors.h | 44 | ||||
-rw-r--r-- | Eigen/src/Core/GenericPacketMath.h | 12 | ||||
-rw-r--r-- | Eigen/src/Core/GlobalFunctions.h | 4 | ||||
-rw-r--r-- | Eigen/src/Core/MathFunctions.h | 214 | ||||
-rw-r--r-- | Eigen/src/plugins/ArrayCwiseUnaryOps.h | 29 | ||||
-rw-r--r-- | doc/snippets/Cwise_acos.cpp | 2 | ||||
-rw-r--r-- | test/array.cpp | 5 | ||||
-rw-r--r-- | test/packetmath.cpp | 9 |
8 files changed, 126 insertions, 193 deletions
diff --git a/Eigen/src/Core/Functors.h b/Eigen/src/Core/Functors.h index 9671f0f45..ddfc67d82 100644 --- a/Eigen/src/Core/Functors.h +++ b/Eigen/src/Core/Functors.h @@ -669,7 +669,7 @@ struct functor_traits<scalar_sqrt_op<Scalar> > /** \internal * \brief Template functor to compute the cosine of a scalar - * \sa class CwiseUnaryOp, Cwise::cos() + * \sa class CwiseUnaryOp, ArrayBase::cos() */ template<typename Scalar> struct scalar_cos_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op) @@ -688,7 +688,7 @@ struct functor_traits<scalar_cos_op<Scalar> > /** \internal * \brief Template functor to compute the sine of a scalar - * \sa class CwiseUnaryOp, Cwise::sin() + * \sa class CwiseUnaryOp, ArrayBase::sin() */ template<typename Scalar> struct scalar_sin_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op) @@ -708,7 +708,7 @@ struct functor_traits<scalar_sin_op<Scalar> > /** \internal * \brief Template functor to compute the tan of a scalar - * \sa class CwiseUnaryOp, Cwise::tan() + * \sa class CwiseUnaryOp, ArrayBase::tan() */ template<typename Scalar> struct scalar_tan_op { EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op) @@ -726,6 +726,44 @@ struct functor_traits<scalar_tan_op<Scalar> > }; /** \internal + * \brief Template functor to compute the arc cosine of a scalar + * \sa class CwiseUnaryOp, ArrayBase::acos() + */ +template<typename Scalar> struct scalar_acos_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op) + inline const Scalar operator() (const Scalar& a) const { return acos(a); } + typedef typename packet_traits<Scalar>::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pacos(a); } +}; +template<typename Scalar> +struct functor_traits<scalar_acos_op<Scalar> > +{ + enum { + Cost = 5 * NumTraits<Scalar>::MulCost, + PacketAccess = packet_traits<Scalar>::HasACos + }; +}; + +/** \internal + * \brief Template functor to compute the arc sine of a scalar + * \sa class CwiseUnaryOp, ArrayBase::asin() + */ +template<typename Scalar> struct scalar_asin_op { + EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op) + inline const Scalar operator() (const Scalar& a) const { return acos(a); } + typedef typename packet_traits<Scalar>::type Packet; + inline Packet packetOp(const Packet& a) const { return internal::pacos(a); } +}; +template<typename Scalar> +struct functor_traits<scalar_asin_op<Scalar> > +{ + enum { + Cost = 5 * NumTraits<Scalar>::MulCost, + PacketAccess = packet_traits<Scalar>::HasASin + }; +}; + +/** \internal * \brief Template functor to raise a scalar to a power * \sa class CwiseUnaryOp, Cwise::pow */ diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h index e3d492b8d..052aa8330 100644 --- a/Eigen/src/Core/GenericPacketMath.h +++ b/Eigen/src/Core/GenericPacketMath.h @@ -229,11 +229,11 @@ template<typename Packet> inline Packet preverse(const Packet& a) * Special math functions ***************************/ -/** \internal \returns the sin of \a a (coeff-wise) */ +/** \internal \returns the sine of \a a (coeff-wise) */ template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet psin(const Packet& a) { return sin(a); } -/** \internal \returns the cos of \a a (coeff-wise) */ +/** \internal \returns the cosine of \a a (coeff-wise) */ template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pcos(const Packet& a) { return cos(a); } @@ -241,6 +241,14 @@ Packet pcos(const Packet& a) { return cos(a); } template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet ptan(const Packet& a) { return tan(a); } +/** \internal \returns the arc sine of \a a (coeff-wise) */ +template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet pasin(const Packet& a) { return asin(a); } + +/** \internal \returns the arc cosine of \a a (coeff-wise) */ +template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS +Packet pacos(const Packet& a) { return acos(a); } + /** \internal \returns the exp of \a a (coeff-wise) */ template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS Packet pexp(const Packet& a) { return exp(a); } diff --git a/Eigen/src/Core/GlobalFunctions.h b/Eigen/src/Core/GlobalFunctions.h index f049bff42..144145a95 100644 --- a/Eigen/src/Core/GlobalFunctions.h +++ b/Eigen/src/Core/GlobalFunctions.h @@ -56,6 +56,8 @@ namespace std EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(imag,scalar_imag_op) EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(sin,scalar_sin_op) EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(cos,scalar_cos_op) + EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(asin,scalar_asin_op) + EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(acos,scalar_acos_op) EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(tan,scalar_tan_op) EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(exp,scalar_exp_op) EIGEN_ARRAY_DECLARE_GLOBAL_STD_UNARY(log,scalar_log_op) @@ -77,6 +79,8 @@ namespace Eigen EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(imag,scalar_imag_op) EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(sin,scalar_sin_op) EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(cos,scalar_cos_op) + EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(asin,scalar_asin_op) + EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(acos,scalar_acos_op) EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(tan,scalar_tan_op) EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(exp,scalar_exp_op) EIGEN_ARRAY_DECLARE_GLOBAL_EIGEN_UNARY(log,scalar_log_op) diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index 3f1405c62..2760e67b1 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -454,194 +454,36 @@ inline EIGEN_MATHFUNC_RETVAL(sqrt, Scalar) sqrt(const Scalar& x) } /**************************************************************************** -* Implementation of exp * +* Implementation of standard unary real functions (exp, log, sin, cos, ... * ****************************************************************************/ -template<typename Scalar, bool IsInteger> -struct exp_default_impl -{ - static inline Scalar run(const Scalar& x) - { - return std::exp(x); - } -}; - -template<typename Scalar> -struct exp_default_impl<Scalar, true> -{ - static inline Scalar run(const Scalar&) - { - EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) - return Scalar(0); - } -}; - -template<typename Scalar> -struct exp_impl : exp_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {}; - -template<typename Scalar> -struct exp_retval -{ - typedef Scalar type; -}; - -template<typename Scalar> -inline EIGEN_MATHFUNC_RETVAL(exp, Scalar) exp(const Scalar& x) -{ - return EIGEN_MATHFUNC_IMPL(exp, Scalar)::run(x); -} - -/**************************************************************************** -* Implementation of cos * -****************************************************************************/ - -template<typename Scalar, bool IsInteger> -struct cos_default_impl -{ - static inline Scalar run(const Scalar& x) - { - return std::cos(x); - } -}; - -template<typename Scalar> -struct cos_default_impl<Scalar, true> -{ - static inline Scalar run(const Scalar&) - { - EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) - return Scalar(0); - } -}; - -template<typename Scalar> -struct cos_impl : cos_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {}; - -template<typename Scalar> -struct cos_retval -{ - typedef Scalar type; -}; - -template<typename Scalar> -inline EIGEN_MATHFUNC_RETVAL(cos, Scalar) cos(const Scalar& x) -{ - return EIGEN_MATHFUNC_IMPL(cos, Scalar)::run(x); -} - -/**************************************************************************** -* Implementation of sin * -****************************************************************************/ - -template<typename Scalar, bool IsInteger> -struct sin_default_impl -{ - static inline Scalar run(const Scalar& x) - { - return std::sin(x); - } -}; - -template<typename Scalar> -struct sin_default_impl<Scalar, true> -{ - static inline Scalar run(const Scalar&) - { - EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) - return Scalar(0); - } -}; - -template<typename Scalar> -struct sin_impl : sin_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {}; - -template<typename Scalar> -struct sin_retval -{ - typedef Scalar type; -}; - -template<typename Scalar> -inline EIGEN_MATHFUNC_RETVAL(sin, Scalar) sin(const Scalar& x) -{ - return EIGEN_MATHFUNC_IMPL(sin, Scalar)::run(x); -} - -/**************************************************************************** -* Implementation of tan * -****************************************************************************/ - -template<typename Scalar, bool IsInteger> -struct tan_default_impl -{ - static inline Scalar run(const Scalar& x) - { - return std::tan(x); - } -}; - -template<typename Scalar> -struct tan_default_impl<Scalar, true> -{ - static inline Scalar run(const Scalar&) - { - EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) - return Scalar(0); - } -}; - -template<typename Scalar> -struct tan_impl : tan_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {}; - -template<typename Scalar> -struct tan_retval -{ - typedef Scalar type; -}; - -template<typename Scalar> -inline EIGEN_MATHFUNC_RETVAL(tan, Scalar) tan(const Scalar& x) -{ - return EIGEN_MATHFUNC_IMPL(tan, Scalar)::run(x); -} - -/**************************************************************************** -* Implementation of log * -****************************************************************************/ - -template<typename Scalar, bool IsInteger> -struct log_default_impl -{ - static inline Scalar run(const Scalar& x) - { - return std::log(x); - } -}; - -template<typename Scalar> -struct log_default_impl<Scalar, true> -{ - static inline Scalar run(const Scalar&) - { - EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) - return Scalar(0); - } -}; - -template<typename Scalar> -struct log_impl : log_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {}; - -template<typename Scalar> -struct log_retval -{ - typedef Scalar type; -}; - -template<typename Scalar> -inline EIGEN_MATHFUNC_RETVAL(log, Scalar) log(const Scalar& x) -{ - return EIGEN_MATHFUNC_IMPL(log, Scalar)::run(x); -} +// This macro instanciate all the necessary template mechanism which is common to all unary real functions. +#define EIGEN_MATHFUNC_STANDARD_REAL_UNARY(NAME) \ + template<typename Scalar, bool IsInteger> struct NAME##_default_impl { \ + static inline Scalar run(const Scalar& x) { return std::NAME(x); } \ + }; \ + template<typename Scalar> struct NAME##_default_impl<Scalar, true> { \ + static inline Scalar run(const Scalar&) { \ + EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) \ + return Scalar(0); \ + } \ + }; \ + template<typename Scalar> struct NAME##_impl \ + : NAME##_default_impl<Scalar, NumTraits<Scalar>::IsInteger> \ + {}; \ + template<typename Scalar> struct NAME##_retval { typedef Scalar type; }; \ + template<typename Scalar> \ + inline EIGEN_MATHFUNC_RETVAL(NAME, Scalar) NAME(const Scalar& x) { \ + return EIGEN_MATHFUNC_IMPL(NAME, Scalar)::run(x); \ + } + +EIGEN_MATHFUNC_STANDARD_REAL_UNARY(exp) +EIGEN_MATHFUNC_STANDARD_REAL_UNARY(log) +EIGEN_MATHFUNC_STANDARD_REAL_UNARY(sin) +EIGEN_MATHFUNC_STANDARD_REAL_UNARY(cos) +EIGEN_MATHFUNC_STANDARD_REAL_UNARY(tan) +EIGEN_MATHFUNC_STANDARD_REAL_UNARY(asin) +EIGEN_MATHFUNC_STANDARD_REAL_UNARY(acos) /**************************************************************************** * Implementation of atan2 * diff --git a/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/Eigen/src/plugins/ArrayCwiseUnaryOps.h index 7e0c827db..0dffaf413 100644 --- a/Eigen/src/plugins/ArrayCwiseUnaryOps.h +++ b/Eigen/src/plugins/ArrayCwiseUnaryOps.h @@ -70,7 +70,7 @@ sqrt() const * Example: \include Cwise_cos.cpp * Output: \verbinclude Cwise_cos.out * - * \sa sin(), exp() + * \sa sin(), acos() */ inline const CwiseUnaryOp<internal::scalar_cos_op<Scalar>, const Derived> cos() const @@ -84,7 +84,7 @@ cos() const * Example: \include Cwise_sin.cpp * Output: \verbinclude Cwise_sin.out * - * \sa cos(), exp() + * \sa cos(), asin() */ inline const CwiseUnaryOp<internal::scalar_sin_op<Scalar>, const Derived> sin() const @@ -92,6 +92,31 @@ sin() const return derived(); } +/** \returns an expression of the coefficient-wise arc cosine of *this. + * + * Example: \include Cwise_acos.cpp + * Output: \verbinclude Cwise_acos.out + * + * \sa cos(), asin() + */ +inline const CwiseUnaryOp<internal::scalar_acos_op<Scalar>, const Derived> +acos() const +{ + return derived(); +} + +/** \returns an expression of the coefficient-wise arc sine of *this. + * + * Example: \include Cwise_asin.cpp + * Output: \verbinclude Cwise_asin.out + * + * \sa sin(), acos() + */ +inline const CwiseUnaryOp<internal::scalar_asin_op<Scalar>, const Derived> +asin() const +{ + return derived(); +} /** \returns an expression of the coefficient-wise tan of *this. * diff --git a/doc/snippets/Cwise_acos.cpp b/doc/snippets/Cwise_acos.cpp new file mode 100644 index 000000000..34432cbac --- /dev/null +++ b/doc/snippets/Cwise_acos.cpp @@ -0,0 +1,2 @@ +Array3d v(0, sqrt(2.)/2, 1); +cout << v.acos() << endl; diff --git a/test/array.cpp b/test/array.cpp index 26c6c33b7..8ec80d55f 100644 --- a/test/array.cpp +++ b/test/array.cpp @@ -169,10 +169,15 @@ template<typename ArrayType> void array_real(const ArrayType& m) m2 = ArrayType::Random(rows, cols), m3(rows, cols); + // these these are mostly to check possible compilation issues. VERIFY_IS_APPROX(m1.sin(), std::sin(m1)); VERIFY_IS_APPROX(m1.sin(), internal::sin(m1)); VERIFY_IS_APPROX(m1.cos(), std::cos(m1)); VERIFY_IS_APPROX(m1.cos(), internal::cos(m1)); + VERIFY_IS_APPROX(m1.asin(), std::sin(m1)); + VERIFY_IS_APPROX(m1.asin(), internal::sin(m1)); + VERIFY_IS_APPROX(m1.acos(), std::acos(m1)); + VERIFY_IS_APPROX(m1.acos(), internal::acos(m1)); VERIFY_IS_APPROX(m1.tan(), std::tan(m1)); VERIFY_IS_APPROX(m1.tan(), internal::tan(m1)); diff --git a/test/packetmath.cpp b/test/packetmath.cpp index 001dbc4d2..c6c5bd3b0 100644 --- a/test/packetmath.cpp +++ b/test/packetmath.cpp @@ -223,6 +223,15 @@ template<typename Scalar> void packetmath_real() } CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasSin, internal::sin, internal::psin); CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasCos, internal::cos, internal::pcos); + CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasTan, internal::tan, internal::ptan); + + for (int i=0; i<size; ++i) + { + data1[i] = internal::random<Scalar>(-1,1); + data2[i] = internal::random<Scalar>(-1,1); + } + CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasASin, internal::asin, internal::pasin); + CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasACos, internal::acos, internal::pacos); for (int i=0; i<size; ++i) { |