Additional unary coeff-wise functors (isnan, round, arg, e.g.)

This commit is contained in:
Deanna Hood 2015-03-11 06:39:23 +10:00
parent fd78874888
commit 31fdd67756
7 changed files with 401 additions and 12 deletions

View File

@ -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_COMPLEX_LA(EIGENOP, VMLOP)
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sin, Sin) 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(asin, Asin)
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(cos, Cos) 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(acos, Acos)
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(tan, Tan) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(tan, Tan)
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(atan, Atan) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(atan, Atan)
//EIGEN_MKL_VML_DECLARE_UNARY_CALLS(abs, Abs) //EIGEN_MKL_VML_DECLARE_UNARY_CALLS(abs, Abs)
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(exp, Exp) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(arg, Arg)
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(log, Ln) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(exp, Exp)
EIGEN_MKL_VML_DECLARE_UNARY_CALLS_LA(sqrt, Sqrt) 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) EIGEN_MKL_VML_DECLARE_UNARY_CALLS_REAL(square, Sqr)

View File

@ -49,6 +49,7 @@ struct default_packet_traits
HasMul = 1, HasMul = 1,
HasNegate = 1, HasNegate = 1,
HasAbs = 1, HasAbs = 1,
HasArg = 0,
HasAbs2 = 1, HasAbs2 = 1,
HasMin = 1, HasMin = 1,
HasMax = 1, HasMax = 1,
@ -67,7 +68,13 @@ struct default_packet_traits
HasTan = 0, HasTan = 0,
HasASin = 0, HasASin = 0,
HasACos = 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 template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
pabs(const Packet& a) { using std::abs; return abs(a); } 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 */ /** \internal \returns the bitwise and of \a a and \a b */
template<typename Packet> EIGEN_DEVICE_FUNC inline Packet template<typename Packet> EIGEN_DEVICE_FUNC inline Packet
pand(const Packet& a, const Packet& b) { return a & b; } 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 template<typename Packet> EIGEN_DECLARE_FUNCTION_ALLOWING_MULTIPLE_DEFINITIONS
Packet psqrt(const Packet& a) { using std::sqrt; return sqrt(a); } 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 * The following functions might not have to be overwritten for vectorized types
***************************************************************************/ ***************************************************************************/

View File

