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