Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Apache Math3 MersenneTwister VS Python random

I have the task of porting some python code to Scala for research purposes. Now I use the Apache Math3 commons library and am having difficulty with the MersenneTwister.

In Python:

SEED = 1234567890

PRIMARY_RNG = random.Random()
PRIMARY_RNG.seed(SEED)
n = PRIMARY_RNG.randrange((2**31) - 1) #1977150888

In Scala:

val Seed = 1234567890
val PrimaryRNG = new MersenneTwister(Seed)
val n = PrimaryRNG.nextInt(Int.MaxValue) //1328851649

What am I missing here? Both are MersenneTwister's,
and Int.MaxValue = 2147483647 = (2**31) - 1

like image 232
WiR3D Avatar asked Aug 04 '14 20:08

WiR3D


2 Answers

Apache Commons Math apparently uses an integer as the base source of randomness, though I'm not quite sure how it extracts it, while Python uses the double generated by a C version of the algorithm.

There may also be differences in how the seed values are processed, but since they don't even read out the bits in the same way, one wouldn't expect them to be comparable even if the underlying pseudorandom generator is the same.

like image 68
Rex Kerr Avatar answered Sep 22 '22 07:09

Rex Kerr


As I have already posted in the comments the main algorithm to get the next integer is the same between Python and Apache Math (source code here, here, and here). Tracing through the code it seems that the main difference is in how the two versions seed the generator. The Python version will convert the given seed into an array and seed from the array while the Apache Math version has a separate algorithm for seeding from a single number. Thus in order to get the Apache Math nextInt(...) method to act in the save way as the Python randrange(...) method you should seed the Apache Math version with an array.

(I don't know Scala so the following code is in Java)

MersenneTwister rng = new MersenneTwister();
rng.setSeed(new int[] {1234567890});
System.out.println(rng.nextInt(Integer.MAX_VALUE)); // 1977150888

Note also that all of the other methods such as random() vs. nextDouble() are completely different so this seeding mechanism will probably only work to make nextInt(...) and randrange(...) to return the same results.

like image 33
SamYonnou Avatar answered Sep 21 '22 07:09

SamYonnou