Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What type of random number engine to use with a specified random distribution?

Tags:

c++

random

c++11

The C++11 way of generating random numbers is:

  1. Instantiate a random number engine
  2. Instantiate a random distribution
  3. Push the random numbers from the engine through the distribution

The problem is that both a random number engine and a random distribution are templated with respect to the type of arithmetic you are using.

How do these two types of arithmetic need to be related?

Can you use a 32 bit integer for the engine and a 64 bit integer for the distribution and opposite? What are the dangers? What about floating point types?

I hypothesize a guideline that the number of possible numbers generated by an engine should be greater or equal than the number of distinct random numbers you are hoping to get. Unfortunately I was not able to test my hypothesis, since on my computer uint_fast32_t and uint_fast64_t are the same and therefore both suggested engines for each of the three C++11 generators produce the same results.

The documentation on C++11 distributions like std::uniform_real_distribution or std::uniform_int_distribution is incomplete in this regard:

This section is incomplete. Reason: requirements on Generator

But for exapmple the gcc 4.7 implementation of uniform_real_distribution is:

  template<typename _UniformRandomNumberGenerator>
result_type
operator()(_UniformRandomNumberGenerator& __urng,
       const param_type& __p)
{
  __detail::_Adaptor<_UniformRandomNumberGenerator, result_type>
    __aurng(__urng);
  return (__aurng() * (__p.b() - __p.a())) + __p.a();
}

Where the Adaptor is:

An adaptor class for converting the output of any Generator into the input for a specific Distribution.

The "any" sounds reassuring, but is it standard? I am especially worried about hidden overflows that are hard to detect and which may compromise the correctness of the distribution.

like image 701
Martin Drozdik Avatar asked Jul 26 '13 02:07

Martin Drozdik


People also ask

Which distribution is used to generate random numbers?

The uniform probability distribution is used to generate random numbers from other distributions and also is useful as a “first guess” if no information about a random variable X is known other than that it is between a and b.

What is a random number for what purpose is it used?

A random number is a number chosen as if by chance from some specified distribution such that selection of a large set of these numbers reproduces the underlying distribution. Almost always, such numbers are also required to be independent, so that there are no correlations between successive numbers.

How do you generate a random number with a range in C++?

How to Generate Random Numbers in C++ Within a Range. Similar to 1 and 10, you can generate random numbers within any range using the modulus operator. For instance, to generate numbers between 1 and 100, you can write int random = 1+ (rand() % 100).

How do you generate a random number between 1 and 10 in C++?

rand() function generates random number and when you use rand()%10 , it will give you last digit of the number. Since we require random number between 1 and 10, we have used rand()%10+1 to generate random number between 1 and 10 in C++.


1 Answers

You're allowed to use any uniform random number generator (URNG) for any distribution function. The distribution function is assumed to know what it needs, and the URNG is required to describe what it provides, so that the distribution function can request sufficient entropy for its needs. (Note that an "engine" is a URNG, with some additional requirements like seedability.)

The "universal" adaptor you mention from the GNU standard library implementation takes a uniform random number generator G (actually it's name is much longer, but that will get tedious) and a result type R, which must be a numeric type. G must define G::min and G::max, the minimum and maximum values it can return, and it is supposed to return all values between those limits with equal probability. So it's easy to know how many bits of randomness are available from a call to G(). Moreover, from numeric_limits<R> will tell us how many bits are needed for an R. So dividing the entropy required by the entropy available tells the adaptor how many times it needs to call G to produce a uniformly random R. So the adaptor takes any URNG/engine which produces some result type, and adapts it to produce a different result type.

like image 167
rici Avatar answered Sep 20 '22 18:09

rici