I am using c++11 new <random>
header in my application and in one class in different methods I need different random number with different distributions. I just put a random engine std::default_random_engine
as class member seed it in the class constructor with std::random_device
and use it for different distributions in my methods. Is that OK to use the random engine in this way or I should declare different engines for every distribution I use.
4 Answers
It's ok.
Reasons to not share the generator:
- threading (standard RNG implementations are not thread safe)
determinism of random sequences:
If you wish to be able (for testing/bug hunting) to control the exact sequences generated, you will by likely have fewer troubles by isolating the RNGs used, especially when not all RNGs consumption is deterministic.

- 374,641
- 47
- 450
- 633
You should be careful when using one pseudo random number generator for different random variables, because in doing so they become correlated.
Here is an example: If you want to simulate Brownian motion in two dimensions (e.g. x and y) you need randomness in both dimensions. If you take the random numbers from one generator (noise()) and assign them successively
while(simulating)
x = x + noise()
y = y + noise()
then the variables x and y become correlated, because the algorithms of the pseudo number generators only make statements about how good they are, if you take every single number generated and not only every second one like in this example. Here, the Brownian particles could maybe move into the positive x and y directions with a higher probability than in the negative directions and thus introduce an artificial drift.
For two further reasons to use different generators look at sehe's answer.
-
I understand the idea, but how can it be that drawing two times uncorrelated random numbers should lead to a correlation? – davidhigh Jan 29 '18 at 13:18
-
@davidhigh The numbers being "drawn" are not true uncorrelated random numbers, they are so-called pseudorandom numbers and are calculated in a deterministic way. This is usually much faster than drawing true random numbers and it has the benefit of being reproducible by using the same seed again. One disadvantage is that the calculated numbers in a stream are not truly uncorrelated and one should use every single generated number from the stream in order to ensure a good quality of randomness. – LSchueler Jan 30 '18 at 07:54
MosteM's answer isn't correct. It's correct to do this so long as you want the draws from the distributions to be independent. If for some reason you need exactly the same random input into draws of different distributions, then you may want different RNGs. If you want correlation between two random variables, it's better to build them starting from a common random variable using mathematical principal: e.g., if A, B are independent normal(0,1), then A and aA +sqrt(1-a**2)B are normal(0,1) with correlation a.
EDIT: I found a great resource on the C++11 random library which may be useful to you.

- 650
- 1
- 8
- 27
-
What is wrong with the answer "You should be careful when using one pseudo random number generator for different random variables, because in doing so they become correlated."? Correlations are not mentioned anywhere in the question. – LSchueler Jan 03 '17 at 10:58
-
1Indeed, the question does not mention correlation but your answer does in a way which is not quite correct. A PRN sequence from a given seed is supposed to mimick statistically a sequence drawn from a truely i.i.d. sequence. (How well it does this depends on the quality of the PRNG, and the C++11 standard is pretty good) Different seeds may have overlapping sequences, leading to correlation, so in fact you should pay more attention when using different seeds. In fact, depending on how many random numbers you want, I'd say your while loop is pretty good unless you want to multithread. – Plamen Jan 03 '17 at 19:00
-
@Plamen: I had the same objection (before reading your post), see the comment to MosteMs answer. – davidhigh Jan 29 '18 at 13:19
There is no reason not to do it like this. Depending on which random generator you use, the period is quite huge (2^19937 in case of Mersenne-Twister), so in most cases, you won't even reach the end of one period during the execution of your program. And even if it is not said that, it's worse to reach the period with all distributions using the same generator than having 3 generators each doing 1/3 of their period.
In my programs, I use one generator for each thread, and it works fine. I think that's the main reason they split up the generator and distributions in C++11, since if you weren't allowed to do this, there would be no benefit from having the generator and the distribution separate, if one needs one generator for each distribution anyway.

- 1,642
- 4
- 21
- 40

- 9,021
- 10
- 58
- 95
-
Actually, even with requiring one generator per distribution, there is a clear benefit in separating the two: separation of concerns. If I have M generators and N distributions, then I need MxN combined classes (ouch!) and adding 1 generator requires N new combined classes. With the decoupled approach, as long as you respect the "Concept" of a generator, adding one generator is just writing the code for that generator and that's it. And anybody can use it with any other distribution. Composability begets reuse. – Matthieu M. Mar 26 '12 at 12:09
-
True, I only thougth of the "standart" generators, which could be just a parameter of the constructor of the distributions, avoiding MxN classes. But you are right, this concept would break when it comes to self implemented generators. – Haatschii Mar 26 '12 at 12:51