Reputation: 5279
We have been using boost::random for sometime now in our projects. Recently, a failing test unit got me intrigued about one of its properties: the sequence of numbers generated across different versions of Boost may be different, depending on the used distribution.
This behavior does not seem to be consistent across all distributions. Most of the time, uniform distributions using a RNG with the same seed yield the same results. Other distributions such as normal
, lognormal
, binomial
and discrete
may show these differences.
I have put together a simple C++ program that shows the issue:
#include <iostream>
#include <boost/random.hpp>
#include <stdint.h>
void uniform() {
uint32_t seed = 42;
boost::mt19937 rng(seed);
boost::random::uniform_real_distribution<double> distro(0., 1.);
std::cout << "uniform" << std::endl;
for (int i=0; i<10; ++i) {
std::cout << distro(rng) << std::endl;
}
}
void normal() {
uint32_t seed = 42;
boost::mt19937 rng(seed);
boost::random::normal_distribution<double> distro(0., 1.);
std::cout << "normal" << std::endl;
for (int i=0; i<10; ++i) {
std::cout << distro(rng) << std::endl;
}
}
void discrete() {
uint32_t seed = 42;
boost::mt19937 rng(seed);
std::vector<double> P;
P.push_back(0.3);
P.push_back(0.4);
P.push_back(0.3);
boost::random::discrete_distribution<uint64_t> distro(P.begin(), P.end());
std::cout << "discrete" << std::endl;
for (int i=0; i<10; ++i) {
std::cout << distro(rng) << std::endl;
}
}
int main() {
uniform();
normal();
discrete();
}
This simple program will show different sequences of numbers for Boost 1.56 (running on OSX):
uniform
0.37454
0.796543
0.950714
0.183435
0.731994
0.779691
0.598658
0.59685
0.156019
0.445833
normal
-0.638714
-0.836808
-0.400566
-0.869232
-0.972045
-0.758932
-1.30435
1.22996
0.249399
0.286848
discrete
1
2
2
1
0
0
0
2
1
2
Or with Boost 1.50 (running on Ubuntu 12.10):
uniform
0.37454
0.796543
0.950714
0.183435
0.731994
0.779691
0.598658
0.59685
0.156019
0.445833
normal
-1.25821
1.2655
0.606347
-0.19401
-0.196366
-1.72826
-1.09713
-0.783069
0.604964
0.90255
discrete
2
1
2
1
1
0
1
1
0
1
Notice that the uniform distribution works as expected: i.e., the same seed generates a consistent sequence of numbers on both versions. The normal and discrete distribution do not behave the same.
Is there a way to "fix" this? I.e. have different platforms generate the exact same sequence independently of the boost version?
Upvotes: 3
Views: 1160
Reputation: 2424
it seems boost::random does not guarantee that you get the same sequence of numbers for certain seeds with different versions boost.
E.g. in version 1.56 they have changed the algorithm to generate normal distributed random numbers from the Box-Muller method to the Ziggurat method:
https://github.com/boostorg/random/commit/f0ec97ba36c05ef00f2d29dcf66094e3f4abdcde
This method is faster but also produces different number sequences.
Similar changes have probably been done to the other distributions. The uniform distribution still produces the same result as that is typically the output of the base rng which is a mersenne twister 19937 by default.
Upvotes: 2