10 #ifndef EIGEN_MATHFUNCTIONS_H
11 #define EIGEN_MATHFUNCTIONS_H
37 template<
typename T,
typename dummy =
void>
38 struct global_math_functions_filtering_base
43 template<
typename T>
struct always_void {
typedef void type; };
46 struct 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
62 template<
typename Scalar>
65 typedef typename NumTraits<Scalar>::Real RealScalar;
66 static inline RealScalar run(
const Scalar& x)
72 template<
typename RealScalar>
73 struct real_impl<std::complex<RealScalar> >
75 static inline RealScalar run(
const std::complex<RealScalar>& x)
82 template<
typename Scalar>
85 typedef typename NumTraits<Scalar>::Real type;
88 template<
typename Scalar>
89 inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
91 return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
98 template<
typename Scalar>
101 typedef typename NumTraits<Scalar>::Real RealScalar;
102 static inline RealScalar run(
const Scalar&)
104 return RealScalar(0);
108 template<
typename RealScalar>
109 struct imag_impl<std::complex<RealScalar> >
111 static inline RealScalar run(
const std::complex<RealScalar>& x)
118 template<
typename Scalar>
121 typedef typename NumTraits<Scalar>::Real type;
124 template<
typename Scalar>
125 inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
127 return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
134 template<
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];
148 template<
typename Scalar>
149 struct real_ref_retval
151 typedef typename NumTraits<Scalar>::Real & type;
154 template<
typename Scalar>
155 inline 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);
160 template<
typename Scalar>
161 inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
163 return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
170 template<
typename Scalar,
bool IsComplex>
171 struct 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];
184 template<
typename Scalar>
185 struct imag_ref_default_impl<Scalar, false>
187 static inline Scalar run(Scalar&)
191 static inline const Scalar run(
const Scalar&)
197 template<
typename Scalar>
198 struct imag_ref_impl : imag_ref_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
200 template<
typename Scalar>
201 struct imag_ref_retval
203 typedef typename NumTraits<Scalar>::Real & type;
206 template<
typename Scalar>
207 inline 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);
212 template<
typename Scalar>
213 inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
215 return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
222 template<
typename Scalar>
225 static inline Scalar run(
const Scalar& x)
231 template<
typename RealScalar>
232 struct conj_impl<std::complex<RealScalar> >
234 static inline std::complex<RealScalar> run(
const std::complex<RealScalar>& x)
241 template<
typename Scalar>
247 template<
typename Scalar>
248 inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
250 return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
257 template<
typename Scalar>
260 typedef typename NumTraits<Scalar>::Real RealScalar;
261 static inline RealScalar run(
const Scalar& x)
268 template<
typename Scalar>
271 typedef typename NumTraits<Scalar>::Real type;
274 template<
typename Scalar>
275 inline EIGEN_MATHFUNC_RETVAL(abs, Scalar) abs(const Scalar& x)
277 return EIGEN_MATHFUNC_IMPL(abs, Scalar)::run(x);
284 template<
typename Scalar>
287 typedef typename NumTraits<Scalar>::Real RealScalar;
288 static inline RealScalar run(
const Scalar& x)
294 template<
typename RealScalar>
295 struct 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);
303 template<
typename Scalar>
306 typedef typename NumTraits<Scalar>::Real type;
309 template<
typename Scalar>
310 inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
312 return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
319 template<
typename Scalar,
bool IsComplex>
320 struct 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));
329 template<
typename Scalar>
330 struct norm1_default_impl<Scalar, false>
332 static inline Scalar run(
const Scalar& x)
338 template<
typename Scalar>
339 struct norm1_impl : norm1_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
341 template<
typename Scalar>
344 typedef typename NumTraits<Scalar>::Real type;
347 template<
typename Scalar>
348 inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
350 return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
357 template<
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);
374 template<
typename Scalar>
377 typedef typename NumTraits<Scalar>::Real type;
380 template<
typename Scalar>
381 inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y)
383 return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
390 template<
typename OldType,
typename NewType>
393 static inline NewType run(
const OldType& x)
395 return static_cast<NewType
>(x);
401 template<
typename OldType,
typename NewType>
402 inline NewType cast(
const OldType& x)
404 return cast_impl<OldType, NewType>::run(x);
411 template<
typename Scalar,
bool IsInteger>
412 struct sqrt_default_impl
414 static inline Scalar run(
const Scalar& x)
421 template<
typename Scalar>
422 struct sqrt_default_impl<Scalar, true>
424 static inline Scalar run(
const Scalar&)
426 #ifdef EIGEN2_SUPPORT
427 eigen_assert(!NumTraits<Scalar>::IsInteger);
429 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
435 template<
typename Scalar>
436 struct sqrt_impl : sqrt_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
438 template<
typename Scalar>
444 template<
typename Scalar>
445 inline 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); \
474 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(exp)
475 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(log)
476 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(sin)
477 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(cos)
478 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(tan)
479 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(asin)
480 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(acos)
486 template<typename Scalar,
bool IsInteger>
487 struct atan2_default_impl
489 typedef Scalar retval;
490 static inline Scalar run(
const Scalar& x,
const Scalar& y)
497 template<
typename Scalar>
498 struct atan2_default_impl<Scalar, true>
500 static inline Scalar run(
const Scalar&,
const Scalar&)
502 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
507 template<typename Scalar>
508 struct atan2_impl : atan2_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
510 template<
typename Scalar>
516 template<
typename Scalar>
517 inline EIGEN_MATHFUNC_RETVAL(atan2, Scalar) atan2(const Scalar& x, const Scalar& y)
519 return EIGEN_MATHFUNC_IMPL(atan2, Scalar)::run(x, y);
526 template<
typename Scalar,
bool IsInteger>
527 struct pow_default_impl
529 typedef Scalar retval;
530 static inline Scalar run(
const Scalar& x,
const Scalar& y)
537 template<
typename Scalar>
538 struct pow_default_impl<Scalar, true>
540 static inline Scalar run(Scalar x, Scalar y)
543 eigen_assert(!NumTraits<Scalar>::IsSigned || y >= 0);
556 template<
typename Scalar>
557 struct pow_impl : pow_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
559 template<
typename Scalar>
565 template<
typename Scalar>
566 inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y)
568 return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y);
575 template<
typename Scalar,
578 struct random_default_impl {};
580 template<
typename Scalar>
581 struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
583 template<
typename Scalar>
589 template<
typename Scalar>
inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y);
590 template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random();
592 template<typename Scalar>
593 struct 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,
612 template<
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)
622 template<
unsigned int n,
624 int upper =
sizeof(
unsigned int) * CHAR_BIT - 1,
625 int selector = floor_log2_selector<n, lower, upper>::value>
626 struct floor_log2 {};
628 template<
unsigned int n,
int lower,
int upper>
629 struct floor_log2<n, lower, upper, floor_log2_move_down>
631 enum { value = floor_log2<n, lower, floor_log2_selector<n, lower, upper>::middle>::value };
634 template<
unsigned int n,
int lower,
int upper>
635 struct floor_log2<n, lower, upper, floor_log2_move_up>
637 enum { value = floor_log2<n, floor_log2_selector<n, lower, upper>::middle, upper>::value };
640 template<
unsigned int n,
int lower,
int upper>
641 struct floor_log2<n, lower, upper, floor_log2_terminate>
643 enum { value = (n >= ((
unsigned int)(1) << (lower+1))) ? lower+1 : lower };
646 template<
unsigned int n,
int lower,
int upper>
647 struct floor_log2<n, lower, upper, floor_log2_bogus>
652 template<
typename Scalar>
653 struct 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);
678 template<
typename Scalar>
679 struct 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>());
693 template<
typename Scalar>
694 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y)
696 return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y);
699 template<
typename Scalar>
700 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
702 return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
709 template<
typename Scalar,
712 struct scalar_fuzzy_default_impl {};
714 template<
typename Scalar>
715 struct 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);
734 template<
typename Scalar>
735 struct 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&)
753 template<
typename Scalar>
754 struct 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;
769 template<
typename Scalar>
770 struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
772 template<
typename Scalar,
typename OtherScalar>
773 inline 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);
779 template<
typename Scalar>
780 inline 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);
786 template<
typename Scalar>
787 inline 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);
797 template<>
struct random_impl<bool>
799 static inline bool run()
801 return random<int>(0,1)==0 ?
false :
true;
805 template<>
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&)
833 template<
typename T> bool (isfinite)(
const T& x)
835 return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest();
842 #endif // EIGEN_MATHFUNCTIONS_H