Boost logo

Boost :

From: Damien Fisher (damien_at_[hidden])
Date: 2003-10-04 03:22:10


The following code demonstrates a bug in normal_distribution (in the
random library):

#include <boost/random/linear_congruential.hpp>
#include <boost/random/normal_distribution.hpp>

int main(void)
{
    boost::minstd_rand generator(1);
    boost::normal_distribution<boost::minstd_rand> r(generator);

    r(); // Call r once, this will calculate two values (caching the second)
    generator.seed(2);
    std::cout << "First value: " << r() << std::endl;
    std::cout << "First value (cache flushed): " << r() << std::endl;
    generator.seed(2);
    std::cout << "Second value: " << r() << std::endl;
    r(); // Flush the cache
    generator.seed(2);
    std::cout << "Third value: " << r() << std::endl;
}

In my opinion, the first, third, and fourth values printed should be the
same. The output on my machine is:

First value: 5.95404e-05
First value (cache flushed): 0.610586
Second value: 0.000172468
Third value: 0.000172468

The reason for the first value being different is that the
normal_distribution generator calculates two values (using a Box-Muller
transform) and caches the second. When the seed is reset, it still
returns the cached value before generating values with the new seed.

This is clearly undesirable behavior: when changing the seed to a
specific value, the programmer expects, and sometimes requires, that the
values generated are always the same. I don't see any easy way of
fixing this, without some sort of mechanism for the normal_distribution
class to detect when the seed has changed.

Secondly, I noticed this page:

http://www.wikipedia.org/wiki/Box-Muller_transformation

According to the author of the page, the second variant of the transform
given is faster than the method currently used by normal_distribution.
I don't know whether this is true or not, but maybe it is worth
implementing.

Damien


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk