alpar@1835: /* -*- C++ -*- alpar@1835: * alpar@1956: * This file is a part of LEMON, a generic C++ optimization library alpar@1956: * alpar@2391: * Copyright (C) 2003-2007 alpar@1956: * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport alpar@1835: * (Egervary Research Group on Combinatorial Optimization, EGRES). alpar@1835: * alpar@1835: * Permission to use, modify and distribute this software is granted alpar@1835: * provided that this copyright notice appears in all copies. For alpar@1835: * precise terms see the accompanying LICENSE file. alpar@1835: * alpar@1835: * This software is provided "AS IS" with no warranty of any kind, alpar@1835: * express or implied, and with no claim as to its suitability for any alpar@1835: * purpose. alpar@1835: * alpar@1835: */ alpar@1835: alpar@1835: #ifndef LEMON_TOLERANCE_H alpar@1835: #define LEMON_TOLERANCE_H alpar@1835: alpar@1835: ///\ingroup misc alpar@1835: ///\file alpar@1835: ///\brief A basic tool to handle the anomalies of calculation with alpar@1835: ///floating point numbers. alpar@1835: /// alpar@1835: ///\todo It should be in a module like "Basic tools" alpar@1835: alpar@1835: alpar@1835: namespace lemon { alpar@1835: alpar@1835: /// \addtogroup misc alpar@1835: /// @{ alpar@1835: alpar@1835: ///\brief A class to provide a basic way to alpar@1835: ///handle the comparison of numbers that are obtained alpar@1835: ///as a result of a probably inexact computation. alpar@1835: /// alpar@1835: ///Tolerance is a class to provide a basic way to alpar@1835: ///handle the comparison of numbers that are obtained alpar@1835: ///as a result of a probably inexact computation. alpar@1835: /// alpar@1835: ///This is an abstract class, it should be specialized for all numerical alpar@1953: ///data types. These specialized classes like \ref Tolerance\ alpar@1835: ///may offer additional tuning parameters. alpar@1835: /// alpar@1835: ///\sa Tolerance alpar@1835: ///\sa Tolerance alpar@1897: ///\sa Tolerance alpar@1835: ///\sa Tolerance alpar@1835: ///\sa Tolerance alpar@2154: ///\sa Tolerance alpar@2154: ///\sa Tolerance alpar@1835: alpar@1835: template alpar@1835: class Tolerance alpar@1835: { alpar@1835: public: alpar@1835: typedef T Value; alpar@1835: alpar@1835: ///\name Comparisons alpar@1835: ///The concept is that these bool functions return with \c true only if alpar@1835: ///the related comparisons hold even if some numerical error appeared alpar@1835: ///during the computations. alpar@1835: alpar@1835: ///@{ alpar@1835: alpar@1835: ///Returns \c true if \c a is \e surely strictly less than \c b alpar@1835: static bool less(Value a,Value b) {return false;} alpar@1835: ///Returns \c true if \c a is \e surely different from \c b alpar@1835: static bool different(Value a,Value b) {return false;} alpar@1835: ///Returns \c true if \c a is \e surely positive alpar@1835: static bool positive(Value a) {return false;} alpar@1835: ///Returns \c true if \c a is \e surely negative alpar@1835: static bool negative(Value a) {return false;} alpar@1835: ///Returns \c true if \c a is \e surely non-zero alpar@1835: static bool nonZero(Value a) {return false;} alpar@1835: alpar@1835: ///@} alpar@1835: alpar@1835: ///Returns the zero value. alpar@1835: static Value zero() {return T();} alpar@1835: alpar@1835: // static bool finite(Value a) {} alpar@1835: // static Value big() {} alpar@1835: // static Value negativeBig() {} alpar@1835: }; alpar@1835: alpar@1835: alpar@1897: ///Float specialization of \ref Tolerance. alpar@1897: alpar@1897: ///Float specialization of \ref Tolerance. alpar@1897: ///\sa Tolerance alpar@1897: ///\relates Tolerance alpar@1897: template<> alpar@1897: class Tolerance alpar@1897: { alpar@1897: static float def_epsilon; alpar@1897: float _epsilon; alpar@1897: public: alpar@1897: ///\e alpar@1897: typedef float Value; alpar@1897: alpar@1897: ///Constructor setting the epsilon tolerance to the default value. alpar@1897: Tolerance() : _epsilon(def_epsilon) {} alpar@1897: ///Constructor setting the epsilon tolerance. alpar@1897: Tolerance(float e) : _epsilon(e) {} alpar@1897: alpar@1897: ///Return the epsilon value. alpar@2073: Value epsilon() const {return _epsilon;} alpar@1897: ///Set the epsilon value. alpar@1897: void epsilon(Value e) {_epsilon=e;} alpar@1897: alpar@1897: ///Return the default epsilon value. alpar@1897: static Value defaultEpsilon() {return def_epsilon;} alpar@1897: ///Set the default epsilon value. alpar@1897: static void defaultEpsilon(Value e) {def_epsilon=e;} alpar@1897: alpar@1897: ///\name Comparisons alpar@1897: ///See class Tolerance for more details. alpar@1897: alpar@1897: ///@{ alpar@1897: alpar@1897: ///Returns \c true if \c a is \e surely strictly less than \c b alpar@2073: bool less(Value a,Value b) const {return a+_epsilona; } alpar@1897: ///Returns \c true if \c a is \e surely non-zero alpar@2073: bool nonZero(Value a) const { return positive(a)||negative(a); }; alpar@1897: alpar@1897: ///@} alpar@1897: alpar@1897: ///Returns zero alpar@1897: static Value zero() {return 0;} alpar@1897: }; alpar@1897: alpar@1835: ///Double specialization of \ref Tolerance. alpar@1835: alpar@1835: ///Double specialization of \ref Tolerance. alpar@1835: ///\sa Tolerance alpar@1835: ///\relates Tolerance alpar@1835: template<> alpar@1835: class Tolerance alpar@1835: { alpar@1835: static double def_epsilon; alpar@1835: double _epsilon; alpar@1835: public: alpar@1835: ///\e alpar@1835: typedef double Value; alpar@1835: alpar@1835: ///Constructor setting the epsilon tolerance to the default value. alpar@1835: Tolerance() : _epsilon(def_epsilon) {} alpar@1835: ///Constructor setting the epsilon tolerance. alpar@1835: Tolerance(double e) : _epsilon(e) {} alpar@1835: alpar@1835: ///Return the epsilon value. alpar@2073: Value epsilon() const {return _epsilon;} alpar@1835: ///Set the epsilon value. alpar@1835: void epsilon(Value e) {_epsilon=e;} alpar@1835: alpar@1835: ///Return the default epsilon value. alpar@1835: static Value defaultEpsilon() {return def_epsilon;} alpar@1835: ///Set the default epsilon value. alpar@1835: static void defaultEpsilon(Value e) {def_epsilon=e;} alpar@1835: alpar@1835: ///\name Comparisons alpar@1835: ///See class Tolerance for more details. alpar@1835: alpar@1835: ///@{ alpar@1835: alpar@1835: ///Returns \c true if \c a is \e surely strictly less than \c b alpar@2073: bool less(Value a,Value b) const {return a+_epsilona; } alpar@1835: ///Returns \c true if \c a is \e surely non-zero alpar@2073: bool nonZero(Value a) const { return positive(a)||negative(a); }; alpar@1835: alpar@1835: ///@} alpar@1835: alpar@1835: ///Returns zero alpar@1835: static Value zero() {return 0;} alpar@1835: }; alpar@1835: alpar@1897: ///Long double specialization of \ref Tolerance. alpar@1835: alpar@1897: ///Long double specialization of \ref Tolerance. alpar@1835: ///\sa Tolerance alpar@1835: ///\relates Tolerance alpar@1835: template<> alpar@1897: class Tolerance alpar@1835: { alpar@1897: static long double def_epsilon; alpar@1897: long double _epsilon; alpar@1835: public: alpar@1835: ///\e alpar@1897: typedef long double Value; alpar@1835: alpar@1835: ///Constructor setting the epsilon tolerance to the default value. alpar@1835: Tolerance() : _epsilon(def_epsilon) {} alpar@1835: ///Constructor setting the epsilon tolerance. alpar@1897: Tolerance(long double e) : _epsilon(e) {} alpar@1835: alpar@1835: ///Return the epsilon value. alpar@2073: Value epsilon() const {return _epsilon;} alpar@1835: ///Set the epsilon value. alpar@1835: void epsilon(Value e) {_epsilon=e;} alpar@1835: alpar@1835: ///Return the default epsilon value. alpar@1835: static Value defaultEpsilon() {return def_epsilon;} alpar@1835: ///Set the default epsilon value. alpar@1835: static void defaultEpsilon(Value e) {def_epsilon=e;} alpar@1835: alpar@1835: ///\name Comparisons alpar@1835: ///See class Tolerance for more details. alpar@1835: alpar@1835: ///@{ alpar@1835: alpar@1835: ///Returns \c true if \c a is \e surely strictly less than \c b alpar@2073: bool less(Value a,Value b) const {return a+_epsilona; } alpar@1835: ///Returns \c true if \c a is \e surely non-zero alpar@2073: bool nonZero(Value a) const { return positive(a)||negative(a); }; alpar@1835: alpar@1835: ///@} alpar@1835: alpar@1835: ///Returns zero alpar@1835: static Value zero() {return 0;} alpar@1835: }; alpar@1835: alpar@1835: ///Integer specialization of \ref Tolerance. alpar@1835: alpar@1835: ///Integer specialization of \ref Tolerance. alpar@1835: ///\sa Tolerance alpar@1835: template<> alpar@1835: class Tolerance alpar@1835: { alpar@1835: public: alpar@1835: ///\e alpar@1835: typedef int Value; alpar@1835: alpar@1835: ///\name Comparisons alpar@1835: ///See \ref Tolerance for more details. alpar@1835: alpar@1835: ///@{ alpar@1835: alpar@1835: ///Returns \c true if \c a is \e surely strictly less than \c b alpar@1835: static bool less(Value a,Value b) { return aa; } alpar@1835: ///Returns \c true if \c a is \e surely non-zero alpar@2073: static bool nonZero(Value a) { return a!=0; }; alpar@1835: alpar@1835: ///@} alpar@1835: alpar@1835: ///Returns zero alpar@1835: static Value zero() {return 0;} alpar@1835: }; alpar@1835: alpar@2154: ///Unsigned integer specialization of \ref Tolerance. alpar@2154: alpar@2154: ///Unsigned integer specialization of \ref Tolerance. alpar@2154: ///\sa Tolerance alpar@2154: template<> alpar@2154: class Tolerance alpar@2154: { alpar@2154: public: alpar@2154: ///\e alpar@2154: typedef unsigned int Value; alpar@2154: alpar@2154: ///\name Comparisons alpar@2154: ///See \ref Tolerance for more details. alpar@2154: alpar@2154: ///@{ alpar@2154: alpar@2154: ///Returns \c true if \c a is \e surely strictly less than \c b alpar@2154: static bool less(Value a,Value b) { return a deba@2413: class Tolerance deba@2413: { deba@2413: public: deba@2413: ///\e deba@2413: typedef long int Value; deba@2413: deba@2413: ///\name Comparisons deba@2413: ///See \ref Tolerance for more details. deba@2413: deba@2413: ///@{ deba@2413: deba@2413: ///Returns \c true if \c a is \e surely strictly less than \c b deba@2413: static bool less(Value a,Value b) { return aa; } deba@2413: ///Returns \c true if \c a is \e surely non-zero deba@2413: static bool nonZero(Value a) { return a!=0;}; deba@2413: deba@2413: ///@} deba@2413: deba@2413: ///Returns zero deba@2413: static Value zero() {return 0;} deba@2413: }; deba@2413: deba@2413: ///Unsigned long integer specialization of \ref Tolerance. deba@2413: deba@2413: ///Unsigned long integer specialization of \ref Tolerance. deba@2413: ///\sa Tolerance deba@2413: template<> deba@2413: class Tolerance deba@2413: { deba@2413: public: deba@2413: ///\e deba@2413: typedef unsigned long int Value; deba@2413: deba@2413: ///\name Comparisons deba@2413: ///See \ref Tolerance for more details. deba@2413: deba@2413: ///@{ deba@2413: deba@2413: ///Returns \c true if \c a is \e surely strictly less than \c b deba@2413: static bool less(Value a,Value b) { return along long) alpar@2154: ///is not ansi compatible. alpar@1835: ///\sa Tolerance alpar@1835: template<> alpar@1835: class Tolerance alpar@1835: { alpar@1835: public: alpar@1835: ///\e alpar@1835: typedef long long int Value; alpar@1835: alpar@1835: ///\name Comparisons alpar@1835: ///See \ref Tolerance for more details. alpar@1835: alpar@1835: ///@{ alpar@1835: alpar@1835: ///Returns \c true if \c a is \e surely strictly less than \c b alpar@1835: static bool less(Value a,Value b) { return aa; } alpar@1835: ///Returns \c true if \c a is \e surely non-zero alpar@2073: static bool nonZero(Value a) { return a!=0;}; alpar@1835: alpar@1835: ///@} alpar@1835: alpar@1835: ///Returns zero alpar@1835: static Value zero() {return 0;} alpar@1835: }; alpar@1835: alpar@2154: ///Unsigned long long integer specialization of \ref Tolerance. alpar@2154: alpar@2154: ///Unsigned long long integer specialization of \ref Tolerance. alpar@2154: ///\warning This class (more exactly, type unsigned long long) alpar@2154: ///is not ansi compatible. alpar@2154: ///\sa Tolerance alpar@2154: template<> alpar@2154: class Tolerance alpar@2154: { alpar@2154: public: alpar@2154: ///\e alpar@2154: typedef unsigned long long int Value; alpar@2154: alpar@2154: ///\name Comparisons alpar@2154: ///See \ref Tolerance for more details. alpar@2154: alpar@2154: ///@{ alpar@2154: alpar@2154: ///Returns \c true if \c a is \e surely strictly less than \c b alpar@2154: static bool less(Value a,Value b) { return a