lemon/tolerance.h
author Akos Ladanyi <ladanyi@tmit.bme.hu>
Fri, 29 May 2009 17:46:48 +0100
changeset 680 257e91516e09
parent 440 88ed40ad0d4f
parent 497 7d7d9debb29a
permissions -rw-r--r--
Set the version to 'hg-tip' if everything fails
alpar@209
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
alpar@7
     2
 *
alpar@209
     3
 * This file is a part of LEMON, a generic C++ optimization library.
alpar@7
     4
 *
alpar@440
     5
 * Copyright (C) 2003-2009
alpar@7
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
alpar@7
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
alpar@7
     8
 *
alpar@7
     9
 * Permission to use, modify and distribute this software is granted
alpar@7
    10
 * provided that this copyright notice appears in all copies. For
alpar@7
    11
 * precise terms see the accompanying LICENSE file.
alpar@7
    12
 *
alpar@7
    13
 * This software is provided "AS IS" with no warranty of any kind,
alpar@7
    14
 * express or implied, and with no claim as to its suitability for any
alpar@7
    15
 * purpose.
alpar@7
    16
 *
alpar@7
    17
 */
alpar@7
    18
alpar@7
    19
#ifndef LEMON_TOLERANCE_H
alpar@7
    20
#define LEMON_TOLERANCE_H
alpar@7
    21
alpar@7
    22
///\ingroup misc
alpar@7
    23
///\file
alpar@7
    24
///\brief A basic tool to handle the anomalies of calculation with
alpar@7
    25
///floating point numbers.
alpar@7
    26
///
alpar@7
    27
alpar@7
    28
