lemon/tolerance.h
author Alpar Juttner <alpar@cs.elte.hu>
Thu, 03 Jan 2008 11:13:29 +0100
changeset 22 45f8b617339e
parent 7 4d461e9867da
child 39 0a01d811071f
permissions -rw-r--r--
Merge
     1 /* -*- C++ -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library
     4  *
     5  * Copyright (C) 2003-2007
     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 #if defined __GNUC__ && !defined __STRICT_ANSI__  
    52   ///\sa Tolerance<long long int>
    53 #endif
    54   ///\sa Tolerance<unsigned int>
    55 #if defined __GNUC__ && !defined __STRICT_ANSI__  
    56   ///\sa Tolerance<unsigned long long int>
    57 #endif
    58 
    59   template<class T>
    60   class Tolerance
    61   {
    62   public:
    63     typedef T Value;
    64 
    65     ///\name Comparisons
    66     ///The concept is that these bool functions return with \c true only if
    67     ///the related comparisons hold even if some numerical error appeared
    68     ///during the computations.
    69 
    70     ///@{
    71 
    72     ///Returns \c true if \c a is \e surely strictly less than \c b
    73     static bool less(Value a,Value b) {return false;}
    74     ///Returns \c true if \c a is \e surely different from \c b
    75     static bool different(Value a,Value b) {return false;}
    76     ///Returns \c true if \c a is \e surely positive
    77     static bool positive(Value a) {return false;}
    78     ///Returns \c true if \c a is \e surely negative
    79     static bool negative(Value a) {return false;}
    80     ///Returns \c true if \c a is \e surely non-zero
    81     static bool nonZero(Value a) {return false;}
    82 
    83     ///@}
    84 
    85     ///Returns the zero value.
    86     static Value zero() {return T();}
    87 
    88     //   static bool finite(Value a) {}
    89     //   static Value big() {}
    90     //   static Value negativeBig() {}
    91   };
    92 
    93 
    94   ///Float specialization of \ref Tolerance.
    95 
    96   ///Float specialization of \ref Tolerance.
    97   ///\sa Tolerance
    98   ///\relates Tolerance
    99   template<>
   100   class Tolerance<float>
   101   {
   102     static float def_epsilon;
   103     float _epsilon;
   104   public:
   105     ///\e
   106     typedef float Value;
   107 
   108     ///Constructor setting the epsilon tolerance to the default value.
   109     Tolerance() : _epsilon(def_epsilon) {}
   110     ///Constructor setting the epsilon tolerance.
   111     Tolerance(float e) : _epsilon(e) {}
   112 
   113     ///Return the epsilon value.
   114     Value epsilon() const {return _epsilon;}
   115     ///Set the epsilon value.
   116     void epsilon(Value e) {_epsilon=e;}
   117 
   118     ///Return the default epsilon value.
   119     static Value defaultEpsilon() {return def_epsilon;}
   120     ///Set the default epsilon value.
   121     static void defaultEpsilon(Value e) {def_epsilon=e;}
   122 
   123     ///\name Comparisons
   124     ///See class Tolerance for more details.
   125 
   126     ///@{
   127 
   128     ///Returns \c true if \c a is \e surely strictly less than \c b
   129     bool less(Value a,Value b) const {return a+_epsilon<b;}
   130     ///Returns \c true if \c a is \e surely different from \c b
   131     bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
   132     ///Returns \c true if \c a is \e surely positive
   133     bool positive(Value a) const { return _epsilon<a; }
   134     ///Returns \c true if \c a is \e surely negative
   135     bool negative(Value a) const { return -_epsilon>a; }
   136     ///Returns \c true if \c a is \e surely non-zero
   137     bool nonZero(Value a) const { return positive(a)||negative(a); }
   138 
   139     ///@}
   140 
   141     ///Returns zero
   142     static Value zero() {return 0;}
   143   };
   144 
   145   ///Double specialization of \ref Tolerance.
   146 
   147   ///Double specialization of \ref Tolerance.
   148   ///\sa Tolerance
   149   ///\relates Tolerance
   150   template<>
   151   class Tolerance<double>
   152   {
   153     static double def_epsilon;
   154     double _epsilon;
   155   public:
   156     ///\e
   157     typedef double Value;
   158 
   159     ///Constructor setting the epsilon tolerance to the default value.
   160     Tolerance() : _epsilon(def_epsilon) {}
   161     ///Constructor setting the epsilon tolerance.
   162     Tolerance(double e) : _epsilon(e) {}
   163 
   164     ///Return the epsilon value.
   165     Value epsilon() const {return _epsilon;}
   166     ///Set the epsilon value.
   167     void epsilon(Value e) {_epsilon=e;}
   168 
   169     ///Return the default epsilon value.
   170     static Value defaultEpsilon() {return def_epsilon;}
   171     ///Set the default epsilon value.
   172     static void defaultEpsilon(Value e) {def_epsilon=e;}
   173 
   174     ///\name Comparisons
   175     ///See class Tolerance for more details.
   176 
   177     ///@{
   178 
   179     ///Returns \c true if \c a is \e surely strictly less than \c b
   180     bool less(Value a,Value b) const {return a+_epsilon<b;}
   181     ///Returns \c true if \c a is \e surely different from \c b
   182     bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
   183     ///Returns \c true if \c a is \e surely positive
   184     bool positive(Value a) const { return _epsilon<a; }
   185     ///Returns \c true if \c a is \e surely negative
   186     bool negative(Value a) const { return -_epsilon>a; }
   187     ///Returns \c true if \c a is \e surely non-zero
   188     bool nonZero(Value a) const { return positive(a)||negative(a); }
   189 
   190     ///@}
   191 
   192     ///Returns zero
   193     static Value zero() {return 0;}
   194   };
   195 
   196   ///Long double specialization of \ref Tolerance.
   197 
   198   ///Long double specialization of \ref Tolerance.
   199   ///\sa Tolerance
   200   ///\relates Tolerance
   201   template<>
   202   class Tolerance<long double>
   203   {
   204     static long double def_epsilon;
   205     long double _epsilon;
   206   public:
   207     ///\e
   208     typedef long double Value;
   209 
   210     ///Constructor setting the epsilon tolerance to the default value.
   211     Tolerance() : _epsilon(def_epsilon) {}
   212     ///Constructor setting the epsilon tolerance.
   213     Tolerance(long double e) : _epsilon(e) {}
   214 
   215     ///Return the epsilon value.
   216     Value epsilon() const {return _epsilon;}
   217     ///Set the epsilon value.
   218     void epsilon(Value e) {_epsilon=e;}
   219 
   220     ///Return the default epsilon value.
   221     static Value defaultEpsilon() {return def_epsilon;}
   222     ///Set the default epsilon value.
   223     static void defaultEpsilon(Value e) {def_epsilon=e;}
   224 
   225     ///\name Comparisons
   226     ///See class Tolerance for more details.
   227 
   228     ///@{
   229 
   230     ///Returns \c true if \c a is \e surely strictly less than \c b
   231     bool less(Value a,Value b) const {return a+_epsilon<b;}
   232     ///Returns \c true if \c a is \e surely different from \c b
   233     bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
   234     ///Returns \c true if \c a is \e surely positive
   235     bool positive(Value a) const { return _epsilon<a; }
   236     ///Returns \c true if \c a is \e surely negative
   237     bool negative(Value a) const { return -_epsilon>a; }
   238     ///Returns \c true if \c a is \e surely non-zero
   239     bool nonZero(Value a) const { return positive(a)||negative(a); }
   240 
   241     ///@}
   242 
   243     ///Returns zero
   244     static Value zero() {return 0;}
   245   };
   246 
   247   ///Integer specialization of \ref Tolerance.
   248 
   249   ///Integer specialization of \ref Tolerance.
   250   ///\sa Tolerance
   251   template<>
   252   class Tolerance<int>
   253   {
   254   public:
   255     ///\e
   256     typedef int Value;
   257 
   258     ///\name Comparisons
   259     ///See \ref Tolerance for more details.
   260 
   261     ///@{
   262 
   263     ///Returns \c true if \c a is \e surely strictly less than \c b
   264     static bool less(Value a,Value b) { return a<b;}
   265     ///Returns \c true if \c a is \e surely different from \c b
   266     static bool different(Value a,Value b) { return a!=b; }
   267     ///Returns \c true if \c a is \e surely positive
   268     static bool positive(Value a) { return 0<a; }
   269     ///Returns \c true if \c a is \e surely negative
   270     static bool negative(Value a) { return 0>a; }
   271     ///Returns \c true if \c a is \e surely non-zero
   272     static bool nonZero(Value a) { return a!=0; }
   273 
   274     ///@}
   275 
   276     ///Returns zero
   277     static Value zero() {return 0;}
   278   };
   279 
   280   ///Unsigned integer specialization of \ref Tolerance.
   281 
   282   ///Unsigned integer specialization of \ref Tolerance.
   283   ///\sa Tolerance
   284   template<>
   285   class Tolerance<unsigned int>
   286   {
   287   public:
   288     ///\e
   289     typedef unsigned int Value;
   290 
   291     ///\name Comparisons
   292     ///See \ref Tolerance for more details.
   293 
   294     ///@{
   295 
   296     ///Returns \c true if \c a is \e surely strictly less than \c b
   297     static bool less(Value a,Value b) { return a<b;}
   298     ///Returns \c true if \c a is \e surely different from \c b
   299     static bool different(Value a,Value b) { return a!=b; }
   300     ///Returns \c true if \c a is \e surely positive
   301     static bool positive(Value a) { return 0<a; }
   302     ///Returns \c true if \c a is \e surely negative
   303     static bool negative(Value) { return false; }
   304     ///Returns \c true if \c a is \e surely non-zero
   305     static bool nonZero(Value a) { return a!=0; }
   306 
   307     ///@}
   308 
   309     ///Returns zero
   310     static Value zero() {return 0;}
   311   };
   312   
   313 
   314   ///Long integer specialization of \ref Tolerance.
   315 
   316   ///Long integer specialization of \ref Tolerance.
   317   ///\sa Tolerance
   318   template<>
   319   class Tolerance<long int>
   320   {
   321   public:
   322     ///\e
   323     typedef long int Value;
   324 
   325     ///\name Comparisons
   326     ///See \ref Tolerance for more details.
   327 
   328     ///@{
   329 
   330     ///Returns \c true if \c a is \e surely strictly less than \c b
   331     static bool less(Value a,Value b) { return a<b;}
   332     ///Returns \c true if \c a is \e surely different from \c b
   333     static bool different(Value a,Value b) { return a!=b; }
   334     ///Returns \c true if \c a is \e surely positive
   335     static bool positive(Value a) { return 0<a; }
   336     ///Returns \c true if \c a is \e surely negative
   337     static bool negative(Value a) { return 0>a; }
   338     ///Returns \c true if \c a is \e surely non-zero
   339     static bool nonZero(Value a) { return a!=0;}
   340 
   341     ///@}
   342 
   343     ///Returns zero
   344     static Value zero() {return 0;}
   345   };
   346 
   347   ///Unsigned long integer specialization of \ref Tolerance.
   348 
   349   ///Unsigned long integer specialization of \ref Tolerance.
   350   ///\sa Tolerance
   351   template<>
   352   class Tolerance<unsigned long int>
   353   {
   354   public:
   355     ///\e
   356     typedef unsigned long int Value;
   357 
   358     ///\name Comparisons
   359     ///See \ref Tolerance for more details.
   360 
   361     ///@{
   362 
   363     ///Returns \c true if \c a is \e surely strictly less than \c b
   364     static bool less(Value a,Value b) { return a<b;}
   365     ///Returns \c true if \c a is \e surely different from \c b
   366     static bool different(Value a,Value b) { return a!=b; }
   367     ///Returns \c true if \c a is \e surely positive
   368     static bool positive(Value a) { return 0<a; }
   369     ///Returns \c true if \c a is \e surely negative
   370     static bool negative(Value) { return false; }
   371     ///Returns \c true if \c a is \e surely non-zero
   372     static bool nonZero(Value a) { return a!=0;}
   373 
   374     ///@}
   375 
   376     ///Returns zero
   377     static Value zero() {return 0;}
   378   };
   379 
   380 #if defined __GNUC__ && !defined __STRICT_ANSI__
   381 
   382   ///Long long integer specialization of \ref Tolerance.
   383 
   384   ///Long long integer specialization of \ref Tolerance.
   385   ///\warning This class (more exactly, type <tt>long long</tt>)
   386   ///is not ansi compatible.
   387   ///\sa Tolerance
   388   template<>
   389   class Tolerance<long long int>
   390   {
   391   public:
   392     ///\e
   393     typedef long long int Value;
   394 
   395     ///\name Comparisons
   396     ///See \ref Tolerance for more details.
   397 
   398     ///@{
   399 
   400     ///Returns \c true if \c a is \e surely strictly less than \c b
   401     static bool less(Value a,Value b) { return a<b;}
   402     ///Returns \c true if \c a is \e surely different from \c b
   403     static bool different(Value a,Value b) { return a!=b; }
   404     ///Returns \c true if \c a is \e surely positive
   405     static bool positive(Value a) { return 0<a; }
   406     ///Returns \c true if \c a is \e surely negative
   407     static bool negative(Value a) { return 0>a; }
   408     ///Returns \c true if \c a is \e surely non-zero
   409     static bool nonZero(Value a) { return a!=0;}
   410 
   411     ///@}
   412 
   413     ///Returns zero
   414     static Value zero() {return 0;}
   415   };
   416 
   417   ///Unsigned long long integer specialization of \ref Tolerance.
   418 
   419   ///Unsigned long long integer specialization of \ref Tolerance.
   420   ///\warning This class (more exactly, type <tt>unsigned long long</tt>)
   421   ///is not ansi compatible.
   422   ///\sa Tolerance
   423   template<>
   424   class Tolerance<unsigned long long int>
   425   {
   426   public:
   427     ///\e
   428     typedef unsigned long long int Value;
   429 
   430     ///\name Comparisons
   431     ///See \ref Tolerance for more details.
   432 
   433     ///@{
   434 
   435     ///Returns \c true if \c a is \e surely strictly less than \c b
   436     static bool less(Value a,Value b) { return a<b;}
   437     ///Returns \c true if \c a is \e surely different from \c b
   438     static bool different(Value a,Value b) { return a!=b; }
   439     ///Returns \c true if \c a is \e surely positive
   440     static bool positive(Value a) { return 0<a; }
   441     ///Returns \c true if \c a is \e surely negative
   442     static bool negative(Value) { return false; }
   443     ///Returns \c true if \c a is \e surely non-zero
   444     static bool nonZero(Value a) { return a!=0;}
   445 
   446     ///@}
   447 
   448     ///Returns zero
   449     static Value zero() {return 0;}
   450   };
   451 
   452 #endif
   453 
   454   /// @}
   455 
   456 } //namespace lemon
   457 
   458 #endif //LEMON_TOLERANCE_H