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