lemon/random.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2242 16523135943d
child 2257 0a9393adc747
permissions -rw-r--r--
Update the Path concept
Concept check for paths

DirPath renamed to Path
The interface updated to the new lemon interface
Make difference between the empty path and the path from one node
Builder interface have not been changed
// I wanted but there was not accordance about it

UPath is removed
It was a buggy implementation, it could not iterate on the
nodes in the right order
Right way to use undirected paths => path of edges in undirected graphs

The tests have been modified to the current implementation
deba@2229
     1
/* -*- C++ -*-
deba@2229
     2
 *
deba@2229
     3
 * This file is a part of LEMON, a generic C++ optimization library
deba@2229
     4
 *
deba@2229
     5
 * Copyright (C) 2003-2006
deba@2229
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@2229
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@2229
     8
 *
deba@2229
     9
 * Permission to use, modify and distribute this software is granted
deba@2229
    10
 * provided that this copyright notice appears in all copies. For
deba@2229
    11
 * precise terms see the accompanying LICENSE file.
deba@2229
    12
 *
deba@2229
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@2229
    14
 * express or implied, and with no claim as to its suitability for any
deba@2229
    15
 * purpose.
deba@2229
    16
 *
deba@2229
    17
 */
deba@2229
    18
deba@2229
    19
#ifndef LEMON_RANDOM_H
deba@2229
    20
#define LEMON_RANDOM_H
deba@2229
    21
deba@2229
    22
#include <algorithm>
deba@2242
    23
#include <iterator>
deba@2242
    24
#include <vector>
deba@2229
    25
deba@2229
    26
#include <ctime>
deba@2229
    27
#include <cmath>
deba@2229
    28
#include <cmath>
deba@2229
    29
deba@2229
    30
///\ingroup misc
deba@2229
    31
///\file
deba@2229
    32
///\brief Mersenne Twister random number generator
deba@2229
    33
///
deba@2229
    34
///\author Balazs Dezso
deba@2229
    35
deba@2229
    36
