Classes | |
struct | abs_less |
comparison by absolute value More... | |
struct | abs_greater |
comparison by absolute value More... | |
struct | Equal_To |
helper structure for comparison of floating values More... | |
struct | Equal_To< const TYPE > |
partial specialization for const-types More... | |
struct | Equal_To< TYPE & > |
partial specialization for references More... | |
struct | Equal_To< double > |
explicit specialization for doubles More... | |
struct | Equal_To< long double > |
explicit specialization for long doubles More... | |
struct | Equal_To< float > |
explicit specialization for floats More... | |
Functions | |
bool | equal_to_double (const double value1, const double value2, const double epsilon=1.0e-6) |
compare two double numbers with relative precision 'epsilon' | |
bool | lomont_compare_float (const float af, const float bf, const unsigned short maxULPs=100) |
equality comparison of float numbers using as the metric the maximal number of Units in the Last Place (ULP). | |
float | next_float (const float af, const short ulps) |
Get the floating number that representation is different with respect to the argument for the certain number of "Units in the Last Position". | |
bool | lomont_compare_double (const double af, const double bf, const unsigned int maxULPs) |
equality comparison of float numbers using as the metric the maximal number of Units in the Last Place (ULP). | |
double | next_double (const double af, const short ulps) |
Get the floating number that representation is different with respect to the argument for the certain number of "Units in the Last Position". | |
template<class TYPE> | |
TYPE | absMin (TYPE v1, TYPE v2) |
return "min_by_abs" | |
template<class TYPE> | |
TYPE | absMax (TYPE v1, TYPE v2) |
return "max_by_abs" | |
int | round (const double x) |
Round to nearest integer. | |
int | round (const float x) |
Round to nearest integer. | |
bool | equal_to_int (const double val, const int ref, const double eps1=1.e-6, const double eps2=0.5e-3/boost::integer_traits< int >::const_max) |
check if the double value is actually equal to the integer value | |
bool | equal_to_int (const int ref, const double val, const double eps1=1.e-6, const double eps2=0.5e-3/boost::integer_traits< int >::const_max) |
check if the double value is actually equal to the integer value | |
bool | equal_to_uint (const double val, const unsigned int ref, const double eps1=1.e-6, const double eps2=1.e-3/boost::integer_traits< unsigned int >::const_max) |
check if the double value is actually equal to the unsigned integer value | |
bool | equal_to_uint (const unsigned int ref, const double val, const double eps1=1.e-6, const double eps2=1.e-3/boost::integer_traits< unsigned int >::const_max) |
check if the double value is actually equal to the integer value | |
Variables | |
static const double | hiTolerance = 1e-40 |
Parameters for numerical calculations (M.Needham). | |
static const double | lowTolerance = 1e-20 |
static const double | looseTolerance = 1e-5 |
static const double | sqrt_12 = 3.4641016151377546 |
static const double | inv_sqrt_12 = 0.2886751345948129 |
bool LHCb::Math::equal_to_double | ( | const double | value1, | |
const double | value2, | |||
const double | epsilon = 1.0e-6 | |||
) |
compare two double numbers with relative precision 'epsilon'
Essentially it is a wrapper to gsl_fcmp function from GSL library See D.E.Knuth, "Seminumerical Algorithms", section 4.2.2
Definition at line 32 of file LHCbMath.cpp.
00035 { 00036 return 00037 !epsilon ? 0 == gsl_fcmp ( value1 , value2 , 1.0e-6 ) : 00038 0 < epsilon ? 0 == gsl_fcmp ( value1 , value2 , epsilon ) : 00039 0 == gsl_fcmp ( value1 , value2 , -epsilon ) ; 00040 }
bool LHCb::Math::lomont_compare_float | ( | const float | af, | |
const float | bf, | |||
const unsigned short | maxULPs = 100 | |||
) |
equality comparison of float numbers using as the metric the maximal number of Units in the Last Place (ULP).
It is a slightly modified version of very efficient implementation of the initial Bruce Dawson's algorithm by Chris Lomont.
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
The effective relative difference depends on the choice of maxULPS
:
af | the first number | |
bf | the second number | |
maxULPS | the maximal metric deciation in the terms of maximal number of units in the last place |
Definition at line 63 of file Lomont.cpp.
00066 { 00067 // ========================================================================== 00068 // prerequisites: 00069 BOOST_STATIC_ASSERT( std::numeric_limits<float> ::is_specialized && 00070 boost::integer_traits<int> ::is_specialized && 00071 boost::integer_traits<unsigned int> ::is_specialized && 00072 sizeof(float)==sizeof(int) && 00073 sizeof(float)==sizeof(unsigned int) && 00074 32 == boost::integer_traits<unsigned int>::digits ) ; 00075 // ========================================================================== 00076 00077 int ai = *reinterpret_cast<const int*>( &af ) ; 00078 int bi = *reinterpret_cast<const int*>( &bf ) ; 00079 00080 int test = (((unsigned int)(ai^bi))>>31)-1; 00081 00082 // assert ( (0==test) || ( boost::integer_traits<unsigned int>::const_max == test ) ) ; 00083 00084 int diff = ((( boost::integer_traits<int>::const_min - ai ) & (~test)) | ( ai& test )) - bi ; 00085 00086 int maxDiff_ = maxULPs ; 00087 00088 int v1 = maxDiff_ + diff ; 00089 int v2 = maxDiff_ - diff ; 00090 00091 return 0<=(v1|v2) ; 00092 }
float LHCb::Math::next_float | ( | const float | af, | |
const short | ulps | |||
) |
Get the floating number that representation is different with respect to the argument for the certain number of "Units in the Last Position".
For ulps=1, it is just next float number, for ulps=-1 is is the previous one.
This routine is very convinient to test the parameter maxULPS for the routine LHCb::Math::lomont_compare_float
af | the reference number | |
ulps | the bias |
Definition at line 111 of file Lomont.cpp.
00112 { 00114 BOOST_STATIC_ASSERT( std::numeric_limits<float> ::is_specialized && 00115 std::numeric_limits<int> ::is_specialized && 00116 sizeof(float)==sizeof(int) ) ; 00117 00118 int ai = *reinterpret_cast<const int*>( &af ) ; 00119 ai += ulps ; 00120 return *reinterpret_cast<float*>(&ai) ; 00121 }
bool LHCb::Math::lomont_compare_double | ( | const double | af, | |
const double | bf, | |||
const unsigned int | maxULPs | |||
) |
equality comparison of float numbers using as the metric the maximal number of Units in the Last Place (ULP).
It is a slightly modified version of very efficient implementation of the initial Bruce Dawson's algorithm by Chris Lomont.
http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
The effective relative difference depends on the choice of maxULPS
:
af | the first number | |
bf | the second number | |
maxULPS | the maximal metric deciation in the terms of maximal number of units in the last place |
Definition at line 193 of file Lomont.cpp.
00196 { 00198 BOOST_STATIC_ASSERT( std::numeric_limits<double> ::is_specialized && 00199 std::numeric_limits<Long> ::is_specialized && 00200 std::numeric_limits<ULong> ::is_specialized && 00201 boost::integer_traits<ULong> ::is_specialized && 00202 boost::integer_traits<Long> ::is_specialized && 00203 sizeof(double)==sizeof(Long) && 00204 sizeof(double)==sizeof(ULong) && 00205 64 == std::numeric_limits<ULong>::digits ) ; 00206 00207 Long ai = *reinterpret_cast<const Long*>( &af ) ; 00208 Long bi = *reinterpret_cast<const Long*>( &bf ) ; 00209 00210 Long test = (((ULong)(ai^bi))>>63)-1; 00211 00212 // assert ( (0==test) || ( boost::integer_traits<ULong>::const_max == test ) ) ; 00213 00214 Long diff = ((( boost::integer_traits<Long>::const_min - ai ) & (~test)) | ( ai& test )) - bi ; 00215 00216 Long maxDiff_ = maxULPs ; 00217 00218 Long v1 = maxDiff_ + diff ; 00219 Long v2 = maxDiff_ - diff ; 00220 00221 return 0<=(v1|v2) ; 00222 }
double LHCb::Math::next_double | ( | const double | af, | |
const short | ulps | |||
) |
Get the floating number that representation is different with respect to the argument for the certain number of "Units in the Last Position".
For ulps=1, it is just next float number, for ulps=-1 is is the previous one.
This routine is very convinient to test the parameter maxULPS for the routine LHCb::Math::lomont_compare_float
af | the reference number | |
ulps | the bias |
Definition at line 241 of file Lomont.cpp.
00242 { 00244 BOOST_STATIC_ASSERT( std::numeric_limits<double> ::is_specialized && 00245 std::numeric_limits<Long> ::is_specialized && 00246 sizeof(double)==sizeof(Long) ) ; 00247 00248 Long al = *reinterpret_cast<const Long*>( &ad ) ; 00249 al += ulps ; 00250 return *reinterpret_cast<double*>(&al) ; 00251 }
TYPE LHCb::Math::absMin | ( | TYPE | v1, | |
TYPE | v2 | |||
) | [inline] |
return "min_by_abs"
Definition at line 86 of file LHCbMath.h.
TYPE LHCb::Math::absMax | ( | TYPE | v1, | |
TYPE | v2 | |||
) | [inline] |
return "max_by_abs"
Definition at line 94 of file LHCbMath.h.
int LHCb::Math::round | ( | const double | x | ) | [inline] |
Round to nearest integer.
Rounds half integers to nearest even integer.
Definition at line 195 of file LHCbMath.h.
00195 { 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 }
int LHCb::Math::round | ( | const float | x | ) | [inline] |
Round to nearest integer.
Rounds half integers to nearest even integer.
Definition at line 213 of file LHCbMath.h.
00214 { 00215 return LHCb::Math::round ( double ( x ) ) ; 00216 }
bool LHCb::Math::equal_to_int | ( | const double | val, | |
const int | ref, | |||
const double | eps1 = 1.e-6 , |
|||
const double | eps2 = 0.5e-3 / boost::integer_traits<int>::const_max | |||
) | [inline] |
check if the double value is actually equal to the integer value
val | value to be compared with the integer | |
ref | the reference integer number | |
eps1 | the absolute precision | |
eps2 | the relative precision |
Definition at line 227 of file LHCbMath.h.
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 }
bool LHCb::Math::equal_to_int | ( | const int | ref, | |
const double | val, | |||
const double | eps1 = 1.e-6 , |
|||
const double | eps2 = 0.5e-3 / boost::integer_traits<int>::const_max | |||
) | [inline] |
check if the double value is actually equal to the integer value
ref | the reference integer number | |
val | value to be compared with the integer | |
eps1 | the absolute precision | |
eps2 | the relative precision |
Definition at line 254 of file LHCbMath.h.
00258 { 00259 BOOST_STATIC_ASSERT(boost::integer_traits<int>::is_specialized ) ; 00260 return equal_to_int ( val , ref , eps1 , eps2 ) ; 00261 }
bool LHCb::Math::equal_to_uint | ( | const double | val, | |
const unsigned int | ref, | |||
const double | eps1 = 1.e-6 , |
|||
const double | eps2 = 1.e-3 / boost::integer_traits<unsigned int>::const_max | |||
) | [inline] |
check if the double value is actually equal to the unsigned integer value
val | value to be compared with the unsigned integer | |
ref | the reference unsigned integer number | |
eps1 | the absolute precision | |
eps2 | the relative precision |
Definition at line 272 of file LHCbMath.h.
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 }
bool LHCb::Math::equal_to_uint | ( | const unsigned int | ref, | |
const double | val, | |||
const double | eps1 = 1.e-6 , |
|||
const double | eps2 = 1.e-3 / boost::integer_traits<unsigned int>::const_max | |||
) | [inline] |
check if the double value is actually equal to the integer value
val | value to be compared with the unsigned integer | |
ref | the reference unsigned integer number | |
eps | the absolute precision |
Definition at line 298 of file LHCbMath.h.
00302 { return equal_to_uint ( val , ref , eps1 , eps2 ) ; }
const double LHCb::Math::hiTolerance = 1e-40 [static] |
const double LHCb::Math::lowTolerance = 1e-20 [static] |
Definition at line 40 of file LHCbMath.h.
const double LHCb::Math::looseTolerance = 1e-5 [static] |
Definition at line 41 of file LHCbMath.h.
const double LHCb::Math::sqrt_12 = 3.4641016151377546 [static] |
Definition at line 42 of file LHCbMath.h.
const double LHCb::Math::inv_sqrt_12 = 0.2886751345948129 [static] |
Definition at line 43 of file LHCbMath.h.