10 #ifndef EIGEN_MATHFUNCTIONS_H
11 #define EIGEN_MATHFUNCTIONS_H
15 #define EIGEN_PI 3.141592653589793238462643383279502884197169399375105820974944592307816406L
22 #if EIGEN_OS_WINCE && EIGEN_COMP_MSVC && EIGEN_COMP_MSVC<=1500
23 long abs(
long x) {
return (labs(x)); }
24 double abs(
double x) {
return (fabs(x)); }
25 float abs(
float x) {
return (fabsf(x)); }
26 long double abs(
long double x) {
return (fabsl(x)); }
51 template<
typename T,
typename dummy =
void>
52 struct global_math_functions_filtering_base
57 template<
typename T>
struct always_void {
typedef void type; };
60 struct global_math_functions_filtering_base
62 typename always_void<typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl>::type
65 typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type;
68 #define EIGEN_MATHFUNC_IMPL(func, scalar) Eigen::internal::func##_impl<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>
69 #define EIGEN_MATHFUNC_RETVAL(func, scalar) typename Eigen::internal::func##_retval<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>::type
75 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
76 struct real_default_impl
78 typedef typename NumTraits<Scalar>::Real RealScalar;
80 static inline RealScalar run(
const Scalar& x)
86 template<
typename Scalar>
87 struct real_default_impl<Scalar,true>
89 typedef typename NumTraits<Scalar>::Real RealScalar;
91 static inline RealScalar run(
const Scalar& x)
98 template<
typename Scalar>
struct real_impl : real_default_impl<Scalar> {};
102 struct real_impl<std::complex<T> >
104 typedef T RealScalar;
106 static inline T run(
const std::complex<T>& x)
113 template<
typename Scalar>
116 typedef typename NumTraits<Scalar>::Real type;
123 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
124 struct imag_default_impl
126 typedef typename NumTraits<Scalar>::Real RealScalar;
128 static inline RealScalar run(
const Scalar&)
130 return RealScalar(0);
134 template<
typename Scalar>
135 struct imag_default_impl<Scalar,true>
137 typedef typename NumTraits<Scalar>::Real RealScalar;
139 static inline RealScalar run(
const Scalar& x)
146 template<
typename Scalar>
struct imag_impl : imag_default_impl<Scalar> {};
150 struct imag_impl<std::complex<T> >
152 typedef T RealScalar;
154 static inline T run(
const std::complex<T>& x)
161 template<
typename Scalar>
164 typedef typename NumTraits<Scalar>::Real type;
171 template<
typename Scalar>
174 typedef typename NumTraits<Scalar>::Real RealScalar;
176 static inline RealScalar& run(Scalar& x)
178 return reinterpret_cast<RealScalar*
>(&x)[0];
181 static inline const RealScalar& run(
const Scalar& x)
183 return reinterpret_cast<const RealScalar*
>(&x)[0];
187 template<
typename Scalar>
188 struct real_ref_retval
190 typedef typename NumTraits<Scalar>::Real & type;
197 template<
typename Scalar,
bool IsComplex>
198 struct imag_ref_default_impl
200 typedef typename NumTraits<Scalar>::Real RealScalar;
202 static inline RealScalar& run(Scalar& x)
204 return reinterpret_cast<RealScalar*
>(&x)[1];
207 static inline const RealScalar& run(
const Scalar& x)
209 return reinterpret_cast<RealScalar*
>(&x)[1];
213 template<
typename Scalar>
214 struct imag_ref_default_impl<Scalar, false>
217 static inline Scalar run(Scalar&)
222 static inline const Scalar run(
const Scalar&)
228 template<
typename Scalar>
229 struct imag_ref_impl : imag_ref_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
231 template<
typename Scalar>
232 struct imag_ref_retval
234 typedef typename NumTraits<Scalar>::Real & type;
241 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
245 static inline Scalar run(
const Scalar& x)
251 template<
typename Scalar>
252 struct conj_impl<Scalar,true>
255 static inline Scalar run(
const Scalar& x)
262 template<
typename Scalar>
272 template<
typename Scalar,
bool IsComplex>
273 struct abs2_impl_default
275 typedef typename NumTraits<Scalar>::Real RealScalar;
277 static inline RealScalar run(
const Scalar& x)
283 template<
typename Scalar>
284 struct abs2_impl_default<Scalar, true>
286 typedef typename NumTraits<Scalar>::Real RealScalar;
288 static inline RealScalar run(
const Scalar& x)
290 return x.real()*x.real() + x.imag()*x.imag();
294 template<
typename Scalar>
297 typedef typename NumTraits<Scalar>::Real RealScalar;
299 static inline RealScalar run(
const Scalar& x)
301 return abs2_impl_default<Scalar,NumTraits<Scalar>::IsComplex>::run(x);
305 template<
typename Scalar>
308 typedef typename NumTraits<Scalar>::Real type;
315 template<
typename Scalar,
bool IsComplex>
316 struct norm1_default_impl;
318 template<
typename Scalar>
319 struct norm1_default_impl<Scalar,true>
321 typedef typename NumTraits<Scalar>::Real RealScalar;
323 static inline RealScalar run(
const Scalar& x)
325 EIGEN_USING_STD_MATH(
abs);
326 return abs(x.real()) +
abs(x.imag());
330 template<
typename Scalar>
331 struct norm1_default_impl<Scalar, false>
334 static inline Scalar run(
const Scalar& x)
336 EIGEN_USING_STD_MATH(
abs);
341 template<
typename Scalar>
342 struct norm1_impl : norm1_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
344 template<
typename Scalar>
347 typedef typename NumTraits<Scalar>::Real type;
354 template<
typename Scalar>
struct hypot_impl;
356 template<
typename Scalar>
359 typedef typename NumTraits<Scalar>::Real type;
366 template<
typename OldType,
typename NewType>
370 static inline NewType run(
const OldType& x)
372 return static_cast<NewType
>(x);
378 template<
typename OldType,
typename NewType>
380 inline NewType cast(
const OldType& x)
382 return cast_impl<OldType, NewType>::run(x);
389 #if EIGEN_HAS_CXX11_MATH
390 template<
typename Scalar>
392 static inline Scalar run(
const Scalar& x)
394 EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
400 template<
typename Scalar>
403 static inline Scalar run(
const Scalar& x)
405 EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
406 EIGEN_USING_STD_MATH(
floor);
407 EIGEN_USING_STD_MATH(
ceil);
408 return (x > Scalar(0)) ?
floor(x + Scalar(0.5)) :
ceil(x - Scalar(0.5));
413 template<
typename Scalar>
423 #if EIGEN_HAS_CXX11_MATH
424 template<
typename Scalar>
426 static inline Scalar run(
const Scalar& x)
428 EIGEN_USING_STD_MATH(
arg);
433 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
434 struct arg_default_impl
436 typedef typename NumTraits<Scalar>::Real RealScalar;
438 static inline RealScalar run(
const Scalar& x)
440 return (x < Scalar(0)) ? Scalar(EIGEN_PI) : Scalar(0); }
443 template<
typename Scalar>
444 struct arg_default_impl<Scalar,true>
446 typedef typename NumTraits<Scalar>::Real RealScalar;
448 static inline RealScalar run(
const Scalar& x)
450 EIGEN_USING_STD_MATH(
arg);
455 template<
typename Scalar>
struct arg_impl : arg_default_impl<Scalar> {};
458 template<
typename Scalar>
461 typedef typename NumTraits<Scalar>::Real type;
468 namespace std_fallback {
471 template<
typename Scalar>
472 EIGEN_DEVICE_FUNC
inline Scalar
log1p(
const Scalar& x) {
473 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
474 typedef typename NumTraits<Scalar>::Real RealScalar;
475 EIGEN_USING_STD_MATH(
log);
476 Scalar x1p = RealScalar(1) + x;
477 return numext::equal_strict(x1p, Scalar(1)) ? x : x * (
log(x1p) / (x1p - RealScalar(1)) );
481 template<
typename Scalar>
483 static inline Scalar run(
const Scalar& x)
485 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
486 #if EIGEN_HAS_CXX11_MATH
489 using std_fallback::log1p;
495 template<
typename Scalar>
505 template<typename ScalarX,typename ScalarY, bool IsInteger = NumTraits<ScalarX>::IsInteger&&NumTraits<ScalarY>::IsInteger>
509 typedef typename ScalarBinaryOpTraits<ScalarX,ScalarY,internal::scalar_pow_op<ScalarX,ScalarY> >::ReturnType result_type;
510 static EIGEN_DEVICE_FUNC
inline result_type run(
const ScalarX& x,
const ScalarY& y)
512 EIGEN_USING_STD_MATH(pow);
517 template<
typename ScalarX,
typename ScalarY>
518 struct pow_impl<ScalarX,ScalarY, true>
520 typedef ScalarX result_type;
521 static EIGEN_DEVICE_FUNC
inline ScalarX run(ScalarX x, ScalarY y)
524 eigen_assert(!NumTraits<ScalarY>::IsSigned || y >= 0);
541 template<
typename Scalar,
544 struct random_default_impl {};
546 template<
typename Scalar>
547 struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
549 template<
typename Scalar>
555 template<
typename Scalar>
inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(
const Scalar& x,
const Scalar& y);
556 template<
typename Scalar>
inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random();
558 template<
typename Scalar>
559 struct random_default_impl<Scalar, false, false>
561 static inline Scalar run(
const Scalar& x,
const Scalar& y)
563 return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX);
565 static inline Scalar run()
567 return run(Scalar(NumTraits<Scalar>::IsSigned ? -1 : 0), Scalar(1));
572 meta_floor_log2_terminate,
573 meta_floor_log2_move_up,
574 meta_floor_log2_move_down,
575 meta_floor_log2_bogus
578 template<
unsigned int n,
int lower,
int upper>
struct meta_floor_log2_selector
580 enum { middle = (lower + upper) / 2,
581 value = (upper <= lower + 1) ? int(meta_floor_log2_terminate)
582 : (n < (1 << middle)) ? int(meta_floor_log2_move_down)
583 : (n==0) ? int(meta_floor_log2_bogus)
584 : int(meta_floor_log2_move_up)
588 template<
unsigned int n,
590 int upper =
sizeof(
unsigned int) * CHAR_BIT - 1,
591 int selector = meta_floor_log2_selector<n, lower, upper>::value>
592 struct meta_floor_log2 {};
594 template<
unsigned int n,
int lower,
int upper>
595 struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_down>
597 enum { value = meta_floor_log2<n, lower, meta_floor_log2_selector<n, lower, upper>::middle>::value };
600 template<
unsigned int n,
int lower,
int upper>
601 struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_up>
603 enum { value = meta_floor_log2<n, meta_floor_log2_selector<n, lower, upper>::middle, upper>::value };
606 template<
unsigned int n,
int lower,
int upper>
607 struct meta_floor_log2<n, lower, upper, meta_floor_log2_terminate>
609 enum { value = (n >= ((
unsigned int)(1) << (lower+1))) ? lower+1 : lower };
612 template<
unsigned int n,
int lower,
int upper>
613 struct meta_floor_log2<n, lower, upper, meta_floor_log2_bogus>
618 template<
typename Scalar>
619 struct random_default_impl<Scalar, false, true>
621 static inline Scalar run(
const Scalar& x,
const Scalar& y)
626 typedef typename make_unsigned<Scalar>::type ScalarU;
630 typedef typename conditional<(ScalarU(-1) > unsigned(-1)), ScalarU,
unsigned>::type ScalarX;
634 ScalarX range = ScalarX(y) - ScalarX(x);
637 ScalarX multiplier = 1;
638 const unsigned rand_max = RAND_MAX;
639 if (range <= rand_max) divisor = (rand_max + 1) / (range + 1);
640 else multiplier = 1 + range / (rand_max + 1);
643 offset = (unsigned(std::rand()) * multiplier) / divisor;
644 }
while (offset > range);
645 return Scalar(ScalarX(x) + offset);
648 static inline Scalar run()
650 #ifdef EIGEN_MAKING_DOCS
651 return run(Scalar(NumTraits<Scalar>::IsSigned ? -10 : 0), Scalar(10));
653 enum { rand_bits = meta_floor_log2<(
unsigned int)(RAND_MAX)+1>::value,
654 scalar_bits =
sizeof(Scalar) * CHAR_BIT,
655 shift = EIGEN_PLAIN_ENUM_MAX(0,
int(rand_bits) - int(scalar_bits)),
656 offset = NumTraits<Scalar>::IsSigned ? (1 << (EIGEN_PLAIN_ENUM_MIN(rand_bits,scalar_bits)-1)) : 0
658 return Scalar((std::rand() >> shift) - offset);
663 template<
typename Scalar>
664 struct random_default_impl<Scalar, true, false>
666 static inline Scalar run(
const Scalar& x,
const Scalar& y)
668 return Scalar(random(x.real(), y.real()),
669 random(x.imag(), y.imag()));
671 static inline Scalar run()
673 typedef typename NumTraits<Scalar>::Real RealScalar;
674 return Scalar(random<RealScalar>(), random<RealScalar>());
678 template<
typename Scalar>
679 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(
const Scalar& x,
const Scalar& y)
681 return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y);
684 template<
typename Scalar>
685 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
687 return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
693 #if (EIGEN_HAS_CXX11_MATH && !(EIGEN_COMP_GNUC_STRICT && __FINITE_MATH_ONLY__)) || (EIGEN_COMP_MSVC>=1800) || (EIGEN_COMP_CLANG)
694 #define EIGEN_USE_STD_FPCLASSIFY 1
696 #define EIGEN_USE_STD_FPCLASSIFY 0
701 typename internal::enable_if<internal::is_integral<T>::value,
bool>::type
702 isnan_impl(
const T&) {
return false; }
706 typename internal::enable_if<internal::is_integral<T>::value,
bool>::type
707 isinf_impl(
const T&) {
return false; }
711 typename internal::enable_if<internal::is_integral<T>::value,
bool>::type
712 isfinite_impl(
const T&) {
return true; }
716 typename internal::enable_if<(!internal::is_integral<T>::value)&&(!NumTraits<T>::IsComplex),
bool>::type
717 isfinite_impl(
const T& x)
721 #elif EIGEN_USE_STD_FPCLASSIFY
723 return isfinite EIGEN_NOT_A_MACRO (x);
725 return x<=NumTraits<T>::highest() && x>=NumTraits<T>::lowest();
731 typename internal::enable_if<(!internal::is_integral<T>::value)&&(!NumTraits<T>::IsComplex),
bool>::type
732 isinf_impl(
const T& x)
736 #elif EIGEN_USE_STD_FPCLASSIFY
738 return isinf EIGEN_NOT_A_MACRO (x);
740 return x>NumTraits<T>::highest() || x<NumTraits<T>::lowest();
746 typename internal::enable_if<(!internal::is_integral<T>::value)&&(!NumTraits<T>::IsComplex),
bool>::type
747 isnan_impl(
const T& x)
751 #elif EIGEN_USE_STD_FPCLASSIFY
753 return isnan EIGEN_NOT_A_MACRO (x);
759 #if (!EIGEN_USE_STD_FPCLASSIFY)
763 template<
typename T> EIGEN_DEVICE_FUNC
bool isinf_msvc_helper(T x)
765 return _fpclass(x)==_FPCLASS_NINF || _fpclass(x)==_FPCLASS_PINF;
769 EIGEN_DEVICE_FUNC
inline bool isnan_impl(
const long double& x) {
return _isnan(x)!=0; }
770 EIGEN_DEVICE_FUNC
inline bool isnan_impl(
const double& x) {
return _isnan(x)!=0; }
771 EIGEN_DEVICE_FUNC
inline bool isnan_impl(
const float& x) {
return _isnan(x)!=0; }
773 EIGEN_DEVICE_FUNC
inline bool isinf_impl(
const long double& x) {
return isinf_msvc_helper(x); }
774 EIGEN_DEVICE_FUNC
inline bool isinf_impl(
const double& x) {
return isinf_msvc_helper(x); }
775 EIGEN_DEVICE_FUNC
inline bool isinf_impl(
const float& x) {
return isinf_msvc_helper(x); }
777 #elif (defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ && EIGEN_COMP_GNUC)
779 #if EIGEN_GNUC_AT_LEAST(5,0)
780 #define EIGEN_TMP_NOOPT_ATTRIB EIGEN_DEVICE_FUNC inline __attribute__((optimize("no-finite-math-only")))
784 #define EIGEN_TMP_NOOPT_ATTRIB EIGEN_DEVICE_FUNC inline __attribute__((noinline,optimize("no-finite-math-only")))
787 template<> EIGEN_TMP_NOOPT_ATTRIB
bool isnan_impl(
const long double& x) {
return __builtin_isnan(x); }
788 template<> EIGEN_TMP_NOOPT_ATTRIB
bool isnan_impl(
const double& x) {
return __builtin_isnan(x); }
789 template<> EIGEN_TMP_NOOPT_ATTRIB
bool isnan_impl(
const float& x) {
return __builtin_isnan(x); }
790 template<> EIGEN_TMP_NOOPT_ATTRIB
bool isinf_impl(
const double& x) {
return __builtin_isinf(x); }
791 template<> EIGEN_TMP_NOOPT_ATTRIB
bool isinf_impl(
const float& x) {
return __builtin_isinf(x); }
792 template<> EIGEN_TMP_NOOPT_ATTRIB
bool isinf_impl(
const long double& x) {
return __builtin_isinf(x); }
794 #undef EIGEN_TMP_NOOPT_ATTRIB
801 template<
typename T> EIGEN_DEVICE_FUNC
bool isfinite_impl(
const std::complex<T>& x);
802 template<
typename T> EIGEN_DEVICE_FUNC
bool isnan_impl(
const std::complex<T>& x);
803 template<
typename T> EIGEN_DEVICE_FUNC
bool isinf_impl(
const std::complex<T>& x);
805 template<
typename T> T generic_fast_tanh_float(
const T& a_x);
815 #ifndef __CUDA_ARCH__
818 EIGEN_ALWAYS_INLINE T mini(
const T& x,
const T& y)
820 EIGEN_USING_STD_MATH(min);
821 return min EIGEN_NOT_A_MACRO (x,y);
826 EIGEN_ALWAYS_INLINE T maxi(
const T& x,
const T& y)
828 EIGEN_USING_STD_MATH(max);
829 return max EIGEN_NOT_A_MACRO (x,y);
834 EIGEN_ALWAYS_INLINE T mini(
const T& x,
const T& y)
836 return y < x ? y : x;
840 EIGEN_ALWAYS_INLINE
float mini(
const float& x,
const float& y)
846 EIGEN_ALWAYS_INLINE T maxi(
const T& x,
const T& y)
848 return x < y ? y : x;
852 EIGEN_ALWAYS_INLINE
float maxi(
const float& x,
const float& y)
859 template<
typename Scalar>
861 inline EIGEN_MATHFUNC_RETVAL(
real, Scalar)
real(
const Scalar& x)
863 return EIGEN_MATHFUNC_IMPL(
real, Scalar)::run(x);
866 template<
typename Scalar>
868 inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(
const Scalar& x)
870 return internal::real_ref_impl<Scalar>::run(x);
873 template<
typename Scalar>
875 inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
877 return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
880 template<
typename Scalar>
882 inline EIGEN_MATHFUNC_RETVAL(
imag, Scalar)
imag(
const Scalar& x)
884 return EIGEN_MATHFUNC_IMPL(
imag, Scalar)::run(x);
887 template<
typename Scalar>
889 inline EIGEN_MATHFUNC_RETVAL(
arg, Scalar)
arg(
const Scalar& x)
891 return EIGEN_MATHFUNC_IMPL(
arg, Scalar)::run(x);
894 template<
typename Scalar>
896 inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(
const Scalar& x)
898 return internal::imag_ref_impl<Scalar>::run(x);
901 template<
typename Scalar>
903 inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
905 return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
908 template<
typename Scalar>
910 inline EIGEN_MATHFUNC_RETVAL(
conj, Scalar)
conj(
const Scalar& x)
912 return EIGEN_MATHFUNC_IMPL(
conj, Scalar)::run(x);
915 template<
typename Scalar>
917 inline EIGEN_MATHFUNC_RETVAL(
abs2, Scalar)
abs2(
const Scalar& x)
919 return EIGEN_MATHFUNC_IMPL(
abs2, Scalar)::run(x);
923 inline bool abs2(
bool x) {
return x; }
925 template<
typename Scalar>
927 inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(
const Scalar& x)
929 return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
932 template<
typename Scalar>
934 inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(
const Scalar& x,
const Scalar& y)
936 return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
939 template<
typename Scalar>
941 inline EIGEN_MATHFUNC_RETVAL(
log1p, Scalar)
log1p(
const Scalar& x)
943 return EIGEN_MATHFUNC_IMPL(
log1p, Scalar)::run(x);
947 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
948 float log1p(
const float &x) { return ::log1pf(x); }
950 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
951 double log1p(
const double &x) { return ::log1p(x); }
954 template<
typename ScalarX,
typename ScalarY>
956 inline typename internal::pow_impl<ScalarX,ScalarY>::result_type pow(
const ScalarX& x,
const ScalarY& y)
958 return internal::pow_impl<ScalarX,ScalarY>::run(x, y);
961 template<
typename T> EIGEN_DEVICE_FUNC bool (
isnan) (
const T &x) {
return internal::isnan_impl(x); }
962 template<
typename T> EIGEN_DEVICE_FUNC bool (
isinf) (
const T &x) {
return internal::isinf_impl(x); }
963 template<
typename T> EIGEN_DEVICE_FUNC bool (
isfinite)(
const T &x) {
return internal::isfinite_impl(x); }
965 template<
typename Scalar>
967 inline EIGEN_MATHFUNC_RETVAL(
round, Scalar)
round(
const Scalar& x)
969 return EIGEN_MATHFUNC_IMPL(
round, Scalar)::run(x);
974 T (
floor)(
const T& x)
976 EIGEN_USING_STD_MATH(
floor);
981 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
982 float floor(
const float &x) { return ::floorf(x); }
984 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
985 double floor(
const double &x) { return ::floor(x); }
992 EIGEN_USING_STD_MATH(
ceil);
997 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
998 float ceil(
const float &x) { return ::ceilf(x); }
1000 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1001 double ceil(
const double &x) { return ::ceil(x); }
1007 inline int log2(
int x)
1011 static const int table[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
1017 return table[(v * 0x07C4ACDDU) >> 27];
1029 template<
typename T>
1030 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1033 EIGEN_USING_STD_MATH(
sqrt);
1037 template<
typename T>
1038 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1040 EIGEN_USING_STD_MATH(
log);
1045 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1046 float log(
const float &x) { return ::logf(x); }
1048 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1049 double log(
const double &x) { return ::log(x); }
1052 template<
typename T>
1053 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1054 typename internal::enable_if<NumTraits<T>::IsSigned || NumTraits<T>::IsComplex,
typename NumTraits<T>::Real>::type
1056 EIGEN_USING_STD_MATH(
abs);
1060 template<
typename T>
1061 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1062 typename internal::enable_if<!(NumTraits<T>::IsSigned || NumTraits<T>::IsComplex),
typename NumTraits<T>::Real>::type
1067 #if defined(__SYCL_DEVICE_ONLY__)
1068 EIGEN_ALWAYS_INLINE
float abs(
float x) {
return cl::sycl::fabs(x); }
1069 EIGEN_ALWAYS_INLINE
double abs(
double x) {
return cl::sycl::fabs(x); }
1070 #endif // defined(__SYCL_DEVICE_ONLY__)
1073 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1074 float abs(
const float &x) { return ::fabsf(x); }
1076 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1077 double abs(
const double &x) { return ::fabs(x); }
1079 template <> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1080 float abs(
const std::complex<float>& x) {
1081 return ::hypotf(x.real(), x.imag());
1084 template <> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1085 double abs(
const std::complex<double>& x) {
1086 return ::hypot(x.real(), x.imag());
1090 template<
typename T>
1091 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1093 EIGEN_USING_STD_MATH(
exp);
1098 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1099 float exp(
const float &x) { return ::expf(x); }
1101 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1102 double exp(
const double &x) { return ::exp(x); }
1105 template<
typename T>
1106 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1108 EIGEN_USING_STD_MATH(
cos);
1113 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1114 float cos(
const float &x) { return ::cosf(x); }
1116 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1117 double cos(
const double &x) { return ::cos(x); }
1120 template<
typename T>
1121 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1123 EIGEN_USING_STD_MATH(
sin);
1128 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1129 float sin(
const float &x) { return ::sinf(x); }
1131 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1132 double sin(
const double &x) { return ::sin(x); }
1135 template<
typename T>
1136 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1138 EIGEN_USING_STD_MATH(
tan);
1143 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1144 float tan(
const float &x) { return ::tanf(x); }
1146 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1147 double tan(
const double &x) { return ::tan(x); }
1150 template<
typename T>
1151 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1152 T
acos(
const T &x) {
1153 EIGEN_USING_STD_MATH(
acos);
1158 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1159 float acos(
const float &x) { return ::acosf(x); }
1161 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1162 double acos(
const double &x) { return ::acos(x); }
1165 template<
typename T>
1166 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1167 T
asin(
const T &x) {
1168 EIGEN_USING_STD_MATH(
asin);
1173 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1174 float asin(
const float &x) { return ::asinf(x); }
1176 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1177 double asin(
const double &x) { return ::asin(x); }
1180 template<
typename T>
1181 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1182 T
atan(
const T &x) {
1183 EIGEN_USING_STD_MATH(
atan);
1188 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1189 float atan(
const float &x) { return ::atanf(x); }
1191 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1192 double atan(
const double &x) { return ::atan(x); }
1196 template<
typename T>
1197 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1198 T
cosh(
const T &x) {
1199 EIGEN_USING_STD_MATH(
cosh);
1204 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1205 float cosh(
const float &x) { return ::coshf(x); }
1207 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1208 double cosh(
const double &x) { return ::cosh(x); }
1211 template<
typename T>
1212 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1213 T
sinh(
const T &x) {
1214 EIGEN_USING_STD_MATH(
sinh);
1219 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1220 float sinh(
const float &x) { return ::sinhf(x); }
1222 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1223 double sinh(
const double &x) { return ::sinh(x); }
1226 template<
typename T>
1227 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1228 T
tanh(
const T &x) {
1229 EIGEN_USING_STD_MATH(
tanh);
1233 #if (!defined(__CUDACC__)) && EIGEN_FAST_MATH
1234 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1235 float tanh(
float x) {
return internal::generic_fast_tanh_float(x); }
1239 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1240 float tanh(
const float &x) { return ::tanhf(x); }
1242 template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1243 double tanh(
const double &x) { return ::tanh(x); }
1246 template <
typename T>
1247 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1248 T fmod(
const T& a,
const T& b) {
1249 EIGEN_USING_STD_MATH(fmod);
1255 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1256 float fmod(
const float& a,
const float& b) {
1257 return ::fmodf(a, b);
1261 EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
1262 double fmod(
const double& a,
const double& b) {
1263 return ::fmod(a, b);
1269 namespace internal {
1271 template<
typename T>
1272 EIGEN_DEVICE_FUNC
bool isfinite_impl(
const std::complex<T>& x)
1274 return (numext::isfinite)(numext::real(x)) && (numext::isfinite)(numext::imag(x));
1277 template<
typename T>
1278 EIGEN_DEVICE_FUNC
bool isnan_impl(
const std::complex<T>& x)
1280 return (numext::isnan)(numext::real(x)) || (numext::isnan)(numext::imag(x));
1283 template<
typename T>
1284 EIGEN_DEVICE_FUNC
bool isinf_impl(
const std::complex<T>& x)
1286 return ((numext::isinf)(numext::real(x)) || (numext::isinf)(numext::imag(x))) && (!(numext::isnan)(x));
1293 template<
typename Scalar,
1296 struct scalar_fuzzy_default_impl {};
1298 template<
typename Scalar>
1299 struct scalar_fuzzy_default_impl<Scalar, false, false>
1301 typedef typename NumTraits<Scalar>::Real RealScalar;
1302 template<
typename OtherScalar> EIGEN_DEVICE_FUNC
1303 static inline bool isMuchSmallerThan(
const Scalar& x,
const OtherScalar& y,
const RealScalar& prec)
1305 return numext::abs(x) <= numext::abs(y) * prec;
1308 static inline bool isApprox(
const Scalar& x,
const Scalar& y,
const RealScalar& prec)
1310 return numext::abs(x - y) <= numext::mini(numext::abs(x), numext::abs(y)) * prec;
1313 static inline bool isApproxOrLessThan(
const Scalar& x,
const Scalar& y,
const RealScalar& prec)
1315 return x <= y || isApprox(x, y, prec);
1319 template<
typename Scalar>
1320 struct scalar_fuzzy_default_impl<Scalar, false, true>
1322 typedef typename NumTraits<Scalar>::Real RealScalar;
1323 template<
typename OtherScalar> EIGEN_DEVICE_FUNC
1324 static inline bool isMuchSmallerThan(
const Scalar& x,
const Scalar&,
const RealScalar&)
1326 return x == Scalar(0);
1329 static inline bool isApprox(
const Scalar& x,
const Scalar& y,
const RealScalar&)
1334 static inline bool isApproxOrLessThan(
const Scalar& x,
const Scalar& y,
const RealScalar&)
1340 template<
typename Scalar>
1341 struct scalar_fuzzy_default_impl<Scalar, true, false>
1343 typedef typename NumTraits<Scalar>::Real RealScalar;
1344 template<
typename OtherScalar> EIGEN_DEVICE_FUNC
1345 static inline bool isMuchSmallerThan(
const Scalar& x,
const OtherScalar& y,
const RealScalar& prec)
1347 return numext::abs2(x) <= numext::abs2(y) * prec * prec;
1350 static inline bool isApprox(
const Scalar& x,
const Scalar& y,
const RealScalar& prec)
1352 return numext::abs2(x - y) <= numext::mini(numext::abs2(x), numext::abs2(y)) * prec * prec;
1356 template<
typename Scalar>
1357 struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
1359 template<
typename Scalar,
typename OtherScalar> EIGEN_DEVICE_FUNC
1360 inline bool isMuchSmallerThan(
const Scalar& x,
const OtherScalar& y,
1361 const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
1363 return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision);
1366 template<
typename Scalar> EIGEN_DEVICE_FUNC
1367 inline bool isApprox(
const Scalar& x,
const Scalar& y,
1368 const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
1370 return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
1373 template<
typename Scalar> EIGEN_DEVICE_FUNC
1374 inline bool isApproxOrLessThan(
const Scalar& x,
const Scalar& y,
1375 const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
1377 return scalar_fuzzy_impl<Scalar>::isApproxOrLessThan(x, y, precision);
1384 template<>
struct random_impl<bool>
1386 static inline bool run()
1388 return random<int>(0,1)==0 ? false :
true;
1392 template<>
struct scalar_fuzzy_impl<bool>
1394 typedef bool RealScalar;
1396 template<
typename OtherScalar> EIGEN_DEVICE_FUNC
1397 static inline bool isMuchSmallerThan(
const bool& x,
const bool&,
const bool&)
1403 static inline bool isApprox(
bool x,
bool y,
bool)
1409 static inline bool isApproxOrLessThan(
const bool& x,
const bool& y,
const bool&)
1421 #endif // EIGEN_MATHFUNCTIONS_H