00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef EIGEN_MATHFUNCTIONS_H
00026 #define EIGEN_MATHFUNCTIONS_H
00027
00028 namespace internal {
00029
00050 template<typename T, typename dummy = void>
00051 struct global_math_functions_filtering_base
00052 {
00053 typedef T type;
00054 };
00055
00056 template<typename T> struct always_void { typedef void type; };
00057
00058 template<typename T>
00059 struct global_math_functions_filtering_base
00060 <T,
00061 typename always_void<typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl>::type
00062 >
00063 {
00064 typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type;
00065 };
00066
00067 #define EIGEN_MATHFUNC_IMPL(func, scalar) func##_impl<typename global_math_functions_filtering_base<scalar>::type>
00068 #define EIGEN_MATHFUNC_RETVAL(func, scalar) typename func##_retval<typename global_math_functions_filtering_base<scalar>::type>::type
00069
00070
00071
00072
00073
00074
00075 template<typename Scalar>
00076 struct real_impl
00077 {
00078 typedef typename NumTraits<Scalar>::Real RealScalar;
00079 static inline RealScalar run(const Scalar& x)
00080 {
00081 return x;
00082 }
00083 };
00084
00085 template<typename RealScalar>
00086 struct real_impl<std::complex<RealScalar> >
00087 {
00088 static inline RealScalar run(const std::complex<RealScalar>& x)
00089 {
00090 using std::real;
00091 return real(x);
00092 }
00093 };
00094
00095 template<typename Scalar>
00096 struct real_retval
00097 {
00098 typedef typename NumTraits<Scalar>::Real type;
00099 };
00100
00101 template<typename Scalar>
00102 inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
00103 {
00104 return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
00105 }
00106
00107
00108
00109
00110
00111 template<typename Scalar>
00112 struct imag_impl
00113 {
00114 typedef typename NumTraits<Scalar>::Real RealScalar;
00115 static inline RealScalar run(const Scalar&)
00116 {
00117 return RealScalar(0);
00118 }
00119 };
00120
00121 template<typename RealScalar>
00122 struct imag_impl<std::complex<RealScalar> >
00123 {
00124 static inline RealScalar run(const std::complex<RealScalar>& x)
00125 {
00126 using std::imag;
00127 return imag(x);
00128 }
00129 };
00130
00131 template<typename Scalar>
00132 struct imag_retval
00133 {
00134 typedef typename NumTraits<Scalar>::Real type;
00135 };
00136
00137 template<typename Scalar>
00138 inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
00139 {
00140 return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
00141 }
00142
00143
00144
00145
00146
00147 template<typename Scalar>
00148 struct real_ref_impl
00149 {
00150 typedef typename NumTraits<Scalar>::Real RealScalar;
00151 static inline RealScalar& run(Scalar& x)
00152 {
00153 return reinterpret_cast<RealScalar*>(&x)[0];
00154 }
00155 static inline const RealScalar& run(const Scalar& x)
00156 {
00157 return reinterpret_cast<const RealScalar*>(&x)[0];
00158 }
00159 };
00160
00161 template<typename Scalar>
00162 struct real_ref_retval
00163 {
00164 typedef typename NumTraits<Scalar>::Real & type;
00165 };
00166
00167 template<typename Scalar>
00168 inline typename add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x)
00169 {
00170 return real_ref_impl<Scalar>::run(x);
00171 }
00172
00173 template<typename Scalar>
00174 inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
00175 {
00176 return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
00177 }
00178
00179
00180
00181
00182
00183 template<typename Scalar, bool IsComplex>
00184 struct imag_ref_default_impl
00185 {
00186 typedef typename NumTraits<Scalar>::Real RealScalar;
00187 static inline RealScalar& run(Scalar& x)
00188 {
00189 return reinterpret_cast<RealScalar*>(&x)[1];
00190 }
00191 static inline const RealScalar& run(const Scalar& x)
00192 {
00193 return reinterpret_cast<RealScalar*>(&x)[1];
00194 }
00195 };
00196
00197 template<typename Scalar>
00198 struct imag_ref_default_impl<Scalar, false>
00199 {
00200 static inline Scalar run(Scalar&)
00201 {
00202 return Scalar(0);
00203 }
00204 static inline const Scalar run(const Scalar&)
00205 {
00206 return Scalar(0);
00207 }
00208 };
00209
00210 template<typename Scalar>
00211 struct imag_ref_impl : imag_ref_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
00212
00213 template<typename Scalar>
00214 struct imag_ref_retval
00215 {
00216 typedef typename NumTraits<Scalar>::Real & type;
00217 };
00218
00219 template<typename Scalar>
00220 inline typename add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x)
00221 {
00222 return imag_ref_impl<Scalar>::run(x);
00223 }
00224
00225 template<typename Scalar>
00226 inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
00227 {
00228 return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
00229 }
00230
00231
00232
00233
00234
00235 template<typename Scalar>
00236 struct conj_impl
00237 {
00238 static inline Scalar run(const Scalar& x)
00239 {
00240 return x;
00241 }
00242 };
00243
00244 template<typename RealScalar>
00245 struct conj_impl<std::complex<RealScalar> >
00246 {
00247 static inline std::complex<RealScalar> run(const std::complex<RealScalar>& x)
00248 {
00249 using std::conj;
00250 return conj(x);
00251 }
00252 };
00253
00254 template<typename Scalar>
00255 struct conj_retval
00256 {
00257 typedef Scalar type;
00258 };
00259
00260 template<typename Scalar>
00261 inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
00262 {
00263 return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
00264 }
00265
00266
00267
00268
00269
00270 template<typename Scalar>
00271 struct abs_impl
00272 {
00273 typedef typename NumTraits<Scalar>::Real RealScalar;
00274 static inline RealScalar run(const Scalar& x)
00275 {
00276 using std::abs;
00277 return abs(x);
00278 }
00279 };
00280
00281 template<typename Scalar>
00282 struct abs_retval
00283 {
00284 typedef typename NumTraits<Scalar>::Real type;
00285 };
00286
00287 template<typename Scalar>
00288 inline EIGEN_MATHFUNC_RETVAL(abs, Scalar) abs(const Scalar& x)
00289 {
00290 return EIGEN_MATHFUNC_IMPL(abs, Scalar)::run(x);
00291 }
00292
00293
00294
00295
00296
00297 template<typename Scalar>
00298 struct abs2_impl
00299 {
00300 typedef typename NumTraits<Scalar>::Real RealScalar;
00301 static inline RealScalar run(const Scalar& x)
00302 {
00303 return x*x;
00304 }
00305 };
00306
00307 template<typename RealScalar>
00308 struct abs2_impl<std::complex<RealScalar> >
00309 {
00310 static inline RealScalar run(const std::complex<RealScalar>& x)
00311 {
00312 using std::norm;
00313 return norm(x);
00314 }
00315 };
00316
00317 template<typename Scalar>
00318 struct abs2_retval
00319 {
00320 typedef typename NumTraits<Scalar>::Real type;
00321 };
00322
00323 template<typename Scalar>
00324 inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
00325 {
00326 return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
00327 }
00328
00329
00330
00331
00332
00333 template<typename Scalar, bool IsComplex>
00334 struct norm1_default_impl
00335 {
00336 typedef typename NumTraits<Scalar>::Real RealScalar;
00337 static inline RealScalar run(const Scalar& x)
00338 {
00339 return abs(real(x)) + abs(imag(x));
00340 }
00341 };
00342
00343 template<typename Scalar>
00344 struct norm1_default_impl<Scalar, false>
00345 {
00346 static inline Scalar run(const Scalar& x)
00347 {
00348 return abs(x);
00349 }
00350 };
00351
00352 template<typename Scalar>
00353 struct norm1_impl : norm1_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
00354
00355 template<typename Scalar>
00356 struct norm1_retval
00357 {
00358 typedef typename NumTraits<Scalar>::Real type;
00359 };
00360
00361 template<typename Scalar>
00362 inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
00363 {
00364 return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
00365 }
00366
00367
00368
00369
00370
00371 template<typename Scalar>
00372 struct hypot_impl
00373 {
00374 typedef typename NumTraits<Scalar>::Real RealScalar;
00375 static inline RealScalar run(const Scalar& x, const Scalar& y)
00376 {
00377 using std::max;
00378 using std::min;
00379 RealScalar _x = abs(x);
00380 RealScalar _y = abs(y);
00381 RealScalar p = (max)(_x, _y);
00382 RealScalar q = (min)(_x, _y);
00383 RealScalar qp = q/p;
00384 return p * sqrt(RealScalar(1) + qp*qp);
00385 }
00386 };
00387
00388 template<typename Scalar>
00389 struct hypot_retval
00390 {
00391 typedef typename NumTraits<Scalar>::Real type;
00392 };
00393
00394 template<typename Scalar>
00395 inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y)
00396 {
00397 return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
00398 }
00399
00400
00401
00402
00403
00404 template<typename OldType, typename NewType>
00405 struct cast_impl
00406 {
00407 static inline NewType run(const OldType& x)
00408 {
00409 return static_cast<NewType>(x);
00410 }
00411 };
00412
00413
00414
00415 template<typename OldType, typename NewType>
00416 inline NewType cast(const OldType& x)
00417 {
00418 return cast_impl<OldType, NewType>::run(x);
00419 }
00420
00421
00422
00423
00424
00425 template<typename Scalar, bool IsInteger>
00426 struct sqrt_default_impl
00427 {
00428 static inline Scalar run(const Scalar& x)
00429 {
00430 using std::sqrt;
00431 return sqrt(x);
00432 }
00433 };
00434
00435 template<typename Scalar>
00436 struct sqrt_default_impl<Scalar, true>
00437 {
00438 static inline Scalar run(const Scalar&)
00439 {
00440 #ifdef EIGEN2_SUPPORT
00441 eigen_assert(!NumTraits<Scalar>::IsInteger);
00442 #else
00443 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
00444 #endif
00445 return Scalar(0);
00446 }
00447 };
00448
00449 template<typename Scalar>
00450 struct sqrt_impl : sqrt_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
00451
00452 template<typename Scalar>
00453 struct sqrt_retval
00454 {
00455 typedef Scalar type;
00456 };
00457
00458 template<typename Scalar>
00459 inline EIGEN_MATHFUNC_RETVAL(sqrt, Scalar) sqrt(const Scalar& x)
00460 {
00461 return EIGEN_MATHFUNC_IMPL(sqrt, Scalar)::run(x);
00462 }
00463
00464
00465
00466
00467
00468
00469 #define EIGEN_MATHFUNC_STANDARD_REAL_UNARY(NAME) \
00470 template<typename Scalar, bool IsInteger> struct NAME##_default_impl { \
00471 static inline Scalar run(const Scalar& x) { using std::NAME; return NAME(x); } \
00472 }; \
00473 template<typename Scalar> struct NAME##_default_impl<Scalar, true> { \
00474 static inline Scalar run(const Scalar&) { \
00475 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) \
00476 return Scalar(0); \
00477 } \
00478 }; \
00479 template<typename Scalar> struct NAME##_impl \
00480 : NAME##_default_impl<Scalar, NumTraits<Scalar>::IsInteger> \
00481 {}; \
00482 template<typename Scalar> struct NAME##_retval { typedef Scalar type; }; \
00483 template<typename Scalar> \
00484 inline EIGEN_MATHFUNC_RETVAL(NAME, Scalar) NAME(const Scalar& x) { \
00485 return EIGEN_MATHFUNC_IMPL(NAME, Scalar)::run(x); \
00486 }
00487
00488 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(exp)
00489 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(log)
00490 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(sin)
00491 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(cos)
00492 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(tan)
00493 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(asin)
00494 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(acos)
00495
00496
00497
00498
00499
00500 template<typename Scalar, bool IsInteger>
00501 struct atan2_default_impl
00502 {
00503 typedef Scalar retval;
00504 static inline Scalar run(const Scalar& x, const Scalar& y)
00505 {
00506 using std::atan2;
00507 return atan2(x, y);
00508 }
00509 };
00510
00511 template<typename Scalar>
00512 struct atan2_default_impl<Scalar, true>
00513 {
00514 static inline Scalar run(const Scalar&, const Scalar&)
00515 {
00516 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
00517 return Scalar(0);
00518 }
00519 };
00520
00521 template<typename Scalar>
00522 struct atan2_impl : atan2_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
00523
00524 template<typename Scalar>
00525 struct atan2_retval
00526 {
00527 typedef Scalar type;
00528 };
00529
00530 template<typename Scalar>
00531 inline EIGEN_MATHFUNC_RETVAL(atan2, Scalar) atan2(const Scalar& x, const Scalar& y)
00532 {
00533 return EIGEN_MATHFUNC_IMPL(atan2, Scalar)::run(x, y);
00534 }
00535
00536
00537
00538
00539
00540 template<typename Scalar, bool IsInteger>
00541 struct pow_default_impl
00542 {
00543 typedef Scalar retval;
00544 static inline Scalar run(const Scalar& x, const Scalar& y)
00545 {
00546 using std::pow;
00547 return pow(x, y);
00548 }
00549 };
00550
00551 template<typename Scalar>
00552 struct pow_default_impl<Scalar, true>
00553 {
00554 static inline Scalar run(Scalar x, Scalar y)
00555 {
00556 Scalar res = 1;
00557 eigen_assert(!NumTraits<Scalar>::IsSigned || y >= 0);
00558 if(y & 1) res *= x;
00559 y >>= 1;
00560 while(y)
00561 {
00562 x *= x;
00563 if(y&1) res *= x;
00564 y >>= 1;
00565 }
00566 return res;
00567 }
00568 };
00569
00570 template<typename Scalar>
00571 struct pow_impl : pow_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
00572
00573 template<typename Scalar>
00574 struct pow_retval
00575 {
00576 typedef Scalar type;
00577 };
00578
00579 template<typename Scalar>
00580 inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y)
00581 {
00582 return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y);
00583 }
00584
00585
00586
00587
00588
00589 template<typename Scalar,
00590 bool IsComplex,
00591 bool IsInteger>
00592 struct random_default_impl {};
00593
00594 template<typename Scalar>
00595 struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
00596
00597 template<typename Scalar>
00598 struct random_retval
00599 {
00600 typedef Scalar type;
00601 };
00602
00603 template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y);
00604 template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random();
00605
00606 template<typename Scalar>
00607 struct random_default_impl<Scalar, false, false>
00608 {
00609 static inline Scalar run(const Scalar& x, const Scalar& y)
00610 {
00611 return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX);
00612 }
00613 static inline Scalar run()
00614 {
00615 return run(Scalar(NumTraits<Scalar>::IsSigned ? -1 : 0), Scalar(1));
00616 }
00617 };
00618
00619 enum {
00620 floor_log2_terminate,
00621 floor_log2_move_up,
00622 floor_log2_move_down,
00623 floor_log2_bogus
00624 };
00625
00626 template<unsigned int n, int lower, int upper> struct floor_log2_selector
00627 {
00628 enum { middle = (lower + upper) / 2,
00629 value = (upper <= lower + 1) ? int(floor_log2_terminate)
00630 : (n < (1 << middle)) ? int(floor_log2_move_down)
00631 : (n==0) ? int(floor_log2_bogus)
00632 : int(floor_log2_move_up)
00633 };
00634 };
00635
00636 template<unsigned int n,
00637 int lower = 0,
00638 int upper = sizeof(unsigned int) * CHAR_BIT - 1,
00639 int selector = floor_log2_selector<n, lower, upper>::value>
00640 struct floor_log2 {};
00641
00642 template<unsigned int n, int lower, int upper>
00643 struct floor_log2<n, lower, upper, floor_log2_move_down>
00644 {
00645 enum { value = floor_log2<n, lower, floor_log2_selector<n, lower, upper>::middle>::value };
00646 };
00647
00648 template<unsigned int n, int lower, int upper>
00649 struct floor_log2<n, lower, upper, floor_log2_move_up>
00650 {
00651 enum { value = floor_log2<n, floor_log2_selector<n, lower, upper>::middle, upper>::value };
00652 };
00653
00654 template<unsigned int n, int lower, int upper>
00655 struct floor_log2<n, lower, upper, floor_log2_terminate>
00656 {
00657 enum { value = (n >= ((unsigned int)(1) << (lower+1))) ? lower+1 : lower };
00658 };
00659
00660 template<unsigned int n, int lower, int upper>
00661 struct floor_log2<n, lower, upper, floor_log2_bogus>
00662 {
00663
00664 };
00665
00666 template<typename Scalar>
00667 struct random_default_impl<Scalar, false, true>
00668 {
00669 typedef typename NumTraits<Scalar>::NonInteger NonInteger;
00670
00671 static inline Scalar run(const Scalar& x, const Scalar& y)
00672 {
00673 return x + Scalar((NonInteger(y)-x+1) * std::rand() / (RAND_MAX + NonInteger(1)));
00674 }
00675
00676 static inline Scalar run()
00677 {
00678 #ifdef EIGEN_MAKING_DOCS
00679 return run(Scalar(NumTraits<Scalar>::IsSigned ? -10 : 0), Scalar(10));
00680 #else
00681 enum { rand_bits = floor_log2<(unsigned int)(RAND_MAX)+1>::value,
00682 scalar_bits = sizeof(Scalar) * CHAR_BIT,
00683 shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits))
00684 };
00685 Scalar x = Scalar(std::rand() >> shift);
00686 Scalar offset = NumTraits<Scalar>::IsSigned ? Scalar(1 << (rand_bits-1)) : Scalar(0);
00687 return x - offset;
00688 #endif
00689 }
00690 };
00691
00692 template<typename Scalar>
00693 struct random_default_impl<Scalar, true, false>
00694 {
00695 static inline Scalar run(const Scalar& x, const Scalar& y)
00696 {
00697 return Scalar(random(real(x), real(y)),
00698 random(imag(x), imag(y)));
00699 }
00700 static inline Scalar run()
00701 {
00702 typedef typename NumTraits<Scalar>::Real RealScalar;
00703 return Scalar(random<RealScalar>(), random<RealScalar>());
00704 }
00705 };
00706
00707 template<typename Scalar>
00708 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y)
00709 {
00710 return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y);
00711 }
00712
00713 template<typename Scalar>
00714 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
00715 {
00716 return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
00717 }
00718
00719
00720
00721
00722
00723 template<typename Scalar,
00724 bool IsComplex,
00725 bool IsInteger>
00726 struct scalar_fuzzy_default_impl {};
00727
00728 template<typename Scalar>
00729 struct scalar_fuzzy_default_impl<Scalar, false, false>
00730 {
00731 typedef typename NumTraits<Scalar>::Real RealScalar;
00732 template<typename OtherScalar>
00733 static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
00734 {
00735 return abs(x) <= abs(y) * prec;
00736 }
00737 static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
00738 {
00739 using std::min;
00740 return abs(x - y) <= (min)(abs(x), abs(y)) * prec;
00741 }
00742 static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec)
00743 {
00744 return x <= y || isApprox(x, y, prec);
00745 }
00746 };
00747
00748 template<typename Scalar>
00749 struct scalar_fuzzy_default_impl<Scalar, false, true>
00750 {
00751 typedef typename NumTraits<Scalar>::Real RealScalar;
00752 template<typename OtherScalar>
00753 static inline bool isMuchSmallerThan(const Scalar& x, const Scalar&, const RealScalar&)
00754 {
00755 return x == Scalar(0);
00756 }
00757 static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar&)
00758 {
00759 return x == y;
00760 }
00761 static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar&)
00762 {
00763 return x <= y;
00764 }
00765 };
00766
00767 template<typename Scalar>
00768 struct scalar_fuzzy_default_impl<Scalar, true, false>
00769 {
00770 typedef typename NumTraits<Scalar>::Real RealScalar;
00771 template<typename OtherScalar>
00772 static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
00773 {
00774 return abs2(x) <= abs2(y) * prec * prec;
00775 }
00776 static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
00777 {
00778 using std::min;
00779 return abs2(x - y) <= (min)(abs2(x), abs2(y)) * prec * prec;
00780 }
00781 };
00782
00783 template<typename Scalar>
00784 struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
00785
00786 template<typename Scalar, typename OtherScalar>
00787 inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y,
00788 typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
00789 {
00790 return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision);
00791 }
00792
00793 template<typename Scalar>
00794 inline bool isApprox(const Scalar& x, const Scalar& y,
00795 typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
00796 {
00797 return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
00798 }
00799
00800 template<typename Scalar>
00801 inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y,
00802 typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
00803 {
00804 return scalar_fuzzy_impl<Scalar>::isApproxOrLessThan(x, y, precision);
00805 }
00806
00807
00808
00809
00810
00811 template<> struct random_impl<bool>
00812 {
00813 static inline bool run()
00814 {
00815 return random<int>(0,1)==0 ? false : true;
00816 }
00817 };
00818
00819 template<> struct scalar_fuzzy_impl<bool>
00820 {
00821 typedef bool RealScalar;
00822
00823 template<typename OtherScalar>
00824 static inline bool isMuchSmallerThan(const bool& x, const bool&, const bool&)
00825 {
00826 return !x;
00827 }
00828
00829 static inline bool isApprox(bool x, bool y, bool)
00830 {
00831 return x == y;
00832 }
00833
00834 static inline bool isApproxOrLessThan(const bool& x, const bool& y, const bool&)
00835 {
00836 return (!x) || y;
00837 }
00838
00839 };
00840
00841 }
00842
00843 #endif // EIGEN_MATHFUNCTIONS_H