10#ifndef EIGEN_MATHFUNCTIONS_H
11#define EIGEN_MATHFUNCTIONS_H
37template<
typename T,
typename dummy =
void>
38struct global_math_functions_filtering_base
43template<
typename T>
struct always_void {
typedef void type; };
46struct global_math_functions_filtering_base
48 typename always_void<typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl>::type
51 typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type;
54#define EIGEN_MATHFUNC_IMPL(func, scalar) func##_impl<typename global_math_functions_filtering_base<scalar>::type>
55#define EIGEN_MATHFUNC_RETVAL(func, scalar) typename func##_retval<typename global_math_functions_filtering_base<scalar>::type>::type
62template<
typename Scalar>
65 typedef typename NumTraits<Scalar>::Real RealScalar;
66 static inline RealScalar run(
const Scalar& x)
72template<
typename RealScalar>
73struct real_impl<std::complex<RealScalar> >
75 static inline RealScalar run(
const std::complex<RealScalar>& x)
82template<
typename Scalar>
85 typedef typename NumTraits<Scalar>::Real type;
88template<
typename Scalar>
89inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(
const Scalar& x)
91 return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
98template<
typename Scalar>
101 typedef typename NumTraits<Scalar>::Real RealScalar;
102 static inline RealScalar run(
const Scalar&)
104 return RealScalar(0);
108template<
typename RealScalar>
109struct imag_impl<std::complex<RealScalar> >
111 static inline RealScalar run(
const std::complex<RealScalar>& x)
118template<
typename Scalar>
121 typedef typename NumTraits<Scalar>::Real type;
124template<
typename Scalar>
125inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(
const Scalar& x)
127 return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
134template<
typename Scalar>
137 typedef typename NumTraits<Scalar>::Real RealScalar;
138 static inline RealScalar& run(Scalar& x)
140 return reinterpret_cast<RealScalar*
>(&x)[0];
142 static inline const RealScalar& run(
const Scalar& x)
144 return reinterpret_cast<const RealScalar*
>(&x)[0];
148template<
typename Scalar>
149struct real_ref_retval
151 typedef typename NumTraits<Scalar>::Real & type;
154template<
typename Scalar>
155inline typename add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(
const Scalar& x)
157 return real_ref_impl<Scalar>::run(x);
160template<
typename Scalar>
161inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
163 return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
170template<
typename Scalar,
bool IsComplex>
171struct imag_ref_default_impl
173 typedef typename NumTraits<Scalar>::Real RealScalar;
174 static inline RealScalar& run(Scalar& x)
176 return reinterpret_cast<RealScalar*
>(&x)[1];
178 static inline const RealScalar& run(
const Scalar& x)
180 return reinterpret_cast<RealScalar*
>(&x)[1];
184template<
typename Scalar>
185struct imag_ref_default_impl<Scalar, false>
187 static inline Scalar run(Scalar&)
191 static inline const Scalar run(
const Scalar&)
197template<
typename Scalar>
198struct imag_ref_impl : imag_ref_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
200template<
typename Scalar>
201struct imag_ref_retval
203 typedef typename NumTraits<Scalar>::Real & type;
206template<
typename Scalar>
207inline typename add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(
const Scalar& x)
209 return imag_ref_impl<Scalar>::run(x);
212template<
typename Scalar>
213inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
215 return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
222template<
typename Scalar>
225 static inline Scalar run(
const Scalar& x)
231template<
typename RealScalar>
232struct conj_impl<std::complex<RealScalar> >
234 static inline std::complex<RealScalar> run(
const std::complex<RealScalar>& x)
241template<
typename Scalar>
247template<
typename Scalar>
248inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(
const Scalar& x)
250 return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
257template<
typename Scalar>
260 typedef typename NumTraits<Scalar>::Real RealScalar;
261 static inline RealScalar run(
const Scalar& x)
268template<
typename Scalar>
271 typedef typename NumTraits<Scalar>::Real type;
274template<
typename Scalar>
275inline EIGEN_MATHFUNC_RETVAL(abs, Scalar) abs(
const Scalar& x)
277 return EIGEN_MATHFUNC_IMPL(abs, Scalar)::run(x);
284template<
typename Scalar>
287 typedef typename NumTraits<Scalar>::Real RealScalar;
288 static inline RealScalar run(
const Scalar& x)
294template<
typename RealScalar>
295struct abs2_impl<std::complex<RealScalar> >
297 static inline RealScalar run(
const std::complex<RealScalar>& x)
299 return real(x)*real(x) + imag(x)*imag(x);
303template<
typename Scalar>
306 typedef typename NumTraits<Scalar>::Real type;
309template<
typename Scalar>
310inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(
const Scalar& x)
312 return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
319template<
typename Scalar,
bool IsComplex>
320struct norm1_default_impl
322 typedef typename NumTraits<Scalar>::Real RealScalar;
323 static inline RealScalar run(
const Scalar& x)
325 return abs(real(x)) + abs(imag(x));
329template<
typename Scalar>
330struct norm1_default_impl<Scalar, false>
332 static inline Scalar run(
const Scalar& x)
338template<
typename Scalar>
339struct norm1_impl : norm1_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
341template<
typename Scalar>
344 typedef typename NumTraits<Scalar>::Real type;
347template<
typename Scalar>
348inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(
const Scalar& x)
350 return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
357template<
typename Scalar>
360 typedef typename NumTraits<Scalar>::Real RealScalar;
361 static inline RealScalar run(
const Scalar& x,
const Scalar& y)
365 RealScalar _x = abs(x);
366 RealScalar _y = abs(y);
367 RealScalar p = (max)(_x, _y);
368 RealScalar q = (min)(_x, _y);
370 return p * sqrt(RealScalar(1) + qp*qp);
374template<
typename Scalar>
377 typedef typename NumTraits<Scalar>::Real type;
380template<
typename Scalar>
381inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(
const Scalar& x,
const Scalar& y)
383 return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
390template<
typename OldType,
typename NewType>
393 static inline NewType run(
const OldType& x)
395 return static_cast<NewType
>(x);
401template<
typename OldType,
typename NewType>
402inline NewType cast(
const OldType& x)
404 return cast_impl<OldType, NewType>::run(x);
411template<
typename Scalar,
bool IsInteger>
412struct sqrt_default_impl
414 static inline Scalar run(
const Scalar& x)
421template<
typename Scalar>
422struct sqrt_default_impl<Scalar, true>
424 static inline Scalar run(
const Scalar&)
427 eigen_assert(!NumTraits<Scalar>::IsInteger);
429 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
435template<
typename Scalar>
436struct sqrt_impl : sqrt_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
438template<
typename Scalar>
444template<
typename Scalar>
445inline EIGEN_MATHFUNC_RETVAL(sqrt, Scalar) sqrt(
const Scalar& x)
447 return EIGEN_MATHFUNC_IMPL(sqrt, Scalar)::run(x);
455#define EIGEN_MATHFUNC_STANDARD_REAL_UNARY(NAME) \
456 template<typename Scalar, bool IsInteger> struct NAME##_default_impl { \
457 static inline Scalar run(const Scalar& x) { using std::NAME; return NAME(x); } \
459 template<typename Scalar> struct NAME##_default_impl<Scalar, true> { \
460 static inline Scalar run(const Scalar&) { \
461 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) \
465 template<typename Scalar> struct NAME##_impl \
466 : NAME##_default_impl<Scalar, NumTraits<Scalar>::IsInteger> \
468 template<typename Scalar> struct NAME##_retval { typedef Scalar type; }; \
469 template<typename Scalar> \
470 inline EIGEN_MATHFUNC_RETVAL(NAME, Scalar) NAME(const Scalar& x) { \
471 return EIGEN_MATHFUNC_IMPL(NAME, Scalar)::run(x); \
474EIGEN_MATHFUNC_STANDARD_REAL_UNARY(exp)
475EIGEN_MATHFUNC_STANDARD_REAL_UNARY(log)
476EIGEN_MATHFUNC_STANDARD_REAL_UNARY(sin)
477EIGEN_MATHFUNC_STANDARD_REAL_UNARY(cos)
478EIGEN_MATHFUNC_STANDARD_REAL_UNARY(tan)
479EIGEN_MATHFUNC_STANDARD_REAL_UNARY(asin)
480EIGEN_MATHFUNC_STANDARD_REAL_UNARY(acos)
486template<
typename Scalar,
bool IsInteger>
487struct atan2_default_impl
489 typedef Scalar retval;
490 static inline Scalar run(
const Scalar& x,
const Scalar& y)
497template<
typename Scalar>
498struct atan2_default_impl<Scalar, true>
500 static inline Scalar run(
const Scalar&,
const Scalar&)
502 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
507template<
typename Scalar>
508struct atan2_impl : atan2_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
510template<
typename Scalar>
516template<
typename Scalar>
517inline EIGEN_MATHFUNC_RETVAL(atan2, Scalar) atan2(
const Scalar& x,
const Scalar& y)
519 return EIGEN_MATHFUNC_IMPL(atan2, Scalar)::run(x, y);
526template<
typename Scalar,
bool IsInteger>
527struct pow_default_impl
529 typedef Scalar retval;
530 static inline Scalar run(
const Scalar& x,
const Scalar& y)
537template<
typename Scalar>
538struct pow_default_impl<Scalar, true>
540 static inline Scalar run(Scalar x, Scalar y)
543 eigen_assert(!NumTraits<Scalar>::IsSigned || y >= 0);
556template<
typename Scalar>
557struct pow_impl : pow_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
559template<
typename Scalar>
565template<
typename Scalar>
566inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(
const Scalar& x,
const Scalar& y)
568 return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y);
575template<
typename Scalar,
578struct random_default_impl {};
580template<
typename Scalar>
581struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
583template<
typename Scalar>
589template<
typename Scalar>
inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(
const Scalar& x,
const Scalar& y);
590template<
typename Scalar>
inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random();
592template<
typename Scalar>
593struct random_default_impl<Scalar, false, false>
595 static inline Scalar run(
const Scalar& x,
const Scalar& y)
597 return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX);
599 static inline Scalar run()
601 return run(Scalar(NumTraits<Scalar>::IsSigned ? -1 : 0), Scalar(1));
606 floor_log2_terminate,
608 floor_log2_move_down,
612template<
unsigned int n,
int lower,
int upper>
struct floor_log2_selector
614 enum { middle = (lower + upper) / 2,
615 value = (upper <= lower + 1) ? int(floor_log2_terminate)
616 : (n < (1 << middle)) ? int(floor_log2_move_down)
617 : (n==0) ? int(floor_log2_bogus)
618 : int(floor_log2_move_up)
622template<
unsigned int n,
624 int upper =
sizeof(
unsigned int) * CHAR_BIT - 1,
625 int selector = floor_log2_selector<n, lower, upper>::value>
628template<
unsigned int n,
int lower,
int upper>
629struct floor_log2<n, lower, upper, floor_log2_move_down>
631 enum { value = floor_log2<n, lower, floor_log2_selector<n, lower, upper>::middle>::value };
634template<
unsigned int n,
int lower,
int upper>
635struct floor_log2<n, lower, upper, floor_log2_move_up>
637 enum { value = floor_log2<n, floor_log2_selector<n, lower, upper>::middle, upper>::value };
640template<
unsigned int n,
int lower,
int upper>
641struct floor_log2<n, lower, upper, floor_log2_terminate>
643 enum { value = (n >= ((
unsigned int)(1) << (lower+1))) ? lower+1 : lower };
646template<
unsigned int n,
int lower,
int upper>
647struct floor_log2<n, lower, upper, floor_log2_bogus>
652template<
typename Scalar>
653struct random_default_impl<Scalar, false, true>
655 typedef typename NumTraits<Scalar>::NonInteger NonInteger;
657 static inline Scalar run(
const Scalar& x,
const Scalar& y)
659 return x + Scalar((NonInteger(y)-x+1) * std::rand() / (RAND_MAX + NonInteger(1)));
662 static inline Scalar run()
664#ifdef EIGEN_MAKING_DOCS
665 return run(Scalar(NumTraits<Scalar>::IsSigned ? -10 : 0), Scalar(10));
667 enum { rand_bits = floor_log2<(
unsigned int)(RAND_MAX)+1>::value,
668 scalar_bits =
sizeof(Scalar) * CHAR_BIT,
669 shift = EIGEN_PLAIN_ENUM_MAX(0,
int(rand_bits) -
int(scalar_bits))
671 Scalar x = Scalar(std::rand() >> shift);
672 Scalar offset = NumTraits<Scalar>::IsSigned ? Scalar(1 << (rand_bits-1)) : Scalar(0);
678template<
typename Scalar>
679struct random_default_impl<Scalar, true, false>
681 static inline Scalar run(
const Scalar& x,
const Scalar& y)
683 return Scalar(random(real(x), real(y)),
684 random(imag(x), imag(y)));
686 static inline Scalar run()
688 typedef typename NumTraits<Scalar>::Real RealScalar;
689 return Scalar(random<RealScalar>(), random<RealScalar>());
693template<
typename Scalar>
694inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(
const Scalar& x,
const Scalar& y)
696 return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y);
699template<
typename Scalar>
700inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
702 return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
709template<
typename Scalar,
712struct scalar_fuzzy_default_impl {};
714template<
typename Scalar>
715struct scalar_fuzzy_default_impl<Scalar, false, false>
717 typedef typename NumTraits<Scalar>::Real RealScalar;
718 template<
typename OtherScalar>
719 static inline bool isMuchSmallerThan(
const Scalar& x,
const OtherScalar& y,
const RealScalar& prec)
721 return abs(x) <= abs(y) * prec;
723 static inline bool isApprox(
const Scalar& x,
const Scalar& y,
const RealScalar& prec)
726 return abs(x - y) <= (min)(abs(x), abs(y)) * prec;
728 static inline bool isApproxOrLessThan(
const Scalar& x,
const Scalar& y,
const RealScalar& prec)
730 return x <= y || isApprox(x, y, prec);
734template<
typename Scalar>
735struct scalar_fuzzy_default_impl<Scalar, false, true>
737 typedef typename NumTraits<Scalar>::Real RealScalar;
738 template<
typename OtherScalar>
739 static inline bool isMuchSmallerThan(
const Scalar& x,
const Scalar&,
const RealScalar&)
741 return x == Scalar(0);
743 static inline bool isApprox(
const Scalar& x,
const Scalar& y,
const RealScalar&)
747 static inline bool isApproxOrLessThan(
const Scalar& x,
const Scalar& y,
const RealScalar&)
753template<
typename Scalar>
754struct scalar_fuzzy_default_impl<Scalar, true, false>
756 typedef typename NumTraits<Scalar>::Real RealScalar;
757 template<
typename OtherScalar>
758 static inline bool isMuchSmallerThan(
const Scalar& x,
const OtherScalar& y,
const RealScalar& prec)
760 return abs2(x) <= abs2(y) * prec * prec;
762 static inline bool isApprox(
const Scalar& x,
const Scalar& y,
const RealScalar& prec)
765 return abs2(x - y) <= (min)(abs2(x), abs2(y)) * prec * prec;
769template<
typename Scalar>
770struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
772template<
typename Scalar,
typename OtherScalar>
773inline bool isMuchSmallerThan(
const Scalar& x,
const OtherScalar& y,
774 typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
776 return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision);
779template<
typename Scalar>
780inline bool isApprox(
const Scalar& x,
const Scalar& y,
781 typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
783 return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
786template<
typename Scalar>
787inline bool isApproxOrLessThan(
const Scalar& x,
const Scalar& y,
788 typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
790 return scalar_fuzzy_impl<Scalar>::isApproxOrLessThan(x, y, precision);
797template<>
struct random_impl<bool>
799 static inline bool run()
801 return random<int>(0,1)==0 ? false :
true;
805template<>
struct scalar_fuzzy_impl<bool>
807 typedef bool RealScalar;
809 template<
typename OtherScalar>
810 static inline bool isMuchSmallerThan(
const bool& x,
const bool&,
const bool&)
815 static inline bool isApprox(
bool x,
bool y,
bool)
820 static inline bool isApproxOrLessThan(
const bool& x,
const bool& y,
const bool&)
833template<
typename T> bool (isfinite)(
const T& x)
835 return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest();