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


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:31:52