I am trying to use the C++11 approach to random number generation:
#include <random>
#include <functional>
#include <iostream>
int main(int argc, char *argv[])
{
std::normal_distribution<double> normal(0, 1);
std::mt19937 engine; // Mersenne twister MT19937
auto generator = std::bind(normal, engine);
int size = 2;
engine.seed(0);
normal.reset();
for (int i = 0; i < size; ++i)
std::cout << generator() << std::endl;
std::cout << std::endl;
engine.seed(1);
normal.reset();
for (int i = 0; i < size; ++i)
std::cout << generator() << std::endl;
std::cout << std::endl;
engine.seed(0);
normal.reset();
for (int i = 0; i < size; ++i)
std::cout << generator() << std::endl;
return 0;
}
The output is:
0.13453
-0.146382
0.46065
-1.87138
0.163712
-0.214253
That means that the first and the third sequence are not identical even if they are seeded with the same number. Please, what am I doing wrong? Is the
std::normal_distribution<double>
Just a function in the mathematical sense (produces y out of x deterministically) or am I missing something? If it is just a function, what does the reset method actually do?
With some random number generators, it's possible to select the seed carefully to manipulate the output. Sometimes this is easy to do. Sometimes it's hard but doable. Sometimes it's theoretically possible but practically impossible.
Use seedrnd() to reset the random number generator and produce more random numbers - C Data Type.
If you want to avoid repeating the same random number arrays when MATLAB restarts, then execute the command, rng('shuffle'); before calling rand , randn , randi , or randperm . This command ensures that you do not repeat a result from a previous MATLAB session.
Set and Restore Generator SettingsSet the random number generator to the default seed ( 0 ) and algorithm (Mersenne Twister), then save the generator settings. Create a 1-by-5 row vector of random values between 0 and 1. Change the generator seed and algorithm, and create a new random row vector.
You are binding the engine and the distribution, such the following calls on reset won't affect the bound function.
The solution is to bind references to the engine and the distro
auto generator = std::bind(std::ref(normal), std::ref(engine));
The problem you are having is with std::bind
. std::bind
makes copies of its arguments. The reason std::bind
makes copies is because the function will be called at some unknown point in the future when the arguments may no longer exist. This means your calls to engine.seed()
, etc. are useless. Using std::ref
you can bind your arguments by reference which will give you the expected output.
auto generator = std::bind(std::ref(normal), std::ref(engine));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With