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 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 #ifdef EIGEN2_SUPPORT
00433 eigen_assert(!NumTraits<Scalar>::IsInteger);
00434 #else
00435 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
00436 #endif
00437 return Scalar(0);
00438 }
00439 };
00440
00441 template<typename Scalar>
00442 struct sqrt_impl : sqrt_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
00443
00444 template<typename Scalar>
00445 struct sqrt_retval
00446 {
00447 typedef Scalar type;
00448 };
00449
00450 template<typename Scalar>
00451 inline EIGEN_MATHFUNC_RETVAL(sqrt, Scalar) sqrt(const Scalar& x)
00452 {
00453 return EIGEN_MATHFUNC_IMPL(sqrt, Scalar)::run(x);
00454 }
00455
00456
00457
00458
00459
00460
00461 #define EIGEN_MATHFUNC_STANDARD_REAL_UNARY(NAME) \
00462 template<typename Scalar, bool IsInteger> struct NAME##_default_impl { \
00463 static inline Scalar run(const Scalar& x) { return std::NAME(x); } \
00464 }; \
00465 template<typename Scalar> struct NAME##_default_impl<Scalar, true> { \
00466 static inline Scalar run(const Scalar&) { \
00467 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar) \
00468 return Scalar(0); \
00469 } \
00470 }; \
00471 template<typename Scalar> struct NAME##_impl \
00472 : NAME##_default_impl<Scalar, NumTraits<Scalar>::IsInteger> \
00473 {}; \
00474 template<typename Scalar> struct NAME##_retval { typedef Scalar type; }; \
00475 template<typename Scalar> \
00476 inline EIGEN_MATHFUNC_RETVAL(NAME, Scalar) NAME(const Scalar& x) { \
00477 return EIGEN_MATHFUNC_IMPL(NAME, Scalar)::run(x); \
00478 }
00479
00480 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(exp)
00481 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(log)
00482 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(sin)
00483 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(cos)
00484 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(tan)
00485 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(asin)
00486 EIGEN_MATHFUNC_STANDARD_REAL_UNARY(acos)
00487
00488
00489
00490
00491
00492 template<typename Scalar, bool IsInteger>
00493 struct atan2_default_impl
00494 {
00495 typedef Scalar retval;
00496 static inline Scalar run(const Scalar& x, const Scalar& y)
00497 {
00498 return std::atan2(x, y);
00499 }
00500 };
00501
00502 template<typename Scalar>
00503 struct atan2_default_impl<Scalar, true>
00504 {
00505 static inline Scalar run(const Scalar&, const Scalar&)
00506 {
00507 EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
00508 return Scalar(0);
00509 }
00510 };
00511
00512 template<typename Scalar>
00513 struct atan2_impl : atan2_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
00514
00515 template<typename Scalar>
00516 struct atan2_retval
00517 {
00518 typedef Scalar type;
00519 };
00520
00521 template<typename Scalar>
00522 inline EIGEN_MATHFUNC_RETVAL(atan2, Scalar) atan2(const Scalar& x, const Scalar& y)
00523 {
00524 return EIGEN_MATHFUNC_IMPL(atan2, Scalar)::run(x, y);
00525 }
00526
00527
00528
00529
00530
00531 template<typename Scalar, bool IsInteger>
00532 struct pow_default_impl
00533 {
00534 typedef Scalar retval;
00535 static inline Scalar run(const Scalar& x, const Scalar& y)
00536 {
00537 return std::pow(x, y);
00538 }
00539 };
00540
00541 template<typename Scalar>
00542 struct pow_default_impl<Scalar, true>
00543 {
00544 static inline Scalar run(Scalar x, Scalar y)
00545 {
00546 Scalar res = 1;
00547 eigen_assert(!NumTraits<Scalar>::IsSigned || y >= 0);
00548 if(y & 1) res *= x;
00549 y >>= 1;
00550 while(y)
00551 {
00552 x *= x;
00553 if(y&1) res *= x;
00554 y >>= 1;
00555 }
00556 return res;
00557 }
00558 };
00559
00560 template<typename Scalar>
00561 struct pow_impl : pow_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
00562
00563 template<typename Scalar>
00564 struct pow_retval
00565 {
00566 typedef Scalar type;
00567 };
00568
00569 template<typename Scalar>
00570 inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y)
00571 {
00572 return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y);
00573 }
00574
00575
00576
00577
00578
00579 template<typename Scalar,
00580 bool IsComplex,
00581 bool IsInteger>
00582 struct random_default_impl {};
00583
00584 template<typename Scalar>
00585 struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
00586
00587 template<typename Scalar>
00588 struct random_retval
00589 {
00590 typedef Scalar type;
00591 };
00592
00593 template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y);
00594 template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random();
00595
00596 template<typename Scalar>
00597 struct random_default_impl<Scalar, false, false>
00598 {
00599 static inline Scalar run(const Scalar& x, const Scalar& y)
00600 {
00601 return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX);
00602 }
00603 static inline Scalar run()
00604 {
00605 return run(Scalar(NumTraits<Scalar>::IsSigned ? -1 : 0), Scalar(1));
00606 }
00607 };
00608
00609 enum {
00610 floor_log2_terminate,
00611 floor_log2_move_up,
00612 floor_log2_move_down,
00613 floor_log2_bogus
00614 };
00615
00616 template<unsigned int n, int lower, int upper> struct floor_log2_selector
00617 {
00618 enum { middle = (lower + upper) / 2,
00619 value = (upper <= lower + 1) ? int(floor_log2_terminate)
00620 : (n < (1 << middle)) ? int(floor_log2_move_down)
00621 : (n==0) ? int(floor_log2_bogus)
00622 : int(floor_log2_move_up)
00623 };
00624 };
00625
00626 template<unsigned int n,
00627 int lower = 0,
00628 int upper = sizeof(unsigned int) * CHAR_BIT - 1,
00629 int selector = floor_log2_selector<n, lower, upper>::value>
00630 struct floor_log2 {};
00631
00632 template<unsigned int n, int lower, int upper>
00633 struct floor_log2<n, lower, upper, floor_log2_move_down>
00634 {
00635 enum { value = floor_log2<n, lower, floor_log2_selector<n, lower, upper>::middle>::value };
00636 };
00637
00638 template<unsigned int n, int lower, int upper>
00639 struct floor_log2<n, lower, upper, floor_log2_move_up>
00640 {
00641 enum { value = floor_log2<n, floor_log2_selector<n, lower, upper>::middle, upper>::value };
00642 };
00643
00644 template<unsigned int n, int lower, int upper>
00645 struct floor_log2<n, lower, upper, floor_log2_terminate>
00646 {
00647 enum { value = (n >= ((unsigned int)(1) << (lower+1))) ? lower+1 : lower };
00648 };
00649
00650 template<unsigned int n, int lower, int upper>
00651 struct floor_log2<n, lower, upper, floor_log2_bogus>
00652 {
00653
00654 };
00655
00656 template<typename Scalar>
00657 struct random_default_impl<Scalar, false, true>
00658 {
00659 typedef typename NumTraits<Scalar>::NonInteger NonInteger;
00660
00661 static inline Scalar run(const Scalar& x, const Scalar& y)
00662 {
00663 return x + Scalar((NonInteger(y)-x+1) * std::rand() / (RAND_MAX + NonInteger(1)));
00664 }
00665
00666 static inline Scalar run()
00667 {
00668 #ifdef EIGEN_MAKING_DOCS
00669 return run(Scalar(NumTraits<Scalar>::IsSigned ? -10 : 0), Scalar(10));
00670 #else
00671 enum { rand_bits = floor_log2<(unsigned int)(RAND_MAX)+1>::value,
00672 scalar_bits = sizeof(Scalar) * CHAR_BIT,
00673 shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits))
00674 };
00675 Scalar x = Scalar(std::rand() >> shift);
00676 Scalar offset = NumTraits<Scalar>::IsSigned ? Scalar(1 << (rand_bits-1)) : Scalar(0);
00677 return x - offset;
00678 #endif
00679 }
00680 };
00681
00682 template<typename Scalar>
00683 struct random_default_impl<Scalar, true, false>
00684 {
00685 static inline Scalar run(const Scalar& x, const Scalar& y)
00686 {
00687 return Scalar(random(real(x), real(y)),
00688 random(imag(x), imag(y)));
00689 }
00690 static inline Scalar run()
00691 {
00692 typedef typename NumTraits<Scalar>::Real RealScalar;
00693 return Scalar(random<RealScalar>(), random<RealScalar>());
00694 }
00695 };
00696
00697 template<typename Scalar>
00698 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y)
00699 {
00700 return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y);
00701 }
00702
00703 template<typename Scalar>
00704 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
00705 {
00706 return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
00707 }
00708
00709
00710
00711
00712
00713 template<typename Scalar,
00714 bool IsComplex,
00715 bool IsInteger>
00716 struct scalar_fuzzy_default_impl {};
00717
00718 template<typename Scalar>
00719 struct scalar_fuzzy_default_impl<Scalar, false, false>
00720 {
00721 typedef typename NumTraits<Scalar>::Real RealScalar;
00722 template<typename OtherScalar>
00723 static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
00724 {
00725 return abs(x) <= abs(y) * prec;
00726 }
00727 static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
00728 {
00729 return abs(x - y) <= std::min(abs(x), abs(y)) * prec;
00730 }
00731 static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec)
00732 {
00733 return x <= y || isApprox(x, y, prec);
00734 }
00735 };
00736
00737 template<typename Scalar>
00738 struct scalar_fuzzy_default_impl<Scalar, false, true>
00739 {
00740 typedef typename NumTraits<Scalar>::Real RealScalar;
00741 template<typename OtherScalar>
00742 static inline bool isMuchSmallerThan(const Scalar& x, const Scalar&, const RealScalar&)
00743 {
00744 return x == Scalar(0);
00745 }
00746 static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar&)
00747 {
00748 return x == y;
00749 }
00750 static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar&)
00751 {
00752 return x <= y;
00753 }
00754 };
00755
00756 template<typename Scalar>
00757 struct scalar_fuzzy_default_impl<Scalar, true, false>
00758 {
00759 typedef typename NumTraits<Scalar>::Real RealScalar;
00760 template<typename OtherScalar>
00761 static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
00762 {
00763 return abs2(x) <= abs2(y) * prec * prec;
00764 }
00765 static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
00766 {
00767 return abs2(x - y) <= std::min(abs2(x), abs2(y)) * prec * prec;
00768 }
00769 };
00770
00771 template<typename Scalar>
00772 struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
00773
00774 template<typename Scalar, typename OtherScalar>
00775 inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y,
00776 typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
00777 {
00778 return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision);
00779 }
00780
00781 template<typename Scalar>
00782 inline bool isApprox(const Scalar& x, const Scalar& y,
00783 typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
00784 {
00785 return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
00786 }
00787
00788 template<typename Scalar>
00789 inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y,
00790 typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
00791 {
00792 return scalar_fuzzy_impl<Scalar>::isApproxOrLessThan(x, y, precision);
00793 }
00794
00795
00796
00797
00798
00799 template<> struct random_impl<bool>
00800 {
00801 static inline bool run()
00802 {
00803 return random<int>(0,1)==0 ? false : true;
00804 }
00805 };
00806
00807 template<> struct scalar_fuzzy_impl<bool>
00808 {
00809 typedef bool RealScalar;
00810
00811 template<typename OtherScalar>
00812 static inline bool isMuchSmallerThan(const bool& x, const bool&, const bool&)
00813 {
00814 return !x;
00815 }
00816
00817 static inline bool isApprox(bool x, bool y, bool)
00818 {
00819 return x == y;
00820 }
00821
00822 static inline bool isApproxOrLessThan(const bool& x, const bool& y, const bool&)
00823 {
00824 return (!x) || y;
00825 }
00826
00827 };
00828
00829 }
00830
00831 #endif // EIGEN_MATHFUNCTIONS_H