lemon/random.h
author Alpar Juttner <alpar@cs.elte.hu>
Thu, 14 May 2015 16:07:38 +0200
changeset 1142 2f479109a71d
parent 1132 0998f70d0b2d
parent 1134 f70f688d9ef9
child 1163 db1d342a1087
permissions -rw-r--r--
Documentation for VF2 (#597)

The implementation of this feature was sponsored by QuantumBio Inc.
     1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
     2  *
     3  * This file is a part of LEMON, a generic C++ optimization library.
     4  *
     5  * Copyright (C) 2003-2009
     6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     8  *
     9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 /*
    20  * This file contains the reimplemented version of the Mersenne Twister
    21  * Generator of Matsumoto and Nishimura.
    22  *
    23  * See the appropriate copyright notice below.
    24  *
    25  * Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
    26  * All rights reserved.
    27  *
    28  * Redistribution and use in source and binary forms, with or without
    29  * modification, are permitted provided that the following conditions
    30  * are met:
    31  *
    32  * 1. Redistributions of source code must retain the above copyright
    33  *    notice, this list of conditions and the following disclaimer.
    34  *
    35  * 2. Redistributions in binary form must reproduce the above copyright
    36  *    notice, this list of conditions and the following disclaimer in the
    37  *    documentation and/or other materials provided with the distribution.
    38  *
    39  * 3. The names of its contributors may not be used to endorse or promote
    40  *    products derived from this software without specific prior written
    41  *    permission.
    42  *
    43  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    44  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    45  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
    46  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
    47  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
    48  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    49  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    50  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
    51  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    52  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    53  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
    54  * OF THE POSSIBILITY OF SUCH DAMAGE.
    55  *
    56  *
    57  * Any feedback is very welcome.
    58  * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
    59  * email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space)
    60  */
    61 
    62 #ifndef LEMON_RANDOM_H
    63 #define LEMON_RANDOM_H
    64 
    65 #include <lemon/config.h>
    66 
    67 #include <algorithm>
    68 #include <iterator>
    69 #include <vector>
    70 #include <limits>
    71 #include <fstream>
    72 
    73 #include <lemon/math.h>
    74 #include <lemon/dim2.h>
    75 
    76 #ifndef LEMON_WIN32
    77 #include <sys/time.h>
    78 #include <ctime>
    79 #include <sys/types.h>
    80 #include <unistd.h>
    81 #else
    82 #include <lemon/bits/windows.h>
    83 #endif
    84 
    85 ///\ingroup misc
    86 ///\file
    87 ///\brief Mersenne Twister random number generator
    88 
    89 namespace lemon {
    90 
    91   namespace _random_bits {
    92 
    93     template <typename _Word, int _bits = std::numeric_limits<_Word>::digits>
    94     struct RandomTraits {};
    95 
    96     template <typename _Word>
    97     struct RandomTraits<_Word, 32> {
    98 
    99       typedef _Word Word;
   100       static const int bits = 32;
   101 
   102       static const int length = 624;
   103       static const int shift = 397;
   104 
   105       static const Word mul = 0x6c078965u;
   106       static const Word arrayInit = 0x012BD6AAu;
   107       static const Word arrayMul1 = 0x0019660Du;
   108       static const Word arrayMul2 = 0x5D588B65u;
   109 
   110       static const Word mask = 0x9908B0DFu;
   111       static const Word loMask = (1u << 31) - 1;
   112       static const Word hiMask = ~loMask;
   113 
   114 
   115       static Word tempering(Word rnd) {
   116         rnd ^= (rnd >> 11);
   117         rnd ^= (rnd << 7) & 0x9D2C5680u;
   118         rnd ^= (rnd << 15) & 0xEFC60000u;
   119         rnd ^= (rnd >> 18);
   120         return rnd;
   121       }
   122 
   123     };
   124 
   125     template <typename _Word>
   126     struct RandomTraits<_Word, 64> {
   127 
   128       typedef _Word Word;
   129       static const int bits = 64;
   130 
   131       static const int length = 312;
   132       static const int shift = 156;
   133 
   134       static const Word mul = Word(0x5851F42Du) << 32 | Word(0x4C957F2Du);
   135       static const Word arrayInit = Word(0x00000000u) << 32 |Word(0x012BD6AAu);
   136       static const Word arrayMul1 = Word(0x369DEA0Fu) << 32 |Word(0x31A53F85u);
   137       static const Word arrayMul2 = Word(0x27BB2EE6u) << 32 |Word(0x87B0B0FDu);
   138 
   139       static const Word mask = Word(0xB5026F5Au) << 32 | Word(0xA96619E9u);
   140       static const Word loMask = (Word(1u) << 31) - 1;
   141       static const Word hiMask = ~loMask;
   142 
   143       static Word tempering(Word rnd) {
   144         rnd ^= (rnd >> 29) & (Word(0x55555555u) << 32 | Word(0x55555555u));
   145         rnd ^= (rnd << 17) & (Word(0x71D67FFFu) << 32 | Word(0xEDA60000u));
   146         rnd ^= (rnd << 37) & (Word(0xFFF7EEE0u) << 32 | Word(0x00000000u));
   147         rnd ^= (rnd >> 43);
   148         return rnd;
   149       }
   150 
   151     };
   152 
   153     template <typename _Word>
   154     class RandomCore {
   155     public:
   156 
   157       typedef _Word Word;
   158 
   159     private:
   160 
   161       static const int bits = RandomTraits<Word>::bits;
   162 
   163       static const int length = RandomTraits<Word>::length;
   164       static const int shift = RandomTraits<Word>::shift;
   165 
   166     public:
   167 
   168       void initState() {
   169         static const Word seedArray[4] = {
   170           0x12345u, 0x23456u, 0x34567u, 0x45678u
   171         };
   172 
   173         initState(seedArray, seedArray + 4);
   174       }
   175 
   176       void initState(Word seed) {
   177 
   178         static const Word mul = RandomTraits<Word>::mul;
   179 
   180         current = state;
   181 
   182         Word *curr = state + length - 1;
   183         curr[0] = seed; --curr;
   184         for (int i = 1; i < length; ++i) {
   185           curr[0] = (mul * ( curr[1] ^ (curr[1] >> (bits - 2)) ) + i);
   186           --curr;
   187         }
   188       }
   189 
   190       template <typename Iterator>
   191       void initState(Iterator begin, Iterator end) {
   192 
   193         static const Word init = RandomTraits<Word>::arrayInit;
   194         static const Word mul1 = RandomTraits<Word>::arrayMul1;
   195         static const Word mul2 = RandomTraits<Word>::arrayMul2;
   196 
   197 
   198         Word *curr = state + length - 1; --curr;
   199         Iterator it = begin; int cnt = 0;
   200         int num;
   201 
   202         initState(init);
   203 
   204         num = static_cast<int>(length > end - begin ? length : end - begin);
   205         while (num--) {
   206           curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul1))
   207             + *it + cnt;
   208           ++it; ++cnt;
   209           if (it == end) {
   210             it = begin; cnt = 0;
   211           }
   212           if (curr == state) {
   213             curr = state + length - 1; curr[0] = state[0];
   214           }
   215           --curr;
   216         }
   217 
   218         num = length - 1; cnt = static_cast<int>(length - (curr - state) - 1);
   219         while (num--) {
   220           curr[0] = (curr[0] ^ ((curr[1] ^ (curr[1] >> (bits - 2))) * mul2))
   221             - cnt;
   222           --curr; ++cnt;
   223           if (curr == state) {
   224             curr = state + length - 1; curr[0] = state[0]; --curr;
   225             cnt = 1;
   226           }
   227         }
   228 
   229         state[length - 1] = Word(1) << (bits - 1);
   230       }
   231 
   232       void copyState(const RandomCore& other) {
   233         std::copy(other.state, other.state + length, state);
   234         current = state + (other.current - other.state);
   235       }
   236 
   237       Word operator()() {
   238         if (current == state) fillState();
   239         --current;
   240         Word rnd = *current;
   241         return RandomTraits<Word>::tempering(rnd);
   242       }
   243 
   244     private:
   245 
   246 
   247       void fillState() {
   248         static const Word mask[2] = { 0x0ul, RandomTraits<Word>::mask };
   249         static const Word loMask = RandomTraits<Word>::loMask;
   250         static const Word hiMask = RandomTraits<Word>::hiMask;
   251 
   252         current = state + length;
   253 
   254         Word *curr = state + length - 1;
   255         long num;
   256 
   257         num = length - shift;
   258         while (num--) {
   259           curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
   260             curr[- shift] ^ mask[curr[-1] & 1ul];
   261           --curr;
   262         }
   263         num = shift - 1;
   264         while (num--) {
   265           curr[0] = (((curr[0] & hiMask) | (curr[-1] & loMask)) >> 1) ^
   266             curr[length - shift] ^ mask[curr[-1] & 1ul];
   267           --curr;
   268         }
   269         state[0] = (((state[0] & hiMask) | (curr[length - 1] & loMask)) >> 1) ^
   270           curr[length - shift] ^ mask[curr[length - 1] & 1ul];
   271 
   272       }
   273 
   274 
   275       Word *current;
   276       Word state[length];
   277 
   278     };
   279 
   280 
   281     template <typename Result,
   282               int shift = (std::numeric_limits<Result>::digits + 1) / 2>
   283     struct Masker {
   284       static Result mask(const Result& result) {
   285         return Masker<Result, (shift + 1) / 2>::
   286           mask(static_cast<Result>(result | (result >> shift)));
   287       }
   288     };
   289 
   290     template <typename Result>
   291     struct Masker<Result, 1> {
   292       static Result mask(const Result& result) {
   293         return static_cast<Result>(result | (result >> 1));
   294       }
   295     };
   296 
   297     template <typename Result, typename Word,
   298               int rest = std::numeric_limits<Result>::digits, int shift = 0,
   299               bool last = rest <= std::numeric_limits<Word>::digits>
   300     struct IntConversion {
   301       static const int bits = std::numeric_limits<Word>::digits;
   302 
   303       static Result convert(RandomCore<Word>& rnd) {
   304         return static_cast<Result>(rnd() >> (bits - rest)) << shift;
   305       }
   306 
   307     };
   308 
   309     template <typename Result, typename Word, int rest, int shift>
   310     struct IntConversion<Result, Word, rest, shift, false> {
   311       static const int bits = std::numeric_limits<Word>::digits;
   312 
   313       static Result convert(RandomCore<Word>& rnd) {
   314         return (static_cast<Result>(rnd()) << shift) |
   315           IntConversion<Result, Word, rest - bits, shift + bits>::convert(rnd);
   316       }
   317     };
   318 
   319 
   320     template <typename Result, typename Word,
   321               bool one_word = (std::numeric_limits<Word>::digits <
   322                                std::numeric_limits<Result>::digits) >
   323     struct Mapping {
   324       static Result map(RandomCore<Word>& rnd, const Result& bound) {
   325         Word max = Word(bound - 1);
   326         Result mask = Masker<Result>::mask(bound - 1);
   327         Result num;
   328         do {
   329           num = IntConversion<Result, Word>::convert(rnd) & mask;
   330         } while (num > max);
   331         return num;
   332       }
   333     };
   334 
   335     template <typename Result, typename Word>
   336     struct Mapping<Result, Word, false> {
   337       static Result map(RandomCore<Word>& rnd, const Result& bound) {
   338         Word max = Word(bound - 1);
   339         Word mask = Masker<Word, (std::numeric_limits<Result>::digits + 1) / 2>
   340           ::mask(max);
   341         Word num;
   342         do {
   343           num = rnd() & mask;
   344         } while (num > max);
   345         return num;
   346       }
   347     };
   348 
   349     template <typename Result, int exp>
   350     struct ShiftMultiplier {
   351       static const Result multiplier() {
   352         Result res = ShiftMultiplier<Result, exp / 2>::multiplier();
   353         res *= res;
   354         if ((exp & 1) == 1) res *= static_cast<Result>(0.5);
   355         return res;
   356       }
   357     };
   358 
   359     template <typename Result>
   360     struct ShiftMultiplier<Result, 0> {
   361       static const Result multiplier() {
   362         return static_cast<Result>(1.0);
   363       }
   364     };
   365 
   366     template <typename Result>
   367     struct ShiftMultiplier<Result, 20> {
   368       static const Result multiplier() {
   369         return static_cast<Result>(1.0/1048576.0);
   370       }
   371     };
   372 
   373     template <typename Result>
   374     struct ShiftMultiplier<Result, 32> {
   375       static const Result multiplier() {
   376         return static_cast<Result>(1.0/4294967296.0);
   377       }
   378     };
   379 
   380     template <typename Result>
   381     struct ShiftMultiplier<Result, 53> {
   382       static const Result multiplier() {
   383         return static_cast<Result>(1.0/9007199254740992.0);
   384       }
   385     };
   386 
   387     template <typename Result>
   388     struct ShiftMultiplier<Result, 64> {
   389       static const Result multiplier() {
   390         return static_cast<Result>(1.0/18446744073709551616.0);
   391       }
   392     };
   393 
   394     template <typename Result, int exp>
   395     struct Shifting {
   396       static Result shift(const Result& result) {
   397         return result * ShiftMultiplier<Result, exp>::multiplier();
   398       }
   399     };
   400 
   401     template <typename Result, typename Word,
   402               int rest = std::numeric_limits<Result>::digits, int shift = 0,
   403               bool last = rest <= std::numeric_limits<Word>::digits>
   404     struct RealConversion{
   405       static const int bits = std::numeric_limits<Word>::digits;
   406 
   407       static Result convert(RandomCore<Word>& rnd) {
   408         return Shifting<Result, shift + rest>::
   409           shift(static_cast<Result>(rnd() >> (bits - rest)));
   410       }
   411     };
   412 
   413     template <typename Result, typename Word, int rest, int shift>
   414     struct RealConversion<Result, Word, rest, shift, false> {
   415       static const int bits = std::numeric_limits<Word>::digits;
   416 
   417       static Result convert(RandomCore<Word>& rnd) {
   418         return Shifting<Result, shift + bits>::
   419           shift(static_cast<Result>(rnd())) +
   420           RealConversion<Result, Word, rest-bits, shift + bits>::
   421           convert(rnd);
   422       }
   423     };
   424 
   425     template <typename Result, typename Word>
   426     struct Initializer {
   427 
   428       template <typename Iterator>
   429       static void init(RandomCore<Word>& rnd, Iterator begin, Iterator end) {
   430         std::vector<Word> ws;
   431         for (Iterator it = begin; it != end; ++it) {
   432           ws.push_back(Word(*it));
   433         }
   434         rnd.initState(ws.begin(), ws.end());
   435       }
   436 
   437       static void init(RandomCore<Word>& rnd, Result seed) {
   438         rnd.initState(seed);
   439       }
   440     };
   441 
   442     template <typename Word>
   443     struct BoolConversion {
   444       static bool convert(RandomCore<Word>& rnd) {
   445         return (rnd() & 1) == 1;
   446       }
   447     };
   448 
   449     template <typename Word>
   450     struct BoolProducer {
   451       Word buffer;
   452       int num;
   453 
   454       BoolProducer() : num(0) {}
   455 
   456       bool convert(RandomCore<Word>& rnd) {
   457         if (num == 0) {
   458           buffer = rnd();
   459           num = RandomTraits<Word>::bits;
   460         }
   461         bool r = (buffer & 1);
   462         buffer >>= 1;
   463         --num;
   464         return r;
   465       }
   466     };
   467 
   468   }
   469 
   470   /// \ingroup misc
   471   ///
   472   /// \brief Mersenne Twister random number generator
   473   ///
   474   /// The Mersenne Twister is a twisted generalized feedback
   475   /// shift-register generator of Matsumoto and Nishimura. The period
   476   /// of this generator is \f$ 2^{19937} - 1 \f$ and it is
   477   /// equi-distributed in 623 dimensions for 32-bit numbers. The time
   478   /// performance of this generator is comparable to the commonly used
   479   /// generators.
   480   ///
   481   /// This implementation is specialized for both 32-bit and 64-bit
   482   /// architectures. The generators differ sligthly in the
   483   /// initialization and generation phase so they produce two
   484   /// completly different sequences.
   485   ///
   486   /// The generator gives back random numbers of serveral types. To
   487   /// get a random number from a range of a floating point type you
   488   /// can use one form of the \c operator() or the \c real() member
   489   /// function. If you want to get random number from the {0, 1, ...,
   490   /// n-1} integer range use the \c operator[] or the \c integer()
   491   /// method. And to get random number from the whole range of an
   492   /// integer type you can use the argumentless \c integer() or \c
   493   /// uinteger() functions. After all you can get random bool with
   494   /// equal chance of true and false or given probability of true
   495   /// result with the \c boolean() member functions.
   496   ///
   497   ///\code
   498   /// // The commented code is identical to the other
   499   /// double a = rnd();                     // [0.0, 1.0)
   500   /// // double a = rnd.real();             // [0.0, 1.0)
   501   /// double b = rnd(100.0);                // [0.0, 100.0)
   502   /// // double b = rnd.real(100.0);        // [0.0, 100.0)
   503   /// double c = rnd(1.0, 2.0);             // [1.0, 2.0)
   504   /// // double c = rnd.real(1.0, 2.0);     // [1.0, 2.0)
   505   /// int d = rnd[100000];                  // 0..99999
   506   /// // int d = rnd.integer(100000);       // 0..99999
   507   /// int e = rnd[6] + 1;                   // 1..6
   508   /// // int e = rnd.integer(1, 1 + 6);     // 1..6
   509   /// int b = rnd.uinteger<int>();          // 0 .. 2^31 - 1
   510   /// int c = rnd.integer<int>();           // - 2^31 .. 2^31 - 1
   511   /// bool g = rnd.boolean();               // P(g = true) = 0.5
   512   /// bool h = rnd.boolean(0.8);            // P(h = true) = 0.8
   513   ///\endcode
   514   ///
   515   /// LEMON provides a global instance of the random number
   516   /// generator which name is \ref lemon::rnd "rnd". Usually it is a
   517   /// good programming convenience to use this global generator to get
   518   /// random numbers.
   519   class Random {
   520   private:
   521 
   522     // Architecture word
   523     typedef unsigned long Word;
   524 
   525     _random_bits::RandomCore<Word> core;
   526     _random_bits::BoolProducer<Word> bool_producer;
   527 
   528 
   529   public:
   530 
   531     ///\name Initialization
   532     ///
   533     /// @{
   534 
   535     /// \brief Default constructor
   536     ///
   537     /// Constructor with constant seeding.
   538     Random() { core.initState(); }
   539 
   540     /// \brief Constructor with seed
   541     ///
   542     /// Constructor with seed. The current number type will be converted
   543     /// to the architecture word type.
   544     template <typename Number>
   545     Random(Number seed) {
   546       _random_bits::Initializer<Number, Word>::init(core, seed);
   547     }
   548 
   549     /// \brief Constructor with array seeding
   550     ///
   551     /// Constructor with array seeding. The given range should contain
   552     /// any number type and the numbers will be converted to the
   553     /// architecture word type.
   554     template <typename Iterator>
   555     Random(Iterator begin, Iterator end) {
   556       typedef typename std::iterator_traits<Iterator>::value_type Number;
   557       _random_bits::Initializer<Number, Word>::init(core, begin, end);
   558     }
   559 
   560     /// \brief Copy constructor
   561     ///
   562     /// Copy constructor. The generated sequence will be identical to
   563     /// the other sequence. It can be used to save the current state
   564     /// of the generator and later use it to generate the same
   565     /// sequence.
   566     Random(const Random& other) {
   567       core.copyState(other.core);
   568     }
   569 
   570     /// \brief Assign operator
   571     ///
   572     /// Assign operator. The generated sequence will be identical to
   573     /// the other sequence. It can be used to save the current state
   574     /// of the generator and later use it to generate the same
   575     /// sequence.
   576     Random& operator=(const Random& other) {
   577       if (&other != this) {
   578         core.copyState(other.core);
   579       }
   580       return *this;
   581     }
   582 
   583     /// \brief Seeding random sequence
   584     ///
   585     /// Seeding the random sequence. The current number type will be
   586     /// converted to the architecture word type.
   587     template <typename Number>
   588     void seed(Number seed) {
   589       _random_bits::Initializer<Number, Word>::init(core, seed);
   590     }
   591 
   592     /// \brief Seeding random sequence
   593     ///
   594     /// Seeding the random sequence. The given range should contain
   595     /// any number type and the numbers will be converted to the
   596     /// architecture word type.
   597     template <typename Iterator>
   598     void seed(Iterator begin, Iterator end) {
   599       typedef typename std::iterator_traits<Iterator>::value_type Number;
   600       _random_bits::Initializer<Number, Word>::init(core, begin, end);
   601     }
   602 
   603     /// \brief Seeding from file or from process id and time
   604     ///
   605     /// By default, this function calls the \c seedFromFile() member
   606     /// function with the <tt>/dev/urandom</tt> file. If it does not success,
   607     /// it uses the \c seedFromTime().
   608     /// \return Currently always \c true.
   609     bool seed() {
   610 #ifndef LEMON_WIN32
   611       if (seedFromFile("/dev/urandom", 0)) return true;
   612 #endif
   613       if (seedFromTime()) return true;
   614       return false;
   615     }
   616 
   617     /// \brief Seeding from file
   618     ///
   619     /// Seeding the random sequence from file. The linux kernel has two
   620     /// devices, <tt>/dev/random</tt> and <tt>/dev/urandom</tt> which
   621     /// could give good seed values for pseudo random generators (The
   622     /// difference between two devices is that the <tt>random</tt> may
   623     /// block the reading operation while the kernel can give good
   624     /// source of randomness, while the <tt>urandom</tt> does not
   625     /// block the input, but it could give back bytes with worse
   626     /// entropy).
   627     /// \param file The source file
   628     /// \param offset The offset, from the file read.
   629     /// \return \c true when the seeding successes.
   630 #ifndef LEMON_WIN32
   631     bool seedFromFile(const std::string& file = "/dev/urandom", int offset = 0)
   632 #else
   633     bool seedFromFile(const std::string& file = "", int offset = 0)
   634 #endif
   635     {
   636       std::ifstream rs(file.c_str());
   637       const int size = 4;
   638       Word buf[size];
   639       if (offset != 0 && !rs.seekg(offset)) return false;
   640       if (!rs.read(reinterpret_cast<char*>(buf), sizeof(buf))) return false;
   641       seed(buf, buf + size);
   642       return true;
   643     }
   644 
   645     /// \brief Seding from process id and time
   646     ///
   647     /// Seding from process id and time. This function uses the
   648     /// current process id and the current time for initialize the
   649     /// random sequence.
   650     /// \return Currently always \c true.
   651     bool seedFromTime() {
   652 #ifndef LEMON_WIN32
   653       timeval tv;
   654       gettimeofday(&tv, 0);
   655       seed(getpid() + tv.tv_sec + tv.tv_usec);
   656 #else
   657       seed(bits::getWinRndSeed());
   658 #endif
   659       return true;
   660     }
   661 
   662     /// @}
   663 
   664     ///\name Uniform Distributions
   665     ///
   666     /// @{
   667 
   668     /// \brief Returns a random real number from the range [0, 1)
   669     ///
   670     /// It returns a random real number from the range [0, 1). The
   671     /// default Number type is \c double.
   672     template <typename Number>
   673     Number real() {
   674       return _random_bits::RealConversion<Number, Word>::convert(core);
   675     }
   676 
   677     double real() {
   678       return real<double>();
   679     }
   680 
   681     /// \brief Returns a random real number from the range [0, 1)
   682     ///
   683     /// It returns a random double from the range [0, 1).
   684     double operator()() {
   685       return real<double>();
   686     }
   687 
   688     /// \brief Returns a random real number from the range [0, b)
   689     ///
   690     /// It returns a random real number from the range [0, b).
   691     double operator()(double b) {
   692       return real<double>() * b;
   693     }
   694 
   695     /// \brief Returns a random real number from the range [a, b)
   696     ///
   697     /// It returns a random real number from the range [a, b).
   698     double operator()(double a, double b) {
   699       return real<double>() * (b - a) + a;
   700     }
   701 
   702     /// \brief Returns a random integer from a range
   703     ///
   704     /// It returns a random integer from the range {0, 1, ..., b - 1}.
   705     template <typename Number>
   706     Number integer(Number b) {
   707       return _random_bits::Mapping<Number, Word>::map(core, b);
   708     }
   709 
   710     /// \brief Returns a random integer from a range
   711     ///
   712     /// It returns a random integer from the range {a, a + 1, ..., b - 1}.
   713     template <typename Number>
   714     Number integer(Number a, Number b) {
   715       return _random_bits::Mapping<Number, Word>::map(core, b - a) + a;
   716     }
   717 
   718     /// \brief Returns a random integer from a range
   719     ///
   720     /// It returns a random integer from the range {0, 1, ..., b - 1}.
   721     template <typename Number>
   722     Number operator[](Number b) {
   723       return _random_bits::Mapping<Number, Word>::map(core, b);
   724     }
   725 
   726     /// \brief Returns a random non-negative integer
   727     ///
   728     /// It returns a random non-negative integer uniformly from the
   729     /// whole range of the current \c Number type. The default result
   730     /// type of this function is <tt>unsigned int</tt>.
   731     template <typename Number>
   732     Number uinteger() {
   733       return _random_bits::IntConversion<Number, Word>::convert(core);
   734     }
   735 
   736     unsigned int uinteger() {
   737       return uinteger<unsigned int>();
   738     }
   739 
   740     /// \brief Returns a random integer
   741     ///
   742     /// It returns a random integer uniformly from the whole range of
   743     /// the current \c Number type. The default result type of this
   744     /// function is \c int.
   745     template <typename Number>
   746     Number integer() {
   747       static const int nb = std::numeric_limits<Number>::digits +
   748         (std::numeric_limits<Number>::is_signed ? 1 : 0);
   749       return _random_bits::IntConversion<Number, Word, nb>::convert(core);
   750     }
   751 
   752     int integer() {
   753       return integer<int>();
   754     }
   755 
   756     /// \brief Returns a random bool
   757     ///
   758     /// It returns a random bool. The generator holds a buffer for
   759     /// random bits. Every time when it become empty the generator makes
   760     /// a new random word and fill the buffer up.
   761     bool boolean() {
   762       return bool_producer.convert(core);
   763     }
   764 
   765     /// @}
   766 
   767     ///\name Non-uniform Distributions
   768     ///
   769     ///@{
   770 
   771     /// \brief Returns a random bool with given probability of true result.
   772     ///
   773     /// It returns a random bool with given probability of true result.
   774     bool boolean(double p) {
   775       return operator()() < p;
   776     }
   777 
   778     /// Standard normal (Gauss) distribution
   779 
   780     /// Standard normal (Gauss) distribution.
   781     /// \note The Cartesian form of the Box-Muller
   782     /// transformation is used to generate a random normal distribution.
   783     double gauss()
   784     {
   785       double V1,V2,S;
   786       do {
   787         V1=2*real<double>()-1;
   788         V2=2*real<double>()-1;
   789         S=V1*V1+V2*V2;
   790       } while(S>=1);
   791       return std::sqrt(-2*std::log(S)/S)*V1;
   792     }
   793     /// Normal (Gauss) distribution with given mean and standard deviation
   794 
   795     /// Normal (Gauss) distribution with given mean and standard deviation.
   796     /// \sa gauss()
   797     double gauss(double mean,double std_dev)
   798     {
   799       return gauss()*std_dev+mean;
   800     }
   801 
   802     /// Lognormal distribution
   803 
   804     /// Lognormal distribution. The parameters are the mean and the standard
   805     /// deviation of <tt>exp(X)</tt>.
   806     ///
   807     double lognormal(double n_mean,double n_std_dev)
   808     {
   809       return std::exp(gauss(n_mean,n_std_dev));
   810     }
   811     /// Lognormal distribution
   812 
   813     /// Lognormal distribution. The parameter is an <tt>std::pair</tt> of
   814     /// the mean and the standard deviation of <tt>exp(X)</tt>.
   815     ///
   816     double lognormal(const std::pair<double,double> &params)
   817     {
   818       return std::exp(gauss(params.first,params.second));
   819     }
   820     /// Compute the lognormal parameters from mean and standard deviation
   821 
   822     /// This function computes the lognormal parameters from mean and
   823     /// standard deviation. The return value can direcly be passed to
   824     /// lognormal().
   825     std::pair<double,double> lognormalParamsFromMD(double mean,
   826                                                    double std_dev)
   827     {
   828       double fr=std_dev/mean;
   829       fr*=fr;
   830       double lg=std::log(1+fr);
   831       return std::pair<double,double>(std::log(mean)-lg/2.0,std::sqrt(lg));
   832     }
   833     /// Lognormal distribution with given mean and standard deviation
   834 
   835     /// Lognormal distribution with given mean and standard deviation.
   836     ///
   837     double lognormalMD(double mean,double std_dev)
   838     {
   839       return lognormal(lognormalParamsFromMD(mean,std_dev));
   840     }
   841 
   842     /// Exponential distribution with given mean
   843 
   844     /// This function generates an exponential distribution random number
   845     /// with mean <tt>1/lambda</tt>.
   846     ///
   847     double exponential(double lambda=1.0)
   848     {
   849       return -std::log(1.0-real<double>())/lambda;
   850     }
   851 
   852     /// Gamma distribution with given integer shape
   853 
   854     /// This function generates a gamma distribution random number.
   855     ///
   856     ///\param k shape parameter (<tt>k>0</tt> integer)
   857     double gamma(int k)
   858     {
   859       double s = 0;
   860       for(int i=0;i<k;i++) s-=std::log(1.0-real<double>());
   861       return s;
   862     }
   863 
   864     /// Gamma distribution with given shape and scale parameter
   865 
   866     /// This function generates a gamma distribution random number.
   867     ///
   868     ///\param k shape parameter (<tt>k>0</tt>)
   869     ///\param theta scale parameter
   870     ///
   871     double gamma(double k,double theta=1.0)
   872     {
   873       double xi,nu;
   874       const double delta = k-std::floor(k);
   875       const double v0=E/(E-delta);
   876       do {
   877         double V0=1.0-real<double>();
   878         double V1=1.0-real<double>();
   879         double V2=1.0-real<double>();
   880         if(V2<=v0)
   881           {
   882             xi=std::pow(V1,1.0/delta);
   883             nu=V0*std::pow(xi,delta-1.0);
   884           }
   885         else
   886           {
   887             xi=1.0-std::log(V1);
   888             nu=V0*std::exp(-xi);
   889           }
   890       } while(nu>std::pow(xi,delta-1.0)*std::exp(-xi));
   891       return theta*(xi+gamma(int(std::floor(k))));
   892     }
   893 
   894     /// Weibull distribution
   895 
   896     /// This function generates a Weibull distribution random number.
   897     ///
   898     ///\param k shape parameter (<tt>k>0</tt>)
   899     ///\param lambda scale parameter (<tt>lambda>0</tt>)
   900     ///
   901     double weibull(double k,double lambda)
   902     {
   903       return lambda*pow(-std::log(1.0-real<double>()),1.0/k);
   904     }
   905 
   906     /// Pareto distribution
   907 
   908     /// This function generates a Pareto distribution random number.
   909     ///
   910     ///\param k shape parameter (<tt>k>0</tt>)
   911     ///\param x_min location parameter (<tt>x_min>0</tt>)
   912     ///
   913     double pareto(double k,double x_min)
   914     {
   915       return exponential(gamma(k,1.0/x_min))+x_min;
   916     }
   917 
   918     /// Poisson distribution
   919 
   920     /// This function generates a Poisson distribution random number with
   921     /// parameter \c lambda.
   922     ///
   923     /// The probability mass function of this distribusion is
   924     /// \f[ \frac{e^{-\lambda}\lambda^k}{k!} \f]
   925     /// \note The algorithm is taken from the book of Donald E. Knuth titled
   926     /// ''Seminumerical Algorithms'' (1969). Its running time is linear in the
   927     /// return value.
   928 
   929     int poisson(double lambda)
   930     {
   931       const double l = std::exp(-lambda);
   932       int k=0;
   933       double p = 1.0;
   934       do {
   935         k++;
   936         p*=real<double>();
   937       } while (p>=l);
   938       return k-1;
   939     }
   940 
   941     ///@}
   942 
   943     ///\name Two Dimensional Distributions
   944     ///
   945     ///@{
   946 
   947     /// Uniform distribution on the full unit circle
   948 
   949     /// Uniform distribution on the full unit circle.
   950     ///
   951     dim2::Point<double> disc()
   952     {
   953       double V1,V2;
   954       do {
   955         V1=2*real<double>()-1;
   956         V2=2*real<double>()-1;
   957 
   958       } while(V1*V1+V2*V2>=1);
   959       return dim2::Point<double>(V1,V2);
   960     }
   961     /// A kind of two dimensional normal (Gauss) distribution
   962 
   963     /// This function provides a turning symmetric two-dimensional distribution.
   964     /// Both coordinates are of standard normal distribution, but they are not
   965     /// independent.
   966     ///
   967     /// \note The coordinates are the two random variables provided by
   968     /// the Box-Muller method.
   969     dim2::Point<double> gauss2()
   970     {
   971       double V1,V2,S;
   972       do {
   973         V1=2*real<double>()-1;
   974         V2=2*real<double>()-1;
   975         S=V1*V1+V2*V2;
   976       } while(S>=1);
   977       double W=std::sqrt(-2*std::log(S)/S);
   978       return dim2::Point<double>(W*V1,W*V2);
   979     }
   980     /// A kind of two dimensional exponential distribution
   981 
   982     /// This function provides a turning symmetric two-dimensional distribution.
   983     /// The x-coordinate is of conditionally exponential distribution
   984     /// with the condition that x is positive and y=0. If x is negative and
   985     /// y=0 then, -x is of exponential distribution. The same is true for the
   986     /// y-coordinate.
   987     dim2::Point<double> exponential2()
   988     {
   989       double V1,V2,S;
   990       do {
   991         V1=2*real<double>()-1;
   992         V2=2*real<double>()-1;
   993         S=V1*V1+V2*V2;
   994       } while(S>=1);
   995       double W=-std::log(S)/S;
   996       return dim2::Point<double>(W*V1,W*V2);
   997     }
   998 
   999     ///@}
  1000   };
  1001 
  1002 
  1003   extern Random rnd;
  1004 
  1005 }
  1006 
  1007 #endif