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