RandomLib  1.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Macros Pages
RandomCanonical.hpp
Go to the documentation of this file.
1 /**
2  * \file RandomCanonical.hpp
3  * \brief Header for RandomCanonical.
4  *
5  * Use the random bits from Generator to produce random integers of various
6  * sizes, random reals with various precisions, a random probability, etc.
7  *
8  * Copyright (c) Charles Karney (2006-2011) <charles@karney.com> and licensed
9  * under the MIT/X11 License. For more information, see
10  * http://randomlib.sourceforge.net/
11  **********************************************************************/
12 
13 #if !defined(RANDOMLIB_RANDOMCANONICAL_HPP)
14 #define RANDOMLIB_RANDOMCANONICAL_HPP 1
15 
16 #include <bitset>
19 
20 #if defined(_MSC_VER)
21 // Squelch warnings about constant conditional expressions and casts truncating
22 // constants
23 # pragma warning (push)
24 # pragma warning (disable: 4127 4310)
25 #endif
26 
27 namespace RandomLib {
28  /**
29  * \brief Generate random integers, reals, and booleans.
30  *
31  * Use the random bits from Generator to produce random integers of various
32  * sizes, random reals with various precisions, a random probability, etc.
33  * RandomCanonical assumes that Generator produces random results as 32-bit
34  * quantities (of type uint32_t) via Generator::Ran32(), 64-bit quantities
35  * (of type uint64_t) via Generator::Ran64(), and in "natural" units of
36  * Generator::width bits (of type Generator::result_type) via
37  * Generator::Ran().
38  *
39  * For the most part this class uses Ran() when needing \e width or fewer
40  * bits, otherwise it uses Ran64(). However, when \e width = 64, the
41  * resulting code is RandomCanonical::Unsigned(\e n) is inefficient because
42  * of the 64-bit arithmetic. For this reason RandomCanonical::Unsigned(\e n)
43  * uses Ran32() if less than 32 bits are required (even though this results
44  * in more numbers being produced by the Generator).
45  *
46  * This class has been tested with the 32-bit and 64-bit versions of MT19937
47  * and SFMT19937. Other random number generators could be used provided that
48  * they provide a whole number of random bits so that Ran() is uniformly
49  * distributed in [0,2<sup><i>w</i></sup>). Probably some modifications
50  * would be needed if \e w is not 32 or 64.
51  *
52  * @tparam Generator the type of the underlying generator.
53  **********************************************************************/
54  template<class Generator>
55  class RandomCanonical : public Generator {
56  public:
57  /**
58  * The type of operator()().
59  **********************************************************************/
60  typedef typename Generator::result_type result_type;
61  /**
62  * The type of elements of Seed().
63  **********************************************************************/
64  typedef typename RandomSeed::seed_type seed_type;
65  enum {
66  /**
67  * The number of random bits in result_type.
68  **********************************************************************/
69  width = Generator::width
70  };
71 
72  /**
73  * \name Constructors which set the seed
74  **********************************************************************/
75  ///@{
76  /**
77  * Initialize from a vector.
78  *
79  * @tparam IntType the integral type of the elements of the vector.
80  * @param[in] v the vector of elements.
81  **********************************************************************/
82  template<typename IntType>
83  explicit RandomCanonical(const std::vector<IntType>& v) : Generator(v) {}
84  /**
85  * Initialize from a pair of iterator setting seed to [\e a, \e b)
86  *
87  * @tparam InputIterator the type of the iterator.
88  * @param[in] a the beginning iterator.
89  * @param[in] b the ending iterator.
90  **********************************************************************/
91  template<typename InputIterator>
92  RandomCanonical(InputIterator a, InputIterator b) : Generator(a, b) {}
93  /**
94  * Initialize with seed [\e n]
95  *
96  * @param[in] n the new seed to use.
97  **********************************************************************/
98  explicit RandomCanonical(seed_type n);
99  /**
100  * Initialize with seed []. This can be followed by a call to Reseed() to
101  * select a unique seed.
102  **********************************************************************/
103  RandomCanonical() : Generator() {}
104  /**
105  * Initialize from a string. See RandomCanonical::StringToVector
106  *
107  * @param[in] s the string to be decoded into a seed.
108  **********************************************************************/
109  explicit RandomCanonical(const std::string& s) : Generator(s) {}
110  ///@}
111 
112  /**
113  * \name Member functions returning integers
114  **********************************************************************/
115  ///@{
116  /**
117  * Return a raw result in [0, 2<sup><i>w</i></sup>) from the
118  * underlying Generator.
119  *
120  * @return a <i>w</i>-bit random number.
121  **********************************************************************/
122  result_type operator()() throw() { return Generator::Ran(); }
123 
124  /**
125  * A random integer in [0, \e n). This allows a RandomCanonical object to
126  * be passed to those standard template library routines that require
127  * random numbers. E.g.,
128  * \code
129  RandomCanonical r;
130  int a[] = {0, 1, 2, 3, 4};
131  std::random_shuffle(a, a+5, r);
132  \endcode
133  *
134  * @param[in] n the upper end of the interval. The upper end of the
135  * interval is open, so \e n is never returned.
136  * @return the random integer in [0, \e n).
137  **********************************************************************/
139  { return Integer<result_type>(n); }
140 
141  // Integer results (binary range)
142 
143  /**
144  * A random integer of type IntType in [0, 2<sup><i>b</i></sup>).
145  *
146  * @tparam IntType the integer type of the returned random numbers.
147  * @tparam bits how many random bits to return.
148  * @return the random result.
149  **********************************************************************/
150  template<typename IntType, int bits> IntType Integer() throw() {
151  // A random integer of type IntType in [0, 2^bits)
152  STATIC_ASSERT(std::numeric_limits<IntType>::is_integer &&
153  std::numeric_limits<IntType>::radix == 2,
154  "Integer<T,b>(): bad integer type IntType");
155  // Check that we have enough digits in Ran64
156  STATIC_ASSERT(bits > 0 && bits <= std::numeric_limits<IntType>::digits &&
157  bits <= 64, "Integer<T,b>(): invalid value for bits");
158  // Prefer masking to shifting so that we don't have to worry about sign
159  // extension (a non-issue, because Ran/64 are unsigned?).
160  return bits <= width ?
161  IntType(Generator::Ran() & Generator::mask
162  >> (bits <= width ? width - bits : 0)) :
163  IntType(Generator::Ran64() & u64::mask >> (64 - bits));
164  }
165 
166  /**
167  * A random integer in [0, 2<sup><i>b</i></sup>).
168  *
169  * @tparam bits how many random bits to return.
170  * @return the random result.
171  **********************************************************************/
172  template<int bits>
173  result_type Integer() throw() { return Integer<result_type, bits>(); }
174 
175  /**
176  * A random integer of type IntType in
177  * [std::numeric_limits<IntType>::min(), std::numeric_limits::max()].
178  *
179  * @tparam IntType the integer type of the returned random numbers.
180  * @return the random result.
181  **********************************************************************/
182  template<typename IntType> IntType Integer() throw();
183 
184  /**
185  * A random result_type in [0, std::numeric_limits<result_type>::max()].
186  *
187  * @return the random result.
188  **********************************************************************/
190  { return Integer<result_type>(); }
191 
192  // Integer results (finite range)
193 
194  /**
195  * A random integer of type IntType in [0, \e n). \e Excludes \e n. If \e
196  * n == 0, treat as std::numeric_limits::max() + 1. If \e n < 0, return 0.
197  * Compare RandomCanonical::Integer<int>(0) which returns a result in
198  * [0,2<sup>31</sup>) with RandomCanonical::Integer<int>() which returns a
199  * result in [&minus;2<sup>31</sup>,2<sup>31</sup>).
200  *
201  * @tparam IntType the integer type of the returned random numbers.
202  * @param[in] n the upper end of the semi-open interval.
203  * @return the random result in [0, \e n).
204  **********************************************************************/
205  template<typename IntType> IntType Integer(IntType n) throw();
206  /**
207  * A random integer of type IntType in Closed interval [0, \e n]. \e
208  * Includes \e n. If \e n < 0, return 0.
209  *
210  * @tparam IntType the integer type of the returned random numbers.
211  * @param[in] n the upper end of the closed interval.
212  * @return the random result in [0, \e n].
213  **********************************************************************/
214  template<typename IntType> IntType IntegerC(IntType n) throw();
215  /**
216  * A random integer of type IntType in Closed interval [\e m, \e n]. \e
217  * Includes both endpoints. If \e n < \e m, return \e m.
218  *
219  * @tparam IntType the integer type of the returned random numbers.
220  * @param[in] m the lower end of the closed interval.
221  * @param[in] n the upper end of the closed interval.
222  * @return the random result in [\e m, \e n].
223  **********************************************************************/
224  template<typename IntType> IntType IntegerC(IntType m, IntType n) throw();
225  ///@}
226 
227  /**
228  * \name Member functions returning real fixed-point numbers
229  **********************************************************************/
230  ///@{
231  /**
232  * In the description of the functions FixedX returning \ref fixed
233  * "fixed-point" numbers, \e u is a random real number uniformly
234  * distributed in (0, 1), \e p is the precision, and \e h =
235  * 1/2<sup><i>p</i></sup>. Each of the functions come in three variants,
236  * e.g.,
237  * - RandomCanonical::Fixed<RealType,p>() --- return \ref fixed
238  * "fixed-point" real of type RealType, precision \e p;
239  * - RandomCanonical::Fixed<RealType>() --- as above with \e p =
240  * std::numeric_limits<RealType>::digits;
241  * - RandomCanonical::Fixed() --- as above with RealType = double.
242  *
243  * See the \ref reals "summary" for a comparison of the functions.
244  *
245  * Return \e i \e h with \e i in [0,2<sup><i>p</i></sup>) by rounding \e u
246  * down to the previous \ref fixed "fixed" real. Result is in default
247  * interval [0,1).
248  *
249  * @tparam RealType the real type of the returned random numbers.
250  * @tparam prec the precision of the returned random numbers.
251  * @return the random result.
252  **********************************************************************/
253  template<typename RealType, int prec> RealType Fixed() throw() {
254  // RandomCanonical reals in [0, 1). Results are of the form i/2^prec for
255  // integer i in [0,2^prec).
256  STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer &&
257  std::numeric_limits<RealType>::radix == 2,
258  "Fixed(): bad real type RealType");
259  STATIC_ASSERT(prec > 0 && prec <= std::numeric_limits<RealType>::digits,
260  "Fixed(): invalid precision");
261  RealType x = 0; // Accumulator
262  int s = 0; // How many bits so far
263  // Let n be the loop count. Typically prec = 24, n = 1 for float; prec =
264  // 53, n = 2 for double; prec = 64, n = 2 for long double. For Sun
265  // Sparc's, we have prec = 113, n = 4 for long double. For Windows, long
266  // double is the same as double (prec = 53).
267  do {
268  s += width;
269  x += RandomPower2::shiftf<RealType>
270  (RealType(Generator::Ran() >> (s > prec ? s - prec : 0)),
271  -(s > prec ? prec : s));
272  } while (s < prec);
273  return x;
274  }
275  /**
276  * See documentation for RandomCanonical::Fixed<RealType,prec>().
277  *
278  * @tparam RealType the real type of the returned random numbers.
279  * @return the random result with the full precision of RealType.
280  **********************************************************************/
281  template<typename RealType> RealType Fixed() throw()
282  { return Fixed<RealType, std::numeric_limits<RealType>::digits>(); }
283  /**
284  * See documentation for RandomCanonical::Fixed<RealType,prec>().
285  *
286  * @return the random double.
287  **********************************************************************/
288  double Fixed() throw() { return Fixed<double>(); }
289 
290  /**
291  * An alias for RandomCanonical::Fixed<RealType>(). Returns a random
292  * number of type RealType in [0,1).
293  *
294  * @tparam RealType the real type of the returned random numbers.
295  * @return the random result with the full precision of RealType.
296  **********************************************************************/
297  template<typename RealType> RealType Real() throw()
298  { return Fixed<RealType>(); }
299  /**
300  * An alias for RandomCanonical::Fixed(). Returns a random double in
301  * [0,1).
302  *
303  * @return the random double.
304  **********************************************************************/
305  double Real() throw() { return Fixed(); }
306 
307  /**
308  * Return \e i \e h with \e i in (0,2<sup><i>p</i></sup>] by rounding \e u
309  * up to the next \ref fixed "fixed" real. Result is in upper interval
310  * (0,1].
311  *
312  * @tparam RealType the real type of the returned random numbers.
313  * @tparam prec the precision of the returned random numbers.
314  * @return the random result.
315  **********************************************************************/
316  template<typename RealType, int prec> RealType FixedU() throw()
317  { return RealType(1) - Fixed<RealType, prec>(); }
318  /**
319  * See documentation for RandomCanonical::FixedU<RealType,prec>().
320  *
321  * @tparam RealType the real type of the returned random numbers.
322  * @return the random result with the full precision of RealType.
323  **********************************************************************/
324  template<typename RealType> RealType FixedU() throw()
325  { return FixedU<RealType, std::numeric_limits<RealType>::digits>(); }
326  /**
327  * See documentation for RandomCanonical::FixedU<RealType,prec>().
328  *
329  * @return the random double.
330  **********************************************************************/
331  double FixedU() throw() { return FixedU<double>(); }
332 
333  /**
334  * Return \e i \e h with \e i in [0,2<sup><i>p</i></sup>] by rounding \e u
335  * to the nearest \ref fixed "fixed" real. Result is in nearest interval
336  * [0,1]. The probability of returning interior values is <i>h</i> while
337  * the probability of returning the endpoints is <i>h</i>/2.
338  *
339  * @tparam RealType the real type of the returned random numbers.
340  * @tparam prec the precision of the returned random numbers.
341  * @return the random result.
342  **********************************************************************/
343  template<typename RealType, int prec> RealType FixedN() throw() {
344  const RealType x = Fixed<RealType, prec>();
345  return x || Boolean() ? x : RealType(1);
346  }
347  /**
348  * See documentation for RandomCanonical::FixedN<RealType,prec>().
349  *
350  * @tparam RealType the real type of the returned random numbers.
351  * @return the random result with the full precision of RealType.
352  **********************************************************************/
353  template<typename RealType> RealType FixedN() throw()
354  { return FixedN<RealType, std::numeric_limits<RealType>::digits>(); }
355  /**
356  * See documentation for RandomCanonical::FixedN<RealType,prec>().
357  *
358  * @return the random double.
359  **********************************************************************/
360  double FixedN() throw() { return FixedN<double>(); }
361 
362  /**
363  * Return \e i \e h with \e i in [&minus;2<sup><i>p</i></sup>,
364  * 2<sup><i>p</i></sup>] by rounding 2\e u &minus; 1 to the nearest \ref
365  * fixed "fixed" real. Result is in wide interval [&minus;1,1]. The
366  * probability of returning interior values is <i>h</i>/2 while the
367  * probability of returning the endpoints is <i>h</i>/4.
368  *
369  * @tparam RealType the real type of the returned random numbers.
370  * @tparam prec the precision of the returned random numbers.
371  * @return the random result.
372  **********************************************************************/
373  template<typename RealType, int prec> RealType FixedW() throw() {
374  // Random reals in [-1, 1]. Round random in [-1, 1] to nearest multiple
375  // of 1/2^prec. Results are of the form i/2^prec for integer i in
376  // [-2^prec,2^prec].
377  STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer &&
378  std::numeric_limits<RealType>::radix == 2,
379  "FixedW(): bad real type RealType");
380  STATIC_ASSERT(prec > 0 && prec <= std::numeric_limits<RealType>::digits,
381  "FixedW(): invalid precision");
382  RealType x = -RealType(1); // Accumulator
383  int s = -1; // How many bits so far
384  do {
385  s += width;
386  x += RandomPower2::shiftf<RealType>
387  (RealType(Generator::Ran() >> (s > prec ? s - prec : 0)),
388  -(s > prec ? prec : s));
389  } while (s < prec);
390  return (x + RealType(1) != RealType(0)) || Boolean() ? x : RealType(1);
391  }
392  /**
393  * See documentation for RandomCanonical::FixedW<RealType,prec>().
394  *
395  * @tparam RealType the real type of the returned random numbers.
396  * @return the random result with the full precision of RealType.
397  **********************************************************************/
398  template<typename RealType> RealType FixedW() throw()
399  { return FixedW<RealType, std::numeric_limits<RealType>::digits>(); }
400  /**
401  * See documentation for RandomCanonical::FixedW<RealType,prec>().
402  *
403  * @return the random double.
404  **********************************************************************/
405  double FixedW() throw() { return FixedW<double>(); }
406 
407  /**
408  * Return (<i>i</i>+1/2)\e h with \e i in [2<sup><i>p</i>&minus;1</sup>,
409  * 2<sup><i>p</i>&minus;1</sup>) by rounding \e u &minus; 1/2 to nearest
410  * offset \ref fixed "fixed" real. Result is in symmetric interval
411  * (&minus;1/2,1/2).
412  *
413  * @tparam RealType the real type of the returned random numbers.
414  * @tparam prec the precision of the returned random numbers.
415  * @return the random result.
416  **********************************************************************/
417  template<typename RealType, int prec> RealType FixedS() throw()
418  { return Fixed<RealType, prec>() -
419  ( RealType(1) - RandomPower2::pow2<RealType>(-prec) ) / 2; }
420  /**
421  * See documentation for RandomCanonical::FixedS<RealType,prec>().
422  *
423  * @tparam RealType the real type of the returned random numbers.
424  * @return the random result with the full precision of RealType.
425  **********************************************************************/
426  template<typename RealType> RealType FixedS() throw()
427  { return FixedS<RealType, std::numeric_limits<RealType>::digits>(); }
428  /**
429  * See documentation for RandomCanonical::FixedS<RealType,prec>().
430  *
431  * @return the random double.
432  **********************************************************************/
433  double FixedS() throw() { return FixedS<double>(); }
434 
435  /**
436  * Return \e i \e h with \e i in (0,2<sup><i>p</i></sup>) by rounding (1
437  * &minus; \e h)\e u up to next \ref fixed "fixed" real. Result is in open
438  * interval (0,1).
439  *
440  * @tparam RealType the real type of the returned random numbers.
441  * @tparam prec the precision of the returned random numbers.
442  * @return the random result.
443  **********************************************************************/
444  template<typename RealType, int prec> RealType FixedO() throw() {
445  // A real of type RealType in (0, 1) with precision prec
446  STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer &&
447  std::numeric_limits<RealType>::radix == 2,
448  "FixedO(): bad real type RealType");
449  STATIC_ASSERT(prec > 0 && prec <= std::numeric_limits<RealType>::digits,
450  "FixedO(): invalid precision");
451  RealType x;
452  // Loop executed 2^prec/(2^prec-1) times on average.
453  do
454  x = Fixed<RealType, prec>();
455  while (x == 0);
456  return x;
457  }
458  /**
459  * See documentation for RandomCanonical::FixedO<RealType,prec>().
460  *
461  * @tparam RealType the real type of the returned random numbers.
462  * @return the random result with the full precision of RealType.
463  **********************************************************************/
464  template<typename RealType> RealType FixedO() throw()
465  { return FixedO<RealType, std::numeric_limits<RealType>::digits>(); }
466  /**
467  * See documentation for RandomCanonical::FixedO<RealType,prec>().
468  *
469  * @return the random double.
470  **********************************************************************/
471  double FixedO() throw() { return FixedO<double>(); }
472 
473  /**
474  * Return \e i \e h with \e i in [0,2<sup><i>p</i></sup>] by rounding (1 +
475  * \e h)\e u down to previous \ref fixed "fixed" real. Result is in closed
476  * interval [0,1].
477  *
478  * @tparam RealType the real type of the returned random numbers.
479  * @tparam prec the precision of the returned random numbers.
480  * @return the random result.
481  **********************************************************************/
482  template<typename RealType, int prec> RealType FixedC() throw() {
483  // A real of type RealType in [0, 1] with precision prec
484  STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer &&
485  std::numeric_limits<RealType>::radix == 2,
486  "FixedC(): bad real type RealType");
487  STATIC_ASSERT(prec > 0 && prec <= std::numeric_limits<RealType>::digits,
488  "FixedC(): invalid precision");
489  if (prec < width) {
490  // Sample an integer in [0, n) where n = 2^prec + 1. This uses the
491  // same logic as Unsigned(n - 1). However, unlike Unsigned, there
492  // doesn't seem to be much of a penalty for the 64-bit arithmetic here
493  // when result_type = unsigned long long. Presumably this is because
494  // the compiler can do some of the arithmetic.
495  const result_type
496  n = (result_type(1) << (prec < width ? prec : 0)) + 1,
497  // Computing this instead of 2^width/n suffices, because of the form
498  // of n.
499  r = Generator::mask / n,
500  m = r * n;
501  result_type u;
502  do
503  u = Generator::Ran();
504  while (u >= m);
505  // u is rv in [0, r * n)
506  return RandomPower2::shiftf<RealType>(RealType(u / r), -prec);
507  // Could also special case prec < 64, using Ran64(). However the
508  // general code below is faster.
509  } else { // prec >= width
510  // Synthesize a prec+1 bit random, Y, width bits at a time. If number
511  // is odd, return Fixed<RealType, prec>() (w prob 1/2); else if number
512  // is zero, return 1 (w prob 1/2^(prec+1)); else repeat. Normalizing
513  // probabilities on returned results we find that Fixed<RealType,
514  // prec>() is returned with prob 2^prec/(2^prec+1), and 1 is return
515  // with prob 1/(2^prec+1), as required. Loop executed twice on average
516  // and so consumes 2rvs more than rvs for Fixed<RealType, prec>(). As
517  // in FloatZ, do NOT try to save on calls to Ran() by using the
518  // leftover bits from Fixed.
519  while (true) {
520  // If prec + 1 < width then mask x with (1 << prec + 1) - 1
521  const result_type x = Generator::Ran(); // Low width bits of Y
522  if (x & 1u) // Y odd?
523  return Fixed<RealType, prec>(); // Prob 1/2 on each loop iteration
524  if (x)
525  continue; // Y nonzero
526  int s = prec + 1 - width; // Bits left to check (s >= 0)
527  while (true) {
528  if (s <= 0) // We're done. Y = 0
529  // Prob 1/2^(prec+1) on each loop iteration
530  return RealType(1); // We get here once every 60000 yrs (p = 64)!
531  // Check the next min(s, width) bits.
532  if (Generator::Ran() >> (s > width ? 0 : width - s))
533  break;
534  s -= width; // Decrement s
535  }
536  }
537  }
538  }
539  /**
540  * See documentation for RandomCanonical::FixedC<RealType,prec>().
541  *
542  * @tparam RealType the real type of the returned random numbers.
543  * @return the random result with the full precision of RealType.
544  **********************************************************************/
545  template<typename RealType> RealType FixedC() throw()
546  { return FixedC<RealType, std::numeric_limits<RealType>::digits>(); }
547  /**
548  * See documentation for RandomCanonical::FixedC<RealType,prec>().
549  *
550  * @return the random double.
551  **********************************************************************/
552  double FixedC() throw() { return FixedC<double>(); }
553  ///@}
554 
555  /**
556  * \name Member functions returning real floating-point numbers
557  **********************************************************************/
558  ///@{
559 
560  // The floating results produces results on a floating scale. Here the
561  // separation between possible results is smaller for smaller numbers.
562 
563  /**
564  * In the description of the functions FloatX returning \ref floating
565  * "floating-point" numbers, \e u is a random real number uniformly
566  * distributed in (0, 1), \e p is the precision, and \e e is the exponent
567  * range. Each of the functions come in three variants, e.g.,
568  * - RandomCanonical::Float<RealType,p,e>() --- return \ref floating
569  * "floating-point" real of type RealType, precision \e p, and exponent
570  * range \e e;
571  * - RandomCanonical::Float<RealType>() --- as above with \e p =
572  * std::numeric_limits<RealType>::digits and \e e =
573  * - std::numeric_limits<RealType>::min_exponent;
574  * - RandomCanonical::Float() --- as above with RealType = double.
575  *
576  * See the \ref reals "summary" for a comparison of the functions.
577  *
578  * Return result is in default interval [0,1) by rounding \e u down
579  * to the previous \ref floating "floating" real.
580  *
581  * @tparam RealType the real type of the returned random numbers.
582  * @tparam prec the precision of the returned random numbers.
583  * @tparam erange the exponent range of the returned random numbers.
584  * @return the random result.
585  **********************************************************************/
586  template<typename RealType, int prec, int erange> RealType Float() throw()
587  { return FloatZ<RealType, prec, erange, false>(0, 0); }
588  /**
589  * See documentation for RandomCanonical::Float<RealType,prec,erange>().
590  *
591  * @tparam RealType the real type of the returned random numbers.
592  * @return the random result with the full precision of RealType.
593  **********************************************************************/
594  template<typename RealType> RealType Float() throw() {
595  return Float<RealType, std::numeric_limits<RealType>::digits,
596  -std::numeric_limits<RealType>::min_exponent>();
597  }
598  /**
599  * See documentation for RandomCanonical::Float<RealType,prec,erange>().
600  *
601  * @return the random double.
602  **********************************************************************/
603  double Float() throw() { return Float<double>(); }
604 
605  /**
606  * Return result is in upper interval (0,1] by round \e u up to the
607  * next \ref floating "floating" real.
608  *
609  * @tparam RealType the real type of the returned random numbers.
610  * @tparam prec the precision of the returned random numbers.
611  * @tparam erange the exponent range of the returned random numbers.
612  * @return the random result.
613  **********************************************************************/
614  template<typename RealType, int prec, int erange> RealType FloatU() throw()
615  { return FloatZ<RealType, prec, erange, true>(0, 0); }
616  /**
617  * See documentation for RandomCanonical::FloatU<RealType,prec,erange>().
618  *
619  * @tparam RealType the real type of the returned random numbers.
620  * @return the random result with the full precision of RealType.
621  **********************************************************************/
622  template<typename RealType> RealType FloatU() throw() {
623  return FloatU<RealType, std::numeric_limits<RealType>::digits,
624  -std::numeric_limits<RealType>::min_exponent>();
625  }
626  /**
627  * See documentation for RandomCanonical::FloatU<RealType,prec,erange>().
628  *
629  * @return the random double.
630  **********************************************************************/
631  double FloatU() throw() { return FloatU<double>(); }
632 
633  /**
634  * Return result is in nearest interval [0,1] by rounding \e u to
635  * the nearest \ref floating "floating" real.
636  *
637  * @tparam RealType the real type of the returned random numbers.
638  * @tparam prec the precision of the returned random numbers.
639  * @tparam erange the exponent range of the returned random numbers.
640  * @return the random result.
641  **********************************************************************/
642  template<typename RealType, int prec, int erange> RealType FloatN()
643  throw() {
644  // Use Float or FloatU each with prob 1/2, i.e., return Boolean() ?
645  // Float() : FloatU(). However, rather than use Boolean(), we pick the
646  // high bit off a Ran() and pass the rest of the number to FloatZ to use.
647  // This saves 1/2 a call to Ran().
648  const result_type x = Generator::Ran();
649  return x >> (width - 1) ? // equivalent to Boolean()
650  // Float<RealType, prec, erange>()
651  FloatZ<RealType, prec, erange, false>(width - 1, x) :
652  // FloatU<RealType, prec, erange>()
653  FloatZ<RealType, prec, erange, true>(width - 1, x);
654  }
655  /**
656  * See documentation for RandomCanonical::FloatN<RealType,prec,erange>().
657  *
658  * @tparam RealType the real type of the returned random numbers.
659  * @return the random result with the full precision of RealType.
660  **********************************************************************/
661  template<typename RealType> RealType FloatN() throw() {
662  return FloatN<RealType, std::numeric_limits<RealType>::digits,
663  -std::numeric_limits<RealType>::min_exponent>();
664  }
665  /**
666  * See documentation for RandomCanonical::FloatN<RealType,prec,erange>().
667  *
668  * @return the random double.
669  **********************************************************************/
670  double FloatN() throw() { return FloatN<double>(); }
671 
672  /**
673  * Return result is in wide interval [&minus;1,1], by rounding 2\e u
674  * &minus; 1 to the nearest \ref floating "floating" real.
675  *
676  * @tparam RealType the real type of the returned random numbers.
677  * @tparam prec the precision of the returned random numbers.
678  * @tparam erange the exponent range of the returned random numbers.
679  * @return the random result.
680  **********************************************************************/
681  template<typename RealType, int prec, int erange>
682  RealType FloatW() throw() {
683  const result_type x = Generator::Ran();
684  const int y = int(x >> (width - 2));
685  return (1 - (y & 2)) * // Equiv to (Boolean() ? -1 : 1) *
686  ( y & 1 ? // equivalent to Boolean()
687  // Float<RealType, prec, erange>()
688  FloatZ<RealType, prec, erange, false>(width - 2, x) :
689  // FloatU<RealType, prec, erange>()
690  FloatZ<RealType, prec, erange, true>(width - 2, x) );
691  }
692  /**
693  * See documentation for RandomCanonical::FloatW<RealType,prec,erange>().
694  *
695  * @tparam RealType the real type of the returned random numbers.
696  * @return the random result with the full precision of RealType.
697  **********************************************************************/
698  template<typename RealType> RealType FloatW() throw() {
699  return FloatW<RealType, std::numeric_limits<RealType>::digits,
700  -std::numeric_limits<RealType>::min_exponent>();
701  }
702  /**
703  * See documentation for RandomCanonical::FloatW<RealType,prec,erange>().
704  *
705  * @return the random double.
706  **********************************************************************/
707  double FloatW() throw() { return FloatW<double>(); }
708  ///@}
709 
710  /**
711  * \name Member functions returning booleans
712  **********************************************************************/
713  ///@{
714  /**
715  * A coin toss. Equivalent to RandomCanonical::Integer<bool>().
716  *
717  * @return true with probability 1/2.
718  **********************************************************************/
719  bool Boolean() throw() { return Generator::Ran() & 1u; }
720 
721  /**
722  * The Bernoulli distribution, true with probability \e p. False if \e p
723  * &le; 0; true if \e p &ge; 1. Equivalent to RandomCanonical::Float() <
724  * \e p, but typically faster.
725  *
726  * @tparam NumericType the type (integer or real) of the argument.
727  * @param[in] p the probability.
728  * @return true with probability \e p.
729  **********************************************************************/
730  template<typename NumericType> bool Prob(NumericType p) throw();
731 
732  /**
733  * True with probability <i>m</i>/<i>n</i>. False if \e m &le; 0 or \e n <
734  * 0; true if \e m &ge; \e n. With real types, Prob(\e x, \e y) is exact
735  * but slower than Prob(<i>x</i>/<i>y</i>).
736  *
737  * @tparam NumericType the type (integer or real) of the argument.
738  * @param[in] m the numerator of the probability.
739  * @param[in] n the denominator of the probability.
740  * @return true with probability <i>m</i>/<i>n</i>.
741  **********************************************************************/
742  template<typename NumericType>
743  bool Prob(NumericType m, NumericType n) throw();
744  ///@}
745 
746  // Bits
747 
748  /**
749  * \name Functions returning bitsets
750  * These return random bits in a std::bitset.
751  **********************************************************************/
752  ///@{
753 
754  /**
755  * Return \e nbits random bits
756  *
757  * @tparam nbits the number of bits in the bitset.
758  * @return the random bitset.
759  **********************************************************************/
760  template<int nbits> std::bitset<nbits> Bits() throw();
761 
762  ///@}
763 
764  /**
765  * A "global" random number generator (not thread-safe!), initialized with
766  * a fixed seed [].
767  **********************************************************************/
769 
770  private:
771  typedef RandomSeed::u32 u32;
772  typedef RandomSeed::u64 u64;
773  /**
774  * A helper for Integer(\e n). A random unsigned integer in [0, \e n]. If
775  * \e n &ge; 2<sup>32</sup>, this \e must be invoked with \e onep = false.
776  * Otherwise, it \e should be invoked with \e onep = true.
777  **********************************************************************/
778  template<typename UIntT>
779  typename UIntT::type Unsigned(typename UIntT::type n) throw();
780 
781  /**
782  * A helper for Float and FloatU. Produces \e up ? FloatU() : Float(). On
783  * entry the low \e b bits of \e m are usable random bits.
784  **********************************************************************/
785  template<typename RealType, int prec, int erange, bool up>
786  RealType FloatZ(int b, result_type m) throw();
787 
788  /**
789  * The one-argument version of Prob for real types
790  **********************************************************************/
791  template<typename RealType> bool ProbF(RealType z) throw();
792  /**
793  * The two-argument version of Prob for real types
794  **********************************************************************/
795  template<typename RealType> bool ProbF(RealType x, RealType y) throw();
796  };
797 
798  template<class Generator>
800  : Generator(n) {
801  // Compile-time checks on real types
802 #if HAVE_LONG_DOUBLE
803  STATIC_ASSERT(std::numeric_limits<float>::radix == 2 &&
804  std::numeric_limits<double>::radix == 2 &&
805  std::numeric_limits<long double>::radix == 2,
806  "RandomCanonical: illegal floating type");
807  STATIC_ASSERT(0 <= std::numeric_limits<float>::digits &&
808  std::numeric_limits<float>::digits <=
809  std::numeric_limits<double>::digits &&
810  std::numeric_limits<double>::digits <=
811  std::numeric_limits<long double>::digits,
812  "RandomCanonical: inconsistent floating precision");
813 #else
814  STATIC_ASSERT(std::numeric_limits<float>::radix == 2 &&
815  std::numeric_limits<double>::radix == 2,
816  "RandomCanonical: illegal floating type");
817  STATIC_ASSERT(0 <= std::numeric_limits<float>::digits &&
818  std::numeric_limits<float>::digits <=
819  std::numeric_limits<double>::digits,
820  "RandomCanonical: inconsistent floating precision");
821 #endif
822 #if HAVE_LONG_DOUBLE
823 #endif
824 #if RANDOMLIB_POWERTABLE
825  // checks on power2
826 #if HAVE_LONG_DOUBLE
827  STATIC_ASSERT(std::numeric_limits<long double>::digits ==
829  "RandomPower2: RANDOMLIB_LONGDOUBLEPREC incorrect");
830 #else
831  STATIC_ASSERT(std::numeric_limits<double>::digits ==
833  "RandomPower2: RANDOMLIB_LONGDOUBLEPREC incorrect");
834 #endif
835  // Make sure table hasn't underflowed
837  std::numeric_limits<float>::min_exponent -
838  (RANDOMLIB_HASDENORM(float) ?
839  std::numeric_limits<float>::digits : 1),
840  "RandomPower2 table underflow");
842  "RandomPower2 table empty");
843  // Needed by RandomCanonical::Fixed<long double>()
844 #if HAVE_LONG_DOUBLE
846  -std::numeric_limits<long double>::digits,
847  "RandomPower2 minpow not small enough for long double");
848 #else
850  -std::numeric_limits<double>::digits,
851  "RandomPower2 minpow not small enough for double");
852 #endif
853  // Needed by ProbF
855  "RandomPower2 maxpow not large enough for ProbF");
856 #endif
857  // Needed for RandomCanonical::Bits()
858  STATIC_ASSERT(2 * std::numeric_limits<unsigned long>::digits - width >= 0,
859  "Bits<n>(): unsigned long too small");
860  }
861 
862  template<class Generator> template<typename IntType>
863  inline IntType RandomCanonical<Generator>::Integer() throw() {
864  // A random integer of type IntType in [min(IntType), max(IntType)].
865  STATIC_ASSERT(std::numeric_limits<IntType>::is_integer &&
866  std::numeric_limits<IntType>::radix == 2,
867  "Integer: bad integer type IntType");
868  const int d = std::numeric_limits<IntType>::digits +
869  std::numeric_limits<IntType>::is_signed; // Include the sign bit
870  // Check that we have enough digits in Ran64
871  STATIC_ASSERT(d > 0 && d <= 64, "Integer: bad bit-size");
872  if (d <= width)
873  return IntType(Generator::Ran());
874  else // d <= 64
875  return IntType(Generator::Ran64());
876  }
877 
878  template<class Generator> template<typename UIntT>
879  inline typename UIntT::type
880  RandomCanonical<Generator>::Unsigned(typename UIntT::type n) throw() {
881  // A random unsigned in [0, n]. In n fits in 32-bits, call with UIntType =
882  // u32 and onep = true else call with UIntType = u64 and onep = false.
883  // There are a few cases (e.g., n = 0x80000000) where on a 64-bit machine
884  // with a 64-bit Generator it would be quicker to call this with UIntType =
885  // result_type and invoke Ran(). However this speed advantage disappears
886  // if the argument isn't a compile time constant.
887  //
888  // Special case n == 0 is handled by the callers of Unsigned. The
889  // following is to guard against a division by 0 in the return statement
890  // (but it shouldn't happen).
891  n = n ? n : 1U; // n >= 1
892  // n1 = n + 1, but replace overflowed value by 1. Overflow occurs, e.g.,
893  // when n = u32::mask and then we have r1 = 0, m = u32::mask.
894  const typename UIntT::type n1 = ~n ? n + 1U : 1U;
895  // "Ratio method". Find m = r * n1 - 1, s.t., 0 < (q - n1) < m <= q, where
896  // q = max(UIntType), and sample in u in [0, m] and return u / r. If onep
897  // then we use Ran32() else Rand64().
898  const typename UIntT::type
899  // r = floor((q + 1)/n1), r1 = r - 1, avoiding overflow. Actually
900  // overflow can occur if std::numeric_limits<u32>::digits == 64, because
901  // then we can have onep && n > U32_MASK. This is however ruled out by
902  // the callers to Unsigned. (If Unsigned is called in this way, the
903  // results are bogus, but there is no error condition.)
904  r1 = ((UIntT::width == 32 ? typename UIntT::type(u32::mask) :
905  typename UIntT::type(u64::mask)) - n) / n1,
906  m = r1 * n1 + n; // m = r * n1 - 1, avoiding overflow
907  // Here r1 in [0, (q-1)/2], m in [(q+1)/2, q]
908  typename UIntT::type u; // Find a random number in [0, m]
909  do
910  // For small n1, this is executed once (since m is nearly q). In the
911  // worst case the loop is executed slightly less than twice on average.
912  u = UIntT::width == 32 ? typename UIntT::type(Generator::Ran32()) :
913  typename UIntT::type(Generator::Ran64());
914  while (u > m);
915  // Now u is in [0, m] = [0, r * n1), so u / r is in [0, n1) = [0, n]. An
916  // alternative unbiased method would be u % n1; but / appears to be faster.
917  return u / (r1 + 1U);
918  }
919 
920  template<class Generator> template<typename IntType>
921  inline IntType RandomCanonical<Generator>::Integer(IntType n) throw() {
922  // A random integer of type IntType in [0, n). If n == 0, treat as
923  // max(IntType) + 1. If n < 0, treat as 1 and return 0.
924  // N.B. Integer<IntType>(0) is equivalent to Integer<IntType>() for
925  // unsigned types. For signed types, the former returns a non-negative
926  // result and the latter returns a result in the full range.
927  STATIC_ASSERT(std::numeric_limits<IntType>::is_integer &&
928  std::numeric_limits<IntType>::radix == 2,
929  "Integer(n): bad integer type IntType");
930  const int d = std::numeric_limits<IntType>::digits;
931  // Check that we have enough digits in Ran64
932  STATIC_ASSERT(d > 0 && d <= 64, "Integer(n): bad bit-size");
933  return n > IntType(1) ?
934  (d <= 32 || n - 1 <= IntType(u32::mask) ?
935  IntType(Unsigned<u32>(u32::type(n - 1))) :
936  IntType(Unsigned<u64>(u64::type(n - 1)))) :
937  ( n ? IntType(0) : // n == 1 || n < 0
938  Integer<IntType, d>()); // n == 0
939  }
940 
941  template<class Generator> template<typename IntType>
942  inline IntType RandomCanonical<Generator>::IntegerC(IntType n) throw() {
943  // A random integer of type IntType in [0, n]
944  STATIC_ASSERT(std::numeric_limits<IntType>::is_integer &&
945  std::numeric_limits<IntType>::radix == 2,
946  "IntegerC(n): bad integer type IntType");
947  const int d = std::numeric_limits<IntType>::digits;
948  // Check that we have enough digits in Ran64
949  STATIC_ASSERT(d > 0 && d <= 64, "IntegerC(n): bad bit-size");
950  return n > IntType(0) ?
951  (d <= 32 || n <= IntType(u32::mask) ?
952  IntType(Unsigned<u32>(u32::type(n))) :
953  IntType(Unsigned<u64>(u64::type(n))))
954  : IntType(0); // n <= 0
955  }
956 
957  template<class Generator> template<typename IntType>
958  inline IntType RandomCanonical<Generator>::IntegerC(IntType m, IntType n)
959  throw() {
960  // A random integer of type IntType in [m, n]
961  STATIC_ASSERT(std::numeric_limits<IntType>::is_integer &&
962  std::numeric_limits<IntType>::radix == 2,
963  "IntegerC(m,n): bad integer type IntType");
964  const int d = std::numeric_limits<IntType>::digits +
965  std::numeric_limits<IntType>::is_signed; // Include sign bit
966  // Check that we have enough digits in Ran64
967  STATIC_ASSERT(d > 0 && d <= 64, "IntegerC(m,n): bad bit-size");
968  // The unsigned subtraction, n - m, avoids the underflow that is possible
969  // in the signed operation.
970  return m + (n <= m ? 0 :
971  d <= 32 ?
972  IntType(IntegerC<u32::type>(u32::type(n) - u32::type(m))) :
973  IntType(IntegerC<u64::type>(u64::type(n) - u64::type(m))));
974  }
975 
976  template<class Generator>
977  template<typename RealType, int prec, int erange, bool up> inline
978  RealType RandomCanonical<Generator>::FloatZ(int b, result_type m) throw() {
979  // Produce up ? FloatU() : Float(). On entry the low b bits of m are
980  // usable random bits.
981  STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer &&
982  std::numeric_limits<RealType>::radix == 2,
983  "FloatZ: bad real type RealType");
984  STATIC_ASSERT(prec > 0 && prec <= std::numeric_limits<RealType>::digits,
985  "FloatZ: invalid precision");
986  STATIC_ASSERT(erange >= 0, "FloatZ: invalid exponent range");
987  // With subnormals: condition that smallest number is representable
988  STATIC_ASSERT(!RANDOMLIB_HASDENORM(RealType) ||
989  // Need 1/2^(erange+prec) > 0
990  prec + erange <= std::numeric_limits<RealType>::digits -
991  std::numeric_limits<RealType>::min_exponent,
992  "FloatZ: smallest number cannot be represented");
993  // Without subnormals :condition for no underflow in while loop
995  // Need 1/2^(erange+1) > 0
996  erange <= - std::numeric_limits<RealType>::min_exponent,
997  "FloatZ: underflow possible");
998 
999  // Simpler (but slower) version of FloatZ. However this method cannot
1000  // handle the full range of exponents and, in addition, is slower on
1001  // average.
1002  // template<typename RealType, int prec, int erange, bool up>
1003  // RealType FloatZ() {
1004  // RealType x = Fixed<RealType, erange + 1>();
1005  // int s; // Determine exponent (-erange <= s <= 0)
1006  // frexp(x, &s); // Prob(s) = 2^(s-1)
1007  // // Scale number in [1,2) by 2^(s-1). If x == 0 scale number in [0,1).
1008  // return ((up ? FixedU<RealType, prec - 1>() :
1009  // Fixed<RealType, prec - 1>()) + (x ? 1 : 0)) *
1010  // RandomPower2::pow2<RealType>(s - 1);
1011  // }
1012  //
1013  // Use {a, b} to denote the inteval: up ? (a, b] : [a, b)
1014  //
1015  // The code produces the number as
1016  //
1017  // Interval count prob = spacing
1018  // {1,2} / 2 2^(prec-1) 1/2^prec
1019  // {1,2} / 2^s 2^(prec-1) 1/2^(prec+s-1) for s = 2..erange+1
1020  // {0,1} / 2^(erange+1) 2^(prec-1) 1/2^(prec+erange)
1021 
1022  // Generate prec bits in {0, 1}
1023  RealType x = up ? FixedU<RealType, prec>() : Fixed<RealType, prec>();
1024  // Use whole interval if erange == 0 and handle the interval {1/2, 1}
1025  if (erange == 0 || (up ? x > RealType(0.5) : x >= RealType(0.5)))
1026  return x;
1027  x += RealType(0.5); // Shift remaining portion to {1/2, 1}
1028  if (b == 0) {
1029  m = Generator::Ran(); // Random bits
1030  b = width; // Bits available in m
1031  }
1032  int sm = erange; // sm = erange - s + 2
1033  // Here x in {1, 2} / 2, prob 1/2
1034  do { // s = 2 thru erange+1, sm = erange thru 1
1035  x /= 2;
1036  if (m & 1u)
1037  return x; // x in {1, 2} / 2^s, prob 1/2^s
1038  if (--b)
1039  m >>= 1;
1040  else {
1041  m = Generator::Ran();
1042  b = width;
1043  }
1044  } while (--sm);
1045  // x in {1, 2} / 2^(erange+1), prob 1/2^(erange+1). Don't worry about the
1046  // possible overhead of the calls to pow here. We rarely get here.
1047  if (RANDOMLIB_HASDENORM(RealType) || // subnormals allowed
1048  // No subnormals but smallest number still representable
1049  prec + erange <= -std::numeric_limits<RealType>::min_exponent + 1 ||
1050  // Possibility of underflow, so have to test on x. Here, we have -prec
1051  // + 1 < erange + min_exp <= 0 so pow2 can be used
1052  x >= (RealType(1) +
1053  RandomPower2::pow2<RealType>
1054  (erange + std::numeric_limits<RealType>::min_exponent)) *
1055  (erange + 1 > -RandomPower2::minpow ?
1056  std::pow(RealType(2), - erange - 1) :
1057  RandomPower2::pow2<RealType>(- erange - 1)))
1058  // shift x to {0, 1} / 2^(erange+1)
1059  // Use product of pow's since max(erange + 1) =
1060  // std::numeric_limits<RealType>::digits -
1061  // std::numeric_limits<RealType>::min_exponent and pow may underflow
1062  return x -
1063  (erange + 1 > -RandomPower2::minpow ?
1064  std::pow(RealType(2), -(erange + 1)/2) *
1065  std::pow(RealType(2), -(erange + 1) + (erange + 1)/2) :
1066  RandomPower2::pow2<RealType>(- erange - 1));
1067  else
1068  return up ? // Underflow to up ? min() : 0
1069  // pow is OK here.
1070  std::pow(RealType(2), std::numeric_limits<RealType>::min_exponent - 1)
1071  : RealType(0);
1072  }
1073 
1074  /// \cond SKIP
1075  // True with probability n. Since n is an integer this is equivalent to n >
1076  // 0.
1077  template<class Generator> template<typename IntType>
1078  inline bool RandomCanonical<Generator>::Prob(IntType n) throw() {
1079  STATIC_ASSERT(std::numeric_limits<IntType>::is_integer,
1080  "Prob(n): invalid integer type IntType");
1081  return n > 0;
1082  }
1083  /// \endcond
1084 
1085  // True with probability p. true if p >= 1, false if p <= 0 or isnan(p).
1086  template<class Generator> template<typename RealType>
1087  inline bool RandomCanonical<Generator>::ProbF(RealType p) throw() {
1088  // Simulate Float<RealType>() < p. The definition involves < (instead of
1089  // <=) because Float<RealType>() is in [0,1) so it is "biased downwards".
1090  // Instead of calling Float<RealType>(), we generate only as many bits as
1091  // necessary to determine the result. This makes the routine considerably
1092  // faster than Float<RealType>() < x even for type float. Compared with
1093  // the inexact Fixed<RealType>() < p, this is about 20% slower with floats
1094  // and 20% faster with doubles and long doubles.
1095  STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer &&
1096  std::numeric_limits<RealType>::radix == 2,
1097  "ProbF(p): invalid real type RealType");
1098  // Generate Real() c bits at a time where c is chosen so that cast doesn't
1099  // loose any bits and so that it uses up just one rv.
1100  const int c = std::numeric_limits<RealType>::digits > width ?
1101  width : std::numeric_limits<RealType>::digits;
1102  STATIC_ASSERT(c > 0, "ProbF(p): Illegal chunk size");
1103  const RealType mult = RandomPower2::pow2<RealType>(c);
1104  // A recursive definition:
1105  //
1106  // return p > RealType(0) &&
1107  // (p >= RealType(1) ||
1108  // ProbF(mult * p - RealType(Integer<result_type, c>())));
1109  //
1110  // Pre-loop tests needed to avoid overflow
1111  if (!(p > RealType(0))) // Ensure false if isnan(p)
1112  return false;
1113  else if (p >= RealType(1))
1114  return true;
1115  do { // Loop executed slightly more than once.
1116  // Here p is in (0,1). Write Fixed() = (X + y)/mult where X is an
1117  // integer in [0, mult) and y is a real in [0,1). Then Fixed() < p
1118  // becomes p' > y where p' = p * mult - X.
1119  p *= mult; // Form p'. Multiplication is exact
1120  p -= RealType(Integer<result_type, c>()); // Also exact
1121  if (p <= RealType(0))
1122  return false; // If p' <= 0 the result is definitely false.
1123  // Exit if p' >= 1; the result is definitely true. Otherwise p' is in
1124  // (0,1) and the result is true with probability p'.
1125  } while (p < RealType(1));
1126  return true;
1127  }
1128 
1129  /// \cond SKIP
1130  // True with probability m/n (ratio of integers)
1131  template<class Generator> template<typename IntType>
1132  inline bool RandomCanonical<Generator>::Prob(IntType m, IntType n) throw() {
1133  STATIC_ASSERT(std::numeric_limits<IntType>::is_integer,
1134  "Prob(m,n): invalid integer type IntType");
1135  // Test n >= 0 without triggering compiler warning when n = unsigned
1136  return m > 0 && (n > 0 || n == 0) && (m >= n || Integer<IntType>(n) < m);
1137  }
1138  /// \endcond
1139 
1140  // True with probability x/y (ratio of reals)
1141  template<class Generator> template<typename RealType>
1142  inline bool RandomCanonical<Generator>::ProbF(RealType x, RealType y)
1143  throw() {
1144  STATIC_ASSERT(!std::numeric_limits<RealType>::is_integer &&
1145  std::numeric_limits<RealType>::radix == 2,
1146  "ProbF(x,y): invalid real type RealType");
1147  if (!(x > RealType(0) && y >= RealType(0))) // Do the trivial cases
1148  return false; // Also if either x or y is a nan
1149  else if (x >= y)
1150  return true;
1151  // Now 0 < x < y
1152  int ex, ey; // Extract exponents
1153  x = std::frexp(x, &ex);
1154  y = std::frexp(y, &ey);
1155  // Now 0.5 <= x,y < 1
1156  if (x > y) {
1157  x *= RealType(0.5);
1158  ++ex;
1159  }
1160  int s = ey - ex;
1161  // Now 0.25 < x < y < 1, s >= 0, 0.5 < x/y <= 1
1162  // Return true with prob 2^-s * x/y
1163  while (s > 0) { // With prob 1 - 2^-s return false
1164  // Check the next min(s, width) bits.
1165  if (Generator::Ran() >> (s > width ? 0 : width - s))
1166  return false;
1167  s -= width;
1168  }
1169  // Here with prob 2^-s
1170  const int c = std::numeric_limits<RealType>::digits > width ?
1171  width : std::numeric_limits<RealType>::digits;
1172  STATIC_ASSERT(c > 0, "ProbF(x,y): invalid chunk size");
1173  const RealType mult = RandomPower2::pow2<RealType>(c);
1174  // Generate infinite precision z = Real().
1175  // As soon as we know z > y, start again
1176  // As soon as we know z < x, return true
1177  // As soon as we know x < z < y, return false
1178  while (true) { // Loop executed 1/y on average
1179  RealType xa = x, ya = y;
1180  while (true) { // Loop executed slightly more than once
1181  // xa <= ya, ya > 0, xa < 1.
1182  // Here (xa,ya) are in (0,1). Write z = (Z + z')/mult where Z is an
1183  // integer in [0, mult) and z' is a real in [0,1). Then z < x becomes
1184  // z' < x' where x' = x * mult - Z.
1185  const RealType d = RealType(Integer<result_type, c>());
1186  if (ya < RealType(1)) {
1187  ya *= mult; // Form ya'
1188  ya -= d;
1189  if (ya <= RealType(0))
1190  break; // z > y, start again
1191  }
1192  if (xa > RealType(0)) {
1193  xa *= mult; // Form xa'
1194  xa -= d;
1195  if (xa >= RealType(1))
1196  return true; // z < x
1197  }
1198  if (xa <= RealType(0) && ya >= RealType(1))
1199  return false; // x < z < y
1200  }
1201  }
1202  }
1203 
1204  template<class Generator> template<int nbits>
1205  inline std::bitset<nbits> RandomCanonical<Generator>::Bits() throw() {
1206  // Return nbits random bits
1207  STATIC_ASSERT(nbits >= 0, "Bits<n>(): invalid nbits");
1208  const int ulbits = std::numeric_limits<bitset_uint_t>::digits;
1209  STATIC_ASSERT(2 * ulbits >= width,
1210  "Bits<n>(): integer constructor type too narrow");
1211  std::bitset<nbits> b;
1212  int m = nbits;
1213 
1214  while (m > 0) {
1215  result_type x = Generator::Ran();
1216  if (m < nbits)
1217  b <<= (width > ulbits ? width - ulbits : width);
1218  if (width > ulbits && // x doesn't fit into a bitset_uint_t
1219  // But on the first time through the loop the most significant bits
1220  // may not be needed.
1221  (nbits > ((nbits-1)/width) * width + ulbits || m < nbits)) {
1222  // Handle most significant width - ulbits bits.
1223  b |= (bitset_uint_t)(x >> (width > ulbits ? ulbits : 0));
1224  b <<= ulbits;
1225  }
1226  // Bitsets can be constructed from a bitset_uint_t.
1227  b |= (bitset_uint_t)(x);
1228  m -= width;
1229  }
1230  return b;
1231  }
1232  /// \cond SKIP
1233 
1234  // The specialization of Integer<bool> is required because bool(int) in the
1235  // template definition will test for non-zeroness instead of returning the
1236  // low bit.
1237 #if HAVE_LONG_DOUBLE
1238 #define RANDOMCANONICAL_SPECIALIZE(RandomType) \
1239  template<> template<> \
1240  inline bool RandomType::Integer<bool>() \
1241  throw() { return Boolean(); } \
1242  RANDOMCANONICAL_SPECIALIZE_PROB(RandomType, float) \
1243  RANDOMCANONICAL_SPECIALIZE_PROB(RandomType, double) \
1244  RANDOMCANONICAL_SPECIALIZE_PROB(RandomType, long double)
1245 #else
1246 #define RANDOMCANONICAL_SPECIALIZE(RandomType) \
1247  template<> template<> \
1248  inline bool RandomType::Integer<bool>() \
1249  throw() { return Boolean(); } \
1250  RANDOMCANONICAL_SPECIALIZE_PROB(RandomType, float) \
1251  RANDOMCANONICAL_SPECIALIZE_PROB(RandomType, double)
1252 #endif
1253 
1254  // Connect Prob(p) with ProbF(p) for all real types
1255  // Connect Prob(x, y) with ProbF(x, y) for all real types
1256 #define RANDOMCANONICAL_SPECIALIZE_PROB(RandomType, RealType) \
1257  template<> template<> \
1258  inline bool RandomType::Prob<RealType>(RealType p) \
1259  throw() { return ProbF<RealType>(p); } \
1260  template<> template<> \
1261  inline bool RandomType::Prob<RealType>(RealType x, RealType y) \
1262  throw() { return ProbF<RealType>(x, y); }
1263 
1264  RANDOMCANONICAL_SPECIALIZE(RandomCanonical<MRandomGenerator32>)
1265  RANDOMCANONICAL_SPECIALIZE(RandomCanonical<MRandomGenerator64>)
1266  RANDOMCANONICAL_SPECIALIZE(RandomCanonical<SRandomGenerator32>)
1267  RANDOMCANONICAL_SPECIALIZE(RandomCanonical<SRandomGenerator64>)
1268 
1269 #undef RANDOMCANONICAL_SPECIALIZE
1270 #undef RANDOMCANONICAL_SPECIALIZE_PROB
1271 
1272  /// \endcond
1273 
1274  /**
1275  * Hook XRandomNN to XRandomGeneratorNN
1276  **********************************************************************/
1281 
1282 } // namespace RandomLib
1283 
1284 namespace std {
1285 
1286  /**
1287  * Swap two RandomCanonicals. This is about 3x faster than the default swap.
1288  **********************************************************************/
1289  template<class Generator>
1292  r.swap(s);
1293  }
1294 
1295 } // namespace srd
1296 
1297 #if defined(_MSC_VER)
1298 # pragma warning (pop)
1299 #endif
1300 
1301 #endif // RANDOMLIB_RANDOMCANONICAL_HPP
unsigned long bitset_uint_t
Definition: RandomType.hpp:112
bool Prob(NumericType p)
RandomCanonical< SRandomGenerator32 > SRandom32
Generate random integers, reals, and booleans.
Class to hold bit-width and unsigned type.
Definition: RandomType.hpp:32
RandomSeed::seed_type seed_type
static const type mask
Definition: RandomType.hpp:45
A base class for random generators.
Definition: RandomSeed.hpp:62
RandomCanonical(InputIterator a, InputIterator b)
#define RANDOMLIB_EXPORT
Definition: Random.hpp:83
result_type operator()(result_type n)
std::bitset< nbits > Bits()
#define STATIC_ASSERT(cond, reason)
Definition: MPFRRandom.hpp:31
Generator::result_type result_type
seed_t::type seed_type
Definition: RandomSeed.hpp:73
#define RANDOMLIB_LONGDOUBLEPREC
Definition: Random.hpp:42
void swap(RandomLib::RandomCanonical< Generator > &r, RandomLib::RandomCanonical< Generator > &s)
#define RANDOMLIB_HASDENORM(RealType)
Definition: Random.hpp:72
RandomCanonical(const std::string &s)
RandomCanonical< MRandomGenerator64 > MRandom64
RandomCanonical(const std::vector< IntType > &v)
Header for RandomEngine.
Header for RandomPower2.
Uniform random number generator.
RandomCanonical< SRandomGenerator64 > SRandom64
RandomCanonical< MRandomGenerator32 > MRandom32
RandomCanonical< MRandomGenerator32 > Global
Definition: Random.cpp:1397