|
1 /* -*- C++ -*- |
|
2 * lemon/tolerance.h - Part of LEMON, a generic C++ optimization library |
|
3 * |
|
4 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
|
5 * (Egervary Research Group on Combinatorial Optimization, EGRES). |
|
6 * |
|
7 * Permission to use, modify and distribute this software is granted |
|
8 * provided that this copyright notice appears in all copies. For |
|
9 * precise terms see the accompanying LICENSE file. |
|
10 * |
|
11 * This software is provided "AS IS" with no warranty of any kind, |
|
12 * express or implied, and with no claim as to its suitability for any |
|
13 * purpose. |
|
14 * |
|
15 */ |
|
16 |
|
17 #ifndef LEMON_TOLERANCE_H |
|
18 #define LEMON_TOLERANCE_H |
|
19 |
|
20 ///\ingroup misc |
|
21 ///\file |
|
22 ///\brief A basic tool to handle the anomalies of calculation with |
|
23 ///floating point numbers. |
|
24 /// |
|
25 ///\todo It should be in a module like "Basic tools" |
|
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 ///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 ///This is an abstract class, it should be specialized for all numerical |
|
42 ///data types. These specialized classes like \ref Tolerance<double> |
|
43 ///may offer additional tuning parameters. |
|
44 /// |
|
45 ///\sa Tolerance<float> |
|
46 ///\sa Tolerance<double> |
|
47 ///\sa Tolerance<int> |
|
48 ///\sa Tolerance<long long int> |
|
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 with \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 |
|
64 static bool less(Value a,Value b) {return false;} |
|
65 ///Returns \c true if \c a is \e surely different from \c b |
|
66 static bool different(Value a,Value b) {return false;} |
|
67 ///Returns \c true if \c a is \e surely positive |
|
68 static bool positive(Value a) {return false;} |
|
69 ///Returns \c true if \c a is \e surely negative |
|
70 static bool negative(Value a) {return false;} |
|
71 ///Returns \c true if \c a is \e surely non-zero |
|
72 static bool nonZero(Value a) {return false;} |
|
73 |
|
74 ///@} |
|
75 |
|
76 ///Returns the zero value. |
|
77 static Value zero() {return T();} |
|
78 |
|
79 // static bool finite(Value a) {} |
|
80 // static Value big() {} |
|
81 // static Value negativeBig() {} |
|
82 }; |
|
83 |
|
84 |
|
85 ///Double specialization of \ref Tolerance. |
|
86 |
|
87 ///Double specialization of \ref Tolerance. |
|
88 ///\sa Tolerance |
|
89 ///\relates Tolerance |
|
90 template<> |
|
91 class Tolerance<double> |
|
92 { |
|
93 static double def_epsilon; |
|
94 double _epsilon; |
|
95 public: |
|
96 ///\e |
|
97 typedef double Value; |
|
98 |
|
99 ///Constructor setting the epsilon tolerance to the default value. |
|
100 Tolerance() : _epsilon(def_epsilon) {} |
|
101 ///Constructor setting the epsilon tolerance. |
|
102 Tolerance(double e) : _epsilon(e) {} |
|
103 |
|
104 ///Return the epsilon value. |
|
105 Value epsilon() {return _epsilon;} |
|
106 ///Set the epsilon value. |
|
107 void epsilon(Value e) {_epsilon=e;} |
|
108 |
|
109 ///Return the default epsilon value. |
|
110 static Value defaultEpsilon() {return def_epsilon;} |
|
111 ///Set the default epsilon value. |
|
112 static void defaultEpsilon(Value e) {def_epsilon=e;} |
|
113 |
|
114 ///\name Comparisons |
|
115 ///See class Tolerance for more details. |
|
116 |
|
117 ///@{ |
|
118 |
|
119 ///Returns \c true if \c a is \e surely strictly less than \c b |
|
120 bool less(Value a,Value b) {return a+_epsilon<b;} |
|
121 ///Returns \c true if \c a is \e surely different from \c b |
|
122 bool different(Value a,Value b) { return less(a,b)||less(b,a); } |
|
123 ///Returns \c true if \c a is \e surely positive |
|
124 bool positive(Value a) { return _epsilon<a; } |
|
125 ///Returns \c true if \c a is \e surely negative |
|
126 bool negative(Value a) { return -_epsilon>a; } |
|
127 ///Returns \c true if \c a is \e surely non-zero |
|
128 Value nonZero(Value a) { return positive(a)||negative(a); }; |
|
129 |
|
130 ///@} |
|
131 |
|
132 ///Returns zero |
|
133 static Value zero() {return 0;} |
|
134 }; |
|
135 |
|
136 ///Float specialization of \ref Tolerance. |
|
137 |
|
138 ///Float specialization of \ref Tolerance. |
|
139 ///\sa Tolerance |
|
140 ///\relates Tolerance |
|
141 template<> |
|
142 class Tolerance<float> |
|
143 { |
|
144 static float def_epsilon; |
|
145 float _epsilon; |
|
146 public: |
|
147 ///\e |
|
148 typedef float Value; |
|
149 |
|
150 ///Constructor setting the epsilon tolerance to the default value. |
|
151 Tolerance() : _epsilon(def_epsilon) {} |
|
152 ///Constructor setting the epsilon tolerance. |
|
153 Tolerance(float e) : _epsilon(e) {} |
|
154 |
|
155 ///Return the epsilon value. |
|
156 Value epsilon() {return _epsilon;} |
|
157 ///Set the epsilon value. |
|
158 void epsilon(Value e) {_epsilon=e;} |
|
159 |
|
160 ///Return the default epsilon value. |
|
161 static Value defaultEpsilon() {return def_epsilon;} |
|
162 ///Set the default epsilon value. |
|
163 static void defaultEpsilon(Value e) {def_epsilon=e;} |
|
164 |
|
165 ///\name Comparisons |
|
166 ///See class Tolerance for more details. |
|
167 |
|
168 ///@{ |
|
169 |
|
170 ///Returns \c true if \c a is \e surely strictly less than \c b |
|
171 bool less(Value a,Value b) {return a+_epsilon<b;} |
|
172 ///Returns \c true if \c a is \e surely different from \c b |
|
173 bool different(Value a,Value b) { return less(a,b)||less(b,a); } |
|
174 ///Returns \c true if \c a is \e surely positive |
|
175 bool positive(Value a) { return _epsilon<a; } |
|
176 ///Returns \c true if \c a is \e surely negative |
|
177 bool negative(Value a) { return -_epsilon>a; } |
|
178 ///Returns \c true if \c a is \e surely non-zero |
|
179 Value nonZero(Value a) { return positive(a)||negative(a); }; |
|
180 |
|
181 ///@} |
|
182 |
|
183 ///Returns zero |
|
184 static Value zero() {return 0;} |
|
185 }; |
|
186 |
|
187 ///Integer specialization of \ref Tolerance. |
|
188 |
|
189 ///Integer specialization of \ref Tolerance. |
|
190 ///\sa Tolerance |
|
191 template<> |
|
192 class Tolerance<int> |
|
193 { |
|
194 public: |
|
195 ///\e |
|
196 typedef int Value; |
|
197 |
|
198 ///\name Comparisons |
|
199 ///See \ref Tolerance for more details. |
|
200 |
|
201 ///@{ |
|
202 |
|
203 ///Returns \c true if \c a is \e surely strictly less than \c b |
|
204 static bool less(Value a,Value b) { return a<b;} |
|
205 ///Returns \c true if \c a is \e surely different from \c b |
|
206 static bool different(Value a,Value b) { return a!=b; } |
|
207 ///Returns \c true if \c a is \e surely positive |
|
208 static bool positive(Value a) { return 0<a; } |
|
209 ///Returns \c true if \c a is \e surely negative |
|
210 static bool negative(Value a) { return 0>a; } |
|
211 ///Returns \c true if \c a is \e surely non-zero |
|
212 static Value nonZero(Value a) { return a!=0;}; |
|
213 |
|
214 ///@} |
|
215 |
|
216 ///Returns zero |
|
217 static Value zero() {return 0;} |
|
218 }; |
|
219 |
|
220 ///Long long integer specialization of \ref Tolerance. |
|
221 |
|
222 ///Long long integer specialization of \ref Tolerance. |
|
223 ///\sa Tolerance |
|
224 template<> |
|
225 class Tolerance<long long int> |
|
226 { |
|
227 public: |
|
228 ///\e |
|
229 typedef long long int Value; |
|
230 |
|
231 ///\name Comparisons |
|
232 ///See \ref Tolerance for more details. |
|
233 |
|
234 ///@{ |
|
235 |
|
236 ///Returns \c true if \c a is \e surely strictly less than \c b |
|
237 static bool less(Value a,Value b) { return a<b;} |
|
238 ///Returns \c true if \c a is \e surely different from \c b |
|
239 static bool different(Value a,Value b) { return a!=b; } |
|
240 ///Returns \c true if \c a is \e surely positive |
|
241 static bool positive(Value a) { return 0<a; } |
|
242 ///Returns \c true if \c a is \e surely negative |
|
243 static bool negative(Value a) { return 0>a; } |
|
244 ///Returns \c true if \c a is \e surely non-zero |
|
245 static Value nonZero(Value a) { return a!=0;}; |
|
246 |
|
247 ///@} |
|
248 |
|
249 ///Returns zero |
|
250 static Value zero() {return 0;} |
|
251 }; |
|
252 |
|
253 /// @} |
|
254 |
|
255 } //namespace lemon |
|
256 |
|
257 #endif //LEMON_TOLERANCE_H |