lemon/tolerance.h
author Alpar Juttner <alpar@cs.elte.hu>
Wed, 17 Oct 2018 18:56:32 +0200
changeset 1169 2e0c2c25d63e
parent 440 88ed40ad0d4f
parent 486 7d7d9debb29a
permissions -rw-r--r--
Merge #1.3 related bugfix heads
     1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library.
     4  *
     5  * Copyright (C) 2003-2009
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 #ifndef LEMON_TOLERANCE_H
    20 #define LEMON_TOLERANCE_H
    21 
    22 ///\ingroup misc
    23 ///\file
    24 ///\brief A basic tool to handle the anomalies of calculation with
    25 ///floating point numbers.
    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   ///\ref 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   ///The general implementation is suitable only if the data type is exact,
    42   ///like the integer types, otherwise a specialized version must be
    43   ///implemented. These specialized classes like
    44   ///Tolerance<double> may offer additional tuning parameters.
    45   ///
    46   ///\sa Tolerance<float>
    47   ///\sa Tolerance<double>
    48   ///\sa Tolerance<long double>
    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 \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 a<b;}
    65     ///Returns \c true if \c a is \e surely different from \c b
    66     static bool different(Value a,Value b) {return a!=b;}
    67     ///Returns \c true if \c a is \e surely positive
    68     static bool positive(Value a) {return static_cast<Value>(0) < a;}
    69     ///Returns \c true if \c a is \e surely negative
    70     static bool negative(Value a) {return a < static_cast<Value>(0);}
    71     ///Returns \c true if \c a is \e surely non-zero
    72     static bool nonZero(Value a) {return a != static_cast<Value>(0);}
    73 
    74     ///@}
    75 
    76     ///Returns the zero value.
    77     static Value zero() {return static_cast<Value>(0);}
    78 
    79     //   static bool finite(Value a) {}
    80     //   static Value big() {}
    81     //   static Value negativeBig() {}
    82   };
    83 
    84 
    85   ///Float specialization of Tolerance.
    86 
    87   ///Float specialization of Tolerance.
    88   ///\sa Tolerance
    89   ///\relates Tolerance
    90   template<>
    91   class Tolerance<float>
    92   {
    93     static float def_epsilon;
    94     float _epsilon;
    95   public:
    96     ///\e
    97     typedef float Value;
    98 
    99     ///Constructor setting the epsilon tolerance to the default value.
   100     Tolerance() : _epsilon(def_epsilon) {}
   101     ///Constructor setting the epsilon tolerance to the given value.
   102     Tolerance(float e) : _epsilon(e) {}
   103 
   104     ///Returns the epsilon value.
   105     Value epsilon() const {return _epsilon;}
   106     ///Sets the epsilon value.
   107     void epsilon(Value e) {_epsilon=e;}
   108 
   109     ///Returns the default epsilon value.
   110     static Value defaultEpsilon() {return def_epsilon;}
   111     ///Sets the default epsilon value.
   112     static void defaultEpsilon(Value e) {def_epsilon=e;}
   113 
   114     ///\name Comparisons
   115     ///See \ref lemon::Tolerance "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) const {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) const { return less(a,b)||less(b,a); }
   123     ///Returns \c true if \c a is \e surely positive
   124     bool positive(Value a) const { return _epsilon<a; }
   125     ///Returns \c true if \c a is \e surely negative
   126     bool negative(Value a) const { return -_epsilon>a; }
   127     ///Returns \c true if \c a is \e surely non-zero
   128     bool nonZero(Value a) const { return positive(a)||negative(a); }
   129 
   130     ///@}
   131 
   132     ///Returns zero
   133     static Value zero() {return 0;}
   134   };
   135 
   136   ///Double specialization of Tolerance.
   137 
   138   ///Double specialization of Tolerance.
   139   ///\sa Tolerance
   140   ///\relates Tolerance
   141   template<>
   142   class Tolerance<double>
   143   {
   144     static double def_epsilon;
   145     double _epsilon;
   146   public:
   147     ///\e
   148     typedef double Value;
   149 
   150     ///Constructor setting the epsilon tolerance to the default value.
   151     Tolerance() : _epsilon(def_epsilon) {}
   152     ///Constructor setting the epsilon tolerance to the given value.
   153     Tolerance(double e) : _epsilon(e) {}
   154 
   155     ///Returns the epsilon value.
   156     Value epsilon() const {return _epsilon;}
   157     ///Sets the epsilon value.
   158     void epsilon(Value e) {_epsilon=e;}
   159 
   160     ///Returns the default epsilon value.
   161     static Value defaultEpsilon() {return def_epsilon;}
   162     ///Sets the default epsilon value.
   163     static void defaultEpsilon(Value e) {def_epsilon=e;}
   164 
   165     ///\name Comparisons
   166     ///See \ref lemon::Tolerance "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) const {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) const { return less(a,b)||less(b,a); }
   174     ///Returns \c true if \c a is \e surely positive
   175     bool positive(Value a) const { return _epsilon<a; }
   176     ///Returns \c true if \c a is \e surely negative
   177     bool negative(Value a) const { return -_epsilon>a; }
   178     ///Returns \c true if \c a is \e surely non-zero
   179     bool nonZero(Value a) const { return positive(a)||negative(a); }
   180 
   181     ///@}
   182 
   183     ///Returns zero
   184     static Value zero() {return 0;}
   185   };
   186 
   187   ///Long double specialization of Tolerance.
   188 
   189   ///Long double specialization of Tolerance.
   190   ///\sa Tolerance
   191   ///\relates Tolerance
   192   template<>
   193   class Tolerance<long double>
   194   {
   195     static long double def_epsilon;
   196     long double _epsilon;
   197   public:
   198     ///\e
   199     typedef long double Value;
   200 
   201     ///Constructor setting the epsilon tolerance to the default value.
   202     Tolerance() : _epsilon(def_epsilon) {}
   203     ///Constructor setting the epsilon tolerance to the given value.
   204     Tolerance(long double e) : _epsilon(e) {}
   205 
   206     ///Returns the epsilon value.
   207     Value epsilon() const {return _epsilon;}
   208     ///Sets the epsilon value.
   209     void epsilon(Value e) {_epsilon=e;}
   210 
   211     ///Returns the default epsilon value.
   212     static Value defaultEpsilon() {return def_epsilon;}
   213     ///Sets the default epsilon value.
   214     static void defaultEpsilon(Value e) {def_epsilon=e;}
   215 
   216     ///\name Comparisons
   217     ///See \ref lemon::Tolerance "Tolerance" for more details.
   218 
   219     ///@{
   220 
   221     ///Returns \c true if \c a is \e surely strictly less than \c b
   222     bool less(Value a,Value b) const {return a+_epsilon<b;}
   223     ///Returns \c true if \c a is \e surely different from \c b
   224     bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
   225     ///Returns \c true if \c a is \e surely positive
   226     bool positive(Value a) const { return _epsilon<a; }
   227     ///Returns \c true if \c a is \e surely negative
   228     bool negative(Value a) const { return -_epsilon>a; }
   229     ///Returns \c true if \c a is \e surely non-zero
   230     bool nonZero(Value a) const { return positive(a)||negative(a); }
   231 
   232     ///@}
   233 
   234     ///Returns zero
   235     static Value zero() {return 0;}
   236   };
   237 
   238   /// @}
   239 
   240 } //namespace lemon
   241 
   242 #endif //LEMON_TOLERANCE_H