lemon/tolerance.h
author Alpar Juttner <alpar@cs.elte.hu>
Mon, 18 Aug 2008 20:33:11 +0200
changeset 249 f0b89f242745
parent 72 7050661bdea4
child 280 e7f8647ce760
permissions -rw-r--r--
Ignore the downloaded tag files
     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-2008
     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   ///\ref 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
    44   ///numerical data types. These specialized classes like
    45   ///Tolerance<double> 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 \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 Tolerance.
    91 
    92   ///Float specialization of 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 to the given value.
   107     Tolerance(float e) : _epsilon(e) {}
   108 
   109     ///Returns the epsilon value.
   110     Value epsilon() const {return _epsilon;}
   111     ///Sets the epsilon value.
   112     void epsilon(Value e) {_epsilon=e;}
   113 
   114     ///Returns the default epsilon value.
   115     static Value defaultEpsilon() {return def_epsilon;}
   116     ///Sets the default epsilon value.
   117     static void defaultEpsilon(Value e) {def_epsilon=e;}
   118 
   119     ///\name Comparisons
   120     ///See \ref lemon::Tolerance "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 Tolerance.
   142 
   143   ///Double specialization of 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 to the given value.
   158     Tolerance(double e) : _epsilon(e) {}
   159 
   160     ///Returns the epsilon value.
   161     Value epsilon() const {return _epsilon;}
   162     ///Sets the epsilon value.
   163     void epsilon(Value e) {_epsilon=e;}
   164 
   165     ///Returns the default epsilon value.
   166     static Value defaultEpsilon() {return def_epsilon;}
   167     ///Sets the default epsilon value.
   168     static void defaultEpsilon(Value e) {def_epsilon=e;}
   169 
   170     ///\name Comparisons
   171     ///See \ref lemon::Tolerance "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 Tolerance.
   193 
   194   ///Long double specialization of 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 to the given value.
   209     Tolerance(long double e) : _epsilon(e) {}
   210 
   211     ///Returns the epsilon value.
   212     Value epsilon() const {return _epsilon;}
   213     ///Sets the epsilon value.
   214     void epsilon(Value e) {_epsilon=e;}
   215 
   216     ///Returns the default epsilon value.
   217     static Value defaultEpsilon() {return def_epsilon;}
   218     ///Sets the default epsilon value.
   219     static void defaultEpsilon(Value e) {def_epsilon=e;}
   220 
   221     ///\name Comparisons
   222     ///See \ref lemon::Tolerance "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 Tolerance.
   244 
   245   ///Integer specialization of 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 lemon::Tolerance "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 Tolerance.
   277 
   278   ///Unsigned integer specialization of 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 lemon::Tolerance "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 
   310   ///Long integer specialization of Tolerance.
   311 
   312   ///Long integer specialization of Tolerance.
   313   ///\sa Tolerance
   314   template<>
   315   class Tolerance<long int>
   316   {
   317   public:
   318     ///\e
   319     typedef long int Value;
   320 
   321     ///\name Comparisons
   322     ///See \ref lemon::Tolerance "Tolerance" for more details.
   323 
   324     ///@{
   325 
   326     ///Returns \c true if \c a is \e surely strictly less than \c b
   327     static bool less(Value a,Value b) { return a<b;}
   328     ///Returns \c true if \c a is \e surely different from \c b
   329     static bool different(Value a,Value b) { return a!=b; }
   330     ///Returns \c true if \c a is \e surely positive
   331     static bool positive(Value a) { return 0<a; }
   332     ///Returns \c true if \c a is \e surely negative
   333     static bool negative(Value a) { return 0>a; }
   334     ///Returns \c true if \c a is \e surely non-zero
   335     static bool nonZero(Value a) { return a!=0;}
   336 
   337     ///@}
   338 
   339     ///Returns zero
   340     static Value zero() {return 0;}
   341   };
   342 
   343   ///Unsigned long integer specialization of Tolerance.
   344 
   345   ///Unsigned long integer specialization of Tolerance.
   346   ///\sa Tolerance
   347   template<>
   348   class Tolerance<unsigned long int>
   349   {
   350   public:
   351     ///\e
   352     typedef unsigned long int Value;
   353 
   354     ///\name Comparisons
   355     ///See \ref lemon::Tolerance "Tolerance" for more details.
   356 
   357     ///@{
   358 
   359     ///Returns \c true if \c a is \e surely strictly less than \c b
   360     static bool less(Value a,Value b) { return a<b;}
   361     ///Returns \c true if \c a is \e surely different from \c b
   362     static bool different(Value a,Value b) { return a!=b; }
   363     ///Returns \c true if \c a is \e surely positive
   364     static bool positive(Value a) { return 0<a; }
   365     ///Returns \c true if \c a is \e surely negative
   366     static bool negative(Value) { return false; }
   367     ///Returns \c true if \c a is \e surely non-zero
   368     static bool nonZero(Value a) { return a!=0;}
   369 
   370     ///@}
   371 
   372     ///Returns zero
   373     static Value zero() {return 0;}
   374   };
   375 
   376 #if defined __GNUC__ && !defined __STRICT_ANSI__
   377 
   378   ///Long long integer specialization of Tolerance.
   379 
   380   ///Long long integer specialization of Tolerance.
   381   ///\warning This class (more exactly, type <tt>long long</tt>)
   382   ///is not ansi compatible.
   383   ///\sa Tolerance
   384   template<>
   385   class Tolerance<long long int>
   386   {
   387   public:
   388     ///\e
   389     typedef long long int Value;
   390 
   391     ///\name Comparisons
   392     ///See \ref lemon::Tolerance "Tolerance" for more details.
   393 
   394     ///@{
   395 
   396     ///Returns \c true if \c a is \e surely strictly less than \c b
   397     static bool less(Value a,Value b) { return a<b;}
   398     ///Returns \c true if \c a is \e surely different from \c b
   399     static bool different(Value a,Value b) { return a!=b; }
   400     ///Returns \c true if \c a is \e surely positive
   401     static bool positive(Value a) { return 0<a; }
   402     ///Returns \c true if \c a is \e surely negative
   403     static bool negative(Value a) { return 0>a; }
   404     ///Returns \c true if \c a is \e surely non-zero
   405     static bool nonZero(Value a) { return a!=0;}
   406 
   407     ///@}
   408 
   409     ///Returns zero
   410     static Value zero() {return 0;}
   411   };
   412 
   413   ///Unsigned long long integer specialization of Tolerance.
   414 
   415   ///Unsigned long long integer specialization of Tolerance.
   416   ///\warning This class (more exactly, type <tt>unsigned long long</tt>)
   417   ///is not ansi compatible.
   418   ///\sa Tolerance
   419   template<>
   420   class Tolerance<unsigned long long int>
   421   {
   422   public:
   423     ///\e
   424     typedef unsigned long long int Value;
   425 
   426     ///\name Comparisons
   427     ///See \ref lemon::Tolerance "Tolerance" for more details.
   428 
   429     ///@{
   430 
   431     ///Returns \c true if \c a is \e surely strictly less than \c b
   432     static bool less(Value a,Value b) { return a<b;}
   433     ///Returns \c true if \c a is \e surely different from \c b
   434     static bool different(Value a,Value b) { return a!=b; }
   435     ///Returns \c true if \c a is \e surely positive
   436     static bool positive(Value a) { return 0<a; }
   437     ///Returns \c true if \c a is \e surely negative
   438     static bool negative(Value) { return false; }
   439     ///Returns \c true if \c a is \e surely non-zero
   440     static bool nonZero(Value a) { return a!=0;}
   441 
   442     ///@}
   443 
   444     ///Returns zero
   445     static Value zero() {return 0;}
   446   };
   447 
   448 #endif
   449 
   450   /// @}
   451 
   452 } //namespace lemon
   453 
   454 #endif //LEMON_TOLERANCE_H