Question

I am trying to generate random numbers from a normal distribution. When the code:

normal(eng)

appears in main(), the program works fine. However, if it is called from another function, the next call from main returns the same value generated previously. Below is some code that illustrates this. The first few lines of output are:

-0.710449
-0.710449
0.311983
0.311983
1.72192
1.72192
0.303135
0.303135
0.456779
0.456779

Does anyone know why this occurs?

The compiler is gcc 4.4.1 on Windows.

#include <iostream>
#include <cmath>
#include <ctime>
#include <tr1/random>

typedef std::tr1::ranlux64_base_01 Engine;
//typedef std::tr1::mt19937 Engine;
typedef std::tr1::normal_distribution<double> Normal;

double random_normal(Engine eng, Normal dist) {
    return dist(eng);
}

int main ( int argc, char** argv ) {
    Engine eng;
    eng.seed((unsigned int) time(NULL));

    Normal normal(0,1);

    for (int i = 0; i < 100; i++)
    {
        std::cout << random_normal(eng, normal) << std::endl;
        std::cout << normal(eng) << std::endl;   
    }

    return 0;
}
Was it helpful?

Solution

This is happening because you're passing the engine by value to random_normal. random_normal gets a copy of the engine and so the original engine does not have its state modified, and using that original engine directly will yield the same result as random_normal obtained.

If you modify random_normal to take the engine by reference:

double random_normal(Engine &eng, Normal Dist);

then the original engine will be modified and you won't get repeated values. All the standard distributions take their engines by reference. For example:

template<class IntType = int>
class uniform_int_distribution
{
...
    // generating functions
    template<class URNG>
    result_type operator()(URNG& g);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top