namespace lemon {
deba@2229
    37
deba@2242
    38
  namespace _random_bits {
deba@2242
    39
    
deba@2242
    40
    template <typename _Word, int _bits = std::numeric_limits<_Word>::digits>
deba@2242
    41
    struct RandomTraits {};
deba@2242
    42
deba@2242
    43
    template <typename _Word>
deba@2242
    44
    struct RandomTraits<_Word, 32> {
deba@2242
    45
deba@2242
    46
      typedef _Word Word;
deba@2242
    47
      static const int bits = 32;
deba@2242
    48
deba@2242
    49
      static const int length = 624;
deba@2242
    50
      static const int shift = 397;
deba@2242
    51
      
deba@2242
    52
      static const Word mul = 0x6c078965u;
deba@2242
    53
      static const Word arrayInit = 0x012BD6AAu;
deba@2242
    54
      static const Word arrayMul1 = 0x0019660Du;
deba@2242
    55
      static const Word arrayMul2 = 0x5D588B65u;
deba@2242
    56
deba@2242
    57
      static const Word mask = 0x9908B0DFu;
deba@2242
    58
      static const Word loMask = (1u << 31) - 1;
deba@2242
    59
      static const Word hiMask = ~loMask;
deba@2242
    60
deba@2242
    61
deba@2242
    62
      static Word tempering(Word rnd) {
deba@2242
    63
        rnd ^= (rnd >> 11);
deba@2242
    64
        rnd ^= (rnd << 7) & 0x9D2C5680u;
deba@2242
    65
        rnd ^= (rnd << 15) & 0xEFC60000u;
deba@2242
    66
        rnd ^= (rnd >> 18);
deba@2242
    67
        return rnd;
deba@2242
    68
      }
deba@2242
    69
deba@2242
    70
    };
deba@2242
    71
deba@2242
    72
    template <typename _Word>
deba@2242
    73
    struct RandomTraits<_Word, 64> {
deba@2242
    74
deba@2242
    75
      typedef _Word Word;
deba@2242
    76
      static const int bits = 64;
deba@2242
    77
deba@2242
    78
      static const int length = 312;
deba@2242
    79
      static const int shift = 156;
deba@2242
    80
deba@2242
    81
      static const Word mul = (Word)0x5851F42Du << 32 | (Word)0x4C957F2Du;
deba@2242
    82
      static const Word arrayInit = (Word)0x00000000u << 32 |(Word)0x012BD6AAu;
deba@2242
    83
      static const Word arrayMul1 = (Word)0x369DEA0Fu << 32 |(Word)0x31A53F85u;
deba@2242
    84
      static const Word arrayMul2 = (Word)0x27BB2EE6u << 32 |(Word)0x87B0B0FDu;
deba@2242
    85
deba@2242
    86
      static const Word mask = (Word)0xB5026F5Au << 32 | (Word)0xA96619E9u;
deba@2242
    87
      static const Word loMask = ((Word)1u << 31) - 1;
deba@2242
    88
      static const Word hiMask = ~loMask;
deba@2242
    89
deba@2242
    90
      static Word tempering(Word rnd) {
deba@2242
    91
        rnd ^= (rnd >> 29) & ((Word)0x55555555u << 32 | (Word)0x55555555u);
deba@2242
    92
        rnd ^= (rnd << 17) & ((Word)0x71D67FFFu << 32 | (Word)0xEDA60000u);
deba@2242
    93
        rnd ^= (rnd << 37) & ((Word)0xFFF7EEE0u << 32 | (Word)0x00000000u);
deba@2242
    94
        rnd ^= (rnd >> 43);
deba@2242
    95
        return rnd;
deba@2242
    96
      }
deba@2242
    97
deba@2242
    98
    };
deba@2242
    99
deba@2242
   100
    template <typename _Word>
deba@2242
   101
    class RandomCore {
deba@2242
   102
    public:
deba@2242
   103
deba@2242
   104
      typedef _Word Word;
deba@2242
   105
deba@2242
   106
    private:
deba@2242
   107
deba@2242
   108
      static const int bits = RandomTraits<Word>::bits;
deba@2242
   109
deba@2242
   110
      static const int length = RandomTraits<Word>::length;
deba@2242
   111
      static const int shift = RandomTraits<Word>::shift;
deba@2242
   112
deba@2242
   113
    public:
deba@2242
   114
deba@2242
   115
      void initState() {
deba@2242
   116
        static const Word seedArray[4] = {
deba@2242
   117
          0x12345u, 0x23456u, 0x34567u, 0x45678u
deba@2242
   118
        };
deba@2242
   119
    
deba@2242
   120
        initState(seedArray, seedArray + 4);
deba@2242
   121
      }
deba@2242
   122
deba@2242
   123
      void initState(Word seed) {
deba@2242
   124
deba@2242
   125
        static const Word mul = RandomTraits<Word>::mul;
deba@2242
   126
deba@2242
   127
        current = state; 
deba@2242
   128
deba@2242
   129
        Word *curr = state + length - 1;
deba@2242
   130
        curr[0] = seed; --curr;
deba@2242
   131
        for (int i = 1; i < length; ++i) {
deba@2242
   132
          curr[0] = (mul * ( curr[1] ^ (curr[1] >> (bits - 2)) ) + i);
deba@2242
   133
          --curr;
deba@2242
   134
        }
deba@2242
   135
      }
deba@2242
   136
deba@2242
   137
      template <typename Iterator>
deba@2242
   138
      void initState(Iterator begin, Iterator end) {
deba@2242
   139
deba@2242
   140
        static const Word init = RandomTraits<Word>::arrayInit;
deba@2242
   141
        static const Word mul1 = RandomTraits<Word>::arrayMul1;
deba@2242
   142
        static const Word mul2 = RandomTraits<Word>::arrayMul2;
deba@2242
   143
deba@2242
   144
deba@2242
   145
        Word *curr = state + length - 1; --curr;
deba@2242
   146
        Iterator it = begin; int cnt = 0;
deba@2242
   147
        int num;
deba@2242
   148
deba@2242
   149
        initState(init);
deba@2242
   150
deba@2242
   151
        num = length > end - begin ? length : end - begin;
deba@2242
   152
        while (num--) {
deba@2242
   153
          curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul1)) 
deba@2242
   154
            + *it + cnt;
deba@2242
   155
          ++it; ++cnt;
deba@2242
   156
          if (it == end) {
deba@2242
   157
            it = begin; cnt = 0;
deba@2242
   158
          }
deba@2242
   159
          if (curr == state) {
deba@2242
   160
            curr = state + length - 1; curr[0] = state[0];
deba@2242
   161
          }
deba@2242
   162
          --curr;
deba@2242
   163
        }
deba@2242
   164
deba@2242
   165
        num = length - 1; cnt = length - (curr - state) - 1;
deba@2242
   166
        while (num--) {
deba@2242
   167
          curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul2))
deba@2242
   168
            - cnt;
deba@2242
   169
          --curr; ++cnt;
deba@2242
   170
          if (curr == state) {
deba@2242
   171
            curr = state + length - 1; curr[0] = state[0]; --curr;
deba@2242
   172
            cnt = 1;
deba@2242
   173
          }
deba@2242
   174
        }
