25 #ifndef EIGEN_MATHFUNCTIONS_H
26 #define EIGEN_MATHFUNCTIONS_H
52 template<
typename T,
typename dummy =
void>
53 struct global_math_functions_filtering_base
58 template<
typename T>
struct always_void {
typedef void type; };
61 struct global_math_functions_filtering_base
63 typename always_void<typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl>::type
66 typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type;
69 #define EIGEN_MATHFUNC_IMPL(func, scalar) func##_impl<typename global_math_functions_filtering_base<scalar>::type>
70 #define EIGEN_MATHFUNC_RETVAL(func, scalar) typename func##_retval<typename global_math_functions_filtering_base<scalar>::type>::type
77 template<
typename Scalar>
81 static inline RealScalar run(
const Scalar& x)
87 template<
typename RealScalar>
88 struct real_impl<std::complex<RealScalar> >
90 static inline RealScalar run(
const std::complex<RealScalar>& x)
97 template<
typename Scalar>
103 template<
typename Scalar>
113 template<
typename Scalar>
117 static inline RealScalar run(
const Scalar&)
119 return RealScalar(0);
123 template<
typename RealScalar>
124 struct imag_impl<std::complex<RealScalar> >
126 static inline RealScalar run(
const std::complex<RealScalar>& x)
133 template<
typename Scalar>
139 template<
typename Scalar>
149 template<
typename Scalar>
153 static inline RealScalar& run(Scalar& x)
155 return reinterpret_cast<RealScalar*
>(&x)[0];
157 static inline const RealScalar& run(
const Scalar& x)
159 return reinterpret_cast<const RealScalar*
>(&x)[0];
163 template<
typename Scalar>
164 struct real_ref_retval
169 template<
typename Scalar>
170 inline typename add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type
real_ref(
const Scalar& x)
172 return real_ref_impl<Scalar>::run(x);
175 template<
typename Scalar>
185 template<
typename Scalar,
bool IsComplex>
186 struct imag_ref_default_impl
189 static inline RealScalar& run(Scalar& x)
191 return reinterpret_cast<RealScalar*
>(&x)[1];
193 static inline const RealScalar& run(
const Scalar& x)
195 return reinterpret_cast<RealScalar*
>(&x)[1];
199 template<
typename Scalar>
200 struct imag_ref_default_impl<Scalar, false>
202 static inline Scalar run(Scalar&)
206 static inline const Scalar run(
const Scalar&)
212 template<
typename Scalar>
213 struct imag_ref_impl : imag_ref_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
215 template<
typename Scalar>
216 struct imag_ref_retval
221 template<
typename Scalar>
222 inline typename add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type
imag_ref(
const Scalar& x)
224 return imag_ref_impl<Scalar>::run(x);
227 template<
typename Scalar>
237 template<
typename Scalar>
240 static inline Scalar run(
const Scalar& x)
246 template<
typename RealScalar>
247 struct conj_impl<std::complex<RealScalar> >
249 static inline std::complex<RealScalar> run(
const std::complex<RealScalar>& x)
256 template<
typename Scalar>
262 template<
typename Scalar>
272 template<
typename Scalar>
276 static inline RealScalar run(
const Scalar& x)
283 template<
typename Scalar>
289 template<
typename Scalar>
299 template<
typename Scalar>
303 static inline RealScalar run(
const Scalar& x)
309 template<
typename RealScalar>
310 struct abs2_impl<std::complex<RealScalar> >
312 static inline RealScalar run(
const std::complex<RealScalar>& x)
318 template<
typename Scalar>
324 template<
typename Scalar>
334 template<
typename Scalar,
bool IsComplex>
335 struct norm1_default_impl
338 static inline RealScalar run(
const Scalar& x)
344 template<
typename Scalar>
345 struct norm1_default_impl<Scalar, false>
347 static inline Scalar run(
const Scalar& x)
353 template<
typename Scalar>
354 struct norm1_impl : norm1_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
356 template<
typename Scalar>
362 template<
typename Scalar>
372 template<
typename Scalar>
376 static inline RealScalar run(
const Scalar& x,
const Scalar&
y)
380 RealScalar _x =
abs(x);
381 RealScalar _y =
abs(y);
382 RealScalar
p = (max)(_x, _y);
383 RealScalar
q = (min)(_x, _y);
385 return p *
sqrt(RealScalar(1) + qp*qp);
389 template<
typename Scalar>
395 template<
typename Scalar>
405 template<
typename OldType,
typename NewType>
408 static inline NewType run(
const OldType& x)
410 return static_cast<NewType
>(x);
416 template<
typename OldType,
typename NewType>
417 inline NewType
cast(
const OldType& x)
419 return cast_impl<OldType, NewType>::run(x);
426 template<
typename Scalar,
bool IsInteger>
427 struct sqrt_default_impl
429 static inline Scalar run(
const Scalar& x)
436 template<
typename Scalar>
437 struct sqrt_default_impl<Scalar, true>
439 static inline Scalar run(
const Scalar&)
441 #ifdef EIGEN2_SUPPORT
450 template<
typename Scalar>
451 struct sqrt_impl : sqrt_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
453 template<
typename Scalar>
459 template<
typename Scalar>
470 #define EIGEN_MATHFUNC_STANDARD_REAL_UNARY(NAME) \
471 template<typename Scalar, bool IsInteger> struct NAME##_default_impl { \
472 static inline Scalar run(const Scalar& x) { using std::NAME; return NAME(x); } \
474 template<typename Scalar> struct NAME##_default_impl<Scalar, true> { \
475 static inline Scalar run(const Scalar&) { \
476 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) \
480 template<typename Scalar> struct NAME##_impl \
481 : NAME##_default_impl<Scalar, NumTraits<Scalar>::IsInteger> \
483 template<typename Scalar> struct NAME##_retval { typedef Scalar type; }; \
484 template<typename Scalar> \
485 inline EIGEN_MATHFUNC_RETVAL(NAME, Scalar) NAME(const Scalar& x) { \
486 return EIGEN_MATHFUNC_IMPL(NAME, Scalar)::run(x); \
501 template<typename Scalar,
bool IsInteger>
502 struct atan2_default_impl
505 static inline Scalar run(
const Scalar& x,
const Scalar& y)
512 template<
typename Scalar>
513 struct atan2_default_impl<Scalar, true>
515 static inline Scalar run(
const Scalar&,
const Scalar&)
522 template<typename Scalar>
523 struct atan2_impl : atan2_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
525 template<
typename Scalar>
531 template<
typename Scalar>
541 template<
typename Scalar,
bool IsInteger>
542 struct pow_default_impl
545 static inline Scalar run(
const Scalar& x,
const Scalar& y)
552 template<
typename Scalar>
553 struct pow_default_impl<Scalar, true>
555 static inline Scalar run(Scalar x, Scalar y)
571 template<
typename Scalar>
572 struct pow_impl : pow_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
574 template<
typename Scalar>
580 template<
typename Scalar>
590 template<
typename Scalar,
593 struct random_default_impl {};
595 template<
typename Scalar>
596 struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
598 template<
typename Scalar>
607 template<typename Scalar>
608 struct random_default_impl<Scalar, false, false>
610 static inline Scalar run(
const Scalar& x,
const Scalar& y)
612 return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX);
614 static inline Scalar run()
627 template<
unsigned int n,
int lower,
int upper>
struct floor_log2_selector
629 enum { middle = (lower + upper) / 2,
637 template<
unsigned int n,
639 int upper =
sizeof(
unsigned int) * CHAR_BIT - 1,
640 int selector = floor_log2_selector<n, lower, upper>::value>
641 struct floor_log2 {};
643 template<
unsigned int n,
int lower,
int upper>
644 struct floor_log2<n, lower, upper, floor_log2_move_down>
646 enum { value = floor_log2<n, lower, floor_log2_selector<n, lower, upper>::middle>::value };
649 template<
unsigned int n,
int lower,
int upper>
652 enum { value = floor_log2<n, floor_log2_selector<n, lower, upper>::middle, upper>::value };
655 template<
unsigned int n,
int lower,
int upper>
658 enum { value = (n >= ((
unsigned int)(1) << (lower+1))) ? lower+1 : lower };
661 template<
unsigned int n,
int lower,
int upper>
667 template<
typename Scalar>
668 struct random_default_impl<Scalar, false, true>
670 typedef typename NumTraits<Scalar>::NonInteger NonInteger;
672 static inline Scalar run(
const Scalar& x,
const Scalar& y)
674 return x + Scalar((NonInteger(y)-x+1) * std::rand() / (RAND_MAX + NonInteger(1)));
677 static inline Scalar run()
679 #ifdef EIGEN_MAKING_DOCS
682 enum { rand_bits = floor_log2<(unsigned int)(RAND_MAX)+1>::value,
683 scalar_bits =
sizeof(Scalar) * CHAR_BIT,
686 Scalar x = Scalar(std::rand() >> shift);
693 template<
typename Scalar>
694 struct random_default_impl<Scalar, true, false>
696 static inline Scalar run(
const Scalar& x,
const Scalar& y)
698 return Scalar(random(
real(x),
real(y)),
701 static inline Scalar run()
704 return Scalar(random<RealScalar>(), random<RealScalar>());
708 template<
typename Scalar>
714 template<
typename Scalar>
724 template<
typename Scalar,
727 struct scalar_fuzzy_default_impl {};
729 template<
typename Scalar>
730 struct scalar_fuzzy_default_impl<Scalar, false, false>
733 template<
typename OtherScalar>
734 static inline bool isMuchSmallerThan(
const Scalar& x,
const OtherScalar& y,
const RealScalar& prec)
736 return abs(x) <=
abs(y) * prec;
738 static inline bool isApprox(
const Scalar& x,
const Scalar& y,
const RealScalar& prec)
741 return abs(x - y) <= (min)(
abs(x),
abs(y)) * prec;
743 static inline bool isApproxOrLessThan(
const Scalar& x,
const Scalar& y,
const RealScalar& prec)
745 return x <= y ||
isApprox(x, y, prec);
749 template<
typename Scalar>
750 struct scalar_fuzzy_default_impl<Scalar, false, true>
753 template<
typename OtherScalar>
754 static inline bool isMuchSmallerThan(
const Scalar& x,
const Scalar&,
const RealScalar&)
756 return x == Scalar(0);
758 static inline bool isApprox(
const Scalar& x,
const Scalar& y,
const RealScalar&)
762 static inline bool isApproxOrLessThan(
const Scalar& x,
const Scalar& y,
const RealScalar&)
768 template<
typename Scalar>
769 struct scalar_fuzzy_default_impl<Scalar, true, false>
772 template<
typename OtherScalar>
773 static inline bool isMuchSmallerThan(
const Scalar& x,
const OtherScalar& y,
const RealScalar& prec)
775 return abs2(x) <=
abs2(y) * prec * prec;
777 static inline bool isApprox(
const Scalar& x,
const Scalar& y,
const RealScalar& prec)
780 return abs2(x - y) <= (min)(
abs2(x),
abs2(y)) * prec * prec;
784 template<
typename Scalar>
785 struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
787 template<
typename Scalar,
typename OtherScalar>
791 return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x,
y, precision);
794 template<
typename Scalar>
795 inline bool isApprox(
const Scalar& x,
const Scalar& y,
801 template<
typename Scalar>
812 template<>
struct random_impl<
bool>
814 static inline bool run()
816 return random<int>(0,1)==0 ?
false :
true;
820 template<>
struct scalar_fuzzy_impl<
bool>
822 typedef bool RealScalar;
824 template<
typename OtherScalar>
830 static inline bool isApprox(
bool x,
bool y,
bool)
857 #endif // EIGEN_MATHFUNCTIONS_H