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
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.