10 #ifndef EIGEN_MATHFUNCTIONS_H
11 #define EIGEN_MATHFUNCTIONS_H
14 #define EIGEN_PI 3.141592653589793238462643383279502884197169399375105820974944592307816406
20 #if EIGEN_OS_WINCE && EIGEN_COMP_MSVC && EIGEN_COMP_MSVC<=1500
21 long abs(
long x) {
return (labs(x)); }
22 double abs(
double x) {
return (fabs(x)); }
23 float abs(
float x) {
return (fabsf(x)); }
24 long double abs(
long double x) {
return (fabsl(x)); }
49 template<
typename T,
typename dummy =
void>
50 struct global_math_functions_filtering_base
55 template<
typename T>
struct always_void {
typedef void type; };
58 struct global_math_functions_filtering_base
60 typename always_void<typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl>::type
63 typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type;
66 #define EIGEN_MATHFUNC_IMPL(func, scalar) Eigen::internal::func##_impl<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>
67 #define EIGEN_MATHFUNC_RETVAL(func, scalar) typename Eigen::internal::func##_retval<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>::type
73 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
74 struct real_default_impl
76 typedef typename NumTraits<Scalar>::Real RealScalar;
78 static inline RealScalar run(
const Scalar& x)
84 template<
typename Scalar>
85 struct real_default_impl<Scalar,true>
87 typedef typename NumTraits<Scalar>::Real RealScalar;
89 static inline RealScalar run(
const Scalar& x)
96 template<
typename Scalar>
struct real_impl : real_default_impl<Scalar> {};
98 template<
typename Scalar>
101 typedef typename NumTraits<Scalar>::Real type;
108 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
109 struct imag_default_impl
111 typedef typename NumTraits<Scalar>::Real RealScalar;
113 static inline RealScalar run(
const Scalar&)
115 return RealScalar(0);
119 template<
typename Scalar>
120 struct imag_default_impl<Scalar,true>
122 typedef typename NumTraits<Scalar>::Real RealScalar;
124 static inline RealScalar run(
const Scalar& x)
131 template<
typename Scalar>
struct imag_impl : imag_default_impl<Scalar> {};
133 template<
typename Scalar>
136 typedef typename NumTraits<Scalar>::Real type;
143 template<
typename Scalar>
146 typedef typename NumTraits<Scalar>::Real RealScalar;
148 static inline RealScalar& run(Scalar& x)
150 return reinterpret_cast<RealScalar*
>(&x)[0];
153 static inline const RealScalar& run(
const Scalar& x)
155 return reinterpret_cast<const RealScalar*
>(&x)[0];
159 template<
typename Scalar>
160 struct real_ref_retval
162 typedef typename NumTraits<Scalar>::Real & type;
169 template<
typename Scalar,
bool IsComplex>
170 struct imag_ref_default_impl
172 typedef typename NumTraits<Scalar>::Real RealScalar;
174 static inline RealScalar& run(Scalar& x)
176 return reinterpret_cast<RealScalar*
>(&x)[1];
179 static inline const RealScalar& run(
const Scalar& x)
181 return reinterpret_cast<RealScalar*
>(&x)[1];
185 template<
typename Scalar>
186 struct imag_ref_default_impl<Scalar, false>
189 static inline Scalar run(Scalar&)
194 static inline const Scalar run(
const Scalar&)
200 template<
typename Scalar>
201 struct imag_ref_impl : imag_ref_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
203 template<
typename Scalar>
204 struct imag_ref_retval
206 typedef typename NumTraits<Scalar>::Real & type;
213 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
217 static inline Scalar run(
const Scalar& x)
223 template<
typename Scalar>
224 struct conj_impl<Scalar,true>
227 static inline Scalar run(
const Scalar& x)
234 template<
typename Scalar>
244 template<
typename Scalar>
247 typedef typename NumTraits<Scalar>::Real RealScalar;
249 static inline RealScalar run(
const Scalar& x)
255 template<
typename RealScalar>
256 struct abs2_impl<
std::complex<RealScalar> >
259 static inline RealScalar run(
const std::complex<RealScalar>& x)
261 return real(x)*real(x) + imag(x)*imag(x);
265 template<
typename Scalar>
268 typedef typename NumTraits<Scalar>::Real type;
275 template<
typename Scalar,
bool IsComplex>
276 struct norm1_default_impl
278 typedef typename NumTraits<Scalar>::Real RealScalar;
280 static inline RealScalar run(
const Scalar& x)
282 EIGEN_USING_STD_MATH(abs);
283 return abs(real(x)) + abs(imag(x));
287 template<
typename Scalar>
288 struct norm1_default_impl<Scalar, false>
291 static inline Scalar run(
const Scalar& x)
293 EIGEN_USING_STD_MATH(abs);
298 template<
typename Scalar>
299 struct norm1_impl : norm1_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
301 template<
typename Scalar>
304 typedef typename NumTraits<Scalar>::Real type;
311 template<
typename Scalar>
314 typedef typename NumTraits<Scalar>::Real RealScalar;
315 static inline RealScalar run(
const Scalar& x,
const Scalar& y)
317 EIGEN_USING_STD_MATH(max);
318 EIGEN_USING_STD_MATH(min);
319 EIGEN_USING_STD_MATH(abs);
320 EIGEN_USING_STD_MATH(sqrt);
321 RealScalar _x = abs(x);
322 RealScalar _y = abs(y);
334 if(p==RealScalar(0))
return RealScalar(0);
335 return p * sqrt(RealScalar(1) + qp*qp);
339 template<
typename Scalar>
342 typedef typename NumTraits<Scalar>::Real type;
349 template<
typename OldType,
typename NewType>
353 static inline NewType run(
const OldType& x)
355 return static_cast<NewType
>(x);
361 template<
typename OldType,
typename NewType>
363 inline NewType cast(
const OldType& x)
365 return cast_impl<OldType, NewType>::run(x);
372 #if EIGEN_HAS_CXX11_MATH
373 template<
typename Scalar>
375 static inline Scalar run(
const Scalar& x)
377 EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
383 template<
typename Scalar>
386 static inline Scalar run(
const Scalar& x)
388 EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
389 EIGEN_USING_STD_MATH(floor);
390 EIGEN_USING_STD_MATH(ceil);
391 return (x > Scalar(0)) ? floor(x + Scalar(0.5)) : ceil(x - Scalar(0.5));
396 template<
typename Scalar>
406 #if EIGEN_HAS_CXX11_MATH
407 template<
typename Scalar>
409 static inline Scalar run(
const Scalar& x)
411 EIGEN_USING_STD_MATH(arg);
416 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
417 struct arg_default_impl
419 typedef typename NumTraits<Scalar>::Real RealScalar;
421 static inline RealScalar run(
const Scalar& x)
423 return (x < Scalar(0)) ? Scalar(EIGEN_PI) : Scalar(0); }
426 template<
typename Scalar>
427 struct arg_default_impl<Scalar,true>
429 typedef typename NumTraits<Scalar>::Real RealScalar;
431 static inline RealScalar run(
const Scalar& x)
433 EIGEN_USING_STD_MATH(arg);
438 template<
typename Scalar>
struct arg_impl : arg_default_impl<Scalar> {};
441 template<
typename Scalar>
444 typedef typename NumTraits<Scalar>::Real type;
450 template<typename Scalar, bool isComplex = NumTraits<Scalar>::IsComplex >
453 static inline Scalar run(
const Scalar& x)
455 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
456 typedef typename NumTraits<Scalar>::Real RealScalar;
457 EIGEN_USING_STD_MATH(log);
458 Scalar x1p = RealScalar(1) + x;
459 return ( x1p == Scalar(1) ) ? x : x * ( log(x1p) / (x1p - RealScalar(1)) );
463 #if EIGEN_HAS_CXX11_MATH
464 template<
typename Scalar>
465 struct log1p_impl<Scalar, false> {
466 static inline Scalar run(
const Scalar& x)
468 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
475 template<
typename Scalar>
485 template<
typename Scalar,
bool IsInteger>
486 struct pow_default_impl
488 typedef Scalar retval;
489 static inline Scalar run(
const Scalar& x,
const Scalar& y)
491 EIGEN_USING_STD_MATH(pow);
496 template<
typename Scalar>
497 struct pow_default_impl<Scalar, true>
499 static inline Scalar run(Scalar x, Scalar y)
502 eigen_assert(!NumTraits<Scalar>::IsSigned || y >= 0);
515 template<
typename Scalar>
516 struct pow_impl : pow_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
518 template<
typename Scalar>
528 template<
typename Scalar,
531 struct random_default_impl {};
533 template<
typename Scalar>
534 struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
536 template<
typename Scalar>
542 template<
typename Scalar>
inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y);
543 template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random();
545 template<typename Scalar>
546 struct random_default_impl<Scalar, false, false>
548 static inline Scalar run(
const Scalar& x,
const Scalar& y)
550 return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX);
552 static inline Scalar run()
554 return run(Scalar(NumTraits<Scalar>::IsSigned ? -1 : 0), Scalar(1));
559 meta_floor_log2_terminate,
560 meta_floor_log2_move_up,
561 meta_floor_log2_move_down,
562 meta_floor_log2_bogus
565 template<
unsigned int n,
int lower,
int upper>
struct meta_floor_log2_selector
567 enum { middle = (lower + upper) / 2,
568 value = (upper <= lower + 1) ? int(meta_floor_log2_terminate)
569 : (n < (1 << middle)) ? int(meta_floor_log2_move_down)
570 : (n==0) ? int(meta_floor_log2_bogus)
571 : int(meta_floor_log2_move_up)
575 template<
unsigned int n,
577 int upper =
sizeof(
unsigned int) * CHAR_BIT - 1,
578 int selector = meta_floor_log2_selector<n, lower, upper>::value>
579 struct meta_floor_log2 {};
581 template<
unsigned int n,
int lower,
int upper>
582 struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_down>
584 enum { value = meta_floor_log2<n, lower, meta_floor_log2_selector<n, lower, upper>::middle>::value };
587 template<
unsigned int n,
int lower,
int upper>
588 struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_up>
590 enum { value = meta_floor_log2<n, meta_floor_log2_selector<n, lower, upper>::middle, upper>::value };
593 template<
unsigned int n,
int lower,
int upper>
594 struct meta_floor_log2<n, lower, upper, meta_floor_log2_terminate>
596 enum { value = (n >= ((
unsigned int)(1) << (lower+1))) ? lower+1 : lower };
599 template<
unsigned int n,
int lower,
int upper>
600 struct meta_floor_log2<n, lower, upper, meta_floor_log2_bogus>
605 template<
typename Scalar>
606 struct random_default_impl<Scalar, false, true>
608 static inline Scalar run(
const Scalar& x,
const Scalar& y)
612 typedef typename conditional<NumTraits<Scalar>::IsSigned,std::ptrdiff_t,std::size_t>::type ScalarX;
615 std::size_t range = ScalarX(y)-ScalarX(x);
616 std::size_t offset = 0;
618 std::size_t divisor = (range+RAND_MAX-1)/(range+1);
619 std::size_t multiplier = (range+RAND_MAX-1)/std::size_t(RAND_MAX);
622 offset = ( (std::size_t(std::rand()) * multiplier) / divisor );
623 }
while (offset > range);
625 return Scalar(ScalarX(x) + offset);
628 static inline Scalar run()
630 #ifdef EIGEN_MAKING_DOCS
631 return run(Scalar(NumTraits<Scalar>::IsSigned ? -10 : 0), Scalar(10));
633 enum { rand_bits = meta_floor_log2<(unsigned int)(RAND_MAX)+1>::value,
634 scalar_bits =
sizeof(Scalar) * CHAR_BIT,
635 shift = EIGEN_PLAIN_ENUM_MAX(0,
int(rand_bits) - int(scalar_bits)),
636 offset = NumTraits<Scalar>::IsSigned ? (1 << (EIGEN_PLAIN_ENUM_MIN(rand_bits,scalar_bits)-1)) : 0
638 return Scalar((std::rand() >> shift) - offset);
643 template<
typename Scalar>
644 struct random_default_impl<Scalar, true, false>
646 static inline Scalar run(
const Scalar& x,
const Scalar& y)
648 return Scalar(random(real(x), real(y)),
649 random(imag(x), imag(y)));
651 static inline Scalar run()
653 typedef typename NumTraits<Scalar>::Real RealScalar;
654 return Scalar(random<RealScalar>(), random<RealScalar>());
658 template<
typename Scalar>
659 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y)
661 return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y);
664 template<
typename Scalar>
665 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
667 return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
678 #ifndef __CUDA_ARCH__
681 EIGEN_ALWAYS_INLINE T mini(
const T& x,
const T& y)
683 EIGEN_USING_STD_MATH(min);
684 return min EIGEN_NOT_A_MACRO (x,y);
689 EIGEN_ALWAYS_INLINE T maxi(
const T& x,
const T& y)
691 EIGEN_USING_STD_MATH(max);
692 return max EIGEN_NOT_A_MACRO (x,y);
697 EIGEN_ALWAYS_INLINE T mini(
const T& x,
const T& y)
699 return y < x ? y : x;
703 EIGEN_ALWAYS_INLINE
float mini(
const float& x,
const float& y)
709 EIGEN_ALWAYS_INLINE T maxi(
const T& x,
const T& y)
711 return x < y ? y : x;
715 EIGEN_ALWAYS_INLINE
float maxi(
const float& x,
const float& y)
722 template<
typename Scalar>
724 inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
726 return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
729 template<
typename Scalar>
731 inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(
const Scalar& x)
733 return internal::real_ref_impl<Scalar>::run(x);
736 template<
typename Scalar>
738 inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
740 return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
743 template<
typename Scalar>
745 inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
747 return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
750 template<
typename Scalar>
752 inline EIGEN_MATHFUNC_RETVAL(arg, Scalar) arg(const Scalar& x)
754 return EIGEN_MATHFUNC_IMPL(arg, Scalar)::run(x);
757 template<
typename Scalar>
759 inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(
const Scalar& x)
761 return internal::imag_ref_impl<Scalar>::run(x);
764 template<
typename Scalar>
766 inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
768 return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
771 template<
typename Scalar>
773 inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
775 return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
778 template<
typename Scalar>
780 inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
782 return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
785 template<
typename Scalar>
787 inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
789 return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
792 template<
typename Scalar>
794 inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y)
796 return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
799 template<
typename Scalar>
801 inline EIGEN_MATHFUNC_RETVAL(log1p, Scalar) log1p(const Scalar& x)
803 return EIGEN_MATHFUNC_IMPL(log1p, Scalar)::run(x);
806 template<
typename Scalar>
808 inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y)
810 return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y);
815 bool (isfinite)(
const T& x)
817 #if EIGEN_HAS_CXX11_MATH
819 return isfinite EIGEN_NOT_A_MACRO (x);
821 return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest();
827 bool (isnan)(
const T& x)
829 #if EIGEN_HAS_CXX11_MATH
831 return isnan EIGEN_NOT_A_MACRO (x);
839 bool (isinf)(
const T& x)
841 #if EIGEN_HAS_CXX11_MATH
843 return isinf EIGEN_NOT_A_MACRO (x);
845 return x>NumTraits<T>::highest() || x<NumTraits<T>::lowest();
850 bool (isfinite)(
const std::complex<T>& x)
852 return (numext::isfinite)(numext::real(x)) && (numext::isfinite)(numext::imag(x));
856 bool (isnan)(
const std::complex<T>& x)
858 return (numext::isnan)(numext::real(x)) || (numext::isnan)(numext::imag(x));
862 bool (isinf)(
const std::complex<T>& x)
864 return ((numext::isinf)(numext::real(x)) || (numext::isinf)(numext::imag(x))) && (!(numext::isnan)(x));
867 template<
typename Scalar>
869 inline EIGEN_MATHFUNC_RETVAL(round, Scalar) round(const Scalar& x)
871 return EIGEN_MATHFUNC_IMPL(round, Scalar)::run(x);
876 T (floor)(
const T& x)
878 EIGEN_USING_STD_MATH(floor);
886 EIGEN_USING_STD_MATH(ceil);
892 inline int log2(
int x)
896 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 };
902 return table[(v * 0x07C4ACDDU) >> 27];
913 template<
typename Scalar,
916 struct scalar_fuzzy_default_impl {};
918 template<
typename Scalar>
919 struct scalar_fuzzy_default_impl<Scalar, false, false>
921 typedef typename NumTraits<Scalar>::Real RealScalar;
922 template<
typename OtherScalar> EIGEN_DEVICE_FUNC
923 static inline bool isMuchSmallerThan(
const Scalar& x,
const OtherScalar& y,
const RealScalar& prec)
925 EIGEN_USING_STD_MATH(abs);
926 return abs(x) <= abs(y) * prec;
929 static inline bool isApprox(
const Scalar& x,
const Scalar& y,
const RealScalar& prec)
931 EIGEN_USING_STD_MATH(min);
932 EIGEN_USING_STD_MATH(abs);
933 return abs(x - y) <= (min)(abs(x), abs(y)) * prec;
936 static inline bool isApproxOrLessThan(
const Scalar& x,
const Scalar& y,
const RealScalar& prec)
938 return x <= y || isApprox(x, y, prec);
942 template<
typename Scalar>
943 struct scalar_fuzzy_default_impl<Scalar, false, true>
945 typedef typename NumTraits<Scalar>::Real RealScalar;
946 template<
typename OtherScalar> EIGEN_DEVICE_FUNC
947 static inline bool isMuchSmallerThan(
const Scalar& x,
const Scalar&,
const RealScalar&)
949 return x == Scalar(0);
952 static inline bool isApprox(
const Scalar& x,
const Scalar& y,
const RealScalar&)
957 static inline bool isApproxOrLessThan(
const Scalar& x,
const Scalar& y,
const RealScalar&)
963 template<
typename Scalar>
964 struct scalar_fuzzy_default_impl<Scalar, true, false>
966 typedef typename NumTraits<Scalar>::Real RealScalar;
967 template<
typename OtherScalar>
968 static inline bool isMuchSmallerThan(
const Scalar& x,
const OtherScalar& y,
const RealScalar& prec)
970 return numext::abs2(x) <= numext::abs2(y) * prec * prec;
972 static inline bool isApprox(
const Scalar& x,
const Scalar& y,
const RealScalar& prec)
974 EIGEN_USING_STD_MATH(min);
975 return numext::abs2(x - y) <= (min)(numext::abs2(x), numext::abs2(y)) * prec * prec;
979 template<
typename Scalar>
980 struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
982 template<
typename Scalar,
typename OtherScalar> EIGEN_DEVICE_FUNC
983 inline bool isMuchSmallerThan(
const Scalar& x,
const OtherScalar& y,
984 typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
986 return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision);
989 template<
typename Scalar> EIGEN_DEVICE_FUNC
990 inline bool isApprox(
const Scalar& x,
const Scalar& y,
991 typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
993 return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
996 template<
typename Scalar> EIGEN_DEVICE_FUNC
997 inline bool isApproxOrLessThan(
const Scalar& x,
const Scalar& y,
998 typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
1000 return scalar_fuzzy_impl<Scalar>::isApproxOrLessThan(x, y, precision);
1007 template<>
struct random_impl<bool>
1009 static inline bool run()
1011 return random<int>(0,1)==0 ?
false :
true;
1015 template<>
struct scalar_fuzzy_impl<bool>
1017 typedef bool RealScalar;
1019 template<
typename OtherScalar> EIGEN_DEVICE_FUNC
1020 static inline bool isMuchSmallerThan(
const bool& x,
const bool&,
const bool&)
1026 static inline bool isApprox(
bool x,
bool y,
bool)
1032 static inline bool isApproxOrLessThan(
const bool& x,
const bool& y,
const bool&)
1044 #endif // EIGEN_MATHFUNCTIONS_H
Definition: StdDeque.h:58
Definition: Eigen_Colamd.h:54