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