gravatar
deba@inf.elte.hu
deba@inf.elte.hu
Fix include files in random.h
0 1 0
default
1 file changed with 1 insertions and 2 deletions:
↑ Collapse diff ↑
Ignore white space 1536 line context
1 1
/* -*- C++ -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library
4 4
 *
5 5
 * Copyright (C) 2003-2008
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
/*
20 20
 * This file contains the reimplemented version of the Mersenne Twister
21 21
 * Generator of Matsumoto and Nishimura.
22 22
 *
23 23
 * See the appropriate copyright notice below.
24 24
 * 
25 25
 * Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
26 26
 * All rights reserved.                          
27 27
 *
28 28
 * Redistribution and use in source and binary forms, with or without
29 29
 * modification, are permitted provided that the following conditions
30 30
 * are met:
31 31
 *
32 32
 * 1. Redistributions of source code must retain the above copyright
33 33
 *    notice, this list of conditions and the following disclaimer.
34 34
 *
35 35
 * 2. Redistributions in binary form must reproduce the above copyright
36 36
 *    notice, this list of conditions and the following disclaimer in the
37 37
 *    documentation and/or other materials provided with the distribution.
38 38
 *
39 39
 * 3. The names of its contributors may not be used to endorse or promote 
40 40
 *    products derived from this software without specific prior written 
41 41
 *    permission.
42 42
 *
43 43
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
44 44
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
45 45
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
46 46
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
47 47
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
48 48
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
49 49
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
50 50
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 51
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
52 52
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
53 53
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
54 54
 * OF THE POSSIBILITY OF SUCH DAMAGE.
55 55
 *
56 56
 *
57 57
 * Any feedback is very welcome.
58 58
 * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
59 59
 * email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
60 60
 */
