Reputation: 591
I have a class with a random engine generator object and functions that return functions representing different distributions but using the same generator.
foo.hpp:
class Foo {
private:
default_random_engine generator;
function<float()> sample_pdf1();
foo.cpp:
function<float()> Foo::sample_pdf1() {
float mean = 3.0f;
float stddev = 1.0f;
normal_distribution<float> dist(mean,stddev);
return bind(dist,generator);
}
If I do:
Foo myFoo;
cout << myFoo.sample_pdf1()() << endl;
cout << myFoo.sample_pdf1()() << endl;
Both samples will be the same (always), which is not what I want. What is the problem here? Is generator getting copied in bind(dist,generator)?
Also note that this example is simplified, what I want to do is to give sample_pdf1() different paramters that gives rise to different mean and standard deviations (linear gaussian).
Upvotes: 2
Views: 564
Reputation: 234474
The problem is that the code binds the generator by value. Each sampler returned by the function will have its own copy of the generator. All those copies have the same seed. Generators are deterministic: if you initialise one with the same seed you get the same sequence of numbers.
You could bind the generator by reference: bind(dist, std::ref(generator));
. That way the two samplers will use the same generator instead of each one using its own copy.
Alternatively you could seed a different generator for each sampler, as follows.
function<float()> Foo::sample_pdf1() {
// a source of entropy to obtain seeds
static std::random_device entropy;
float mean = 3.0f;
float stddev = 1.0f;
normal_distribution<float> dist(mean,stddev);
// seed a new generator for this sampler
auto generator = default_random_engine(entropy());
return bind(dist,generator);
}
Upvotes: 6