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