bp236
bp236

Reputation: 11

Random numbers in C++: one engine, multiple distributions -> unexpected behaviour

I am using C++14. I want to generate a random number stream using a random engine and draw random variates from different distributions from this stream. I find, however, that there appears some interaction between the distributions which leads to unexpected behaviour. This is my code (compiled in MS Visual Studio 2019 with deafult compiler settings).

#include <random>
#include <iostream>
#include <vector>

int main()
{
    double alpha;
    std::cin >> alpha;
    std::default_random_engine generator;
    generator.seed(1);

    std::normal_distribution<> distNorm(0., 1.);
    std::gamma_distribution<> distGam(alpha, 1.);

    std::vector<double> normal;
    std::vector<double> gamma;

    for(size_t idxBatch = 0; idxBatch < 2; ++idxBatch)
    {
        for(size_t i = 0; i < 2; ++i)
            normal.push_back(distNorm(generator));

        for(size_t i = 0; i < 1; ++i)
            gamma.push_back(distGam(generator));
    }

    for(size_t i = 0; i < normal.size(); ++i)
        std::cout << normal[i] << std::endl;
    
    std::cout << std::endl;
    
    for(size_t i = 0; i < gamma.size(); ++i)
        std::cout << gamma[i] << std::endl;

    return 0;
}

Running the code with alpha = 1 produces:

-1.40287
-0.549746
0.188437
0.483496

0.490877
1.87282

Running the code with alpha = 2 produces:

-1.40287
-0.549746
-1.95939
0.257594

1.34784
2.28468

In other words, the output of the normal distribution is impacted by the parameter of the gamma distribution (3rd and 4th item in the first block)! This is unwanted. The normal distribution should be invariant against the parameterization of the gamma distribution.

Does anyone know what I am doing wrong?

Upvotes: 1

Views: 202

Answers (1)

Thomas
Thomas

Reputation: 181785

The engine is the source of a stream of random bits. The distribution consumes these bits and turns them into numbers. A distribution may consume more or fewer bits for each number generated (e.g. if it uses rejection sampling). This explains why the output of one distribution is affected by the other.

If you want the output of the distributions to be independent, you should use two separate engines.

Upvotes: 7

Related Questions