MathFunctions.h
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
00005 //
00006 // This Source Code Form is subject to the terms of the Mozilla
00007 // Public License v. 2.0. If a copy of the MPL was not distributed
00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
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 * Implementation of real                                                 *
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 * Implementation of imag                                                 *
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 * Implementation of real_ref                                             *
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 * Implementation of imag_ref                                             *
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 * Implementation of conj                                                 *
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 * Implementation of abs                                                  *
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 * Implementation of abs2                                                 *
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 * Implementation of norm1                                                *
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 * Implementation of hypot                                                *
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 * Implementation of cast                                                 *
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 // here, for once, we're plainly returning NewType: we don't want cast to do weird things.
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 * Implementation of sqrt                                                 *
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 * Implementation of standard unary real functions (exp, log, sin, cos, ...  *
00452 ****************************************************************************/
00453 
00454 // This macro instanciate all the necessary template mechanism which is common to all unary real functions.
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 * Implementation of atan2                                                *
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 * Implementation of pow                                                  *
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 * Implementation of random                                               *
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   // no value, error at compile time
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 * Implementation of fuzzy comparisons                                       *
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 ***  The special case of the  bool type ***
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 * Special functions                                                          *
00829 ****************************************************************************/
00830 
00831 // std::isfinite is non standard, so let's define our own version,
00832 // even though it is not very efficient.
00833 template<typename T> bool (isfinite)(const T& x)
00834 {
00835   return x<NumTraits<T>::highest() && x>NumTraits<T>::lowest();
00836 }
00837 
00838 } // end namespace internal
00839 
00840 } // end namespace Eigen
00841 
00842 #endif // EIGEN_MATHFUNCTIONS_H


win_eigen
Author(s): Daniel Stonier
autogenerated on Wed Sep 16 2015 07:11:13