lemon/random.h
author Peter Kovacs <kpeter@inf.elte.hu>
Tue, 15 Mar 2011 19:32:21 +0100
changeset 936 ddd3c0d3d9bf
parent 559 c5fd2d996909
child 1124 d51126dc39fa
permissions -rw-r--r--
Implement the scaling Price Refinement heuristic in CostScaling (#417)
instead of Early Termination.

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