STXXL  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rand.h
Go to the documentation of this file.
1 /***************************************************************************
2  * include/stxxl/bits/common/rand.h
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
5  *
6  * Copyright (C) 2002, 2003, 2005 Roman Dementiev <[email protected]>
7  * Copyright (C) 2007 Andreas Beckmann <[email protected]>
8  * Copyright (C) 2013 Timo Bingmann <[email protected]>
9  *
10  * Distributed under the Boost Software License, Version 1.0.
11  * (See accompanying file LICENSE_1_0.txt or copy at
12  * http://www.boost.org/LICENSE_1_0.txt)
13  **************************************************************************/
14 
15 #ifndef STXXL_COMMON_RAND_HEADER
16 #define STXXL_COMMON_RAND_HEADER
17 
18 #include <cmath>
19 
20 #include <stxxl/bits/config.h>
22 #include <stxxl/bits/common/seed.h>
23 #include <stxxl/bits/namespace.h>
24 
25 #if STXXL_STD_RANDOM
26  #include <random>
27 #elif STXXL_BOOST_RANDOM
28  #include <boost/random.hpp>
29 #endif
30 
31 // Recommended seeding procedure:
32 // by default, the global seed is initialized from a high resolution timer and the process id
33 // 1. stxxl::set_seed(seed); // optionally, do this if you wan't to us a specific seed to replay a certain program run
34 // 2. seed = stxxl::get_next_seed(); // store/print/... this value can be used for step 1 to replay the program with a specific seed
35 // 3. stxxl::srandom_number32(); // seed the global state of stxxl::random_number32
36 // 4. create all the other prngs used.
37 
38 
40 
41 extern unsigned ran32State;
42 
43 //! Fast uniform [0, 2^32) pseudo-random generator with period 2^32, random
44 //! bits: 32.
45 //! \warning Uses a global state and is not reentrant or thread-safe!
47 {
48  typedef unsigned value_type;
49 
50  //! Returns a random number from [0, 2^32)
51  inline value_type operator () () const
52  {
53  return (ran32State = 1664525 * ran32State + 1013904223);
54  }
55 
56  //! Returns a random number from [0, N)
57  inline value_type operator () (const value_type& N) const
58  {
59  return operator () () % N;
60  }
61 };
62 
63 //! Set a seed value for \c random_number32.
64 inline void srandom_number32(unsigned seed = 0)
65 {
66  if (!seed)
67  seed = get_next_seed();
68  ran32State = seed;
69 }
70 
71 //! Fast uniform [0, 2^32) pseudo-random generator with period 2^32, random
72 //! bits: 32.
73 //! Reentrant variant of random_number32 that keeps it's private state.
75 {
76  typedef unsigned value_type;
77  mutable unsigned state;
78 
79  random_number32_r(unsigned seed = 0)
80  {
81  if (!seed)
82  seed = get_next_seed();
83  state = seed;
84  }
85 
86  //! Returns a random number from [0, 2^32)
87  inline value_type operator () () const
88  {
89  return (state = 1664525 * state + 1013904223);
90  }
91 };
92 
93 //! Fast uniform [0, 255] pseudo-random generator with period 2^8, random bits:
94 //! 8 (one byte).
96 {
99  unsigned int m_pos;
100 
101 public:
102  typedef uint8 value_type;
103 
104  random_number8_r(unsigned seed = 0)
105  : m_rnd32(seed), m_pos(4)
106  { }
107 
108  //! Returns a random byte from [0, 255]
109  inline value_type operator () ()
110  {
111  if (++m_pos >= 4) {
112  m_value = m_rnd32();
113  m_pos = 0;
114  }
115  return ((uint8*)&m_value)[m_pos];
116  }
117 };
118 
119 //! Fast uniform [0.0, 1.0) pseudo-random generator
120 //! \warning Uses a global state and is not reentrant or thread-safe!
122 {
123  typedef double value_type;
125 
126  random_uniform_fast(unsigned /*seed*/ = 0)
127  { }
128 
129  //! Returns a random number from [0.0, 1.0)
130  inline value_type operator () () const
131  {
132  return (double(rnd32()) * (0.5 / 0x80000000));
133  }
134 };
135 
136 #if STXXL_MSVC
137 #pragma warning(push)
138 #pragma warning(disable:4512) // assignment operator could not be generated
139 #endif
140 
141 //! Slow and precise uniform [0.0, 1.0) pseudo-random generator
142 //! period: at least 2^48, random bits: at least 31
143 //!
144 //! \warning Seed is not the same as in the fast generator \c random_uniform_fast
146 {
147  typedef double value_type;
148 #if STXXL_STD_RANDOM
149  typedef std::default_random_engine gen_type;
150  mutable gen_type gen;
151  typedef std::uniform_real_distribution<> uni_type;
152  mutable uni_type uni;
153 
154  random_uniform_slow(unsigned seed = 0)
155  : gen(seed ? seed : get_next_seed()),
156  uni(0.0, 1.0)
157  { }
158 #elif STXXL_BOOST_RANDOM
159  typedef boost::minstd_rand base_generator_type;
160  base_generator_type generator;
161  boost::uniform_real<> uni_dist;
162  mutable boost::variate_generator<base_generator_type&, boost::uniform_real<> > uni;
163 
164  random_uniform_slow(unsigned seed = 0) : uni(generator, uni_dist)
165  {
166  if (!seed)
167  seed = get_next_seed();
168  uni.engine().seed(seed);
169  }
170 #else
171  mutable unsigned short state48[3];
172 /*
173  * embedded erand48.c
174  *
175  * Copyright (c) 1993 Martin Birgmeier
176  * All rights reserved.
177  *
178  * You may redistribute unmodified or modified versions of this source
179  * code provided that the above copyright notice and this and the
180  * following conditions are retained.
181  *
182  * This software is provided ``as is'', and comes with no warranties
183  * of any kind. I shall in no event be liable for anything that happens
184  * to anyone/anything when using this software.
185  */
186  static void
187  _dorand48(unsigned short xseed[3])
188  {
189  unsigned long accu;
190  unsigned short temp[2];
191 
192  static const unsigned short _mult[3] = { 0xe66d, 0xdeec, 0x0005 };
193  static const unsigned short _add = 0x000b;
194 
195  accu = (unsigned long)_mult[0] * (unsigned long)xseed[0]
196  + (unsigned long)_add;
197  temp[0] = (unsigned short)accu; /* lower 16 bits */
198  accu >>= sizeof(unsigned short) * 8;
199  accu += (unsigned long)_mult[0] * (unsigned long)xseed[1]
200  + (unsigned long)_mult[1] * (unsigned long)xseed[0];
201  temp[1] = (unsigned short)accu; /* middle 16 bits */
202  accu >>= sizeof(unsigned short) * 8;
203  accu += _mult[0] * xseed[2] + _mult[1] * xseed[1] + _mult[2] * xseed[0];
204  xseed[0] = temp[0];
205  xseed[1] = temp[1];
206  xseed[2] = (unsigned short)accu;
207  }
208 
209  static double
210  _erand48(unsigned short xseed[3])
211  {
212  _dorand48(xseed);
213  return ldexp((double)xseed[0], -48)
214  + ldexp((double)xseed[1], -32)
215  + ldexp((double)xseed[2], -16);
216  }
217 /* end erand48.c */
218 
219  random_uniform_slow(unsigned seed = 0)
220  {
221  if (!seed)
222  seed = get_next_seed();
223  state48[0] = (unsigned short)(seed & 0xffff);
224  state48[1] = (unsigned short)(seed >> 16);
225  state48[2] = 42;
226  _dorand48(state48);
227  }
228 #endif
229 
230  //! Returns a random number from [0.0, 1.0)
231  inline value_type operator () () const
232  {
233 #if STXXL_STD_RANDOM
234  return uni(gen);
235 #elif STXXL_BOOST_RANDOM
236  return uni();
237 #else
238  return _erand48(state48);
239 #endif
240  }
241 };
242 
243 //! Uniform [0, N) pseudo-random generator
244 template <class UniformRGen_ = random_uniform_fast>
246 {
247  typedef unsigned value_type;
248  UniformRGen_ uniform;
249 
250  random_number(unsigned seed = 0) : uniform(seed)
251  { }
252 
253  //! Returns a random number from [0, N)
254  inline value_type operator () (value_type N) const
255  {
256  return static_cast<value_type>(uniform() * double(N));
257  }
258 };
259 
260 //! Slow and precise uniform [0, 2^64) pseudo-random generator
262 {
265 
266  random_number64(unsigned seed = 0) : uniform(seed)
267  { }
268 
269  //! Returns a random number from [0, 2^64)
270  inline value_type operator () () const
271  {
272  return static_cast<value_type>(uniform() * (18446744073709551616.));
273  }
274 
275  //! Returns a random number from [0, N)
276  inline value_type operator () (value_type N) const
277  {
278  return static_cast<value_type>(uniform() * double(N));
279  }
280 };
281 
282 #if STXXL_MSVC
283 #pragma warning(pop) // assignment operator could not be generated
284 #endif
285 
287 
288 #endif // !STXXL_COMMON_RAND_HEADER
random_number64(unsigned seed=0)
Definition: rand.h:266
Uniform [0, N) pseudo-random generator.
Definition: rand.h:245
void srandom_number32(unsigned seed=0)
Set a seed value for random_number32.
Definition: rand.h:64
random_number(unsigned seed=0)
Definition: rand.h:250
random_uniform_slow uniform
Definition: rand.h:264
unsigned int m_pos
Definition: rand.h:99
unsigned ran32State
Definition: rand.cpp:21
unsigned long long int uint64
Definition: types.h:41
Slow and precise uniform [0.0, 1.0) pseudo-random generator period: at least 2^48, random bits: at least 31.
Definition: rand.h:145
UniformRGen_ uniform
Definition: rand.h:248
unsigned get_next_seed()
get a seed value for prng initialization, subsequent calls return a sequence of different values ...
Definition: seed.cpp:74
unsigned value_type
Definition: rand.h:247
random_number32_r m_rnd32
Definition: rand.h:97
random_uniform_fast(unsigned=0)
Definition: rand.h:126
unsigned int uint32
Definition: types.h:39
static double _erand48(unsigned short xseed[3])
Definition: rand.h:210
random_uniform_slow(unsigned seed=0)
Definition: rand.h:219
Fast uniform [0, 255] pseudo-random generator with period 2^8, random bits: 8 (one byte)...
Definition: rand.h:95
random_number32_r(unsigned seed=0)
Definition: rand.h:79
unsigned char uint8
Definition: types.h:35
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
Fast uniform [0, 2^32) pseudo-random generator with period 2^32, random bits: 32. Reentrant variant o...
Definition: rand.h:74
Fast uniform [0, 2^32) pseudo-random generator with period 2^32, random bits: 32. ...
Definition: rand.h:46
unsigned value_type
Definition: rand.h:76
random_number32 rnd32
Definition: rand.h:124
stxxl::uint64 value_type
Definition: rand.h:263
Fast uniform [0.0, 1.0) pseudo-random generator.
Definition: rand.h:121
unsigned value_type
Definition: rand.h:48
random_number8_r(unsigned seed=0)
Definition: rand.h:104
#define STXXL_END_NAMESPACE
Definition: namespace.h:17
static void _dorand48(unsigned short xseed[3])
Definition: rand.h:187
Slow and precise uniform [0, 2^64) pseudo-random generator.
Definition: rand.h:261