1 /* -*- mode: C++; indent-tabs-mode: nil; -*- 2 * 3 * This file is a part of LEMON, a generic C++ optimization library. 4 * 5 * Copyright (C) 2003-2009 6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport 7 * (Egervary Research Group on Combinatorial Optimization, EGRES). 8 * 9 * Permission to use, modify and distribute this software is granted 10 * provided that this copyright notice appears in all copies. For 11 * precise terms see the accompanying LICENSE file. 12 * 13 * This software is provided "AS IS" with no warranty of any kind, 14 * express or implied, and with no claim as to its suitability for any 15 * purpose. 16 * 17 */ 18 19 #ifndef LEMON_TOLERANCE_H 20 #define LEMON_TOLERANCE_H 21 22 ///\ingroup misc 23 ///\file 24 ///\brief A basic tool to handle the anomalies of calculation with 25 ///floating point numbers. 26 /// 27 28 namespace lemon { 29 30 /// \addtogroup misc 31 /// @{ 32 33 ///\brief A class to provide a basic way to 34 ///handle the comparison of numbers that are obtained 35 ///as a result of a probably inexact computation. 36 /// 37 ///\ref Tolerance is a class to provide a basic way to 38 ///handle the comparison of numbers that are obtained 39 ///as a result of a probably inexact computation. 40 /// 41 ///The general implementation is suitable only if the data type is exact, 42 ///like the integer types, otherwise a specialized version must be 43 ///implemented. These specialized classes like 44 ///Tolerance<double> may offer additional tuning parameters. 45 /// 46 ///\sa Tolerance<float> 47 ///\sa Tolerance<double> 48 ///\sa Tolerance<long double> 49 50 template<class T> 51 class Tolerance 52 { 53 public: 54 typedef T Value; 55 56 ///\name Comparisons 57 ///The concept is that these bool functions return \c true only if 58 ///the related comparisons hold even if some numerical error appeared 59 ///during the computations. 60 61 ///@{ 62 63 ///Returns \c true if \c a is \e surely strictly less than \c b less(Value a,Value b)64 static bool less(Value a,Value b) {return a<b;} 65 ///Returns \c true if \c a is \e surely different from \c b different(Value a,Value b)66 static bool different(Value a,Value b) {return a!=b;} 67 ///Returns \c true if \c a is \e surely positive positive(Value a)68 static bool positive(Value a) {return static_cast<Value>(0) < a;} 69 ///Returns \c true if \c a is \e surely negative negative(Value a)70 static bool negative(Value a) {return a < static_cast<Value>(0);} 71 ///Returns \c true if \c a is \e surely non-zero nonZero(Value a)72 static bool nonZero(Value a) {return a != static_cast<Value>(0);} 73 74 ///@} 75 76 ///Returns the zero value. zero()77 static Value zero() {return static_cast<Value>(0);} 78 79 // static bool finite(Value a) {} 80 // static Value big() {} 81 // static Value negativeBig() {} 82 }; 83 84 85 ///Float specialization of Tolerance. 86 87 ///Float specialization of Tolerance. 88 ///\sa Tolerance 89 ///\relates Tolerance 90 template<> 91 class Tolerance<float> 92 { 93 static float def_epsilon; 94 float _epsilon; 95 public: 96 ///\e 97 typedef float Value; 98 99 ///Constructor setting the epsilon tolerance to the default value. Tolerance()100 Tolerance() : _epsilon(def_epsilon) {} 101 ///Constructor setting the epsilon tolerance to the given value. Tolerance(float e)102 Tolerance(float e) : _epsilon(e) {} 103 104 ///Returns the epsilon value. epsilon()105 Value epsilon() const {return _epsilon;} 106 ///Sets the epsilon value. epsilon(Value e)107 void epsilon(Value e) {_epsilon=e;} 108 109 ///Returns the default epsilon value. defaultEpsilon()110 static Value defaultEpsilon() {return def_epsilon;} 111 ///Sets the default epsilon value. defaultEpsilon(Value e)112 static void defaultEpsilon(Value e) {def_epsilon=e;} 113 114 ///\name Comparisons 115 ///See \ref lemon::Tolerance "Tolerance" for more details. 116 117 ///@{ 118 119 ///Returns \c true if \c a is \e surely strictly less than \c b less(Value a,Value b)120 bool less(Value a,Value b) const {return a+_epsilon<b;} 121 ///Returns \c true if \c a is \e surely different from \c b different(Value a,Value b)122 bool different(Value a,Value b) const { return less(a,b)||less(b,a); } 123 ///Returns \c true if \c a is \e surely positive positive(Value a)124 bool positive(Value a) const { return _epsilon<a; } 125 ///Returns \c true if \c a is \e surely negative negative(Value a)126 bool negative(Value a) const { return -_epsilon>a; } 127 ///Returns \c true if \c a is \e surely non-zero nonZero(Value a)128 bool nonZero(Value a) const { return positive(a)||negative(a); } 129 130 ///@} 131 132 ///Returns zero zero()133 static Value zero() {return 0;} 134 }; 135 136 ///Double specialization of Tolerance. 137 138 ///Double specialization of Tolerance. 139 ///\sa Tolerance 140 ///\relates Tolerance 141 template<> 142 class Tolerance<double> 143 { 144 static double def_epsilon; 145 double _epsilon; 146 public: 147 ///\e 148 typedef double Value; 149 150 ///Constructor setting the epsilon tolerance to the default value. Tolerance()151 Tolerance() : _epsilon(def_epsilon) {} 152 ///Constructor setting the epsilon tolerance to the given value. Tolerance(double e)153 Tolerance(double e) : _epsilon(e) {} 154 155 ///Returns the epsilon value. epsilon()156 Value epsilon() const {return _epsilon;} 157 ///Sets the epsilon value. epsilon(Value e)158 void epsilon(Value e) {_epsilon=e;} 159 160 ///Returns the default epsilon value. defaultEpsilon()161 static Value defaultEpsilon() {return def_epsilon;} 162 ///Sets the default epsilon value. defaultEpsilon(Value e)163 static void defaultEpsilon(Value e) {def_epsilon=e;} 164 165 ///\name Comparisons 166 ///See \ref lemon::Tolerance "Tolerance" for more details. 167 168 ///@{ 169 170 ///Returns \c true if \c a is \e surely strictly less than \c b less(Value a,Value b)171 bool less(Value a,Value b) const {return a+_epsilon<b;} 172 ///Returns \c true if \c a is \e surely different from \c b different(Value a,Value b)173 bool different(Value a,Value b) const { return less(a,b)||less(b,a); } 174 ///Returns \c true if \c a is \e surely positive positive(Value a)175 bool positive(Value a) const { return _epsilon<a; } 176 ///Returns \c true if \c a is \e surely negative negative(Value a)177 bool negative(Value a) const { return -_epsilon>a; } 178 ///Returns \c true if \c a is \e surely non-zero nonZero(Value a)179 bool nonZero(Value a) const { return positive(a)||negative(a); } 180 181 ///@} 182 183 ///Returns zero zero()184 static Value zero() {return 0;} 185 }; 186 187 ///Long double specialization of Tolerance. 188 189 ///Long double specialization of Tolerance. 190 ///\sa Tolerance 191 ///\relates Tolerance 192 template<> 193 class Tolerance<long double> 194 { 195 static long double def_epsilon; 196 long double _epsilon; 197 public: 198 ///\e 199 typedef long double Value; 200 201 ///Constructor setting the epsilon tolerance to the default value. Tolerance()202 Tolerance() : _epsilon(def_epsilon) {} 203 ///Constructor setting the epsilon tolerance to the given value. Tolerance(long double e)204 Tolerance(long double e) : _epsilon(e) {} 205 206 ///Returns the epsilon value. epsilon()207 Value epsilon() const {return _epsilon;} 208 ///Sets the epsilon value. epsilon(Value e)209 void epsilon(Value e) {_epsilon=e;} 210 211 ///Returns the default epsilon value. defaultEpsilon()212 static Value defaultEpsilon() {return def_epsilon;} 213 ///Sets the default epsilon value. defaultEpsilon(Value e)214 static void defaultEpsilon(Value e) {def_epsilon=e;} 215 216 ///\name Comparisons 217 ///See \ref lemon::Tolerance "Tolerance" for more details. 218 219 ///@{ 220 221 ///Returns \c true if \c a is \e surely strictly less than \c b less(Value a,Value b)222 bool less(Value a,Value b) const {return a+_epsilon<b;} 223 ///Returns \c true if \c a is \e surely different from \c b different(Value a,Value b)224 bool different(Value a,Value b) const { return less(a,b)||less(b,a); } 225 ///Returns \c true if \c a is \e surely positive positive(Value a)226 bool positive(Value a) const { return _epsilon<a; } 227 ///Returns \c true if \c a is \e surely negative negative(Value a)228 bool negative(Value a) const { return -_epsilon>a; } 229 ///Returns \c true if \c a is \e surely non-zero nonZero(Value a)230 bool nonZero(Value a) const { return positive(a)||negative(a); } 231 232 ///@} 233 234 ///Returns zero zero()235 static Value zero() {return 0;} 236 }; 237 238 /// @} 239 240 } //namespace lemon 241 242 #endif //LEMON_TOLERANCE_H 243