lemon/tolerance.h
author deba
Fri, 03 Nov 2006 15:21:52 +0000
changeset 2292 38d985e82205
parent 2154 bbc79b698f62
child 2391 14a343be7a5a
permissions -rw-r--r--
General mapping based variant type
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2006
     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 ///\todo It should be in a module like "Basic tools"
    28 
    29 
    30 namespace lemon {
    31 
    32   /// \addtogroup misc
    33   /// @{
    34   
    35   ///\brief A class to provide a basic way to
    36   ///handle the comparison of numbers that are obtained
    37   ///as a result of a probably inexact computation.
    38   ///
    39   ///Tolerance is a class to provide a basic way to
    40   ///handle the comparison of numbers that are obtained
    41   ///as a result of a probably inexact computation.
    42   ///
    43   ///This is an abstract class, it should be specialized for all numerical
    44   ///data types. These specialized classes like \ref Tolerance\<double\>
    45   ///may offer additional tuning parameters.
    46   ///
    47   ///\sa Tolerance<float>
    48   ///\sa Tolerance<double>
    49   ///\sa Tolerance<long double>
    50   ///\sa Tolerance<int>
    51   ///\sa Tolerance<long long int>
    52   ///\sa Tolerance<unsigned int>
    53   ///\sa Tolerance<unsigned long long int>
    54 
    55   template<class T>
    56   class Tolerance
    57   {
    58   public:
    59     typedef T Value;
    60 
    61     ///\name Comparisons
    62     ///The concept is that these bool functions return with \c true only if
    63     ///the related comparisons hold even if some numerical error appeared
    64     ///during the computations.
    65 
    66     ///@{
    67 
    68     ///Returns \c true if \c a is \e surely strictly less than \c b
    69     static bool less(Value a,Value b) {return false;}
    70     ///Returns \c true if \c a is \e surely different from \c b
    71     static bool different(Value a,Value b) {return false;}
    72     ///Returns \c true if \c a is \e surely positive
    73     static bool positive(Value a) {return false;}
    74     ///Returns \c true if \c a is \e surely negative
    75     static bool negative(Value a) {return false;}
    76     ///Returns \c true if \c a is \e surely non-zero
    77     static bool nonZero(Value a) {return false;}
    78 
    79     ///@}
    80 
    81     ///Returns the zero value.
    82     static Value zero() {return T();}
    83 
    84     //   static bool finite(Value a) {}
    85     //   static Value big() {}
    86     //   static Value negativeBig() {}
    87   };
    88 
    89 
    90   ///Float specialization of \ref Tolerance.
    91 
    92   ///Float specialization of \ref Tolerance.
    93   ///\sa Tolerance
    94   ///\relates Tolerance
    95   template<>
    96   class Tolerance<float>
    97   {
    98     static float def_epsilon;
    99     float _epsilon;
   100   public:
   101     ///\e
   102     typedef float Value;
   103 
   104     ///Constructor setting the epsilon tolerance to the default value.
   105     Tolerance() : _epsilon(def_epsilon) {}
   106     ///Constructor setting the epsilon tolerance.
   107     Tolerance(float e) : _epsilon(e) {}
   108 
   109     ///Return the epsilon value.
   110     Value epsilon() const {return _epsilon;}
   111     ///Set the epsilon value.
   112     void epsilon(Value e) {_epsilon=e;}
   113 
   114     ///Return the default epsilon value.
   115     static Value defaultEpsilon() {return def_epsilon;}
   116     ///Set the default epsilon value.
   117     static void defaultEpsilon(Value e) {def_epsilon=e;}
   118 
   119     ///\name Comparisons
   120     ///See class Tolerance for more details.
   121 
   122     ///@{
   123 
   124     ///Returns \c true if \c a is \e surely strictly less than \c b
   125     bool less(Value a,Value b) const {return a+_epsilon<b;}
   126     ///Returns \c true if \c a is \e surely different from \c b
   127     bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
   128     ///Returns \c true if \c a is \e surely positive
   129     bool positive(Value a) const { return _epsilon<a; }
   130     ///Returns \c true if \c a is \e surely negative
   131     bool negative(Value a) const { return -_epsilon>a; }
   132     ///Returns \c true if \c a is \e surely non-zero
   133     bool nonZero(Value a) const { return positive(a)||negative(a); };
   134 
   135     ///@}
   136 
   137     ///Returns zero
   138     static Value zero() {return 0;}
   139   };
   140 
   141   ///Double specialization of \ref Tolerance.
   142 
   143   ///Double specialization of \ref Tolerance.
   144   ///\sa Tolerance
   145   ///\relates Tolerance
   146   template<>
   147   class Tolerance<double>
   148   {
   149     static double def_epsilon;
   150     double _epsilon;
   151   public:
   152     ///\e
   153     typedef double Value;
   154 
   155     ///Constructor setting the epsilon tolerance to the default value.
   156     Tolerance() : _epsilon(def_epsilon) {}
   157     ///Constructor setting the epsilon tolerance.
   158     Tolerance(double e) : _epsilon(e) {}
   159 
   160     ///Return the epsilon value.
   161     Value epsilon() const {return _epsilon;}
   162     ///Set the epsilon value.
   163     void epsilon(Value e) {_epsilon=e;}
   164 
   165     ///Return the default epsilon value.
   166     static Value defaultEpsilon() {return def_epsilon;}
   167     ///Set the default epsilon value.
   168     static void defaultEpsilon(Value e) {def_epsilon=e;}
   169 
   170     ///\name Comparisons
   171     ///See class Tolerance for more details.
   172 
   173     ///@{
   174 
   175     ///Returns \c true if \c a is \e surely strictly less than \c b
   176     bool less(Value a,Value b) const {return a+_epsilon<b;}
   177     ///Returns \c true if \c a is \e surely different from \c b
   178     bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
   179     ///Returns \c true if \c a is \e surely positive
   180     bool positive(Value a) const { return _epsilon<a; }
   181     ///Returns \c true if \c a is \e surely negative
   182     bool negative(Value a) const { return -_epsilon>a; }
   183     ///Returns \c true if \c a is \e surely non-zero
   184     bool nonZero(Value a) const { return positive(a)||negative(a); };
   185 
   186     ///@}
   187 
   188     ///Returns zero
   189     static Value zero() {return 0;}
   190   };
   191 
   192   ///Long double specialization of \ref Tolerance.
   193 
   194   ///Long double specialization of \ref Tolerance.
   195   ///\sa Tolerance
   196   ///\relates Tolerance
   197   template<>
   198   class Tolerance<long double>
   199   {
   200     static long double def_epsilon;
   201     long double _epsilon;
   202   public:
   203     ///\e
   204     typedef long double Value;
   205 
   206     ///Constructor setting the epsilon tolerance to the default value.
   207     Tolerance() : _epsilon(def_epsilon) {}
   208     ///Constructor setting the epsilon tolerance.
   209     Tolerance(long double e) : _epsilon(e) {}
   210 
   211     ///Return the epsilon value.
   212     Value epsilon() const {return _epsilon;}
   213     ///Set the epsilon value.
   214     void epsilon(Value e) {_epsilon=e;}
   215 
   216     ///Return the default epsilon value.
   217     static Value defaultEpsilon() {return def_epsilon;}
   218     ///Set the default epsilon value.
   219     static void defaultEpsilon(Value e) {def_epsilon=e;}
   220 
   221     ///\name Comparisons
   222     ///See class Tolerance for more details.
   223 
   224     ///@{
   225 
   226     ///Returns \c true if \c a is \e surely strictly less than \c b
   227     bool less(Value a,Value b) const {return a+_epsilon<b;}
   228     ///Returns \c true if \c a is \e surely different from \c b
   229     bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
   230     ///Returns \c true if \c a is \e surely positive
   231     bool positive(Value a) const { return _epsilon<a; }
   232     ///Returns \c true if \c a is \e surely negative
   233     bool negative(Value a) const { return -_epsilon>a; }
   234     ///Returns \c true if \c a is \e surely non-zero
   235     bool nonZero(Value a) const { return positive(a)||negative(a); };
   236 
   237     ///@}
   238 
   239     ///Returns zero
   240     static Value zero() {return 0;}
   241   };
   242 
   243   ///Integer specialization of \ref Tolerance.
   244 
   245   ///Integer specialization of \ref Tolerance.
   246   ///\sa Tolerance
   247   template<>
   248   class Tolerance<int>
   249   {
   250   public:
   251     ///\e
   252     typedef int Value;
   253 
   254     ///\name Comparisons
   255     ///See \ref Tolerance for more details.
   256 
   257     ///@{
   258 
   259     ///Returns \c true if \c a is \e surely strictly less than \c b
   260     static bool less(Value a,Value b) { return a<b;}
   261     ///Returns \c true if \c a is \e surely different from \c b
   262     static bool different(Value a,Value b) { return a!=b; }
   263     ///Returns \c true if \c a is \e surely positive
   264     static bool positive(Value a) { return 0<a; }
   265     ///Returns \c true if \c a is \e surely negative
   266     static bool negative(Value a) { return 0>a; }
   267     ///Returns \c true if \c a is \e surely non-zero
   268     static bool nonZero(Value a) { return a!=0; };
   269 
   270     ///@}
   271 
   272     ///Returns zero
   273     static Value zero() {return 0;}
   274   };
   275 
   276   ///Unsigned integer specialization of \ref Tolerance.
   277 
   278   ///Unsigned integer specialization of \ref Tolerance.
   279   ///\sa Tolerance
   280   template<>
   281   class Tolerance<unsigned int>
   282   {
   283   public:
   284     ///\e
   285     typedef unsigned int Value;
   286 
   287     ///\name Comparisons
   288     ///See \ref Tolerance for more details.
   289 
   290     ///@{
   291 
   292     ///Returns \c true if \c a is \e surely strictly less than \c b
   293     static bool less(Value a,Value b) { return a<b;}
   294     ///Returns \c true if \c a is \e surely different from \c b
   295     static bool different(Value a,Value b) { return a!=b; }
   296     ///Returns \c true if \c a is \e surely positive
   297     static bool positive(Value a) { return 0<a; }
   298     ///Returns \c true if \c a is \e surely negative
   299     static bool negative(Value) { return false; }
   300     ///Returns \c true if \c a is \e surely non-zero
   301     static bool nonZero(Value a) { return a!=0; };
   302 
   303     ///@}
   304 
   305     ///Returns zero
   306     static Value zero() {return 0;}
   307   };
   308 
   309 #if defined __GNUC__ && !defined __STRICT_ANSI__
   310 
   311   ///Long long integer specialization of \ref Tolerance.
   312 
   313   ///Long long integer specialization of \ref Tolerance.
   314   ///\warning This class (more exactly, type <tt>long long</tt>)
   315   ///is not ansi compatible.
   316   ///\sa Tolerance
   317   template<>
   318   class Tolerance<long long int>
   319   {
   320   public:
   321     ///\e
   322     typedef long long int Value;
   323 
   324     ///\name Comparisons
   325     ///See \ref Tolerance for more details.
   326 
   327     ///@{
   328 
   329     ///Returns \c true if \c a is \e surely strictly less than \c b
   330     static bool less(Value a,Value b) { return a<b;}
   331     ///Returns \c true if \c a is \e surely different from \c b
   332     static bool different(Value a,Value b) { return a!=b; }
   333     ///Returns \c true if \c a is \e surely positive
   334     static bool positive(Value a) { return 0<a; }
   335     ///Returns \c true if \c a is \e surely negative
   336     static bool negative(Value a) { return 0>a; }
   337     ///Returns \c true if \c a is \e surely non-zero
   338     static bool nonZero(Value a) { return a!=0;};
   339 
   340     ///@}
   341 
   342     ///Returns zero
   343     static Value zero() {return 0;}
   344   };
   345 
   346   ///Unsigned long long integer specialization of \ref Tolerance.
   347 
   348   ///Unsigned long long integer specialization of \ref Tolerance.
   349   ///\warning This class (more exactly, type <tt>unsigned long long</tt>)
   350   ///is not ansi compatible.
   351   ///\sa Tolerance
   352   template<>
   353   class Tolerance<unsigned long long int>
   354   {
   355   public:
   356     ///\e
   357     typedef unsigned long long int Value;
   358 
   359     ///\name Comparisons
   360     ///See \ref Tolerance for more details.
   361 
   362     ///@{
   363 
   364     ///Returns \c true if \c a is \e surely strictly less than \c b
   365     static bool less(Value a,Value b) { return a<b;}
   366     ///Returns \c true if \c a is \e surely different from \c b
   367     static bool different(Value a,Value b) { return a!=b; }
   368     ///Returns \c true if \c a is \e surely positive
   369     static bool positive(Value a) { return 0<a; }
   370     ///Returns \c true if \c a is \e surely negative
   371     static bool negative(Value) { return false; }
   372     ///Returns \c true if \c a is \e surely non-zero
   373     static bool nonZero(Value a) { return a!=0;};
   374 
   375     ///@}
   376 
   377     ///Returns zero
   378     static Value zero() {return 0;}
   379   };
   380 
   381 #endif
   382 
   383   /// @}
   384 
   385 } //namespace lemon
   386 
   387 #endif //LEMON_TOLERANCE_H