namespace lemon {
alpar@7
    29
alpar@7
    30
  /// \addtogroup misc
alpar@7
    31
  /// @{
alpar@209
    32
alpar@7
    33
  ///\brief A class to provide a basic way to
alpar@7
    34
  ///handle the comparison of numbers that are obtained
alpar@7
    35
  ///as a result of a probably inexact computation.
alpar@7
    36
  ///
kpeter@49
    37
  ///\ref Tolerance is a class to provide a basic way to
alpar@7
    38
  ///handle the comparison of numbers that are obtained
alpar@7
    39
  ///as a result of a probably inexact computation.
alpar@7
    40
  ///
alpar@497
    41
  ///The general implementation is suitable only if the data type is exact,
alpar@497
    42
  ///like the integer types, otherwise a specialized version must be
alpar@497
    43
  ///implemented. These specialized classes like
kpeter@72
    44
  ///Tolerance<double> may offer additional tuning parameters.
alpar@7
    45
  ///
alpar@7
    46
  ///\sa Tolerance<float>
alpar@7
    47
  ///\sa Tolerance<double>
alpar@7
    48
  ///\sa Tolerance<long double>
alpar@7
    49
alpar@7
    50
  template<class T>
alpar@7
    51
  class Tolerance
alpar@7
    52
  {
alpar@7
    53
  public:
alpar@7
    54
    typedef T Value;
alpar@7
    55
alpar@7
    56
    ///\name Comparisons
kpeter@49
    57
    ///The concept is that these bool functions return \c true only if
alpar@7
    58
    ///the related comparisons hold even if some numerical error appeared
alpar@7
    59
    ///during the computations.
alpar@7
    60
alpar@7
    61
    ///@{
alpar@7
    62
alpar@7
    63
    ///Returns \c true if \c a is \e surely strictly less than \c b
alpar@497
    64
    static bool less(Value a,Value b) {return a<b;}
alpar@7
    65
    ///Returns \c true if \c a is \e surely different from \c b
alpar@497
    66
    static bool different(Value a,Value b) {return a!=b;}
alpar@7
    67
    ///Returns \c true if \c a is \e surely positive
alpar@497
    68
    static bool positive(Value a) {return static_cast<Value>(0) < a;}
alpar@7
    69
    ///Returns \c true if \c a is \e surely negative
alpar@497
    70
    static bool negative(Value a) {return a < static_cast<Value>(0);}
alpar@7
    71
    ///Returns \c true if \c a is \e surely non-zero
alpar@497
    72
    static bool nonZero(Value a) {return a != static_cast<Value>(0);}
alpar@7
    73
alpar@7
    74
    ///@}
alpar@7
    75
alpar@7
    76
    ///Returns the zero value.
alpar@497
    77
    static Value zero() {return static_cast<Value>(0);}
alpar@7
    78
alpar@7
    79
    //   static bool finite(Value a) {}
alpar@7
    80
    //   static Value big() {}
alpar@7
    81
    //   static Value negativeBig() {}
alpar@7
    82
  };
alpar@7
    83
alpar@7
    84
alpar@42
    85
  ///Float specialization of Tolerance.
alpar@7
    86
alpar@42
    87
  ///Float specialization of Tolerance.
alpar@7
    88
  ///\sa Tolerance
alpar@7
    89
  ///\relates Tolerance
alpar@7
    90
  template<>
alpar@7
    91
  class Tolerance<float>
alpar@7
    92
  {
alpar@7
    93
    static float def_epsilon;
alpar@7
    94
    float _epsilon;
alpar@7
    95
  public:
alpar@7
    96
    ///\e
alpar@7
    97
    typedef float Value;
alpar@7
    98
alpar@7
    99
    ///Constructor setting the epsilon tolerance to the default value.
alpar@7
   100
    Tolerance() : _epsilon(def_epsilon) {}
kpeter@49
   101
    ///Constructor setting the epsilon tolerance to the given value.
alpar@7
   102
    Tolerance(float e) : _epsilon(e) {}
alpar@7
   103
kpeter@49
   104
    ///Returns the epsilon value.
alpar@7
   105
    Value epsilon() const {return _epsilon;}
kpeter@49
   106
    ///Sets the epsilon value.
alpar@7
   107
    void epsilon(Value e) {_epsilon=e;}
alpar@7
   108
kpeter@49
   109
    ///Returns the default epsilon value.
alpar@7
   110
    static Value defaultEpsilon() {return def_epsilon;}
kpeter@49
   111
    ///Sets the default epsilon value.
alpar@7
   112
    static void defaultEpsilon(Value e) {def_epsilon=e;}
alpar@7
   113
alpar@7
   114
    ///\name Comparisons
kpeter@72
   115
    ///See \ref lemon::Tolerance "Tolerance" for more details.
alpar@7
   116
alpar@7
   117
    ///@{
alpar@7
   118
alpar@7
   119
    ///Returns \c true if \c a is \e surely strictly less than \c b
alpar@7
   120
    bool less(Value a,Value b) const {return a+_epsilon<b;}
alpar@7
   121
    ///Returns \c true if \c a is \e surely different from \c b
alpar@7
   122
    bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
alpar@7
   123
    ///Returns \c true if \c a is \e surely positive
alpar@7
   124
    bool positive(Value a) const { return _epsilon<a; }
alpar@7
   125
    ///Returns \c true if \c a is \e surely negative
alpar@7
   126
    bool negative(Value a) const { return -_epsilon>a; }
alpar@7
   127
    ///Returns \c true if \c a is \e surely non-zero
kpeter@16
   128
    bool nonZero(Value a) const { return positive(a)||negative(a); }
alpar@7
   129
alpar@7
   130
    ///@}
alpar@7
   131
alpar@7
   132
    ///Returns zero
alpar@7
   133
    static Value zero() {return 0;}
alpar@7
   134
  };
alpar@7
   135
alpar@42
   136
  ///Double specialization of Tolerance.
alpar@7
   137
alpar@42
   138
  ///Double specialization of Tolerance.
alpar@7
   139
  ///\sa Tolerance
alpar@7
   140
  ///\relates Tolerance
alpar@7
   141
  template<>
alpar@7
   142
  class Tolerance<double>
alpar@7
   143
  {
alpar@7
   144
    static double def_epsilon;
alpar@7
   145
    double _epsilon;
alpar@7
   146
  public:
alpar@7
   147
    ///\e
alpar@7
   148
    typedef double Value;
alpar@7
   149
alpar@7
   150
    ///Constructor setting the epsilon tolerance to the default value.
alpar@7
   151
    Tolerance() : _epsilon(def_epsilon) {}
kpeter@49
   152
    ///Constructor setting the epsilon tolerance to the given value.
alpar@7
   153
    Tolerance(double e) : _epsilon(e) {}
alpar@7
   154
kpeter@49
   155
    ///Returns the epsilon value.
alpar@7
   156
    Value epsilon() const {return _epsilon;}
kpeter@49
   157
    ///Sets the epsilon value.
alpar@7
   158
    void epsilon(Value e) {_epsilon=e;}
alpar@7
   159
kpeter@49
   160
    ///Returns the default epsilon value.
alpar@7
   161
    static Value defaultEpsilon() {return def_epsilon;}
kpeter@49
   162
    ///Sets the default epsilon value.
alpar@7
   163
    static void defaultEpsilon(Value e) {def_epsilon=e;}
alpar@7
   164
alpar@7
   165
    ///\name Comparisons
kpeter@72
   166
    ///See \ref lemon::Tolerance "Tolerance" for more details.
alpar@7
   167
alpar@7
   168
    ///@{
alpar@7
   169
alpar@7
   170
    ///Returns \c true if \c a is \e surely strictly less than \c b
alpar@7
   171
    bool less(Value a,Value b) const {return a+_epsilon<b;}
alpar@7
   172
    ///Returns \c true if \c a is \e surely different from \c b
alpar@7
   173
    bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
alpar@7
   174
    ///Returns \c true if \c a is \e surely positive
alpar@7
   175
    bool positive(Value a) const { return _epsilon<a; }
alpar@7
   176
    ///Returns \c true if \c a is \e surely negative
alpar@7
   177
    bool negative(Value a) const { return -_epsilon>a; }
alpar@7
   178
    ///Returns \c true if \c a is \e surely non-zero
kpeter@16
   179
    bool nonZero(Value a) const { return positive(a)||negative(a); }
alpar@7
   180
alpar@7
   181
    ///@}
alpar@7
   182
alpar@7
   183
    ///Returns zero
alpar@7
   184
    static Value zero() {return 0;}
alpar@7
   185
  };
alpar@7
   186
alpar@42
   187
  ///Long double specialization of Tolerance.
alpar@7
   188
alpar@42
   189
  ///Long double specialization of Tolerance.
alpar@7
   190
  ///\sa Tolerance
alpar@7
   191
  ///\relates Tolerance
alpar@7
   192
  template<>
alpar@7
   193
  class Tolerance<long double>
alpar@7
   194
  {
alpar@7
   195
    static long double def_epsilon;
alpar@7
   196
    long double _epsilon;
alpar@7
   197
  public:
alpar@7
   198
    ///\e
alpar@7
   199
    typedef long double Value;
alpar@7
   200
alpar@7
   201
    ///Constructor setting the epsilon tolerance to the default value.
alpar@7
   202
    Tolerance() : _epsilon(def_epsilon) {}
kpeter@49
   203
    ///Constructor setting the epsilon tolerance to the given value.
alpar@7
   204
    Tolerance(long double e) : _epsilon(e) {}
alpar@7
   205
kpeter@49
   206
    ///Returns the epsilon value.
alpar@7
   207
    Value epsilon() const {return _epsilon;}
kpeter@49
   208
    ///Sets the epsilon value.
alpar@7
   209
    void epsilon(Value e) {_epsilon=e;}
alpar@7
   210
kpeter@49
   211
    ///Returns the default epsilon value.
alpar@7
   212
    static Value defaultEpsilon() {return def_epsilon;}
kpeter@49
   213
    ///Sets the default epsilon value.
alpar@7
   214
    static void defaultEpsilon(Value e) {def_epsilon=e;}
alpar@7
   215
alpar@7
   216
    ///\name Comparisons
kpeter@72
   217
    ///See \ref lemon::Tolerance "Tolerance" for more details.
alpar@7
   218
alpar@7
   219
    ///@{
alpar@7
   220
alpar@7
   221
    ///Returns \c true if \c a is \e surely strictly less than \c b
alpar@7
   222
    bool less(Value a,Value b) const {return a+_epsilon<b;}
alpar@7
   223
    ///Returns \c true if \c a is \e surely different from \c b
alpar@7
   224
    bool different(Value a,Value b) const { return less(a,b)||less(b,a); }
alpar@7
   225
    ///Returns \c true if \c a is \e surely positive
alpar@7
   226
    bool positive(Value a) const { return _epsilon<a; }
alpar@7
   227
    ///Returns \c true if \c a is \e surely negative
alpar@7
   228
    bool negative(Value a) const { return -_epsilon>a; }
alpar@7
   229
    ///Returns \c true if \c a is \e surely non-zero
kpeter@16
   230
    bool nonZero(Value a) const { return positive(a)||negative(a); }
alpar@7
   231
alpar@7
   232
    ///@}
alpar@7
   233
alpar@7
   234
    ///Returns zero
alpar@7
   235
    static Value zero() {return 0;}
alpar@7
   236
  };
alpar@7
   237
alpar@7
   238
  /// @}
alpar@7
   239
alpar@7
   240
} //namespace lemon
alpar@7
   241
alpar@7
   242
#endif //LEMON_TOLERANCE_H