lemon/tolerance.h
author Peter Kovacs <kpeter@inf.elte.hu>
Fri, 03 Apr 2009 18:59:15 +0200
changeset 600 6ac5d9ae1d3d
parent 440 88ed40ad0d4f
parent 497 7d7d9debb29a
permissions -rw-r--r--
Support real types + numerical stability fix in NS (#254)

- Real types are supported by appropriate inicialization.
- A feature of the XTI spanning tree structure is removed to ensure
numerical stability (could cause problems using integer types).
The node potentials are updated always on the lower subtree,
in order to prevent overflow problems.
The former method isn't notably faster during to our tests.
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