61 61

	
62 62
#ifndef LEMON_RANDOM_H
63 63
#define LEMON_RANDOM_H
64 64

	
65 65
#include <algorithm>
66 66
#include <iterator>
67 67
#include <vector>
68

	
69
#include <ctime>
68
#include <limits>
70 69

	
71 70
#include <lemon/math.h>
72 71
#include <lemon/dim2.h>
73 72

	
74 73
///\ingroup misc
75 74
///\file
76 75
///\brief Mersenne Twister random number generator
77 76

	
78 77
namespace lemon {
79 78

	
80 79
  namespace _random_bits {
81 80
    
82 81
    template <typename _Word, int _bits = std::numeric_limits<_Word>::digits>
83 82
    struct RandomTraits {};
84 83

	
85 84
    template <typename _Word>
86 85
    struct RandomTraits<_Word, 32> {
87 86

	
88 87
      typedef _Word Word;
89 88
      static const int bits = 32;
90 89

	
91 90
      static const int length = 624;
92 91
      static const int shift = 397;
93 92
      
94 93
      static const Word mul = 0x6c078965u;
95 94
      static const Word arrayInit = 0x012BD6AAu;
96 95
      static const Word arrayMul1 = 0x0019660Du;
97 96
      static const Word arrayMul2 = 0x5D588B65u;
98 97

	
99 98
      static const Word mask = 0x9908B0DFu;
100 99
      static const Word loMask = (1u << 31) - 1;
101 100
      static const Word hiMask = ~loMask;
102 101

	
103 102

	
104 103
      static Word tempering(Word rnd) {
105 104
        rnd ^= (rnd >> 11);
106 105
        rnd ^= (rnd << 7) & 0x9D2C5680u;
107 106
        rnd ^= (rnd << 15) & 0xEFC60000u;
108 107
        rnd ^= (rnd >> 18);
109 108
        return rnd;
110 109
      }
111 110

	
112 111
    };
113 112

	
114 113
    template <typename _Word>
115 114
    struct RandomTraits<_Word, 64> {
116 115

	
117 116
      typedef _Word Word;
118 117
      static const int bits = 64;
119 118

	
120 119
      static const int length = 312;
121 120
      static const int shift = 156;
122 121

	
123 122
      static const Word mul = Word(0x5851F42Du) << 32 | Word(0x4C957F2Du);
124 123
      static const Word arrayInit = Word(0x00000000u) << 32 |Word(0x012BD6AAu);
125 124
      static const Word arrayMul1 = Word(0x369DEA0Fu) << 32 |Word(0x31A53F85u);
126 125
      static const Word arrayMul2 = Word(0x27BB2EE6u) << 32 |Word(0x87B0B0FDu);
127 126

	
128 127
      static const Word mask = Word(0xB5026F5Au) << 32 | Word(0xA96619E9u);
129 128
      static const Word loMask = (Word(1u) << 31) - 1;
130 129
      static const Word hiMask = ~loMask;
131 130

	
132 131
      static Word tempering(Word rnd) {
133 132
        rnd ^= (rnd >> 29) & (Word(0x55555555u) << 32 | Word(0x55555555u));
134 133
        rnd ^= (rnd << 17) & (Word(0x71D67FFFu) << 32 | Word(0xEDA60000u));
135 134
        rnd ^= (rnd << 37) & (Word(0xFFF7EEE0u) << 32 | Word(0x00000000u));
136 135
        rnd ^= (rnd >> 43);
137 136
        return rnd;
138 137
      }
139 138

	
140 139
    };
141 140

	
142 141
    template <typename _Word>
143 142
    class RandomCore {
144 143
    public:
145 144

	
146 145
      typedef _Word Word;
147 146

	
148 147
    private:
149 148

	
150 149
      static const int bits = RandomTraits<Word>::bits;
151 150

	
152 151
      static const int length = RandomTraits<Word>::length;
153 152
      static const int shift = RandomTraits<Word>::shift;
154 153

	
155 154
    public:
156 155

	
157 156
      void initState() {
158 157
        static const Word seedArray[4] = {
159 158
          0x12345u, 0x23456u, 0x34567u, 0x45678u
160 159
        };
161 160
    
162 161
        initState(seedArray, seedArray + 4);
163 162
      }
164 163

	
165 164
      void initState(Word seed) {
166 165

	
167 166
        static const Word mul = RandomTraits<Word>::mul;
168 167

	
169 168
        current = state; 
170 169

	
171 170
        Word *curr = state + length - 1;
172 171
        curr[0] = seed; --curr;
173 172
        for (int i = 1; i < length; ++i) {
174 173
          curr[0] = (mul * ( curr[1] ^ (curr[1] >> (bits - 2)) ) + i);
175 174
          --curr;
176 175
        }
177 176
      }
178 177

	
179 178
      template <typename Iterator>
180 179
      void initState(Iterator begin, Iterator end) {
181 180

	
182 181
        static const Word init = RandomTraits<Word>::arrayInit;
183 182
        static const Word mul1 = RandomTraits<Word>::arrayMul1;
184 183
        static const Word mul2 = RandomTraits<Word>::arrayMul2;
185 184

	
186 185

	
187 186
        Word *curr = state + length - 1; --curr;
188 187
        Iterator it = begin; int cnt = 0;
189 188
        int num;
190 189

	
191 190
        initState(init);
192 191

	
193 192
        num = length > end - begin ? length : end - begin;
194 193
        while (num--) {
195 194
          curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul1)) 
196 195
            + *it + cnt;
197 196
          ++it; ++cnt;
198 197
          if (it == end) {
199 198
            it = begin; cnt = 0;
200 199
          }
201 200
          if (curr == state) {
202 201
            curr = state + length - 1; curr[0] = state[0];
203 202
          }
204 203
          --curr;
205 204
        }
206 205

	
207 206
        num = length - 1; cnt = length - (curr - state) - 1;
208 207
        while (num--) {
209 208
          curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul2))
210 209
            - cnt;
211 210
          --curr; ++cnt;
212 211
          if (curr == state) {
213 212
            curr = state + length - 1; curr[0] = state[0]; --curr;
214 213
            cnt = 1;
215 214
          }
216 215
        }
217 216
        
218 217
        state[length - 1] = Word(1) << (bits - 1);
219 218
      }
220 219
      
221 220
      void copyState(const RandomCore& other) {
222 221
        std::copy(other.state, other.state + length, state);
223 222
        current = state + (other.current - other.state);
224 223
      }
