aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2011-02-17 17:37:11 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2011-02-17 17:37:11 +0100
commitaea630a98a39a523bfb008e884262d69ee473b8d (patch)
tree9af0e1ae346bc2e07568fd8c155013986dcfe34a
parent2ba55e90db84d33c83fd9aaaa42004d211779a1d (diff)
factorize implementation of standard real unary math functions, and add acos, asin
-rw-r--r--Eigen/src/Core/Functors.h44
-rw-r--r--Eigen/src/Core/GenericPacketMath.h12
-rw-r--r--Eigen/src/Core/GlobalFunctions.h4
-rw-r--r--Eigen/src/Core/MathFunctions.h214
-rw-r--r--Eigen/src/plugins/ArrayCwiseUnaryOps.h29
-rw-r--r--doc/snippets/Cwise_acos.cpp2
-rw-r--r--test/array.cpp5
-rw-r--r--test/packetmath.cpp9
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)
{