Main MRPT website > C++ reference
MRPT logo

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 
00030 /** \internal \struct global_math_functions_filtering_base
00031   *
00032   * What it does:
00033   * Defines a typedef 'type' as follows:
00034   * - if type T has a member typedef Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl, then
00035   *   global_math_functions_filtering_base<T>::type is a typedef for it.
00036   * - otherwise, global_math_functions_filtering_base<T>::type is a typedef for T.
00037   *
00038   * How it's used:
00039   * To allow to defined the global math functions (like sin...) in certain cases, like the Array expressions.
00040   * When you do sin(array1+array2), the object array1+array2 has a complicated expression type, all what you want to know
00041   * is that it inherits ArrayBase. So we implement a partial specialization of sin_impl for ArrayBase<Derived>.
00042   * So we must make sure to use sin_impl<ArrayBase<Derived> > and not sin_impl<Derived>, otherwise our partial specialization
00043   * won't be used. How does sin know that? That's exactly what global_math_functions_filtering_base tells it.
00044   *
00045   * How it's implemented:
00046   * SFINAE in the style of enable_if. Highly susceptible of breaking compilers. With GCC, it sure does work, but if you replace
00047   * the typename dummy by an integer template parameter, it doesn't work anymore!
00048   */
00049 
00050 template<typename T, typename dummy = void>
00051 struct global_math_functions_filtering_base
00052 {
00053   typedef T type;
00054 };
00055 
00056 template<typename T> struct always_void { typedef void type; };
00057 
00058 template<typename T>
00059 struct global_math_functions_filtering_base
00060   <T,
00061    typename always_void<typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl>::type
00062   >
00063 {
00064   typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type;
00065 };
00066 
00067 #define EIGEN_MATHFUNC_IMPL(func, scalar) func##_impl<typename global_math_functions_filtering_base<scalar>::type>
00068 #define EIGEN_MATHFUNC_RETVAL(func, scalar) typename func##_retval<typename global_math_functions_filtering_base<scalar>::type>::type
00069 
00070 
00071 /****************************************************************************
00072 * 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     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 * Implementation of imag                                                 *
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 * Implementation of real_ref                                             *
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 * Implementation of imag_ref                                             *
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 * Implementation of conj                                                 *
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 * Implementation of abs                                                  *
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 * Implementation of abs2                                                 *
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 * Implementation of norm1                                                *
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 * Implementation of hypot                                                *
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 * Implementation of cast                                                 *
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 // here, for once, we're plainly returning NewType: we don't want cast to do weird things.
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 * Implementation of sqrt                                                 *
00416 ****************************************************************************/
00417 
00418 template<typename Scalar, bool IsInteger>
00419 struct sqrt_default_impl
00420 {
00421   static inline Scalar run(const Scalar& x)
00422   {
00423     return std::sqrt(x);
00424   }
00425 };
00426 
00427 template<typename Scalar>
00428 struct sqrt_default_impl<Scalar, true>
00429 {
00430   static inline Scalar run(const Scalar&)
00431   {
00432     EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
00433     return Scalar(0);
00434   }
00435 };
00436 
00437 template<typename Scalar>
00438 struct sqrt_impl : sqrt_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
00439 
00440 template<typename Scalar>
00441 struct sqrt_retval
00442 {
00443   typedef Scalar type;
00444 };
00445 
00446 template<typename Scalar>
00447 inline EIGEN_MATHFUNC_RETVAL(sqrt, Scalar) sqrt(const Scalar& x)
00448 {
00449   return EIGEN_MATHFUNC_IMPL(sqrt, Scalar)::run(x);
00450 }
00451 
00452 /****************************************************************************
00453 * Implementation of exp                                                  *
00454 ****************************************************************************/
00455 
00456 template<typename Scalar, bool IsInteger>
00457 struct exp_default_impl
00458 {
00459   static inline Scalar run(const Scalar& x)
00460   {
00461     return std::exp(x);
00462   }
00463 };
00464 
00465 template<typename Scalar>
00466 struct exp_default_impl<Scalar, true>
00467 {
00468   static inline Scalar run(const Scalar&)
00469   {
00470     EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
00471     return Scalar(0);
00472   }
00473 };
00474 
00475 template<typename Scalar>
00476 struct exp_impl : exp_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
00477 
00478 template<typename Scalar>
00479 struct exp_retval
00480 {
00481   typedef Scalar type;
00482 };
00483 
00484 template<typename Scalar>
00485 inline EIGEN_MATHFUNC_RETVAL(exp, Scalar) exp(const Scalar& x)
00486 {
00487   return EIGEN_MATHFUNC_IMPL(exp, Scalar)::run(x);
00488 }
00489 
00490 /****************************************************************************
00491 * Implementation of cos                                                  *
00492 ****************************************************************************/
00493 
00494 template<typename Scalar, bool IsInteger>
00495 struct cos_default_impl
00496 {
00497   static inline Scalar run(const Scalar& x)
00498   {
00499     return std::cos(x);
00500   }
00501 };
00502 
00503 template<typename Scalar>
00504 struct cos_default_impl<Scalar, true>
00505 {
00506   static inline Scalar run(const Scalar&)
00507   {
00508     EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
00509     return Scalar(0);
00510   }
00511 };
00512 
00513 template<typename Scalar>
00514 struct cos_impl : cos_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
00515 
00516 template<typename Scalar>
00517 struct cos_retval
00518 {
00519   typedef Scalar type;
00520 };
00521 
00522 template<typename Scalar>
00523 inline EIGEN_MATHFUNC_RETVAL(cos, Scalar) cos(const Scalar& x)
00524 {
00525   return EIGEN_MATHFUNC_IMPL(cos, Scalar)::run(x);
00526 }
00527 
00528 /****************************************************************************
00529 * Implementation of sin                                                  *
00530 ****************************************************************************/
00531 
00532 template<typename Scalar, bool IsInteger>
00533 struct sin_default_impl
00534 {
00535   static inline Scalar run(const Scalar& x)
00536   {
00537     return std::sin(x);
00538   }
00539 };
00540 
00541 template<typename Scalar>
00542 struct sin_default_impl<Scalar, true>
00543 {
00544   static inline Scalar run(const Scalar&)
00545   {
00546     EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
00547     return Scalar(0);
00548   }
00549 };
00550 
00551 template<typename Scalar>
00552 struct sin_impl : sin_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
00553 
00554 template<typename Scalar>
00555 struct sin_retval
00556 {
00557   typedef Scalar type;
00558 };
00559 
00560 template<typename Scalar>
00561 inline EIGEN_MATHFUNC_RETVAL(sin, Scalar) sin(const Scalar& x)
00562 {
00563   return EIGEN_MATHFUNC_IMPL(sin, Scalar)::run(x);
00564 }
00565 
00566 /****************************************************************************
00567 * Implementation of log                                                  *
00568 ****************************************************************************/
00569 
00570 template<typename Scalar, bool IsInteger>
00571 struct log_default_impl
00572 {
00573   static inline Scalar run(const Scalar& x)
00574   {
00575     return std::log(x);
00576   }
00577 };
00578 
00579 template<typename Scalar>
00580 struct log_default_impl<Scalar, true>
00581 {
00582   static inline Scalar run(const Scalar&)
00583   {
00584     EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
00585     return Scalar(0);
00586   }
00587 };
00588 
00589 template<typename Scalar>
00590 struct log_impl : log_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
00591 
00592 template<typename Scalar>
00593 struct log_retval
00594 {
00595   typedef Scalar type;
00596 };
00597 
00598 template<typename Scalar>
00599 inline EIGEN_MATHFUNC_RETVAL(log, Scalar) log(const Scalar& x)
00600 {
00601   return EIGEN_MATHFUNC_IMPL(log, Scalar)::run(x);
00602 }
00603 
00604 /****************************************************************************
00605 * Implementation of atan2                                                *
00606 ****************************************************************************/
00607 
00608 template<typename Scalar, bool IsInteger>
00609 struct atan2_default_impl
00610 {
00611   typedef Scalar retval;
00612   static inline Scalar run(const Scalar& x, const Scalar& y)
00613   {
00614     return std::atan2(x, y);
00615   }
00616 };
00617 
00618 template<typename Scalar>
00619 struct atan2_default_impl<Scalar, true>
00620 {
00621   static inline Scalar run(const Scalar&, const Scalar&)
00622   {
00623     EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
00624     return Scalar(0);
00625   }
00626 };
00627 
00628 template<typename Scalar>
00629 struct atan2_impl : atan2_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
00630 
00631 template<typename Scalar>
00632 struct atan2_retval
00633 {
00634   typedef Scalar type;
00635 };
00636 
00637 template<typename Scalar>
00638 inline EIGEN_MATHFUNC_RETVAL(atan2, Scalar) atan2(const Scalar& x, const Scalar& y)
00639 {
00640   return EIGEN_MATHFUNC_IMPL(atan2, Scalar)::run(x, y);
00641 }
00642 
00643 /****************************************************************************
00644 * Implementation of pow                                                  *
00645 ****************************************************************************/
00646 
00647 template<typename Scalar, bool IsInteger>
00648 struct pow_default_impl
00649 {
00650   typedef Scalar retval;
00651   static inline Scalar run(const Scalar& x, const Scalar& y)
00652   {
00653     return std::pow(x, y);
00654   }
00655 };
00656 
00657 template<typename Scalar>
00658 struct pow_default_impl<Scalar, true>
00659 {
00660   static inline Scalar run(Scalar x, Scalar y)
00661   {
00662     Scalar res = 1;
00663     eigen_assert(!NumTraits<Scalar>::IsSigned || y >= 0);
00664     if(y & 1) res *= x;
00665     y >>= 1;
00666     while(y)
00667     {
00668       x *= x;
00669       if(y&1) res *= x;
00670       y >>= 1;
00671     }
00672     return res;
00673   }
00674 };
00675 
00676 template<typename Scalar>
00677 struct pow_impl : pow_default_impl<Scalar, NumTraits<Scalar>::IsInteger> {};
00678 
00679 template<typename Scalar>
00680 struct pow_retval
00681 {
00682   typedef Scalar type;
00683 };
00684 
00685 template<typename Scalar>
00686 inline EIGEN_MATHFUNC_RETVAL(pow, Scalar) pow(const Scalar& x, const Scalar& y)
00687 {
00688   return EIGEN_MATHFUNC_IMPL(pow, Scalar)::run(x, y);
00689 }
00690 
00691 /****************************************************************************
00692 * Implementation of random                                               *
00693 ****************************************************************************/
00694 
00695 template<typename Scalar,
00696          bool IsComplex,
00697          bool IsInteger>
00698 struct random_default_impl {};
00699 
00700 template<typename Scalar>
00701 struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
00702 
00703 template<typename Scalar>
00704 struct random_retval
00705 {
00706   typedef Scalar type;
00707 };
00708 
00709 template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y);
00710 template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random();
00711 
00712 template<typename Scalar>
00713 struct random_default_impl<Scalar, false, false>
00714 {
00715   static inline Scalar run(const Scalar& x, const Scalar& y)
00716   {
00717     return x + (y-x) * Scalar(std::rand()) / float(RAND_MAX);
00718   }
00719   static inline Scalar run()
00720   {
00721     return run(Scalar(NumTraits<Scalar>::IsSigned ? -1 : 0), Scalar(1));
00722   }
00723 };
00724 
00725 template<typename Scalar>
00726 struct random_default_impl<Scalar, false, true>
00727 {
00728   static inline Scalar run(const Scalar& x, const Scalar& y)
00729   {
00730     return x + Scalar((y-x+1) * (std::rand() / (RAND_MAX + typename NumTraits<Scalar>::NonInteger(1))));
00731   }
00732   static inline Scalar run()
00733   {
00734     return run(Scalar(NumTraits<Scalar>::IsSigned ? -10 : 0), Scalar(10));
00735   }
00736 };
00737 
00738 template<typename Scalar>
00739 struct random_default_impl<Scalar, true, false>
00740 {
00741   static inline Scalar run(const Scalar& x, const Scalar& y)
00742   {
00743     return Scalar(random(real(x), real(y)),
00744                   random(imag(x), imag(y)));
00745   }
00746   static inline Scalar run()
00747   {
00748     typedef typename NumTraits<Scalar>::Real RealScalar;
00749     return Scalar(random<RealScalar>(), random<RealScalar>());
00750   }
00751 };
00752 
00753 template<typename Scalar>
00754 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y)
00755 {
00756   return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y);
00757 }
00758 
00759 template<typename Scalar>
00760 inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
00761 {
00762   return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
00763 }
00764 
00765 /****************************************************************************
00766 * Implementation of fuzzy comparisons                                       *
00767 ****************************************************************************/
00768 
00769 template<typename Scalar,
00770          bool IsComplex,
00771          bool IsInteger>
00772 struct scalar_fuzzy_default_impl {};
00773 
00774 template<typename Scalar>
00775 struct scalar_fuzzy_default_impl<Scalar, false, false>
00776 {
00777   typedef typename NumTraits<Scalar>::Real RealScalar;
00778   template<typename OtherScalar>
00779   static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
00780   {
00781     return abs(x) <= abs(y) * prec;
00782   }
00783   static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
00784   {
00785     return abs(x - y) <= std::min(abs(x), abs(y)) * prec;
00786   }
00787   static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec)
00788   {
00789     return x <= y || isApprox(x, y, prec);
00790   }
00791 };
00792 
00793 template<typename Scalar>
00794 struct scalar_fuzzy_default_impl<Scalar, false, true>
00795 {
00796   typedef typename NumTraits<Scalar>::Real RealScalar;
00797   template<typename OtherScalar>
00798   static inline bool isMuchSmallerThan(const Scalar& x, const Scalar&, const RealScalar&)
00799   {
00800     return x == Scalar(0);
00801   }
00802   static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar&)
00803   {
00804     return x == y;
00805   }
00806   static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar&)
00807   {
00808     return x <= y;
00809   }
00810 };
00811 
00812 template<typename Scalar>
00813 struct scalar_fuzzy_default_impl<Scalar, true, false>
00814 {
00815   typedef typename NumTraits<Scalar>::Real RealScalar;
00816   template<typename OtherScalar>
00817   static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
00818   {
00819     return abs2(x) <= abs2(y) * prec * prec;
00820   }
00821   static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
00822   {
00823     return abs2(x - y) <= std::min(abs2(x), abs2(y)) * prec * prec;
00824   }
00825 };
00826 
00827 template<typename Scalar>
00828 struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
00829 
00830 template<typename Scalar, typename OtherScalar>
00831 inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y,
00832                                    typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
00833 {
00834   return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision);
00835 }
00836 
00837 template<typename Scalar>
00838 inline bool isApprox(const Scalar& x, const Scalar& y,
00839                           typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
00840 {
00841   return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
00842 }
00843 
00844 template<typename Scalar>
00845 inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y,
00846                                     typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision())
00847 {
00848   return scalar_fuzzy_impl<Scalar>::isApproxOrLessThan(x, y, precision);
00849 }
00850 
00851 /******************************************
00852 ***  The special case of the  bool type ***
00853 ******************************************/
00854 
00855 template<> struct random_impl<bool>
00856 {
00857   static inline bool run()
00858   {
00859     return random<int>(0,1)==0 ? false : true;
00860   }
00861 };
00862 
00863 template<> struct scalar_fuzzy_impl<bool>
00864 {
00865   typedef bool RealScalar;
00866   
00867   template<typename OtherScalar>
00868   static inline bool isMuchSmallerThan(const bool& x, const bool&, const bool&)
00869   {
00870     return !x;
00871   }
00872   
00873   static inline bool isApprox(bool x, bool y, bool)
00874   {
00875     return x == y;
00876   }
00877 
00878   static inline bool isApproxOrLessThan(const bool& x, const bool& y, const bool&)
00879   {
00880     return (!x) || y;
00881   }
00882   
00883 };
00884 
00885 } // end namespace internal
00886 
00887 #endif // EIGEN_MATHFUNCTIONS_H



Page generated by Doxygen 1.7.3 for MRPT 0.9.4 SVN:exported at Tue Jan 25 21:56:31 UTC 2011