225 224

	
226 225
      Word operator()() {
227 226
        if (current == state) fillState();
228 227
        --current;
229 228
        Word rnd = *current;
230 229
        return RandomTraits<Word>::tempering(rnd);
231 230
      }
232 231

	
233 232
    private:
234 233

	
235 234
  
236 235
      void fillState() {
237 236
        static const Word mask[2] = { 0x0ul, RandomTraits<Word>::mask };
238 237
        static const Word loMask = RandomTraits<Word>::loMask;
239 238
        static const Word hiMask = RandomTraits<Word>::hiMask;
240 239

	
241 240
        current = state + length; 
242 241

	
243 242
        register Word *curr = state + length - 1;
244 243
        register long num;
245 244
      
246 245
        num = length - shift;
247 246
        while (num--) {
248 247
          curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
249 248
            curr[- shift] ^ mask[curr[-1] & 1ul];
250 249
          --curr;
251 250
        }
252 251
        num = shift - 1;
253 252
        while (num--) {
254 253
          curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
255 254
            curr[length - shift] ^ mask[curr[-1] & 1ul];
256 255
          --curr;
257 256
        }
258 257
        state[0] = (((state[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^
259 258
          curr[length - shift] ^ mask[curr[length - 1] & 1ul];
260 259

	
261 260
      }
262 261

	
263 262
  
264 263
      Word *current;
265 264
      Word state[length];
266 265
      
267 266
    };
268 267

	
269 268

	
270 269
    template <typename Result, 
271 270
              int shift = (std::numeric_limits<Result>::digits + 1) / 2>
272 271
    struct Masker {
273 272
      static Result mask(const Result& result) {
274 273
        return Masker<Result, (shift + 1) / 2>::
275 274
          mask(static_cast<Result>(result | (result >> shift)));
276 275
      }
277 276
    };
278 277
    
279 278
    template <typename Result>
280 279
    struct Masker<Result, 1> {
281 280
      static Result mask(const Result& result) {
282 281
        return static_cast<Result>(result | (result >> 1));
283 282
      }
284 283
    };
285 284

	
286 285
    template <typename Result, typename Word, 
287 286
              int rest = std::numeric_limits<Result>::digits, int shift = 0, 
288 287
              bool last = rest <= std::numeric_limits<Word>::digits>
289 288
    struct IntConversion {
290 289
      static const int bits = std::numeric_limits<Word>::digits;
291 290
    
292 291
      static Result convert(RandomCore<Word>& rnd) {
293 292
        return static_cast<Result>(rnd() >> (bits - rest)) << shift;
294 293
      }
295 294
      
296 295
    }; 
297 296

	
298 297
    template <typename Result, typename Word, int rest, int shift> 
299 298
    struct IntConversion<Result, Word, rest, shift, false> {
300 299
      static const int bits = std::numeric_limits<Word>::digits;
301 300

	
302 301
      static Result convert(RandomCore<Word>& rnd) {
303 302
        return (static_cast<Result>(rnd()) << shift) | 
304 303
          IntConversion<Result, Word, rest - bits, shift + bits>::convert(rnd);
305 304
      }
306 305
    };
307 306

	
308 307

	
309 308
    template <typename Result, typename Word,
310 309
              bool one_word = (std::numeric_limits<Word>::digits < 
311 310
			       std::numeric_limits<Result>::digits) >
312 311
    struct Mapping {
313 312
      static Result map(RandomCore<Word>& rnd, const Result& bound) {
314 313
        Word max = Word(bound - 1);
315 314
        Result mask = Masker<Result>::mask(bound - 1);
316 315
        Result num;
317 316
        do {
318 317
          num = IntConversion<Result, Word>::convert(rnd) & mask; 
319 318
        } while (num > max);
320 319
        return num;
321 320
      }
322 321
    };
323 322

	
324 323
    template <typename Result, typename Word>
325 324
    struct Mapping<Result, Word, false> {
326 325
      static Result map(RandomCore<Word>& rnd, const Result& bound) {
327 326
        Word max = Word(bound - 1);
328 327
        Word mask = Masker<Word, (std::numeric_limits<Result>::digits + 1) / 2>
329 328
          ::mask(max);
330 329
        Word num;
331 330
        do {
332 331
          num = rnd() & mask;
333 332
        } while (num > max);
334 333
        return num;
335 334
      }
336 335
    };
337 336

	
338 337
    template <typename Result, int exp, bool pos = (exp >= 0)>
339 338
    struct ShiftMultiplier {
340 339
      static const Result multiplier() {
341 340
        Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
342 341
        res *= res;
343 342
        if ((exp & 1) == 1) res *= static_cast<Result>(2.0);
344 343
        return res; 
345 344
      }
346 345
    };
347 346

	
348 347
    template <typename Result, int exp>
349 348
    struct ShiftMultiplier<Result, exp, false> {
350 349
      static const Result multiplier() {
351 350
        Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
352 351
        res *= res;
353 352
        if ((exp & 1) == 1) res *= static_cast<Result>(0.5);
354 353
        return res; 
355 354
      }
356 355
    };
357 356

	
358 357
    template <typename Result>
359 358
    struct ShiftMultiplier<Result, 0, true> {
360 359
      static const Result multiplier() {
361 360
        return static_cast<Result>(1.0); 
362 361
      }
363 362
    };
364 363

	
365 364
    template <typename Result>
366 365
    struct ShiftMultiplier<Result, -20, true> {
367 366
      static const Result multiplier() {
368 367
        return static_cast<Result>(1.0/1048576.0); 
369 368
      }
370 369
    };
371 370
    
372 371
    template <typename Result>
373 372
    struct ShiftMultiplier<Result, -32, true> {
374 373
      static const Result multiplier() {
375 374
        return static_cast<Result>(1.0/424967296.0); 
376 375
      }
377 376
    };
378 377

	
379 378
    template <typename Result>
380 379
    struct ShiftMultiplier<Result, -53, true> {
381 380
      static const Result multiplier() {
382 381
        return static_cast<Result>(1.0/9007199254740992.0); 
383 382
      }
384 383
    };
385 384

	
386 385
    template <typename Result>
387 386
    struct ShiftMultiplier<Result, -64, true> {
388 387
      static const Result multiplier() {
389 388
        return static_cast<Result>(1.0/18446744073709551616.0); 
390 389
      }
391 390
    };
392 391

	
393 392
    template <typename Result, int exp>
394 393
    struct Shifting {
395 394
      static Result shift(const Result& result) {
396 395
        return result * ShiftMultiplier<Result, exp>::multiplier();
397 396
      }
398 397
    };
399 398

	
400 399
    template <typename Result, typename Word,
401 400
              int rest = std::numeric_limits<Result>::digits, int shift = 0, 
402 401
              bool last = rest <= std::numeric_limits<Word>::digits>
403 402
    struct RealConversion{ 
404 403
      static const int bits = std::numeric_limits<Word>::digits;
405 404

	
406 405
      static Result convert(RandomCore<Word>& rnd) {
407 406
        return Shifting<Result, - shift - rest>::
408 407
          shift(static_cast<Result>(rnd() >> (bits - rest)));
409 408
      }
410 409
    };
411 410

	
412 411
    template <typename Result, typename Word, int rest, int shift>
413 412
    struct RealConversion<Result, Word, rest, shift, false> { 
414 413
      static const int bits = std::numeric_limits<Word>::digits;
415 414

	
416 415
      static Result convert(RandomCore<Word>& rnd) {
417 416
        return Shifting<Result, - shift - bits>::
418 417
          shift(static_cast<Result>(rnd())) +
419 418
          RealConversion<Result, Word, rest-bits, shift + bits>::
420 419
          convert(rnd);
421 420
      }
422 421
    };
423 422

	
424 423
    template <typename Result, typename Word>
425 424
    struct Initializer {
426 425

	
427 426
      template <typename Iterator>
428 427
      static void init(RandomCore<Word>& rnd, Iterator begin, Iterator end) {
429 428
        std::vector<Word> ws;
430 429
        for (Iterator it = begin; it != end; ++it) {
431 430
          ws.push_back(Word(*it));
432 431
        }
433 432
        rnd.initState(ws.begin(), ws.end());
434 433
      }
435 434

	
436 435
      static void init(RandomCore<Word>& rnd, Result seed) {
437 436
        rnd.initState(seed);
438 437
      }
439 438
    };
440 439

	
441 440
    template <typename Word>
442 441
    struct BoolConversion {
443 442
      static bool convert(RandomCore<Word>& rnd) {
444 443
        return (rnd() & 1) == 1;
445 444
      }
446 445
    };
447 446

	
448 447
    template <typename Word>
449 448
    struct BoolProducer {
450 449
      Word buffer;
451 450
      int num;
452 451
      
453 452
      BoolProducer() : num(0) {}
454 453

	
455 454
      bool convert(RandomCore<Word>& rnd) {
456 455
        if (num == 0) {
457 456
          buffer = rnd();
458 457
          num = RandomTraits<Word>::bits;
459 458
        }
460 459
        bool r = (buffer & 1);
461 460
        buffer >>= 1;
462 461
        --num;
463 462
        return r;
464 463
      }
465 464
    };
466 465

	
467 466
  }
468 467

	
469 468
  /// \ingroup misc
470 469
  ///
471 470
  /// \brief Mersenne Twister random number generator
472 471
  ///
473 472
  /// The Mersenne Twister is a twisted generalized feedback
474 473
  /// shift-register generator of Matsumoto and Nishimura. The period
475 474
  /// of this generator is \f$ 2^{19937} - 1 \f$ and it is
476 475
  /// equi-distributed in 623 dimensions for 32-bit numbers. The time
477 476
  /// performance of this generator is comparable to the commonly used
478 477
  /// generators.
479 478
  ///
480 479
  /// This implementation is specialized for both 32-bit and 64-bit
481 480
  /// architectures. The generators differ sligthly in the
482 481
  /// initialization and generation phase so they produce two
483 482
  /// completly different sequences.
484 483
  ///
485 484
  /// The generator gives back random numbers of serveral types. To
486 485
  /// get a random number from a range of a floating point type you
487 486
  /// can use one form of the \c operator() or the \c real() member
488 487
  /// function. If you want to get random number from the {0, 1, ...,
489 488
  /// n-1} integer range use the \c operator[] or the \c integer()
490 489
  /// method. And to get random number from the whole range of an
491 490
  /// integer type you can use the argumentless \c integer() or \c
492 491
  /// uinteger() functions. After all you can get random bool with
493 492
  /// equal chance of true and false or given probability of true
494 493
  /// result with the \c boolean() member functions.
495 494
  ///
496 495
  ///\code
497 496
  /// // The commented code is identical to the other
498 497
  /// double a = rnd();                     // [0.0, 1.0)
499 498
  /// // double a = rnd.real();             // [0.0, 1.0)
500 499
  /// double b = rnd(100.0);                // [0.0, 100.0)
501 500
  /// // double b = rnd.real(100.0);        // [0.0, 100.0)
502 501
  /// double c = rnd(1.0, 2.0);             // [1.0, 2.0)
503 502
  /// // double c = rnd.real(1.0, 2.0);     // [1.0, 2.0)
504 503
  /// int d = rnd[100000];                  // 0..99999
505 504
  /// // int d = rnd.integer(100000);       // 0..99999
506 505
  /// int e = rnd[6] + 1;                   // 1..6
507 506
  /// // int e = rnd.integer(1, 1 + 6);     // 1..6
508 507
  /// int b = rnd.uinteger<int>();          // 0 .. 2^31 - 1
509 508
  /// int c = rnd.integer<int>();           // - 2^31 .. 2^31 - 1
510 509
  /// bool g = rnd.boolean();               // P(g = true) = 0.5
511 510
  /// bool h = rnd.boolean(0.8);            // P(h = true) = 0.8
512 511
  ///\endcode
513 512
  ///
514 513
  /// LEMON provides a global instance of the random number
515 514
  /// generator which name is \ref lemon::rnd "rnd". Usually it is a
516 515
  /// good programming convenience to use this global generator to get
517 516
  /// random numbers.
518 517
  class Random {
519 518
  private:
520 519

	
521 520
    // Architecture word
522 521
    typedef unsigned long Word;
523 522
    
524 523
    _random_bits::RandomCore<Word> core;
525 524
    _random_bits::BoolProducer<Word> bool_producer;
526 525
    
527 526

	
528 527
  public:
529 528

	
530 529
    /// \brief Default constructor
531 530
    ///
532 531
    /// Constructor with constant seeding.
533 532
    Random() { core.initState(); }
534 533

	
535 534
    /// \brief Constructor with seed
536 535
    ///
537 536
    /// Constructor with seed. The current number type will be converted
538 537
    /// to the architecture word type.
539 538
    template <typename Number>
540 539
    Random(Number seed) { 
541 540
      _random_bits::Initializer<Number, Word>::init(core, seed);
542 541
    }
543 542

	
544 543
    /// \brief Constructor with array seeding
545 544
    ///
546 545
    /// Constructor with array seeding. The given range should contain
547 546
    /// any number type and the numbers will be converted to the
548 547
    /// architecture word type.
549 548
    template <typename Iterator>
550 549
    Random(Iterator begin, Iterator end) { 
551 550
      typedef typename std::iterator_traits<Iterator>::value_type Number;
552 551
      _random_bits::Initializer<Number, Word>::init(core, begin, end);
553 552
    }
554 553

	
555 554
    /// \brief Copy constructor
556 555
    ///
557 556
    /// Copy constructor. The generated sequence will be identical to
558 557
    /// the other sequence. It can be used to save the current state
559 558
    /// of the generator and later use it to generate the same
560 559
    /// sequence.
561 560
    Random(const Random& other) {
562 561
      core.copyState(other.core);
563 562
    }
564 563

	
565 564
    /// \brief Assign operator
566 565
    ///
567 566
    /// Assign operator. The generated sequence will be identical to
568 567
    /// the other sequence. It can be used to save the current state
569 568
    /// of the generator and later use it to generate the same
570 569
    /// sequence.
571 570
    Random& operator=(const Random& other) {
572 571
      if (&other != this) {
573 572
        core.copyState(other.core);
574 573
      }
575 574
      return *this;
576 575
    }
577 576

	
578 577
    /// \brief Seeding random sequence
579 578
    ///
580 579
    /// Seeding the random sequence. The current number type will be
581 580
    /// converted to the architecture word type.
582 581
    template <typename Number>
583 582
    void seed(Number seed) { 
584 583
      _random_bits::Initializer<Number, Word>::init(core, seed);
585 584
    }
586 585

	
587 586
    /// \brief Seeding random sequence
588 587
    ///
589 588
    /// Seeding the random sequence. The given range should contain
590 589
    /// any number type and the numbers will be converted to the
591 590
    /// architecture word type.
592 591
    template <typename Iterator>
593 592
    void seed(Iterator begin, Iterator end) { 
594 593
      typedef typename std::iterator_traits<Iterator>::value_type Number;
595 594
      _random_bits::Initializer<Number, Word>::init(core, begin, end);
596 595
    }
597 596

	
598 597
    /// \brief Returns a random real number from the range [0, 1)
599 598
    ///
600 599
    /// It returns a random real number from the range [0, 1). The
601 600
    /// default Number type is \c double.
602 601
    template <typename Number>
603 602
    Number real() {
604 603
      return _random_bits::RealConversion<Number, Word>::convert(core);
605 604
    }
606 605

	
607 606
    double real() {
608 607
      return real<double>();
609 608
    }
610 609

	
611 610
    /// \brief Returns a random real number the range [0, b)
612 611
    ///
613 612
    /// It returns a random real number from the range [0, b).
614 613
    template <typename Number>
615 614
    Number real(Number b) { 
616 615
      return real<Number>() * b; 
617 616
    }
618 617

	
619 618
    /// \brief Returns a random real number from the range [a, b)
620 619
    ///
621 620
    /// It returns a random real number from the range [a, b).
622 621
    template <typename Number>
623 622
    Number real(Number a, Number b) { 
624 623
      return real<Number>() * (b - a) + a; 
625 624
    }
626 625

	
627 626
    /// \brief Returns a random real number from the range [0, 1)
628 627
    ///
629 628
    /// It returns a random double from the range [0, 1).
630 629
    double operator()() {
631 630
      return real<double>();
632 631
    }
633 632

	
634 633
    /// \brief Returns a random real number from the range [0, b)
635 634
    ///
636 635
    /// It returns a random real number from the range [0, b).
637 636
    template <typename Number>
638 637
    Number operator()(Number b) { 
639 638
      return real<Number>() * b; 
640 639
    }
641 640

	
642 641
    /// \brief Returns a random real number from the range [a, b)
643 642
    ///
644 643
    /// It returns a random real number from the range [a, b).
645 644
    template <typename Number>
646 645
    Number operator()(Number a, Number b) { 
647 646
      return real<Number>() * (b - a) + a; 
648 647
    }
649 648

	
650 649
    /// \brief Returns a random integer from a range
651 650
    ///
652 651
    /// It returns a random integer from the range {0, 1, ..., b - 1}.
653 652
    template <typename Number>
654 653
    Number integer(Number b) {
655 654
      return _random_bits::Mapping<Number, Word>::map(core, b);
656 655
    }
657 656

	
658 657
    /// \brief Returns a random integer from a range
659 658
    ///
660 659
    /// It returns a random integer from the range {a, a + 1, ..., b - 1}.
661 660
    template <typename Number>
662 661
    Number integer(Number a, Number b) {
663 662
      return _random_bits::Mapping<Number, Word>::map(core, b - a) + a;
664 663
    }
665 664

	
666 665
    /// \brief Returns a random integer from a range
667 666
    ///
668 667
    /// It returns a random integer from the range {0, 1, ..., b - 1}.
669 668
    template <typename Number>
670 669
    Number operator[](Number b) {
671 670
      return _random_bits::Mapping<Number, Word>::map(core, b);
672 671
    }
673 672

	
674 673
    /// \brief Returns a random non-negative integer
675 674
    ///
676 675
    /// It returns a random non-negative integer uniformly from the
677 676
    /// whole range of the current \c Number type. The default result
678 677
    /// type of this function is <tt>unsigned int</tt>.
679 678
    template <typename Number>
680 679
    Number uinteger() {
681 680
      return _random_bits::IntConversion<Number, Word>::convert(core);
682 681
    }
683 682

	
684 683
    unsigned int uinteger() {
685 684
      return uinteger<unsigned int>();
686 685
    }
687 686

	
688 687
    /// \brief Returns a random integer
689 688
    ///
690 689
    /// It returns a random integer uniformly from the whole range of
691 690
    /// the current \c Number type. The default result type of this
692 691
    /// function is \c int.
693 692
    template <typename Number>
694 693
    Number integer() {
695 694
      static const int nb = std::numeric_limits<Number>::digits + 
696 695
        (std::numeric_limits<Number>::is_signed ? 1 : 0);
697 696
      return _random_bits::IntConversion<Number, Word, nb>::convert(core);
698 697
    }
699 698

	
700 699
    int integer() {
701 700
      return integer<int>();
702 701
    }
703 702
    
704 703
    /// \brief Returns a random bool
705 704
    ///
706 705
    /// It returns a random bool. The generator holds a buffer for
707 706
    /// random bits. Every time when it become empty the generator makes
708 707
    /// a new random word and fill the buffer up.
709 708
    bool boolean() {
710 709
      return bool_producer.convert(core);
711 710
    }
712 711

	
713 712
    ///\name Non-uniform distributions
714 713
    ///
715 714
    
716 715
    ///@{
717 716
    
718 717
    /// \brief Returns a random bool
719 718
    ///
720 719
    /// It returns a random bool with given probability of true result.
721 720
    bool boolean(double p) {
722 721
      return operator()() < p;
723 722
    }
724 723

	
725 724
    /// Standard Gauss distribution
726 725

	
727 726
    /// Standard Gauss distribution.
728 727
    /// \note The Cartesian form of the Box-Muller
729 728
    /// transformation is used to generate a random normal distribution.
730 729
    /// \todo Consider using the "ziggurat" method instead.
731 730
    double gauss() 
732 731
    {
733 732
      double V1,V2,S;
734 733
      do {
735 734
	V1=2*real<double>()-1;
736 735
	V2=2*real<double>()-1;
737 736
	S=V1*V1+V2*V2;
738 737
      } while(S>=1);
739 738
      return std::sqrt(-2*std::log(S)/S)*V1;
740 739
    }
741 740
    /// Gauss distribution with given mean and standard deviation
742 741

	
743 742
    /// Gauss distribution with given mean and standard deviation.
744 743
    /// \sa gauss()
745 744
    double gauss(double mean,double std_dev)
746 745
    {
747 746
      return gauss()*std_dev+mean;
748 747
    }
749 748

	
750 749
    /// Exponential distribution with given mean
751 750

	
752 751
    /// This function generates an exponential distribution random number
753 752
    /// with mean <tt>1/lambda</tt>.
754 753
    ///
755 754
    double exponential(double lambda=1.0)
756 755
    {
757 756
      return -std::log(1.0-real<double>())/lambda;
758 757
    }
759 758

	
760 759
    /// Gamma distribution with given integer shape
761 760

	
762 761
    /// This function generates a gamma distribution random number.
763 762
    /// 
764 763
    ///\param k shape parameter (<tt>k>0</tt> integer)
765 764
    double gamma(int k) 
766 765
    {
767 766
      double s = 0;
768 767
      for(int i=0;i<k;i++) s-=std::log(1.0-real<double>());
769 768
      return s;
770 769
    }
771 770
    
772 771
    /// Gamma distribution with given shape and scale parameter
773 772

	
774 773
    /// This function generates a gamma distribution random number.
775 774
    /// 
776 775
    ///\param k shape parameter (<tt>k>0</tt>)
777 776
    ///\param theta scale parameter
778 777
    ///
779 778
    double gamma(double k,double theta=1.0)
780 779
    {
781 780
      double xi,nu;
782 781
      const double delta = k-std::floor(k);
783 782
      const double v0=E/(E-delta);
784 783
      do {
785 784
	double V0=1.0-real<double>();
786 785
	double V1=1.0-real<double>();
787 786
	double V2=1.0-real<double>();
788 787
	if(V2<=v0) 
789 788
	  {
790 789
	    xi=std::pow(V1,1.0/delta);
791 790
	    nu=V0*std::pow(xi,delta-1.0);
792 791
	  }
793 792
	else 
794 793
	  {
795 794
	    xi=1.0-std::log(V1);
796 795
	    nu=V0*std::exp(-xi);
797 796
	  }
798 797
      } while(nu>std::pow(xi,delta-1.0)*std::exp(-xi));
799 798
      return theta*(xi-gamma(int(std::floor(k))));
800 799
    }
801 800
    
802 801
    /// Weibull distribution
803 802

	
804 803
    /// This function generates a Weibull distribution random number.
805 804
    /// 
806 805
    ///\param k shape parameter (<tt>k>0</tt>)
807 806
    ///\param lambda scale parameter (<tt>lambda>0</tt>)
808 807
    ///
809 808
    double weibull(double k,double lambda)
810 809
    {
811 810
      return lambda*pow(-std::log(1.0-real<double>()),1.0/k);
812 811
    }  
813 812
      
814 813
    /// Pareto distribution
815 814

	
816 815
    /// This function generates a Pareto distribution random number.
817 816
    /// 
818 817
    ///\param k shape parameter (<tt>k>0</tt>)
819 818
    ///\param x_min location parameter (<tt>x_min>0</tt>)
820 819
    ///
821 820
    double pareto(double k,double x_min)
822 821
    {
823 822
      return exponential(gamma(k,1.0/x_min));
824 823
    }  
825 824
      
826 825
    /// Poisson distribution
827 826

	
828 827
    /// This function generates a Poisson distribution random number with
829 828
    /// parameter \c lambda.
830 829
    /// 
831 830
    /// The probability mass function of this distribusion is
832 831
    /// \f[ \frac{e^{-\lambda}\lambda^k}{k!} \f]
833 832
    /// \note The algorithm is taken from the book of Donald E. Knuth titled
834 833
    /// ''Seminumerical Algorithms'' (1969). Its running time is linear in the
835 834
    /// return value.
836 835
    
837 836
    int poisson(double lambda)
0 comments (0 inline)