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