deba@2242
   175
        
deba@2242
   176
        state[length - 1] = (Word)1 << (bits - 1);
deba@2242
   177
      }
deba@2242
   178
      
deba@2242
   179
      void copyState(const RandomCore& other) {
deba@2242
   180
        std::copy(other.state, other.state + length, state);
deba@2242
   181
        current = state + (other.current - other.state);
deba@2242
   182
      }
deba@2242
   183
deba@2242
   184
      Word operator()() {
deba@2242
   185
        if (current == state) fillState();
deba@2242
   186
        --current;
deba@2242
   187
        Word rnd = *current;
deba@2242
   188
        return RandomTraits<Word>::tempering(rnd);
deba@2242
   189
      }
deba@2242
   190
deba@2242
   191
    private:
deba@2242
   192
deba@2242
   193
  
deba@2242
   194
      void fillState() {
deba@2242
   195
        static const Word mask[2] = { 0x0ul, RandomTraits<Word>::mask };
deba@2242
   196
        static const Word loMask = RandomTraits<Word>::loMask;
deba@2242
   197
        static const Word hiMask = RandomTraits<Word>::hiMask;
deba@2242
   198
deba@2242
   199
        current = state + length; 
deba@2242
   200
deba@2242
   201
        register Word *curr = state + length - 1;
deba@2242
   202
        register long num;
deba@2242
   203
      
deba@2242
   204
        num = length - shift;
deba@2242
   205
        while (num--) {
deba@2242
   206
          curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
deba@2242
   207
            curr[- shift] ^ mask[curr[-1] & 1ul];
deba@2242
   208
          --curr;
deba@2242
   209
        }
deba@2242
   210
        num = shift - 1;
deba@2242
   211
        while (num--) {
deba@2242
   212
          curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
deba@2242
   213
            curr[length - shift] ^ mask[curr[-1] & 1ul];
deba@2242
   214
          --curr;
deba@2242
   215
        }
deba@2242
   216
        curr[0] = (((curr[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^
deba@2242
   217
          curr[length - shift] ^ mask[curr[length - 1] & 1ul];
deba@2242
   218
deba@2242
   219
      }
deba@2242
   220
deba@2242
   221
  
deba@2242
   222
      Word *current;
deba@2242
   223
      Word state[length];
deba@2242
   224
      
deba@2242
   225
    };
deba@2242
   226
deba@2242
   227
deba@2242
   228
    template <typename Result, 
deba@2242
   229
              int shift = (std::numeric_limits<Result>::digits + 1) / 2>
deba@2242
   230
    struct Masker {
deba@2242
   231
      static Result mask(const Result& result) {
deba@2242
   232
        return Masker<Result, (shift + 1) / 2>::
deba@2242
   233
          mask((Result)(result | (result >> shift)));
deba@2242
   234
      }
deba@2242
   235
    };
deba@2242
   236
    
deba@2242
   237
    template <typename Result>
deba@2242
   238
    struct Masker<Result, 1> {
deba@2242
   239
      static Result mask(const Result& result) {
deba@2242
   240
        return (Result)(result | (result >> 1));
deba@2242
   241
      }
deba@2242
   242
    };
deba@2242
   243
deba@2242
   244
    template <typename Result, typename Word, 
deba@2242
   245
              int rest = std::numeric_limits<Result>::digits, int shift = 0, 
deba@2242
   246
              bool last = rest <= std::numeric_limits<Word>::digits>
deba@2242
   247
    struct IntConversion {
deba@2242
   248
      static const int bits = std::numeric_limits<Word>::digits;
deba@2242
   249
    
deba@2242
   250
      static Result convert(RandomCore<Word>& rnd) {
deba@2242
   251
        return (Result)(rnd() >> (bits - rest)) << shift;
deba@2242
   252
      }
deba@2242
   253
      
deba@2242
   254
    }; 
deba@2242
   255
deba@2242
   256
    template <typename Result, typename Word, int rest, int shift> 
deba@2242
   257
    struct IntConversion<Result, Word, rest, shift, false> {
deba@2242
   258
      static const int bits = std::numeric_limits<Word>::digits;
deba@2242
   259
deba@2242
   260
      static Result convert(RandomCore<Word>& rnd) {
deba@2242
   261
        return ((Result)rnd() << shift) | 
deba@2242
   262
          IntConversion<Result, Word, rest - bits, shift + bits>::convert(rnd);
deba@2242
   263
      }
deba@2242
   264
    };
deba@2242
   265
deba@2242
   266
deba@2242
   267
    template <typename Result, typename Word,
deba@2242
   268
              bool one_word = std::numeric_limits<Word>::digits < 
deba@2242
   269
                              std::numeric_limits<Result>::digits>
deba@2242
   270
    struct Mapping {
deba@2242
   271
      static Result map(RandomCore<Word>& rnd, const Result& bound) {
deba@2242
   272
        Word max = (Word)(bound - 1);
deba@2242
   273
        Result mask = Masker<Result>::mask(bound - 1);
deba@2242
   274
        Result num;
deba@2242
   275
        do {
deba@2242
   276
          num = IntConversion<Result, Word>::convert(rnd) & mask; 
deba@2242
   277
        } while (num > max);
deba@2242
   278
        return num;
deba@2242
   279
      }
deba@2242
   280
    };
deba@2242
   281
deba@2242
   282
    template <typename Result, typename Word>
deba@2242
   283
    struct Mapping<Result, Word, false> {
deba@2242
   284
      static Result map(RandomCore<Word>& rnd, const Result& bound) {
deba@2242
   285
        Word max = (Word)(bound - 1);
deba@2242
   286
        Word mask = Masker<Word, (std::numeric_limits<Result>::digits + 1) / 2>
deba@2242
   287
          ::mask(max);
deba@2242
   288
        Word num;
deba@2242
   289
        do {
deba@2242
   290
          num = rnd() & mask;
deba@2242
   291
        } while (num > max);
deba@2242
   292
        return num;
deba@2242
   293
      }
deba@2242
   294
    };
deba@2242
   295
deba@2242
   296
    template <typename Result, int exp, bool pos = (exp >= 0)>
deba@2242
   297
    struct ShiftMultiplier {
deba@2242
   298
      static const Result multiplier() {
deba@2242
   299
        Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
deba@2242
   300
        res *= res;
deba@2242
   301
        if ((exp & 1) == 1) res *= (Result)2.0;
deba@2242
   302
        return res; 
deba@2242
   303
      }
deba@2242
   304
    };
deba@2242
   305
deba@2242
   306
    template <typename Result, int exp>
deba@2242
   307
    struct ShiftMultiplier<Result, exp, false> {
deba@2242
   308
      static const Result multiplier() {
deba@2242
   309
        Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
deba@2242
   310
        res *= res;
deba@2242
   311
        if ((exp & 1) == 1) res *= (Result)0.5;
deba@2242
   312
        return res; 
deba@2242
   313
      }
deba@2242
   314
    };
deba@2242
   315
deba@2242
   316
    template <typename Result>
deba@2242
   317
    struct ShiftMultiplier<Result, 0, true> {
deba@2242
   318
      static const Result multiplier() {
deba@2242
   319
        return (Result)1.0; 
deba@2242
   320
      }
deba@2242
   321
    };
deba@2242
   322
deba@2242
   323
    template <typename Result>
deba@2242
   324
    struct ShiftMultiplier<Result, -20, true> {
deba@2242
   325
      static const Result multiplier() {
deba@2242
   326
        return (Result)(1.0/1048576.0); 
deba@2242
   327
      }
deba@2242
   328
    };
deba@2242
   329
    
deba@2242
   330
    template <typename Result>
deba@2242
   331
    struct ShiftMultiplier<Result, -32, true> {
deba@2242
   332
      static const Result multiplier() {
deba@2242
   333
        return (Result)(1.0/424967296.0); 
deba@2242
   334
      }
deba@2242
   335
    };
deba@2242
   336
deba@2242
   337
    template <typename Result>
deba@2242
   338
    struct ShiftMultiplier<Result, -53, true> {
deba@2242
   339
      static const Result multiplier() {
deba@2242
   340
        return (Result)(1.0/9007199254740992.0); 
deba@2242
   341
      }
deba@2242
   342
    };
deba@2242
   343
deba@2242
   344
    template <typename Result>
deba@2242
   345
    struct ShiftMultiplier<Result, -64, true> {
deba@2242
   346
      static const Result multiplier() {
deba@2242
   347
        return (Result)(1.0/18446744073709551616.0); 
deba@2242
   348
      }
deba@2242
   349
    };
deba@2242
   350
deba@2242
   351
    template <typename Result, int exp>
deba@2242
   352
    struct Shifting {
deba@2242
   353
      static Result shift(const Result& result) {
deba@2242
   354
        return result * ShiftMultiplier<Result, exp>::multiplier();
deba@2242
   355
      }
deba@2242
   356
    };
deba@2242
   357
deba@2242
   358
    template <typename Result, typename Word,
deba@2242
   359
              int rest = std::numeric_limits<Result>::digits, int shift = 0, 
deba@2242
   360
              bool last = rest <= std::numeric_limits<Word>::digits>
deba@2242
   361
    struct RealConversion{ 
deba@2242
   362
      static const int bits = std::numeric_limits<Word>::digits;
deba@2242
   363
deba@2242
   364
      static Result convert(RandomCore<Word>& rnd) {
deba@2242
   365
        return Shifting<Result, - shift - rest>::
deba@2242
   366
          shift((Result)(rnd() >> (bits - rest)));
deba@2242
   367
      }
deba@2242
   368
    };
deba@2242
   369
deba@2242
   370
    template <typename Result, typename Word, int rest, int shift>
deba@2242
   371
    struct RealConversion<Result, Word, rest, shift, false> { 
deba@2242
   372
      static const int bits = std::numeric_limits<Word>::digits;
deba@2242
   373
deba@2242
   374
      static Result convert(RandomCore<Word>& rnd) {
deba@2242
   375
        return Shifting<Result, - shift - bits>::shift((Result)rnd()) +
deba@2242
   376
          RealConversion<Result, Word, rest-bits, shift + bits>::convert(rnd);
deba@2242
   377
      }
deba@2242
   378
    };
deba@2242
   379
deba@2242
   380
    template <typename Result, typename Word>
deba@2242
   381
    struct Initializer {
deba@2242
   382
deba@2242
   383
      template <typename Iterator>
deba@2242
   384
      static void init(RandomCore<Word>& rnd, Iterator begin, Iterator end) {
deba@2242
   385
        std::vector<Word> ws;
deba@2242
   386
        for (Iterator it = begin; it != end; ++it) {
deba@2242
   387
          ws.push_back((Word)*it);
deba@2242
   388
        }
deba@2242
   389
        rnd.initState(ws.begin(), ws.end());
deba@2242
   390
      }
deba@2242
   391
deba@2242
   392
      template <typename Iterator>
deba@2242
   393
      static void init(RandomCore<Word>& rnd, Result seed) {
deba@2242
   394
        rnd.initState(seed);
deba@2242
   395
      }
deba@2242
   396
    };
deba@2242
   397
deba@2242
   398
    template <typename Word>
deba@2242
   399
    struct BoolConversion {
deba@2242
   400
      static bool convert(RandomCore<Word>& rnd) {
deba@2242
   401
        return (rnd() & 1) == 1;
deba@2242
   402
      }
deba@2242
   403
    };
deba@2242
   404
deba@2242
   405
  }
deba@2229
   406
deba@2229
   407
  /// \ingroup misc
deba@2229
   408
  ///
deba@2229
   409
  /// \brief Mersenne Twister random number generator
deba@2229
   410
  ///
deba@2229
   411
  /// The Mersenne Twister is a twisted generalized feedback
deba@2242
   412
  /// shift-register generator of Matsumoto and Nishimura. The period
deba@2242
   413
  /// of this generator is \f$ 2^{19937} - 1 \f$ and it is
deba@2242
   414
  /// equi-distributed in 623 dimensions for 32-bit numbers. The time
deba@2242
   415
  /// performance of this generator is comparable to the commonly used
deba@2242
   416
  /// generators.
deba@2242
   417
  ///
deba@2242
   418
  /// This implementation is specialized for both 32-bit and 64-bit
deba@2242
   419
  /// architectures. The generators differ sligthly in the
deba@2242
   420
  /// initialization and generation phase so they produce two
deba@2242
   421
  /// completly different sequences.
deba@2242
   422
  ///
deba@2242
   423
  /// The generator gives back random numbers of serveral types. To
deba@2242
   424
  /// get a random number from a range of a floating point type you
deba@2245
   425
  /// can use one form of the \c operator() or the \c real() member
deba@2245
   426
  /// function. If you want to get random number from the {0, 1, ...,
deba@2245
   427
  /// n-1} integer range use the \c operator[] or the \c integer()
deba@2245
   428
  /// method. And to get random number from the whole range of an
deba@2245
   429
  /// integer type you can use the argumentless \c integer() or \c
deba@2245
   430
  /// uinteger() functions. After all you can get random bool with
deba@2245
   431
  /// equal chance of true and false or given probability of true
deba@2245
   432
  /// result with the \c boolean() member functions.
deba@2242
   433
  ///
deba@2242
   434
  ///\code
deba@2245
   435
  /// // The commented code is identical to the other
deba@2245
   436
  /// double a = rnd();                     // [0.0, 1.0)
deba@2245
   437
  /// // double a = rnd.real();             // [0.0, 1.0)
deba@2245
   438
  /// double b = rnd(100.0);                // [0.0, 100.0)
deba@2245
   439
  /// // double b = rnd.real(100.0);        // [0.0, 100.0)
deba@2245
   440
  /// double c = rnd(1.0, 2.0);             // [1.0, 2.0)
deba@2245
   441
  /// // double c = rnd.real(1.0, 2.0);     // [1.0, 2.0)
deba@2245
   442
  /// int d = rnd[100000];                  // 0..99999
deba@2245
   443
  /// // int d = rnd.integer(100000);       // 0..99999
deba@2245
   444
  /// int e = rnd[6] + 1;                   // 1..6
deba@2245
   445
  /// // int e = rnd.integer(1, 1 + 6);     // 1..6
deba@2242
   446
  /// int b = rnd.uinteger<int>();          // 0 .. 2^31 - 1
deba@2242
   447
  /// int c = rnd.integer<int>();           // - 2^31 .. 2^31 - 1
deba@2242
   448
  /// bool g = rnd.boolean();               // P(g = true) = 0.5
deba@2242
   449
  /// bool h = rnd.boolean(0.8);            // P(h = true) = 0.8
deba@2242
   450
  ///\endcode
deba@2242
   451
  ///
deba@2245
   452
  /// The lemon provides a global instance of the random number
deba@2245
   453
  /// generator which name is \ref lemon::rnd "rnd". Usually it is a
deba@2245
   454
  /// good programming convenience to use this global generator to get
deba@2245
   455
  /// random numbers.
deba@2229
   456
  ///
deba@2229
   457
  /// \author Balazs Dezso
deba@2229
   458
  class Random {
deba@2242
   459
  private:
deba@2229
   460
deba@2245
   461
    // architecture word
deba@2242
   462
    typedef unsigned long Word;
deba@2242
   463
    
deba@2242
   464
    _random_bits::RandomCore<Word> core;
deba@2229
   465
deba@2229
   466
  public:
deba@2229
   467
deba@2229
   468
    /// \brief Constructor
deba@2229
   469
    ///
deba@2242
   470
    /// Constructor with constant seeding.
deba@2242
   471
    Random() { core.initState(); }
deba@2229
   472
deba@2229
   473
    /// \brief Constructor
deba@2229
   474
    ///
deba@2242
   475
    /// Constructor with seed. The current number type will be converted
deba@2242
   476
    /// to the architecture word type.
deba@2242
   477
    template <typename Number>
deba@2242
   478
    Random(Number seed) { 
deba@2242
   479
      _random_bits::Initializer<Number, Word>::init(core, seed);
deba@2242
   480
    }
deba@2242
   481
deba@2242
   482
    /// \brief Constructor
deba@2242
   483
    ///
deba@2242
   484
    /// Constructor with array seeding. The given range should contain
deba@2242
   485
    /// any number type and the numbers will be converted to the
deba@2242
   486
    /// architecture word type.
deba@2242
   487
    template <typename Iterator>
deba@2242
   488
    Random(Iterator begin, Iterator end) { 
deba@2242
   489
      typedef typename std::iterator_traits<Iterator>::value_type Number;
deba@2242
   490
      _random_bits::Initializer<Number, Word>::init(core, begin, end);
deba@2242
   491
    }
deba@2229
   492
deba@2229
   493
    /// \brief Copy constructor
deba@2229
   494
    ///
deba@2229
   495
    /// Copy constructor. The generated sequence will be identical to
deba@2245
   496
    /// the other sequence. It can be used to save the current state
deba@2245
   497
    /// of the generator and later use it to generate the same
deba@2245
   498
    /// sequence.
deba@2242
   499
    Random(const Random& other) {
deba@2242
   500
      core.copyState(other.core);
deba@2229
   501
    }
deba@2229
   502
deba@2229
   503
    /// \brief Assign operator
deba@2229
   504
    ///
deba@2229
   505
    /// Assign operator. The generated sequence will be identical to
deba@2245
   506
    /// the other sequence. It can be used to save the current state
deba@2245
   507
    /// of the generator and later use it to generate the same
deba@2245
   508
    /// sequence.
deba@2229
   509
    Random& operator=(const Random& other) {
deba@2229
   510
      if (&other != this) {
deba@2242
   511
        core.copyState(other.core);
deba@2229
   512
      }
deba@2229
   513
      return *this;
deba@2229
   514
    }
deba@2229
   515
deba@2242
   516
    /// \brief Returns a random real number
deba@2229
   517
    ///
deba@2245
   518
    /// It returns a random real number from the range [0, 1). The
deba@2245
   519
    /// default Number type is double.
deba@2242
   520
    template <typename Number>
deba@2245
   521
    Number real() {
deba@2242
   522
      return _random_bits::RealConversion<Number, Word>::convert(core);
deba@2229
   523
    }
deba@2229
   524
deba@2245
   525
    double real() {
deba@2245
   526
      return real<double>();
deba@2245
   527
    }
deba@2245
   528
deba@2245
   529
    /// \brief Returns a random real number
deba@2245
   530
    ///
deba@2245
   531
    /// It returns a random real number from the range [0, b).
deba@2245
   532
    template <typename Number>
deba@2245
   533
    Number real(Number b) { 
deba@2245
   534
      return real<Number>() * b; 
deba@2245
   535
    }
deba@2245
   536
deba@2245
   537
    /// \brief Returns a random real number
deba@2245
   538
    ///
deba@2245
   539
    /// It returns a random real number from the range [a, b).
deba@2245
   540
    template <typename Number>
deba@2245
   541
    Number real(Number a, Number b) { 
deba@2245
   542
      return real<Number>() * (b - a) + a; 
deba@2245
   543
    }
deba@2245
   544
deba@2245
   545
    /// \brief Returns a random real number
deba@2245
   546
    ///
deba@2245
   547
    /// It returns a random double from the range [0, 1).
deba@2242
   548
    double operator()() {
deba@2245
   549
      return real<double>();
deba@2242
   550
    }
deba@2242
   551
deba@2242
   552
    /// \brief Returns a random real number
deba@2229
   553
    ///
deba@2242
   554
    /// It returns a random real number from the range [0, b).
deba@2242
   555
    template <typename Number>
deba@2242
   556
    Number operator()(Number b) { 
deba@2245
   557
      return real<Number>() * b; 
deba@2242
   558
    }
deba@2242
   559
deba@2242
   560
    /// \brief Returns a random real number
deba@2242
   561
    ///
deba@2242
   562
    /// It returns a random real number from the range [a, b).
deba@2242
   563
    template <typename Number>
deba@2242
   564
    Number operator()(Number a, Number b) { 
deba@2245
   565
      return real<Number>() * (b - a) + a; 
deba@2242
   566
    }
deba@2242
   567
deba@2242
   568
    /// \brief Returns a random integer from a range
deba@2242
   569
    ///
deba@2245
   570
    /// It returns a random integer from the range {0, 1, ..., b - 1}.
deba@2242
   571
    template <typename Number>
deba@2245
   572
    Number integer(Number b) {
deba@2245
   573
      return _random_bits::Mapping<Number, Word>::map(core, b);
deba@2245
   574
    }
deba@2245
   575
deba@2245
   576
    /// \brief Returns a random integer from a range
deba@2245
   577
    ///
deba@2245
   578
    /// It returns a random integer from the range {a, a + 1, ..., b - 1}.
deba@2245
   579
    template <typename Number>
deba@2245
   580
    Number integer(Number a, Number b) {
deba@2245
   581
      return _random_bits::Mapping<Number, Word>::map(core, b - a) + a;
deba@2245
   582
    }
deba@2245
   583
deba@2245
   584
    /// \brief Returns a random integer from a range
deba@2245
   585
    ///
deba@2245
   586
    /// It returns a random integer from the range {0, 1, ..., b - 1}.
deba@2245
   587
    template <typename Number>
deba@2245
   588
    Number operator[](Number b) {
deba@2245
   589
      return _random_bits::Mapping<Number, Word>::map(core, b);
deba@2242
   590
    }
deba@2242
   591
deba@2242
   592
    /// \brief Returns a random non-negative integer
deba@2242
   593
    ///
deba@2242
   594
    /// It returns a random non-negative integer uniformly from the
deba@2242
   595
    /// whole range of the current \c Number type.  The default result
deba@2242
   596
    /// type of this function is unsigned int.
deba@2242
   597
    template <typename Number>
deba@2242
   598
    Number uinteger() {
deba@2242
   599
      return _random_bits::IntConversion<Number, Word>::convert(core);
deba@2242
   600
    }
deba@2242
   601
deba@2242
   602
    unsigned int uinteger() {
deba@2242
   603
      return uinteger<unsigned int>();
deba@2242
   604
    }
deba@2242
   605
deba@2242
   606
    /// \brief Returns a random integer
deba@2242
   607
    ///
deba@2242
   608
    /// It returns a random integer uniformly from the whole range of
deba@2242
   609
    /// the current \c Number type. The default result type of this
deba@2242
   610
    /// function is int.
deba@2242
   611
    template <typename Number>
deba@2242
   612
    Number integer() {
deba@2242
   613
      static const int nb = std::numeric_limits<Number>::digits + 
deba@2242
   614
        (std::numeric_limits<Number>::is_signed ? 1 : 0);
deba@2242
   615
      return _random_bits::IntConversion<Number, Word, nb>::convert(core);
deba@2242
   616
    }
deba@2242
   617
deba@2242
   618
    int integer() {
deba@2242
   619
      return integer<int>();
deba@2229
   620
    }
deba@2229
   621
    
deba@2242
   622
    /// \brief Returns a random bool
deba@2229
   623
    ///
deba@2242
   624
    /// It returns a random bool
deba@2242
   625
    bool boolean() {
deba@2242
   626
      return _random_bits::BoolConversion<Word>::convert(core);
deba@2229
   627
    }
deba@2229
   628
deba@2229
   629
    /// \brief Returns a random bool
deba@2229
   630
    ///
deba@2242
   631
    /// It returns a random bool with given probability of true result
deba@2242
   632
    bool boolean(double p) {
deba@2242
   633
      return operator()() < p;
deba@2229
   634
    }
deba@2229
   635
    
deba@2229
   636
  };
deba@2229
   637
deba@2229
   638
deba@2229
   639
  extern Random rnd;
deba@2229
   640
deba@2229
   641
}
deba@2229
   642
deba@2229
   643
#endif