aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Eigen/src/Core/Assign_MKL.h26
-rw-r--r--Eigen/src/Core/GenericPacketMath.h45
-rw-r--r--Eigen/src/Core/GlobalFunctions.h19
-rw-r--r--Eigen/src/Core/MathFunctions.h174
-rw-r--r--Eigen/src/Core/functors/UnaryFunctors.h222
-rw-r--r--Eigen/src/Core/util/Macros.h10
-rw-r--r--Eigen/src/plugins/ArrayCwiseUnaryOps.h206
-rw-r--r--doc/snippets/Cwise_arg.cpp3
-rw-r--r--doc/snippets/Cwise_boolean_not.cpp5
-rw-r--r--doc/snippets/Cwise_ceil.cpp3
-rw-r--r--doc/snippets/Cwise_cosh.cpp2
-rw-r--r--doc/snippets/Cwise_floor.cpp3
-rw-r--r--doc/snippets/Cwise_isFinite.cpp5
-rw-r--r--doc/snippets/Cwise_isInf.cpp5
-rw-r--r--doc/snippets/Cwise_isNaN.cpp5
-rw-r--r--doc/snippets/Cwise_log10.cpp2
-rw-r--r--doc/snippets/Cwise_round.cpp3
-rw-r--r--doc/snippets/Cwise_sinh.cpp2
-rw-r--r--doc/snippets/Cwise_tanh.cpp2
-rw-r--r--test/array.cpp123
-rw-r--r--test/main.h7
-rw-r--r--test/packetmath.cpp10
-rw-r--r--test/stable_norm.cpp40
23 files changed, 845 insertions, 77 deletions
diff --git a/Eigen/src/Core/Assign_MKL.h b/Eigen/src/Core/Assign_MKL.h
index a7b9e9293..d4ef1d3a4 100644
--- a/Eigen/src/Core/Assign_MKL.h
+++ b/Eigen/src/Core/Assign_MKL.h
@@ -196,18 +196,26 @@ 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(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(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_LA(tanh, Tanh)
+//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(log10, Log10)
+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
diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h
index 77941c059..8a7a0eddc 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,
@@ -61,6 +62,7 @@ struct default_packet_traits
HasRsqrt = 0,
HasExp = 0,
HasLog = 0,
+ HasLog10 = 0,
HasPow = 0,
HasSin = 0,
@@ -68,7 +70,14 @@ struct default_packet_traits
HasTan = 0,
HasASin = 0,
HasACos = 0,
- HasATan = 0
+ HasATan = 0,
+ HasSinh = 0,
+ HasCosh = 0,
+ HasTanh = 0,
+
+ HasRound = 0,
+ HasFloor = 0,
+ HasCeil = 0
};
};
@@ -163,6 +172,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; }
@@ -359,10 +372,22 @@ Packet pasin(const Packet& a) { using std::asin; return asin(a); }
template<typename Packet> 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<typename Packet> 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<typename Packet> 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<typename Packet> 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<typename Packet> 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<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
Packet pexp(const Packet& a) { using std::exp; return exp(a); }
@@ -371,6 +396,10 @@ Packet pexp(const Packet& a) { using std::exp; return exp(a); }
template<typename Packet> 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<typename Packet> 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<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
Packet psqrt(const Packet& a) { using std::sqrt; return sqrt(a); }
@@ -381,6 +410,18 @@ Packet prsqrt(const Packet& a) {
return pdiv(pset1<Packet>(1), psqrt(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); }
+
/***************************************************************************
* 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..1924c8e5f 100644
--- a/Eigen/src/Core/GlobalFunctions.h
+++ b/Eigen/src/Core/GlobalFunctions.h
@@ -40,16 +40,31 @@ 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(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)
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)
+ 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<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 3c240c272..1ce935909 100644
--- a/Eigen/src/Core/MathFunctions.h
+++ b/Eigen/src/Core/MathFunctions.h
@@ -361,7 +361,94 @@ 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<typename Scalar>
+ struct round_impl {
+ static inline Scalar run(const Scalar& x)
+ {
+ EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
+ using std::round;
+ return round(x);
+ }
+ };
+// No C++11, use our own implementation
+#else
+ template<typename Scalar>
+ struct round_impl
+ {
+ static inline Scalar run(const Scalar& x)
+ {
+ EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::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<typename Scalar>
+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<typename Scalar>
+ 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<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> {};
+#endif
+
+template<typename Scalar>
+struct arg_retval
+{
+ typedef typename NumTraits<Scalar>::Real type;
+};
+
+/****************************************************************************
+* Implementation of log1p *
****************************************************************************/
template<typename Scalar, bool isComplex = NumTraits<Scalar>::IsComplex >
struct log1p_impl
@@ -588,7 +675,7 @@ inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
} // end namespace internal
/****************************************************************************
-* Generic math function *
+* Generic math functions *
****************************************************************************/
namespace numext {
@@ -639,6 +726,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);
@@ -693,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<typename T>
EIGEN_DEVICE_FUNC
bool (isfinite)(const T& x)
{
- return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest();
+ #ifdef EIGEN_HAS_C99_MATH
+ using std::isfinite;
+ return isfinite(x);
+ #else
+ return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest();
+ #endif
}
template<typename T>
@@ -711,6 +808,73 @@ 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)
+{
+ #ifdef EIGEN_HAS_C99_MATH
+ using std::isnan;
+ return isnan(x);
+ #else
+ return x != x;
+ #endif
+}
+
+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)
+{
+ #ifdef EIGEN_HAS_C99_MATH
+ using std::isinf;
+ return isinf(x);
+ #else
+ return x>NumTraits<T>::highest() || x<NumTraits<T>::lowest();
+ #endif
+}
+
+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 Scalar>
+EIGEN_DEVICE_FUNC
+inline EIGEN_MATHFUNC_RETVAL(round, Scalar) round(const Scalar& x)
+{
+ return EIGEN_MATHFUNC_IMPL(round, Scalar)::run(x);
+}
+
+template<typename T>
+EIGEN_DEVICE_FUNC
+T (floor)(const T& x)
+{
+ using std::floor;
+ return floor(x);
+}
+
+template<typename T>
+EIGEN_DEVICE_FUNC
+T (ceil)(const T& x)
+{
+ using std::ceil;
+ return ceil(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 4e03761ea..a6fa5ee31 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>::IsComplex ? 5 * NumTraits<Scalar>::MulCost : NumTraits<Scalar>::AddCost,
+ PacketAccess = packet_traits<Scalar>::HasArg
+ };
+};
+/** \internal
* \brief Template functor to cast a scalar to another type
*
* \sa class CwiseUnaryOp, MatrixBase::cast()
@@ -233,6 +254,21 @@ template<typename Scalar>
struct functor_traits<scalar_log_op<Scalar> >
{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasLog }; };
+/** \internal
+ *
+ * \brief Template functor to compute the base-10 logarithm of a scalar
+ *
+ * \sa class CwiseUnaryOp, Cwise::log10()
+ */
+template<typename Scalar> 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<Scalar>::type Packet;
+ inline Packet packetOp(const Packet& a) const { return internal::plog10(a); }
+};
+template<typename Scalar>
+struct functor_traits<scalar_log10_op<Scalar> >
+{ enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasLog10 }; };
/** \internal
* \brief Template functor to compute the square root of a scalar
@@ -367,7 +403,6 @@ struct functor_traits<scalar_asin_op<Scalar> >
};
};
-
/** \internal
* \brief Template functor to compute the atan of a scalar
* \sa class CwiseUnaryOp, ArrayBase::atan()
@@ -388,6 +423,63 @@ struct functor_traits<scalar_atan_op<Scalar> >
};
/** \internal
+ * \brief Template functor to compute the tanh of a scalar
+ * \sa class CwiseUnaryOp, ArrayBase::tanh()
+ */
+template<typename Scalar> 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<Scalar>::type Packet;
+ inline Packet packetOp(const Packet& a) const { return internal::ptanh(a); }
+};
+template<typename Scalar>
+struct functor_traits<scalar_tanh_op<Scalar> >
+{
+ enum {
+ Cost = 5 * NumTraits<Scalar>::MulCost,
+ PacketAccess = packet_traits<Scalar>::HasTanh
+ };
+};
+
+/** \internal
+ * \brief Template functor to compute the sinh of a scalar
+ * \sa class CwiseUnaryOp, ArrayBase::sinh()
+ */
+template<typename Scalar> 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<Scalar>::type Packet;
+ inline Packet packetOp(const Packet& a) const { return internal::psinh(a); }
+};
+template<typename Scalar>
+struct functor_traits<scalar_sinh_op<Scalar> >
+{
+ enum {
+ Cost = 5 * NumTraits<Scalar>::MulCost,
+ PacketAccess = packet_traits<Scalar>::HasSinh
+ };
+};
+
+/** \internal
+ * \brief Template functor to compute the cosh of a scalar
+ * \sa class CwiseUnaryOp, ArrayBase::cosh()
+ */
+template<typename Scalar> 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<Scalar>::type Packet;
+ inline Packet packetOp(const Packet& a) const { return internal::pcosh(a); }
+};
+template<typename Scalar>
+struct functor_traits<scalar_cosh_op<Scalar> >
+{
+ enum {
+ Cost = 5 * NumTraits<Scalar>::MulCost,
+ PacketAccess = packet_traits<Scalar>::HasCosh
+ };
+};
+
+/** \internal
* \brief Template functor to compute the inverse of a scalar
* \sa class CwiseUnaryOp, Cwise::inverse()
*/
@@ -435,6 +527,134 @@ 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 whether a scalar is NaN
+ * \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 Scalar>
+struct functor_traits<scalar_isNaN_op<Scalar> >
+{
+ enum {
+ Cost = NumTraits<Scalar>::MulCost,
+ PacketAccess = false
+ };
+};
+
+/** \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); }
+};
+template<typename Scalar>
+struct functor_traits<scalar_isInf_op<Scalar> >
+{
+ enum {
+ Cost = NumTraits<Scalar>::MulCost,
+ PacketAccess = false
+ };
+};
+
+/** \internal
+ * \brief Template functor to compute the isFinite of a scalar
+ * \sa class CwiseUnaryOp, ArrayBase::isFinite()
+ */
+template<typename Scalar> 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); }
+};
+template<typename Scalar>
+struct functor_traits<scalar_isFinite_op<Scalar> >
+{
+ enum {
+ Cost = NumTraits<Scalar>::MulCost,
+ PacketAccess = false
+ };
+};
+
+/** \internal
+ * \brief Template functor to compute the logical not of a boolean
+ *
+ * \sa class CwiseUnaryOp, ArrayBase::operator!
+ */
+template<typename Scalar> 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<typename Scalar>
+struct functor_traits<scalar_boolean_not_op<Scalar> > {
+ enum {
+ Cost = NumTraits<bool>::AddCost,
+ PacketAccess = false
+ };
+};
+
} // end namespace internal
diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h
index e9754607b..4eeb8211c 100644
--- a/Eigen/src/Core/util/Macros.h
+++ b/Eigen/src/Core/util/Macros.h
@@ -415,6 +415,16 @@
#define EIGEN_HAS_CONSTEXPR 1
#endif
+// Does the compiler support C99 math?
+#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
+
/** 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:
diff --git a/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/Eigen/src/plugins/ArrayCwiseUnaryOps.h
index 3d4693fd1..c9f7c8f6e 100644
--- a/Eigen/src/plugins/ArrayCwiseUnaryOps.h
+++ b/Eigen/src/plugins/ArrayCwiseUnaryOps.h
@@ -1,21 +1,33 @@
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;
+typedef CwiseUnaryOp<internal::scalar_boolean_not_op<Scalar>, const Derived> BooleanNotReturnType;
typedef CwiseUnaryOp<internal::scalar_exp_op<Scalar>, const Derived> ExpReturnType;
typedef CwiseUnaryOp<internal::scalar_log_op<Scalar>, const Derived> LogReturnType;
+typedef CwiseUnaryOp<internal::scalar_log10_op<Scalar>, const Derived> Log10ReturnType;
typedef CwiseUnaryOp<internal::scalar_cos_op<Scalar>, const Derived> CosReturnType;
typedef CwiseUnaryOp<internal::scalar_sin_op<Scalar>, const Derived> SinReturnType;
+typedef CwiseUnaryOp<internal::scalar_tan_op<Scalar>, const Derived> TanReturnType;
typedef CwiseUnaryOp<internal::scalar_acos_op<Scalar>, const Derived> AcosReturnType;
typedef CwiseUnaryOp<internal::scalar_asin_op<Scalar>, const Derived> AsinReturnType;
-typedef CwiseUnaryOp<internal::scalar_tan_op<Scalar>, const Derived> TanReturnType;
typedef CwiseUnaryOp<internal::scalar_atan_op<Scalar>, const Derived> AtanReturnType;
+typedef CwiseUnaryOp<internal::scalar_tanh_op<Scalar>, const Derived> TanhReturnType;
+typedef CwiseUnaryOp<internal::scalar_sinh_op<Scalar>, const Derived> SinhReturnType;
+typedef CwiseUnaryOp<internal::scalar_cosh_op<Scalar>, const Derived> CoshReturnType;
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;
+typedef CwiseUnaryOp<internal::scalar_isFinite_op<Scalar>, const Derived> IsFiniteReturnType;
/** \returns an expression of the coefficient-wise absolute value of \c *this
*
@@ -31,6 +43,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
@@ -79,6 +105,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
@@ -131,6 +173,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
@@ -159,31 +228,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.
@@ -246,5 +327,98 @@ 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 isFinite(), 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(), isFinite()
+ */
+inline const IsInfReturnType
+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(), isInf()
+ */
+inline const IsFiniteReturnType
+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<bool,Scalar>::value),
+ THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL);
+ return BooleanNotReturnType(derived());
+}
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_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/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_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/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_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_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;
diff --git a/test/array.cpp b/test/array.cpp
index 1443f9f88..90c75e9f0 100644
--- a/test/array.cpp
+++ b/test/array.cpp
@@ -201,18 +201,54 @@ template<typename ArrayType> void array_real(const ArrayType& m)
Scalar s1 = internal::random<Scalar>();
- // 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));
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.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((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));
@@ -221,7 +257,7 @@ template<typename ArrayType> void array_real(const ArrayType& m)
// shift argument of logarithm so that it is not zero
Scalar smallNumber = NumTraits<Scalar>::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));
@@ -229,13 +265,15 @@ template<typename ArrayType> 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<RealScalar>::epsilon());
@@ -246,14 +284,16 @@ template<typename ArrayType> 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<typename ArrayType> void array_complex(const ArrayType& m)
{
typedef typename ArrayType::Index Index;
+ typedef typename ArrayType::Scalar Scalar;
+ typedef typename NumTraits<Scalar>::Real RealScalar;
Index rows = m.rows();
Index cols = m.cols();
@@ -261,12 +301,73 @@ template<typename ArrayType> void array_complex(const ArrayType& m)
ArrayType m1 = ArrayType::Random(rows, cols),
m2(rows, cols);
+ Array<RealScalar, -1, -1> m3(rows, cols);
+
+ Scalar s1 = internal::random<Scalar>();
+
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));
+ // 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<RealScalar> 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<RealScalar>::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);
+
}
template<typename ArrayType> void min_max(const ArrayType& m)
diff --git a/test/main.h b/test/main.h
index 3591b57a1..d336d4d9b 100644
--- a/test/main.h
+++ b/test/main.h
@@ -448,12 +448,7 @@ template<typename T> bool isNotNaN(const T& x)
return x==x;
}
-template<typename T> bool isNaN(const T& x)
-{
- return x!=x;
-}
-
-template<typename T> bool isInf(const T& x)
+template<typename T> bool isPlusInf(const T& x)
{
return x > NumTraits<T>::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<typename Scalar> void packetmath_real()
data1[0] = std::numeric_limits<Scalar>::quiet_NaN();
packet_helper<internal::packet_traits<Scalar>::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<size; ++i)
@@ -333,14 +333,14 @@ template<typename Scalar> void packetmath_real()
data1[0] = std::numeric_limits<Scalar>::quiet_NaN();
packet_helper<internal::packet_traits<Scalar>::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<typename MatrixType> void stable_norm(const MatrixType& m)
{
v = vrand;
v(i,j) = std::numeric_limits<RealScalar>::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<RealScalar>::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<RealScalar>::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<typename MatrixType> void stable_norm(const MatrixType& m)
v = vrand;
v(i,j) = -std::numeric_limits<RealScalar>::infinity();
v(i2,j2) = std::numeric_limits<RealScalar>::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()));
}
}