views:

951

answers:

2

It seems that one can use the following code to produce random numbers from a particular Normal distribution:

float mean = 0, variance = 1;
boost::mt19937 randgen(static_cast<unsigned int>(std::time(0)));
boost::normal_distribution<float> noise(mean, variance);
variate_generator<mt19937, normal_distribution<float> > nD(randgen, noise);

float random = nD();

This works fine, however, I would like to be able to draw numbers from several distributions, i.e. one would think something like:

float mean1 = 0, variance1 = 1, mean2 = 10, variance2 = 0.25;
boost::mt19937 randgen(static_cast<unsigned int>(std::time(0)));
boost::normal_distribution<float> noise1(mean1, variance1);
boost::normal_distribution<float> noise2(mean2, variance2);
variate_generator<mt19937, normal_distribution<float> > nD(randgen, noise1);
variate_generator<mt19937, normal_distribution<float> > nC(randgen, noise2);

float random1 = nD();
float random2 = nC();

However, the problem appears to be that nD() and nC() are generating similar sequences of numbers. I hypothesize this is because the constructor for variate_generator appears to make a copy of randgen, not use it explicitly. Thus, the same psuedo-random sequence is being generated and simply pushed through different transformations (due to the different parameters of the distributions).

Does anyone know if there is a way, in Boost, to create a single random number generator and use it for multiple distributions? Alternatively, does the design of the Boost random library intend users to create one random number generator per distribution? Obviously, I could write code to transform a sequence of uniform random numbers to a sequence from an arbitrary distribution, but I'm looking for something simple and already built-in to the library.

Thanks in advance for your help.

A: 
int rand()
{
  return 4; //generated by a role of the dice
};

(sorry, I couldn't resist)

David Oneill
+4  A: 

Your hypothesis is correct. You want both variate_generator instances to use the same random number generator instance. So use a reference to mt19937 as your template parameter.

variate_generator<mt19937 &, normal_distribution<float> > nD(randgen, noise1);
variate_generator<mt19937 &, normal_distribution<float> > nC(randgen, noise2);

Obviously you'll have to ensure randgen does not go out of scope before nD and nC do.

AFoglia
That appears to have worked perfectly. Does making the first template parameter just change the internal storage of the random number generator to be a reference? Thanks.
scandido
AFoglia