boost::random: get same number sequences 32/64 bit?

Hello list, today I found out that boost::random, at least the combination boost::mt19937 rng(<seed>); typedef boost::uniform_int<int> dist_t; dist_t dist (<min>, <max>); boost::variate_generator< boost::mt19937&, dist_t
rand_ (rng, dist);
will give me different results depending on whether I use "g++ (Debian
4.3.2-1.1) 4.3.2" (with sizeof(long)=8) or "g++.exe (TDM-2 mingw32)
4.4.1" (with sizeof(long)=4).
This testcase:
++
#include
rand_ (rng, dist);
int main () { for (int i=0; i<6; ++i) { std::cout << rand_() << std::endl; } } -- will print 16 8 1 6 0 12 with the 64bit variant variant, but 7 16 12 15 0 2 with the 32bit variant. Is there a (preferably portable) way to ensure that they will be the same on all 32bit+ machines? Otherwise this would be a real stopper to use boost::random for me, and I'd have to go back to libcoyotl's Mersenne Twister, which gives consistent results, upon which I really depend. Sincerely Sebastian Mach phresnel@gmail.com

AMDG Sebastian Mach wrote:
today I found out that boost::random, at least the combination
boost::mt19937 rng(<seed>); typedef boost::uniform_int<int> dist_t; dist_t dist (<min>, <max>); boost::variate_generator< boost::mt19937&, dist_t
rand_ (rng, dist);
will give me different results depending on whether I use "g++ (Debian 4.3.2-1.1) 4.3.2" (with sizeof(long)=8) or "g++.exe (TDM-2 mingw32) 4.4.1" (with sizeof(long)=4).
This testcase: ++ #include
boost::mt19937 rng(1); typedef boost::uniform_int<int> dist_t; dist_t dist (0, 16); boost::variate_generator< boost::mt19937&, dist_t
rand_ (rng, dist);
int main () { for (int i=0; i<6; ++i) { std::cout << rand_() << std::endl; } } --
will print 16 8 1 6 0 12 with the 64bit variant variant, but 7 16 12 15 0 2 with the 32bit variant.
Is there a (preferably portable) way to ensure that they will be the same on all 32bit+ machines?
Otherwise this would be a real stopper to use boost::random for me, and I'd have to go back to libcoyotl's Mersenne Twister, which gives consistent results, upon which I really depend.
Are you using the same version of Boost for both? There were a bunch of bug fixes in uniform_int a few releases ago, which change the exact sequence produced. In Christ, Steven Watanabe

Sebastian Mach wrote:
Are you using the same version of Boost for both? There were a bunch of bug fixes in uniform_int a few releases ago, which change the exact sequence produced.
In Christ, Steven Watanabe
Hello Steven, This was indeed the problem. The one box had boost 1.35 installed, the other one 1.41. Thanks for that hint. I guess this is a) not the right place and b) the interest is probably low (and let it be because it's not in the consciousness of many people): * I realized that just replacing uniform_int.hpp with the older version (that is, in a project local directory) and renaming components was not easily possible * hence it might be hard in the future to trust boost::random in the little corner where I really need portable random number sequences (as users will literally work with seeds) * thus, I (and maybe some other persons) would love if, as with spirit::classic, backwards compatibility could be provided somehow, either via a typedef, a #define, or in the future with inline namespaces Of course, if there is already a way that "guarantees" (not as in law), I would be happy (after all, I am already happy to have a small regression test generator which initially showed me the problem; if there is interest, it is at http://gitorious.org/picogen/picogen/trees/master/trunk/kallisto/test :) ). Otherwise, I must really stick to hand written RNGs, which are less portable in code, but more portable in sequences, as no RNG-lib I know seems go have this kind of portability as a guideline. Many thanks for your help so far, Sebastian Mach phresnel@gmail.com

AMDG Sebastian Mach wrote:
This was indeed the problem. The one box had boost 1.35 installed, the other one 1.41. Thanks for that hint.
I guess this is a) not the right place and b) the interest is probably low (and let it be because it's not in the consciousness of many people): * I realized that just replacing uniform_int.hpp with the older version (that is, in a project local directory) and renaming components was not easily possible * hence it might be hard in the future to trust boost::random in the little corner where I really need portable random number sequences (as users will literally work with seeds) * thus, I (and maybe some other persons) would love if, as with spirit::classic, backwards compatibility could be provided somehow, either via a typedef, a #define, or in the future with inline namespaces
Of course, if there is already a way that "guarantees" (not as in law), I would be happy (after all, I am already happy to have a small regression test generator which initially showed me the problem; if there is interest, it is at http://gitorious.org/picogen/picogen/trees/master/trunk/kallisto/test :) ). Otherwise, I must really stick to hand written RNGs, which are less portable in code, but more portable in sequences, as no RNG-lib I know seems go have this kind of portability as a guideline.
You could try using boost::mt19937 directly without uniform_int. The version of mt19937 in C++0x is guaranteed to produce a specific sequence (Required behavior: The 10000th consecutive invocation of a default-constructed object of type mt19937 shall produce the value 4123659995.), and the Boost.Random version will be kept consistent with the standard. Also, boost::uniform_int should not change again unless there is a bug in it, and I'm about 99% certain that it is completely correct now. In Christ, Steven Watanabe

2010/2/1 Steven Watanabe
AMDG
Sebastian Mach wrote:
This was indeed the problem. The one box had boost 1.35 installed, the other one 1.41. Thanks for that hint.
I guess this is a) not the right place and b) the interest is probably low (and let it be because it's not in the consciousness of many people): * I realized that just replacing uniform_int.hpp with the older version (that is, in a project local directory) and renaming components was not easily possible * hence it might be hard in the future to trust boost::random in the little corner where I really need portable random number sequences (as users will literally work with seeds) * thus, I (and maybe some other persons) would love if, as with spirit::classic, backwards compatibility could be provided somehow, either via a typedef, a #define, or in the future with inline namespaces
Of course, if there is already a way that "guarantees" (not as in law), I would be happy (after all, I am already happy to have a small regression test generator which initially showed me the problem; if there is interest, it is at http://gitorious.org/picogen/picogen/trees/master/trunk/kallisto/test :) ). Otherwise, I must really stick to hand written RNGs, which are less portable in code, but more portable in sequences, as no RNG-lib I know seems go have this kind of portability as a guideline.
You could try using boost::mt19937 directly without uniform_int. The version of mt19937 in C++0x is guaranteed to produce a specific sequence (Required behavior: The 10000th consecutive invocation of a default-constructed object of type mt19937 shall produce the value 4123659995.), and the Boost.Random version will be kept consistent with the standard.
Also, boost::uniform_int should not change again unless there is a bug in it, and I'm about 99% certain that it is completely correct now.
Interesting, both the fact that mt19937 can be used directly (I did not know that) and that C++0x will guarantee that sequence. Thank you very much and Happy Programming
participants (2)
-
Sebastian Mach
-
Steven Watanabe