1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/lemon/tolerance.h Thu Dec 20 15:59:06 2007 +0000
1.3 @@ -0,0 +1,454 @@
1.4 +/* -*- C++ -*-
1.5 + *
1.6 + * This file is a part of LEMON, a generic C++ optimization library
1.7 + *
1.8 + * Copyright (C) 2003-2007
1.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
1.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
1.11 + *
1.12 + * Permission to use, modify and distribute this software is granted
1.13 + * provided that this copyright notice appears in all copies. For
1.14 + * precise terms see the accompanying LICENSE file.
1.15 + *
1.16 + * This software is provided "AS IS" with no warranty of any kind,
1.17 + * express or implied, and with no claim as to its suitability for any
1.18 + * purpose.
1.19 + *
1.20 + */
1.21 +
1.22 +#ifndef LEMON_TOLERANCE_H
1.23 +#define LEMON_TOLERANCE_H
1.24 +
1.25 +///\ingroup misc
1.26 +///\file
1.27 +///\brief A basic tool to handle the anomalies of calculation with
1.28 +///floating point numbers.
1.29 +///
1.30 +///\todo It should be in a module like "Basic tools"
1.31 +
1.32 +
1.33 +namespace lemon {
1.34 +
1.35 + /// \addtogroup misc
1.36 + /// @{
1.37 +
1.38 + ///\brief A class to provide a basic way to
1.39 + ///handle the comparison of numbers that are obtained
1.40 + ///as a result of a probably inexact computation.
1.41 + ///
1.42 + ///Tolerance is a class to provide a basic way to
1.43 + ///handle the comparison of numbers that are obtained
1.44 + ///as a result of a probably inexact computation.
1.45 + ///
1.46 + ///This is an abstract class, it should be specialized for all numerical
1.47 + ///data types. These specialized classes like \ref Tolerance\<double\>
1.48 + ///may offer additional tuning parameters.
1.49 + ///
1.50 + ///\sa Tolerance<float>
1.51 + ///\sa Tolerance<double>
1.52 + ///\sa Tolerance<long double>
1.53 + ///\sa Tolerance<int>
1.54 + ///\sa Tolerance<long long int>
1.55 + ///\sa Tolerance<unsigned int>
1.56 + ///\sa Tolerance<unsigned long long int>
1.57 +
1.58 + template<class T>
1.59 + class Tolerance
1.60 + {
1.61 + public:
1.62 + typedef T Value;
1.63 +
1.64 + ///\name Comparisons
1.65 + ///The concept is that these bool functions return with \c true only if
1.66 + ///the related comparisons hold even if some numerical error appeared
1.67 + ///during the computations.
1.68 +
1.69 + ///@{
1.70 +
1.71 + ///Returns \c true if \c a is \e surely strictly less than \c b
1.72 + static bool less(Value a,Value b) {return false;}
1.73 + ///Returns \c true if \c a is \e surely different from \c b
1.74 + static bool different(Value a,Value b) {return false;}
1.75 + ///Returns \c true if \c a is \e surely positive
1.76 + static bool positive(Value a) {return false;}
1.77 + ///Returns \c true if \c a is \e surely negative
1.78 + static bool negative(Value a) {return false;}
1.79 + ///Returns \c true if \c a is \e surely non-zero
1.80 + static bool nonZero(Value a) {return false;}
1.81 +
1.82 + ///@}
1.83 +
1.84 + ///Returns the zero value.
1.85 + static Value zero() {return T();}
1.86 +
1.87 + // static bool finite(Value a) {}
1.88 + // static Value big() {}
1.89 + // static Value negativeBig() {}
1.90 + };
1.91 +
1.92 +
1.93 + ///Float specialization of \ref Tolerance.
1.94 +
1.95 + ///Float specialization of \ref Tolerance.
1.96 + ///\sa Tolerance
1.97 + ///\relates Tolerance
1.98 + template<>
1.99 + class Tolerance<float>
1.100 + {
1.101 + static float def_epsilon;
1.102 + float _epsilon;
1.103 + public:
1.104 + ///\e
1.105 + typedef float Value;
1.106 +
1.107 + ///Constructor setting the epsilon tolerance to the default value.
1.108 + Tolerance() : _epsilon(def_epsilon) {}
1.109 + ///Constructor setting the epsilon tolerance.
1.110 + Tolerance(float e) : _epsilon(e) {}
1.111 +
1.112 + ///Return the epsilon value.
1.113 + Value epsilon() const {return _epsilon;}
1.114 + ///Set the epsilon value.
1.115 + void epsilon(Value e) {_epsilon=e;}
1.116 +
1.117 + ///Return the default epsilon value.
1.118 + static Value defaultEpsilon() {return def_epsilon;}
1.119 + ///Set the default epsilon value.
1.120 + static void defaultEpsilon(Value e) {def_epsilon=e;}
1.121 +
1.122 + ///\name Comparisons
1.123 + ///See class Tolerance for more details.
1.124 +
1.125 + ///@{
1.126 +
1.127 + ///Returns \c true if \c a is \e surely strictly less than \c b
1.128 + bool less(Value a,Value b) const {return a+_epsilon<b;}
1.129 + ///Returns \c true if \c a is \e surely different from \c b
1.130 + bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
1.131 + ///Returns \c true if \c a is \e surely positive
1.132 + bool positive(Value a) const { return _epsilon<a; }
1.133 + ///Returns \c true if \c a is \e surely negative
1.134 + bool negative(Value a) const { return -_epsilon>a; }
1.135 + ///Returns \c true if \c a is \e surely non-zero
1.136 + bool nonZero(Value a) const { return positive(a)||negative(a); };
1.137 +
1.138 + ///@}
1.139 +
1.140 + ///Returns zero
1.141 + static Value zero() {return 0;}
1.142 + };
1.143 +
1.144 + ///Double specialization of \ref Tolerance.
1.145 +
1.146 + ///Double specialization of \ref Tolerance.
1.147 + ///\sa Tolerance
1.148 + ///\relates Tolerance
1.149 + template<>
1.150 + class Tolerance<double>
1.151 + {
1.152 + static double def_epsilon;
1.153 + double _epsilon;
1.154 + public:
1.155 + ///\e
1.156 + typedef double Value;
1.157 +
1.158 + ///Constructor setting the epsilon tolerance to the default value.
1.159 + Tolerance() : _epsilon(def_epsilon) {}
1.160 + ///Constructor setting the epsilon tolerance.
1.161 + Tolerance(double e) : _epsilon(e) {}
1.162 +
1.163 + ///Return the epsilon value.
1.164 + Value epsilon() const {return _epsilon;}
1.165 + ///Set the epsilon value.
1.166 + void epsilon(Value e) {_epsilon=e;}
1.167 +
1.168 + ///Return the default epsilon value.
1.169 + static Value defaultEpsilon() {return def_epsilon;}
1.170 + ///Set the default epsilon value.
1.171 + static void defaultEpsilon(Value e) {def_epsilon=e;}
1.172 +
1.173 + ///\name Comparisons
1.174 + ///See class Tolerance for more details.
1.175 +
1.176 + ///@{
1.177 +
1.178 + ///Returns \c true if \c a is \e surely strictly less than \c b
1.179 + bool less(Value a,Value b) const {return a+_epsilon<b;}
1.180 + ///Returns \c true if \c a is \e surely different from \c b
1.181 + bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
1.182 + ///Returns \c true if \c a is \e surely positive
1.183 + bool positive(Value a) const { return _epsilon<a; }
1.184 + ///Returns \c true if \c a is \e surely negative
1.185 + bool negative(Value a) const { return -_epsilon>a; }
1.186 + ///Returns \c true if \c a is \e surely non-zero
1.187 + bool nonZero(Value a) const { return positive(a)||negative(a); };
1.188 +
1.189 + ///@}
1.190 +
1.191 + ///Returns zero
1.192 + static Value zero() {return 0;}
1.193 + };
1.194 +
1.195 + ///Long double specialization of \ref Tolerance.
1.196 +
1.197 + ///Long double specialization of \ref Tolerance.
1.198 + ///\sa Tolerance
1.199 + ///\relates Tolerance
1.200 + template<>
1.201 + class Tolerance<long double>
1.202 + {
1.203 + static long double def_epsilon;
1.204 + long double _epsilon;
1.205 + public:
1.206 + ///\e
1.207 + typedef long double Value;
1.208 +
1.209 + ///Constructor setting the epsilon tolerance to the default value.
1.210 + Tolerance() : _epsilon(def_epsilon) {}
1.211 + ///Constructor setting the epsilon tolerance.
1.212 + Tolerance(long double e) : _epsilon(e) {}
1.213 +
1.214 + ///Return the epsilon value.
1.215 + Value epsilon() const {return _epsilon;}
1.216 + ///Set the epsilon value.
1.217 + void epsilon(Value e) {_epsilon=e;}
1.218 +
1.219 + ///Return the default epsilon value.
1.220 + static Value defaultEpsilon() {return def_epsilon;}
1.221 + ///Set the default epsilon value.
1.222 + static void defaultEpsilon(Value e) {def_epsilon=e;}
1.223 +
1.224 + ///\name Comparisons
1.225 + ///See class Tolerance for more details.
1.226 +
1.227 + ///@{
1.228 +
1.229 + ///Returns \c true if \c a is \e surely strictly less than \c b
1.230 + bool less(Value a,Value b) const {return a+_epsilon<b;}
1.231 + ///Returns \c true if \c a is \e surely different from \c b
1.232 + bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
1.233 + ///Returns \c true if \c a is \e surely positive
1.234 + bool positive(Value a) const { return _epsilon<a; }
1.235 + ///Returns \c true if \c a is \e surely negative
1.236 + bool negative(Value a) const { return -_epsilon>a; }
1.237 + ///Returns \c true if \c a is \e surely non-zero
1.238 + bool nonZero(Value a) const { return positive(a)||negative(a); };
1.239 +
1.240 + ///@}
1.241 +
1.242 + ///Returns zero
1.243 + static Value zero() {return 0;}
1.244 + };
1.245 +
1.246 + ///Integer specialization of \ref Tolerance.
1.247 +
1.248 + ///Integer specialization of \ref Tolerance.
1.249 + ///\sa Tolerance
1.250 + template<>
1.251 + class Tolerance<int>
1.252 + {
1.253 + public:
1.254 + ///\e
1.255 + typedef int Value;
1.256 +
1.257 + ///\name Comparisons
1.258 + ///See \ref Tolerance for more details.
1.259 +
1.260 + ///@{
1.261 +
1.262 + ///Returns \c true if \c a is \e surely strictly less than \c b
1.263 + static bool less(Value a,Value b) { return a<b;}
1.264 + ///Returns \c true if \c a is \e surely different from \c b
1.265 + static bool different(Value a,Value b) { return a!=b; }
1.266 + ///Returns \c true if \c a is \e surely positive
1.267 + static bool positive(Value a) { return 0<a; }
1.268 + ///Returns \c true if \c a is \e surely negative
1.269 + static bool negative(Value a) { return 0>a; }
1.270 + ///Returns \c true if \c a is \e surely non-zero
1.271 + static bool nonZero(Value a) { return a!=0; };
1.272 +
1.273 + ///@}
1.274 +
1.275 + ///Returns zero
1.276 + static Value zero() {return 0;}
1.277 + };
1.278 +
1.279 + ///Unsigned integer specialization of \ref Tolerance.
1.280 +
1.281 + ///Unsigned integer specialization of \ref Tolerance.
1.282 + ///\sa Tolerance
1.283 + template<>
1.284 + class Tolerance<unsigned int>
1.285 + {
1.286 + public:
1.287 + ///\e
1.288 + typedef unsigned int Value;
1.289 +
1.290 + ///\name Comparisons
1.291 + ///See \ref Tolerance for more details.
1.292 +
1.293 + ///@{
1.294 +
1.295 + ///Returns \c true if \c a is \e surely strictly less than \c b
1.296 + static bool less(Value a,Value b) { return a<b;}
1.297 + ///Returns \c true if \c a is \e surely different from \c b
1.298 + static bool different(Value a,Value b) { return a!=b; }
1.299 + ///Returns \c true if \c a is \e surely positive
1.300 + static bool positive(Value a) { return 0<a; }
1.301 + ///Returns \c true if \c a is \e surely negative
1.302 + static bool negative(Value) { return false; }
1.303 + ///Returns \c true if \c a is \e surely non-zero
1.304 + static bool nonZero(Value a) { return a!=0; };
1.305 +
1.306 + ///@}
1.307 +
1.308 + ///Returns zero
1.309 + static Value zero() {return 0;}
1.310 + };
1.311 +
1.312 +
1.313 + ///Long integer specialization of \ref Tolerance.
1.314 +
1.315 + ///Long integer specialization of \ref Tolerance.
1.316 + ///\sa Tolerance
1.317 + template<>
1.318 + class Tolerance<long int>
1.319 + {
1.320 + public:
1.321 + ///\e
1.322 + typedef long int Value;
1.323 +
1.324 + ///\name Comparisons
1.325 + ///See \ref Tolerance for more details.
1.326 +
1.327 + ///@{
1.328 +
1.329 + ///Returns \c true if \c a is \e surely strictly less than \c b
1.330 + static bool less(Value a,Value b) { return a<b;}
1.331 + ///Returns \c true if \c a is \e surely different from \c b
1.332 + static bool different(Value a,Value b) { return a!=b; }
1.333 + ///Returns \c true if \c a is \e surely positive
1.334 + static bool positive(Value a) { return 0<a; }
1.335 + ///Returns \c true if \c a is \e surely negative
1.336 + static bool negative(Value a) { return 0>a; }
1.337 + ///Returns \c true if \c a is \e surely non-zero
1.338 + static bool nonZero(Value a) { return a!=0;};
1.339 +
1.340 + ///@}
1.341 +
1.342 + ///Returns zero
1.343 + static Value zero() {return 0;}
1.344 + };
1.345 +
1.346 + ///Unsigned long integer specialization of \ref Tolerance.
1.347 +
1.348 + ///Unsigned long integer specialization of \ref Tolerance.
1.349 + ///\sa Tolerance
1.350 + template<>
1.351 + class Tolerance<unsigned long int>
1.352 + {
1.353 + public:
1.354 + ///\e
1.355 + typedef unsigned long int Value;
1.356 +
1.357 + ///\name Comparisons
1.358 + ///See \ref Tolerance for more details.
1.359 +
1.360 + ///@{
1.361 +
1.362 + ///Returns \c true if \c a is \e surely strictly less than \c b
1.363 + static bool less(Value a,Value b) { return a<b;}
1.364 + ///Returns \c true if \c a is \e surely different from \c b
1.365 + static bool different(Value a,Value b) { return a!=b; }
1.366 + ///Returns \c true if \c a is \e surely positive
1.367 + static bool positive(Value a) { return 0<a; }
1.368 + ///Returns \c true if \c a is \e surely negative
1.369 + static bool negative(Value) { return false; }
1.370 + ///Returns \c true if \c a is \e surely non-zero
1.371 + static bool nonZero(Value a) { return a!=0;};
1.372 +
1.373 + ///@}
1.374 +
1.375 + ///Returns zero
1.376 + static Value zero() {return 0;}
1.377 + };
1.378 +
1.379 +#if defined __GNUC__ && !defined __STRICT_ANSI__
1.380 +
1.381 + ///Long long integer specialization of \ref Tolerance.
1.382 +
1.383 + ///Long long integer specialization of \ref Tolerance.
1.384 + ///\warning This class (more exactly, type <tt>long long</tt>)
1.385 + ///is not ansi compatible.
1.386 + ///\sa Tolerance
1.387 + template<>
1.388 + class Tolerance<long long int>
1.389 + {
1.390 + public:
1.391 + ///\e
1.392 + typedef long long int Value;
1.393 +
1.394 + ///\name Comparisons
1.395 + ///See \ref Tolerance for more details.
1.396 +
1.397 + ///@{
1.398 +
1.399 + ///Returns \c true if \c a is \e surely strictly less than \c b
1.400 + static bool less(Value a,Value b) { return a<b;}
1.401 + ///Returns \c true if \c a is \e surely different from \c b
1.402 + static bool different(Value a,Value b) { return a!=b; }
1.403 + ///Returns \c true if \c a is \e surely positive
1.404 + static bool positive(Value a) { return 0<a; }
1.405 + ///Returns \c true if \c a is \e surely negative
1.406 + static bool negative(Value a) { return 0>a; }
1.407 + ///Returns \c true if \c a is \e surely non-zero
1.408 + static bool nonZero(Value a) { return a!=0;};
1.409 +
1.410 + ///@}
1.411 +
1.412 + ///Returns zero
1.413 + static Value zero() {return 0;}
1.414 + };
1.415 +
1.416 + ///Unsigned long long integer specialization of \ref Tolerance.
1.417 +
1.418 + ///Unsigned long long integer specialization of \ref Tolerance.
1.419 + ///\warning This class (more exactly, type <tt>unsigned long long</tt>)
1.420 + ///is not ansi compatible.
1.421 + ///\sa Tolerance
1.422 + template<>
1.423 + class Tolerance<unsigned long long int>
1.424 + {
1.425 + public:
1.426 + ///\e
1.427 + typedef unsigned long long int Value;
1.428 +
1.429 + ///\name Comparisons
1.430 + ///See \ref Tolerance for more details.
1.431 +
1.432 + ///@{
1.433 +
1.434 + ///Returns \c true if \c a is \e surely strictly less than \c b
1.435 + static bool less(Value a,Value b) { return a<b;}
1.436 + ///Returns \c true if \c a is \e surely different from \c b
1.437 + static bool different(Value a,Value b) { return a!=b; }
1.438 + ///Returns \c true if \c a is \e surely positive
1.439 + static bool positive(Value a) { return 0<a; }
1.440 + ///Returns \c true if \c a is \e surely negative
1.441 + static bool negative(Value) { return false; }
1.442 + ///Returns \c true if \c a is \e surely non-zero
1.443 + static bool nonZero(Value a) { return a!=0;};
1.444 +
1.445 + ///@}
1.446 +
1.447 + ///Returns zero
1.448 + static Value zero() {return 0;}
1.449 + };
1.450 +
1.451 +#endif
1.452 +
1.453 + /// @}
1.454 +
1.455 +} //namespace lemon
1.456 +
1.457 +#endif //LEMON_TOLERANCE_H