| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

LHCbMath.h

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------------
00012 // ----------------------------------------------------------------------------
00013 #ifndef LHCBMATH_LHCBMATH_H 
00014 #define LHCBMATH_LHCBMATH_H 1
00015 // ============================================================================
00016 // Include files
00017 // ============================================================================
00018 // STD & STL 
00019 // ============================================================================
00020 #include <cmath>
00021 #include <algorithm>
00022 #include <functional>
00023 // ============================================================================
00024 // Boost 
00025 // ============================================================================
00026 #include "boost/call_traits.hpp"
00027 #include "boost/integer_traits.hpp"
00028 #include "boost/static_assert.hpp"
00029 // ============================================================================
00030 namespace LHCb 
00031 {
00032   // ==========================================================================
00036   namespace Math 
00037   {
00039     static const double hiTolerance    = 1e-40;
00040     static const double lowTolerance   = 1e-20;
00041     static const double looseTolerance = 1e-5;
00042     static const double     sqrt_12 = 3.4641016151377546; // sqrt(12.)
00043     static const double inv_sqrt_12 = 0.2886751345948129; // 1./sqrt(12.)
00044     // ========================================================================
00050     template <class TYPE>
00051     struct abs_less : std::binary_function<TYPE,TYPE,TYPE>
00052     {
00053       inline TYPE operator() 
00054         ( typename boost::call_traits<const TYPE>::param_type v1 ,
00055           typename boost::call_traits<const TYPE>::param_type v2 ) const 
00056       {
00057         return m_eval ( std::fabs( v1 ) , std::fabs( v2 ) ) ; 
00058       }
00060       std::less<TYPE> m_eval ;
00061     } ;
00062     // ========================================================================
00068     template <class TYPE>
00069     struct abs_greater : std::binary_function<TYPE,TYPE,TYPE>
00070     {
00071       inline TYPE operator() 
00072       ( typename boost::call_traits<const TYPE>::param_type v1 ,
00073         typename boost::call_traits<const TYPE>::param_type v2 ) const 
00074       {
00075         return m_eval ( std::fabs( v1 ) , std::fabs( v2 ) ) ; 
00076       }
00078       std::greater<TYPE> m_eval ;
00079     } ;
00080     // ========================================================================
00085     template <class TYPE> 
00086     inline TYPE absMin ( TYPE v1 , TYPE v2 ) 
00087     { return std::min ( std::fabs ( v1 ) , std::fabs ( v2 ) ) ; }
00088     // ========================================================================
00093     template <class TYPE> 
00094     inline TYPE absMax ( TYPE v1 , TYPE v2 ) 
00095     { return std::max ( std::fabs ( v1 ) , std::fabs ( v2 ) ) ; }
00096 
00097     // ========================================================================
00108     bool equal_to_double
00109     ( const double value1           ,
00110       const double value2           ,
00111       const double epsilon = 1.0e-6 ) ;
00112     // ========================================================================
00118     template <class TYPE>
00119     struct Equal_To : public std::binary_function<TYPE,TYPE,bool>
00120     {
00121       typedef typename boost::call_traits<const TYPE>::param_type T ;
00123       Equal_To ( T /* v */ ) {}
00125       inline bool operator() ( T v1 , T v2 ) const
00126       {
00127         std::equal_to<TYPE> cmp ;
00128         return cmp ( v1 , v2 ) ;
00129       }
00130     } ;
00131     // ========================================================================
00133     template <class TYPE>
00134     struct Equal_To<const TYPE>: public Equal_To<TYPE>{} ;
00135     // ========================================================================
00137     template <class TYPE>
00138     struct Equal_To<TYPE&>: public Equal_To<TYPE>{} ;
00139     // ========================================================================
00141     template <>
00142     struct Equal_To<double>
00143     {
00145       Equal_To ( const double eps = 1.0e-6 ) : m_eps ( eps ) {}
00147       inline bool operator() ( const double v1 , const double v2 ) const
00148       {
00149         return equal_to_double ( v1 , v2 , m_eps ) ;
00150       }
00151     private :
00153       double m_eps ;  // the precision 
00154     };
00155     // ========================================================================
00157     template <>
00158     struct Equal_To<long double>
00159     {
00161       Equal_To ( const long double eps = 1.0e-6 ) : m_eps ( eps ) {}
00163       inline bool operator() ( const long double v1 ,
00164                                const long double v2 ) const
00165       {
00166         return equal_to_double
00167           ( static_cast<double> ( v1    ) ,
00168             static_cast<double> ( v2    ) ,
00169             static_cast<double> ( m_eps ) ) ;
00170       }
00171     private :
00173       long double m_eps ; // the precision 
00174     };
00175     // ========================================================================
00177     template <>
00178     struct Equal_To<float>
00179     {
00181       Equal_To ( const float eps = 1.0e-6 ) : m_eps ( eps ) {}
00183       inline bool operator() ( const float v1 , const float v2 ) const
00184       {
00185         return equal_to_double ( v1 , v2 , m_eps ) ;
00186       }
00187     private :
00189       float m_eps ; // the precision 
00190     } ;
00191     // ========================================================================
00195     inline int round ( const double x )  {
00196       int i;
00197       LHCb::Math::Equal_To<double> equal_to(lowTolerance);
00198       if (x >= 0.0) {
00199         i = int(x + 0.5);
00200         if (equal_to(x + 0.5, double(i)) && i & 1) --i;
00201       }
00202       else {
00203         i = int(x - 0.5);
00204         if (equal_to(x - 0.5 , double(i)) && i & 1) ++i;
00205         
00206       }
00207       return i;
00208     }
00209     // ======================================================================== 
00213     inline int round ( const float x )  
00214     {
00215       return LHCb::Math::round ( double ( x ) ) ;
00216     }
00217     // ========================================================================
00226     inline bool equal_to_int 
00227     ( const double val          , 
00228       const int    ref          , 
00229       const double eps1 = 1.e-6 , 
00230       const double eps2 = 0.5e-3 / boost::integer_traits<int>::const_max )
00231     {
00232       BOOST_STATIC_ASSERT(boost::integer_traits<int>::is_specialized ) ;
00233       // 1) try the straightforward comparison 
00234       if ( val == ref                 ) { return true ; } // RETURN 
00235       // 2) check the limits 
00236       if ( val > boost::integer_traits<int>::const_max || 
00237            val < boost::integer_traits<int>::const_min ) { return false ; }
00238       // 3) compare the doubles 
00239       if ( std::fabs ( val - ref ) <= eps1 ) { return true  ; }
00240       // 3') compare the doubles  
00241       LHCb::Math::Equal_To<double> cmp ( eps2 ) ;
00242       return cmp ( val , ref ) ;
00243     }
00244     // ========================================================================
00253     inline bool equal_to_int 
00254     ( const int    ref          , 
00255       const double val          , 
00256       const double eps1 = 1.e-6 , 
00257       const double eps2 = 0.5e-3 / boost::integer_traits<int>::const_max ) 
00258     { 
00259       BOOST_STATIC_ASSERT(boost::integer_traits<int>::is_specialized ) ;
00260       return equal_to_int ( val , ref , eps1 , eps2 ) ; 
00261     }
00262     // ========================================================================
00271     inline bool equal_to_uint 
00272     ( const double       val         , 
00273       const unsigned int ref         , 
00274       const double eps1 = 1.e-6      , 
00275       const double eps2 = 1.e-3 / boost::integer_traits<unsigned int>::const_max )
00276     {
00277       BOOST_STATIC_ASSERT(boost::integer_traits<unsigned int>::is_specialized ) ;
00278       // 1) straightforward comparison 
00279       if ( val == ref ) { return true ; }                             // RETURN 
00280       // check the limits 
00281       if ( val > boost::integer_traits<unsigned int>::const_max || 
00282            val < boost::integer_traits<unsigned int>::const_min ) { return false ; }
00283       // 3) compare the doubles 
00284       if ( std::fabs ( val - ref ) <= eps1 ) { return true  ; }
00285       // 3') compare the doubles  
00286       LHCb::Math::Equal_To<double> cmp ( eps2 ) ;
00287       return cmp ( val , ref ) ;
00288     }
00289     // ========================================================================
00297     inline bool equal_to_uint 
00298     ( const unsigned int ref          , 
00299       const double       val          ,
00300       const double       eps1 = 1.e-6 , 
00301       const double       eps2 = 1.e-3 / boost::integer_traits<unsigned int>::const_max )
00302     { return equal_to_uint ( val , ref , eps1 , eps2 ) ; }
00303     // ========================================================================
00304   } // end of namespace LHcb::Math 
00305   // ==========================================================================
00306 } // end of namespace LHCb 
00307 // ============================================================================
00308 // The END 
00309 // ============================================================================
00310 #endif // LHCBMATH_LHCBMATH_H
00311 // ============================================================================
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:02:57 2011 for LHCbMath by doxygen 1.4.7