I am studying the issue of generating Gaussian draws in C++. As the title says, I seem to get a different result from using bind instead of just drawing from the distribution. That is to say the following code
default_random_engine ran{1};
auto normal_draw = bind(normal_distribution<double>{0, 1}, ran);
for (int i = 0; i < 9; ++i)
cout << normal_draw() << endl;
cout << "new sequence" << endl;
for (int i = 0; i < 9; ++i)
cout << normal_distribution<double>{0, 1}(ran) << endl;
generates the output
-1.40287 -0.549746 -1.04515 1.58275 -1.95939 0.257594 -0.315292 -1.50781 0.071343
new sequence
-1.40287 -1.04515 -1.95939 -0.315292 0.071343 -1.41555 0.631902 -0.903123 0.194431
I find this perplexing as I believed that both sequences would be the same. Note also that if one generates 18 draws using normal_draw() then the sequence comprising the last 9 draws is not equal to the second sequence above. So it seems like drawing directly from the distribution is using a different method than that implicit in bind(), which clearly cannot be the case.
Can someone please explain what I am missing?
thanks in advance!
You are instancing a temporary distribution object every loop iteration. This will create a new state every time. When you don't, they are the same (given the random generator is always initialized with the same state):
#include <random>
#include <iostream>
#include <functional>
int main()
{
std::default_random_engine ran1{1};
auto normal_draw = std::bind(std::normal_distribution<double>{0, 1}, ran1);
for (int i = 0; i < 9; ++i)
std::cout << normal_draw() << ' ';
std::cout << '\n';
std::default_random_engine ran2{1};
std::normal_distribution<double> norman{0, 1};
for (int i = 0; i < 9; ++i)
std::cout << norman(ran2) << ' ';
}