1

I know that the Pseudo random number generator should be initialized only once with one seed. However, in C++, the random number generator and distribution are separated.

Now, Should the distribution function object get created once? Or it doesn't matter? What do I mean is that does it matter to put the distribution object creation call inside or outside when generating random numbers from a distribution. Or it doesn't matter as the distribution function only maps the generator to a number.

The reason I'm asking is because I'm using the generator for generating numbers drawn from several different distributions, it would be nice to put the distribution function object creation call within each function and share the same random number generator.

int main()
{
    boost::mt19937 rng(2);

    //inside the function
    rn_int_1(rng);
    rn_int_1(rng);

    boost::mt19937 rng2(2);
    //outside the function
    boost::random::uniform_int_distribution<> six(1,6);
    rn_int_2(six,rng2);
    rn_int_2(six,rng2);
    exit(0);
}


void rn_int_1(boost::mt19937 & generator)
{
    
    boost::random::uniform_int_distribution<> six(1,6);
    cout<<six(generator)<<endl;
    cout<<six(generator)<<endl;
    cout<<six(generator)<<endl;
}
void rn_int_2(boost::random::uniform_int_distribution<> &six,boost::mt19937 & generator)
{
    cout<<six(generator)<<endl;
    cout<<six(generator)<<endl;
    cout<<six(generator)<<endl;
}

The results are:

3
2
1
6
4
6
3
2
1
6
4
6
weeo
  • 2,619
  • 5
  • 20
  • 29
  • "_Should the distribution function be called once_": Your question is actually whether only one distribution function object should be _created_. `boost::random::uniform_int_distribution<> six(1,6);` is a variable definition, not a function call. The call to the distribution function (object) happens in `six(generator)`. – user17732522 Jan 26 '22 at 22:45
  • @user17732522 Thanks! Modified my question. – weeo Jan 26 '22 at 22:48
  • Does this answer your question? [Should I keep the random distribution object instance or can I always recreate it?](https://stackoverflow.com/questions/8433421/should-i-keep-the-random-distribution-object-instance-or-can-i-always-recreate-i) – user17732522 Jan 26 '22 at 22:50
  • By the way, I just noticed. Is there a reason you are using boost instead of the standard library? Can you not use C++11 or later? – user17732522 Jan 26 '22 at 22:52
  • 1
    @user17732522 Not exactly... This question is concerning about the overhead...I'm more concerned about if it generates the same sequence if the seed is fixed.. – weeo Jan 26 '22 at 22:53
  • (At least for the `std` implementation) it is not guaranteed to be the same sequence. The accepted answer in the linked question explains that. – user17732522 Jan 26 '22 at 22:55
  • @user17732522 yes. the std distribution generates different sequence..that's why i used the boost library... – weeo Jan 26 '22 at 22:56
  • ok, but I am pretty sure that boost has the same behavior – user17732522 Jan 26 '22 at 22:57
  • @user17732522 I tested...boost will be consistent across compilers..https://stackoverflow.com/questions/922358/consistent-pseudo-random-numbers-across-platforms – weeo Jan 26 '22 at 22:59
  • That was not my point. My point is that the sequence of random numbers may be different if you use new distribution objects each time than if you reuse the same one, because the objects may retain unused entropy from the generator. This is explained in the linked question's accepted answer. Which of the boost distributions actually do that and whether it is consistent between versions, I don't know. – user17732522 Jan 26 '22 at 23:02
  • @user17732522 it is correct. But my problem is that the same generator with the same seed is used, only the distribution object is created multiple times. And you can see from the above output, the sequences are the same... – weeo Jan 26 '22 at 23:04

1 Answers1

2

Distributions do not create sequences of random bits. That comes from the random bit engine. Distributions modify the sequence of bits in order to distribute them in some way. Put simply, the randomness comes from the engine, not the distribution.

That being said, recreating distribution objects all the time is bad form. Distributions are not stateless, and they can often retain some number of unused bits from prior invocations that would otherwise be lost if you just throw them away.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Thanks! So in terms of sequences generated, they should be the same. But it is a bad practice to constantly generating new objects? But the distribution objects are generated within a function, so it shouldn't matter? – weeo Jan 26 '22 at 23:01
  • @weeo: "*So in terms of sequences generated, they should be the same.*" No, they shouldn't. They will be in accord with the same *distribution* (between 1 and 6). But because the engine remains the same, you will get different bits from different invocations, which will result in different sequences of *values*. – Nicol Bolas Jan 26 '22 at 23:15
  • I mean both start with the same seed. one creates distribution object multiple times, one is not, but the exact same number of calls are made for the generator... – weeo Jan 26 '22 at 23:19
  • @weeo: No, that may not produce the same value sequence. As I added to my answer, distributions are not stateless. This is part of *why* you shouldn't pointlessly throw them away. – Nicol Bolas Jan 26 '22 at 23:30