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) Eigen::internal::func##_impl<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type> 55 #define EIGEN_MATHFUNC_RETVAL(func, scalar) typename Eigen::internal::func##_retval<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>::type 61 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
62 struct real_default_impl
64 typedef typename NumTraits<Scalar>::Real RealScalar;
65 static inline RealScalar run(
const Scalar& x)
71 template<
typename Scalar>
72 struct real_default_impl<Scalar,true>
74 typedef typename NumTraits<Scalar>::Real RealScalar;
75 static inline RealScalar run(
const Scalar& x)
82 template<
typename Scalar>
struct real_impl : real_default_impl<Scalar> {};
84 template<
typename Scalar>
87 typedef typename NumTraits<Scalar>::Real type;
95 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
96 struct imag_default_impl
98 typedef typename NumTraits<Scalar>::Real RealScalar;
99 static inline RealScalar run(
const Scalar&)
101 return RealScalar(0);
105 template<
typename Scalar>
106 struct imag_default_impl<Scalar,true>
108 typedef typename NumTraits<Scalar>::Real RealScalar;
109 static inline RealScalar run(
const Scalar& x)
116 template<
typename Scalar>
struct imag_impl : imag_default_impl<Scalar> {};
118 template<
typename Scalar>
121 typedef typename NumTraits<Scalar>::Real type;
128 template<
typename Scalar>
131 typedef typename NumTraits<Scalar>::Real RealScalar;
132 static inline RealScalar& run(Scalar& x)
134 return reinterpret_cast<RealScalar*
>(&x)[0];
136 static inline const RealScalar& run(
const Scalar& x)
138 return reinterpret_cast<const RealScalar*
>(&x)[0];
142 template<
typename Scalar>
143 struct real_ref_retval
145 typedef typename NumTraits<Scalar>::Real & type;
152 template<
typename Scalar,
bool IsComplex>
153 struct imag_ref_default_impl
155 typedef typename NumTraits<Scalar>::Real RealScalar;
156 static inline RealScalar& run(Scalar& x)
158 return reinterpret_cast<RealScalar*
>(&x)[1];
160 static inline const RealScalar& run(
const Scalar& x)
162 return reinterpret_cast<RealScalar*
>(&x)[1];
166 template<
typename Scalar>
167 struct imag_ref_default_impl<Scalar, false>
169 static inline Scalar run(Scalar&)
173 static inline const Scalar run(
const Scalar&)
179 template<
typename Scalar>
180 struct imag_ref_impl : imag_ref_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
182 template<
typename Scalar>
183 struct imag_ref_retval
185 typedef typename NumTraits<Scalar>::Real & type;
192 template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
195 static inline Scalar run(
const Scalar& x)
201 template<
typename Scalar>
202 struct conj_impl<Scalar,true>
204 static inline Scalar run(
const Scalar& x)
211 template<
typename Scalar>
221 template<
typename Scalar,
bool IsComplex>
222 struct abs2_impl_default
224 typedef typename NumTraits<Scalar>::Real RealScalar;
225 static inline RealScalar run(
const Scalar& x)
231 template<
typename Scalar>
232 struct abs2_impl_default<Scalar, true>
234 typedef typename NumTraits<Scalar>::Real RealScalar;
235 static inline RealScalar run(
const Scalar& x)
237 return real(x)*real(x) + imag(x)*imag(x);
241 template<
typename Scalar>
244 typedef typename NumTraits<Scalar>::Real RealScalar;
245 static inline RealScalar run(
const Scalar& x)
247 return abs2_impl_default<Scalar,NumTraits<Scalar>::IsComplex>::run(x);
251 template<
typename Scalar>
254 typedef typename NumTraits<Scalar>::Real type;
261 template<
typename Scalar,
bool IsComplex>
262 struct norm1_default_impl
264 typedef typename NumTraits<Scalar>::Real RealScalar;
265 static inline RealScalar run(
const Scalar& x)
268 return abs(real(x)) + abs(imag(x));
272 template<
typename Scalar>
273 struct norm1_default_impl<Scalar, false>
275 static inline Scalar run(
const Scalar& x)
282 template<
typename Scalar>
283 struct norm1_impl : norm1_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
285 template<
typename Scalar>
288 typedef typename NumTraits<Scalar>::Real type;
295 template<
typename Scalar>
298 typedef typename NumTraits<Scalar>::Real RealScalar;
299 static inline RealScalar run(
const Scalar& x,
const Scalar& y)
305 RealScalar _x = abs(x);
306 RealScalar _y = abs(y);
307 RealScalar p = (max)(_x, _y);
308 if(p==RealScalar(0))
return RealScalar(0);
309 RealScalar q = (min)(_x, _y);
311 return p * sqrt(RealScalar(1) + qp*qp);
315 template<
typename Scalar>
318 typedef typename NumTraits<Scalar>::Real type;
325 template<
typename OldType,
typename NewType>
328 static inline NewType run(
const OldType& x)
330 return static_cast<NewType
>(x);
336 template<
typename OldType,
typename NewType>
337 inline NewType cast(
const OldType& x)
339 return cast_impl<OldType, NewType>::run(x);
346 template<
typename Scalar,
bool IsInteger>
347 struct atanh2_default_impl
349 typedef Scalar retval;
350 typedef typename NumTraits<Scalar>::Real RealScalar;
351 static inline Scalar run(
const Scalar& x,
const Scalar& y)
357 if (y == Scalar(0) || abs(z) > sqrt(NumTraits<RealScalar>::epsilon()))
358 return RealScalar(0.5) * log((y + x) / (y - x));
360 return z + z*z*z / RealScalar(3);
364 template<
typename Scalar>
365 struct atanh2_default_impl<Scalar, true>
367 static inline Scalar run(
const Scalar&,
const Scalar&)
369 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
374 template<typename Scalar>
375 struct atanh2_impl : atanh2_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
377 template<
typename Scalar>
387 template<
typename Scalar,
bool IsInteger>
388 struct pow_default_impl
390 typedef Scalar retval;
391 static inline Scalar run(
const Scalar& x,
const Scalar& y)
398 template<
typename Scalar>
399 struct pow_default_impl<Scalar, true>
401 static inline Scalar run(Scalar x, Scalar y)
404 eigen_assert(!NumTraits<Scalar>::IsSigned || y >= 0);
417 template<
typename Scalar>
418 struct pow_impl : pow_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
420 template<
typename Scalar>
430 template<
typename Scalar,
433 struct random_default_impl {};
435 template<
typename Scalar>
436 struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
438 template<
typename Scalar>
444 template<
typename Scalar>
inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y);
445 template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random();
447 template<typename Scalar>
448 struct random_default_impl<Scalar, false, false>
450 static inline Scalar run(
const Scalar& x,
const Scalar& y)
452 return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX);
454 static inline Scalar run()
456 return run(Scalar(NumTraits<Scalar>::IsSigned ? -1 : 0), Scalar(1));
461 floor_log2_terminate,
463 floor_log2_move_down,
467 template<
unsigned int n,
int lower,
int upper>
struct floor_log2_selector
469 enum { middle = (lower + upper) / 2,
470 value = (upper <= lower + 1) ? int(floor_log2_terminate)
471 : (n < (1 << middle)) ? int(floor_log2_move_down)
472 : (n==0) ? int(floor_log2_bogus)
473 : int(floor_log2_move_up)
477 template<
unsigned int n,
479 int upper =
sizeof(
unsigned int) * CHAR_BIT - 1,
480 int selector = floor_log2_selector<n, lower, upper>::value>
481 struct floor_log2 {};
483 template<
unsigned int n,
int lower,
int upper>
484 struct floor_log2<n, lower, upper, floor_log2_move_down>
486 enum { value = floor_log2<n, lower, floor_log2_selector<n, lower, upper>::middle>::value };
489 template<
unsigned int n,
int lower,
int upper>
490 struct floor_log2<n, lower, upper, floor_log2_move_up>
492 enum { value = floor_log2<n, floor_log2_selector<n, lower, upper>::middle, upper>::value };
495 template<
unsigned int n,
int lower,
int upper>
496 struct floor_log2<n, lower, upper, floor_log2_terminate>
498 enum { value = (n >= ((
unsigned int)(1) << (lower+1))) ? lower+1 : lower };
501 template<
unsigned int n,
int lower,
int upper>
502 struct floor_log2<n, lower, upper, floor_log2_bogus>
507 template<
typename Scalar>
508 struct random_default_impl<Scalar, false, true>
510 static inline Scalar run(
const Scalar& x,
const Scalar& y)
512 typedef typename conditional<NumTraits<Scalar>::IsSigned,std::ptrdiff_t,std::size_t>::type ScalarX;
517 std::size_t range = ScalarX(y)-ScalarX(x);
518 std::size_t offset = 0;
520 std::size_t divisor = 1;
521 std::size_t multiplier = 1;
522 if(range<RAND_MAX) divisor = (std::size_t(RAND_MAX)+1)/(range+1);
523 else multiplier = 1 + range/(std::size_t(RAND_MAX)+1);
525 offset = (std::size_t(std::rand()) * multiplier) / divisor;
526 }
while (offset > range);
527 return Scalar(ScalarX(x) + offset);
530 static inline Scalar run()
532 #ifdef EIGEN_MAKING_DOCS 533 return run(Scalar(NumTraits<Scalar>::IsSigned ? -10 : 0), Scalar(10));
535 enum { rand_bits = floor_log2<(unsigned int)(RAND_MAX)+1>::value,
536 scalar_bits =
sizeof(Scalar) * CHAR_BIT,
537 shift = EIGEN_PLAIN_ENUM_MAX(0,
int(rand_bits) - int(scalar_bits)),
538 offset = NumTraits<Scalar>::IsSigned ? (1 << (EIGEN_PLAIN_ENUM_MIN(rand_bits,scalar_bits)-1)) : 0
540 return Scalar((std::rand() >> shift) - offset);
545 template<
typename Scalar>
546 struct random_default_impl<Scalar, true, false>
548 static inline Scalar run(
const Scalar& x,
const Scalar& y)
550 return Scalar(random(real(x), real(y)),
551 random(imag(x), imag(y)));
553 static inline Scalar run()
555 typedef typename NumTraits<Scalar>::Real RealScalar;
556 return Scalar(random<RealScalar>(), random<RealScalar>());
560 template<
typename Scalar>
561 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y)
563 return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y);
566 template<
typename Scalar>
567 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
569 return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
580 template<
typename Scalar>
581 inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
583 return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
586 template<
typename Scalar>
587 inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(
const Scalar& x)
589 return internal::real_ref_impl<Scalar>::run(x);
592 template<
typename Scalar>
593 inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
595 return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
598 template<
typename Scalar>
599 inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
601 return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
604 template<
typename Scalar>
605 inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(
const Scalar& x)
607 return internal::imag_ref_impl<Scalar>::run(x);
610 template<
typename Scalar>
611 inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
613 return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
616 template<
typename Scalar>
617 inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
619 return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
622 template<
typename Scalar>
623 inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
625 return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
628 template<
typename Scalar>
629 inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
631 return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
634 template<
typename Scalar>
635 inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y)
637 return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
640 template<
typename Scalar>
641 inline EIGEN_MATHFUNC_RETVAL(atanh2, Scalar) atanh2(const Scalar& x, const Scalar& y)
643 return EIGEN_MATHFUNC_IMPL(atanh2, Scalar)::run(x, y);
646 template<
typename Scalar>
647 inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y)
649 return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y);
654 template<
typename T> bool (isfinite)(
const T& x)
656 return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest();
667 template<
typename Scalar,
670 struct scalar_fuzzy_default_impl {};
672 template<
typename Scalar>
673 struct scalar_fuzzy_default_impl<Scalar, false, false>
675 typedef typename NumTraits<Scalar>::Real RealScalar;
676 template<
typename OtherScalar>
677 static inline bool isMuchSmallerThan(
const Scalar& x,
const OtherScalar& y,
const RealScalar& prec)
680 return abs(x) <= abs(y) * prec;
682 static inline bool isApprox(
const Scalar& x,
const Scalar& y,
const RealScalar& prec)
686 return abs(x - y) <= (min)(abs(x), abs(y)) * prec;
688 static inline bool isApproxOrLessThan(
const Scalar& x,
const Scalar& y,
const RealScalar& prec)
690 return x <= y || isApprox(x, y, prec);
694 template<
typename Scalar>
695 struct scalar_fuzzy_default_impl<Scalar, false, true>
697 typedef typename NumTraits<Scalar>::Real RealScalar;
698 template<
typename OtherScalar>
699 static inline bool isMuchSmallerThan(
const Scalar& x,
const Scalar&,
const RealScalar&)
701 return x == Scalar(0);
703 static inline bool isApprox(
const Scalar& x,
const Scalar& y,
const RealScalar&)
707 static inline bool isApproxOrLessThan(
const Scalar& x,
const Scalar& y,
const RealScalar&)
713 template<
typename Scalar>
714 struct scalar_fuzzy_default_impl<Scalar, true, false>
716 typedef typename NumTraits<Scalar>::Real RealScalar;
717 template<
typename OtherScalar>
718 static inline bool isMuchSmallerThan(
const Scalar& x,
const OtherScalar& y,
const RealScalar& prec)
720 return numext::abs2(x) <= numext::abs2(y) * prec * prec;
722 static inline bool isApprox(
const Scalar& x,
const Scalar& y,
const RealScalar& prec)
725 return numext::abs2(x - y) <= (min)(numext::abs2(x), numext::abs2(y)) * prec * prec;
729 template<
typename Scalar>
730 struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
732 template<
typename Scalar,
typename OtherScalar>
733 inline bool isMuchSmallerThan(
const Scalar& x,
const OtherScalar& y,
734 const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
736 return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision);
739 template<
typename Scalar>
740 inline bool isApprox(
const Scalar& x,
const Scalar& y,
741 const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
743 return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
746 template<
typename Scalar>
747 inline bool isApproxOrLessThan(
const Scalar& x,
const Scalar& y,
748 const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
750 return scalar_fuzzy_impl<Scalar>::isApproxOrLessThan(x, y, precision);
757 template<>
struct random_impl<bool>
759 static inline bool run()
761 return random<int>(0,1)==0 ?
false :
true;
765 template<>
struct scalar_fuzzy_impl<bool>
767 typedef bool RealScalar;
769 template<
typename OtherScalar>
770 static inline bool isMuchSmallerThan(
const bool& x,
const bool&,
const bool&)
775 static inline bool isApprox(
bool x,
bool y,
bool)
780 static inline bool isApproxOrLessThan(
const bool& x,
const bool& y,
const bool&)
792 #endif // EIGEN_MATHFUNCTIONS_H
Definition: Eigen_Colamd.h:50