@ -49,7 +49,13 @@ namespace Eigen
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp,scalar_exp_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(exp,scalar_exp_op)
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op) EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(log,scalar_log_op)
EIGEN_ARRAY_DECLARE_GLOBAL_UNARY(abs,scalar_abs_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(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> template<typename Derived>
inline const Eigen::CwiseUnaryOp<Eigen::internal::scalar_pow_op<typename Derived::Scalar>, const Derived> inline const Eigen::CwiseUnaryOp<Eigen::internal::scalar_pow_op<typename Derived::Scalar>, const Derived>

View File

@ -133,6 +133,41 @@ struct imag_retval
typedef typename NumTraits<Scalar>::Real type; typedef typename NumTraits<Scalar>::Real type;
}; };
/****************************************************************************
* 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 * * Implementation of real_ref *
****************************************************************************/ ****************************************************************************/
@ -574,7 +609,7 @@ inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
} // end namespace internal } // end namespace internal
/**************************************************************************** /****************************************************************************
* Generic math function * * Generic math functions *
****************************************************************************/ ****************************************************************************/
namespace numext { namespace numext {
@ -623,6 +658,13 @@ inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x); return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(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> template<typename Scalar>
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x) inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x)
@ -697,6 +739,95 @@ bool (isfinite)(const std::complex<T>& x)
return isfinite(real(x)) && isfinite(imag(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. // Log base 2 for 32 bits positive integers.
// Conveniently returns 0 for x==0. // Conveniently returns 0 for x==0.
inline int log2(int x) inline int log2(int x)

View File

@ -122,6 +122,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 /** \internal
* \brief Template functor to cast a scalar to another type * \brief Template functor to cast a scalar to another type
* *
@ -416,6 +437,103 @@ template<typename Scalar>
struct functor_traits<scalar_cube_op<Scalar> > struct functor_traits<scalar_cube_op<Scalar> >
{ enum { Cost = 2*NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; }; { 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 } // end namespace internal

View File

@ -1,6 +1,7 @@
typedef CwiseUnaryOp<internal::scalar_abs_op<Scalar>, const Derived> AbsReturnType; 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_abs2_op<Scalar>, const Derived> Abs2ReturnType;
typedef CwiseUnaryOp<internal::scalar_sqrt_op<Scalar>, const Derived> SqrtReturnType; typedef CwiseUnaryOp<internal::scalar_sqrt_op<Scalar>, const Derived> SqrtReturnType;
typedef CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const Derived> InverseReturnType; 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_pow_op<Scalar>, const Derived> PowReturnType;
typedef CwiseUnaryOp<internal::scalar_square_op<Scalar>, const Derived> SquareReturnType; typedef CwiseUnaryOp<internal::scalar_square_op<Scalar>, const Derived> SquareReturnType;
typedef CwiseUnaryOp<internal::scalar_cube_op<Scalar>, const Derived> CubeReturnType; 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 /** \returns an expression of the coefficient-wise absolute value of \c *this
* *
@ -31,6 +37,20 @@ abs() const
return AbsReturnType(derived()); 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 /** \returns an expression of the coefficient-wise squared absolute value of \c *this
* *
* Example: \include Cwise_abs2.cpp * Example: \include Cwise_abs2.cpp
@ -246,6 +266,71 @@ cube() const
return CubeReturnType(derived()); 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) \ #define EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(METHOD_NAME,FUNCTOR) \
EIGEN_DEVICE_FUNC \ EIGEN_DEVICE_FUNC \
inline const CwiseUnaryOp<std::binder2nd<FUNCTOR<Scalar> >, const Derived> \ inline const CwiseUnaryOp<std::binder2nd<FUNCTOR<Scalar> >, const Derived> \

View File

@ -204,6 +204,11 @@ template<typename ArrayType> void array_real(const ArrayType& m)
VERIFY_IS_APPROX(m1.acos(), acos(m1)); VERIFY_IS_APPROX(m1.acos(), acos(m1));
VERIFY_IS_APPROX(m1.tan(), tan(m1)); VERIFY_IS_APPROX(m1.tan(), tan(m1));
VERIFY_IS_APPROX(m1.atan(), atan(m1)); VERIFY_IS_APPROX(m1.atan(), atan(m1));
VERIFY_IS_APPROX(m1.round(), round(m1));
VERIFY_IS_APPROX(m1.floor(), floor(m1));
VERIFY_IS_APPROX(m1.ceil(), ceil(m1));
VERIFY_IS_APPROX(m1.isnan(), isnan(m1));
VERIFY_IS_APPROX(m1.isinf(), isinf(m1));
VERIFY_IS_APPROX(cos(m1+RealScalar(3)*m2), cos((m1+RealScalar(3)*m2).eval())); VERIFY_IS_APPROX(cos(m1+RealScalar(3)*m2), cos((m1+RealScalar(3)*m2).eval()));
@ -263,6 +268,13 @@ template<typename ArrayType> void array_complex(const ArrayType& m)
VERIFY_IS_APPROX(m1.sqrt(), m2); VERIFY_IS_APPROX(m1.sqrt(), m2);
VERIFY_IS_APPROX(m1.sqrt(), Eigen::sqrt(m1)); VERIFY_IS_APPROX(m1.sqrt(), Eigen::sqrt(m1));
VERIFY_IS_APPROX(m1.arg(), arg(m1));
VERIFY_IS_APPROX(m1.round(), round(m1));
VERIFY_IS_APPROX(m1.floor(), floor(m1));
VERIFY_IS_APPROX(m1.ceil(), ceil(m1));
VERIFY_IS_APPROX(m1.isnan(), isnan(m1));
VERIFY_IS_APPROX(m1.isinf(), isinf(m1));
} }
template<typename ArrayType> void min_max(const ArrayType& m) template<typename ArrayType> void min_max(const ArrayType& m)