Random Sampler behavior

Hello. I’m now rewriting some Monte Carlo simulation code from Java to Julia. It probably was a bad idea to implement it in Java in the first place, but now I use results calculated by Java implementation to verify the correctness of my Julia implementation. Classic Mersenne Twister (MT19937) is used in both variants. And I found a difference in results, let me show it.

Java code:

public static void main(String[] args) {
    MersenneTwister twister = new MersenneTwister(0);

    for (int i = 1; i <= 5; i++) {
        System.out.println( twister.random());
    }

    for (int i = 1; i <= 10; i++) {
        System.out.print((twister.chooseFrom(10) + 1) + " ");
    }
}

Julia code:

using Random
using RandomNumbers.MersenneTwisters

RNG = MT19937(0)
for i in 1:5 println(rand(RNG)) end

s = Random.Sampler(RNG, 1:10)
for i in 1:10 print(rand(RNG, s), " ") end

Java output:
0.548813502304256
0.5928446163889021
0.715189364971593
0.8442657440900803
0.6027633703779429
9 6 9 5 7 7 4 5 3 9

Julia output:
0.548813502304256
0.5928446163889021
0.715189364971593
0.8442657440900803
0.6027633703779429
6 5 7 5 9 10 4 8 6 6

So, as the first 5 lines of outputs prove, both implementations start from the same pseudo-random sequence. But Random.Sampler in Julia provides only even-numbered elements of the sequence:

9 6 9 5 7 7 4 5 3 9 
  6   5   7   5   9 10 4 8 6 6

So it looks like the Sampler makes extra calls to RNG. Is it so? Why this is needed? Does this affect the performance? Is there a way to get rid of that?

Thanks in advance.

this is because Java defaults to Int32:

julia> RNG = MT19937(0)
MT19937(UInt32[0x00000000, 0x00000001, 0x6c078967, 0x714acb41, 0x48077044, 0x93e7383e, 0xf0f54bb2, 0x141f95dc, 0xc0acdbd4, 0x3cb9cadc  …  0xad4200bc, 0xdaa1fb5d, 0x78ff7c7e, 0x71e51784, 0x499b76e3, 0xd522db95, 0x075dea9a, 0x8ccffb2f, 0xb5b4302f, 0x6b1a1930], 625)

julia> for i in 1:5 println(rand(RNG)) end
0.548813502304256
0.5928446163889021
0.715189364971593
0.8442657440900803
0.6027633703779429

julia> for i in 1:10 print(rand(RNG, Int32(1):Int32(10)), " ") end
9 6 9 5 7 7 4 5 3 9 

so you want to change to:

s = Random.Sampler(RNG, Int32(1):Int32(10))
4 Likes

Thank you very much. Do I understand correctly that in my code the Sampler generates 64 random bits at each call but discards half of the result then? If so, it probably means that for the 1:10 range the type could be restricted even further (Int8). Do such things make any significant performance gain?

if you care about performance, don’t use MT to begin with, as the document would tell you: Mersenne Twisters - RandomNumbers.jl

I won’t. I just need it for the debugging time, for the reproducibility of the results. I’ll change it to Xoroshiro after that. Thanks again.