Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to let Boost::random and Matlab produce the same random numbers

Tags:

c++

boost

matlab

To check my C++ code, I would like to be able to let Boost::Random and Matlab produce the same random numbers.

So for Boost I use the code:

boost::mt19937 var(static_cast<unsigned> (std::time(0)));
boost::uniform_int<> dist(1, 6);
boost::variate_generator<boost::mt19937&, boost::uniform_int<> > die(var, dist);
die.engine().seed(0);     
for(int i = 0; i < 10; ++i) {
    std::cout << die() << " ";
}      
std::cout    << std::endl;

Which produces (every run of the program):
4 4 5 6 4 6 4 6 3 4

And for matlab I use:

RandStream.setDefaultStream(RandStream('mt19937ar','seed',0));
randi(6,1,10)

Which produces (every run of the program):
5 6 1 6 4 1 2 4 6 6

Which is bizarre, since both use the same algorithm, and same seed. What do I miss?

It seems that Python (using numpy) and Matlab seems comparable, in the random uniform numbers: Matlab

RandStream.setDefaultStream(RandStream('mt19937ar','seed',203));rand(1,10)

0.8479 0.1889 0.4506 0.6253 0.9697 0.2078 0.5944 0.9115 0.2457 0.7743

Python: random.seed(203);random.random(10)

array([ 0.84790006, 0.18893843, 0.45060688, 0.62534723, 0.96974765, 0.20780668, 0.59444858, 0.91145688, 0.24568615, 0.77430378])

C++Boost

0.8479 0.667228 0.188938 0.715892 0.450607 0.0790326 0.625347 0.972369 0.969748 0.858771

Which is identical to ever other Python and Matlab value...

like image 433
Thomas Avatar asked Dec 16 '22 14:12

Thomas


2 Answers

I have to agree with the other answers, stating that these generators are not "absolute". They may produce different results according to the implementation. I think the simplest solution would be to implement your own generator. It might look daunting (Mersenne twister sure is by the way) but take a look at Xorshift, an extremely simple though powerful one. I copy the C implementation given in the Wikipedia link :

uint32_t xor128(void) {
  static uint32_t x = 123456789;
  static uint32_t y = 362436069;
  static uint32_t z = 521288629;
  static uint32_t w = 88675123;
  uint32_t t;

  t = x ^ (x << 11);
  x = y; y = z; z = w;
  return w = w ^ (w >> 19) ^ (t ^ (t >> 8));
}

To have the same seed, just put any values you want int x,y,z,w (except(0,0,0,0) I believe). You just need to be sure that Matlab and C++ use both 32 bit for these unsigned int.

like image 69
B. Decoster Avatar answered Dec 19 '22 03:12

B. Decoster


Using the interface like

randi(6,1,10)

will apply some kind of transformation on the raw result of the random generator. This transformation is not trivial in general and Matlab will almost certainly do a different selection step than Boost.

Try comparing raw data streams from the RNGs - chances are they are the same

like image 31
sehe Avatar answered Dec 19 '22 05:12

sehe