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