anton skvorts
anton skvorts

Reputation: 441

Setting seed boost::random

I would like to reset random sequences by using different seed numbers. When running this test code:

boost::mt19937 gener(1);
boost::normal_distribution<> normal(0,1);
boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > rng(gener, normal);
cout << rng() << endl;
cout << rng() << endl;
cout << rng() << endl;
gener.seed(2);
cout << rng() << endl;
cout << rng() << endl;
gener.seed(1);
cout << rng() << endl;
gener.seed(2);
cout << rng() << endl;
gener.seed(3);
cout << rng() << endl;

I get the following output:

# seed(1) via constructor
-2.971829031
1.706951063
-0.430498971
# seed(2)
-2.282022417
-0.5887503675
# seed(1)
0.2504171986
# seed(2)
-0.5887503675
# seed(3)
0.2504171986

Obviously I'm doing something very wrong. How may I overcome this problem?

Upvotes: 10

Views: 13913

Answers (4)

anton skvorts
anton skvorts

Reputation: 441

Following Jim, Alan and Igor suggestions made some changes to the code: rng.engine().seed() instead of gener.seed(), and called rng.distribution().reset() after the call to rng.engine().seed() and it worked like a charm.

Many thanks!

Upvotes: 15

Vokram
Vokram

Reputation: 2127

Great to see the problem resolved! But I guess I just figured out why Alan's method wouldn't work...

When writing boost::variate_generator<boost::mt19937&,boost::normal_distribution<> > rng(gener, normal), you didn't create another copy of gener because it's a call by reference, but you did create another copy of normal with the variate_generate.

So instead of normal.reset, which only resets the original normal, you should use rng.distribution().reset(). But you can just keep gener.seed(), which I suspect will have the same effect as rng.engine().seed().

I tested it in my code, and it worked as expected.

Well, just in case anybody would care :)

Upvotes: 2

Alan Stokes
Alan Stokes

Reputation: 18964

You should call normal.reset() after the call to gener.seed(). That is specified to ensure that the output of normal will not depend on any previous output from gener.

(The distribution is probably caching some state that you need to clear out.)

Upvotes: 5

Jim Lewis
Jim Lewis

Reputation: 45045

I believe boost::variate_generator<> makes a copy of your boost::mt19937 gener object. So when you reseed your copy of gener, it has no effect on the rng object that's already been constructed. Constructing a new rng object each time you reseed should give you the behavior you want (disclaimer: not tested!)

Upvotes: 1

Related Questions