Randomness and reproducible results / unit tests

I wonder if this is the suggested approach if one want reproducible results / set unit tests that don’t fail because of the random component, or other approaches are favoured…

using StableRNGs, Random

function myAlgorithm(;seed=nothing)
    rng = (seed==nothing) ? StableRNG(rand(1:typemax(Int64))) : StableRNG(seed)
    # My algorithm with random components that in some cases I want to test or be sure I got the some results every time
    # ...
    return rand(rng,4)
end

There is this nice blog post by Tamas How my Julia coding style changed, see section “Randomness”.

1 Like

Changed titel from “ransomness” to “randomness” to ease my perfectionism

5 Likes

You can use functions in arguments, so it can be just

function myAlgorithm(; rng = StableRNG(rand(1:typemax(Int64))))

But since argument rand uses global random generator anyway, I prefer to use

function myAlgorithm(; rng = Random.GLOBAL_RNG)

Passing rng instead of seed is better, because it gives more flexibility.

1 Like

I see.

This is indeed how it works:

using StableRNGs, Random
const FIXEDSEED = 123
const FIXEDRNG  = StableRNG(FIXEDSEED)

function myAlgorithm(;seed=nothing)
    rng = (seed==nothing) ? StableRNG(rand(1:typemax(Int64))) : StableRNG(seed)
    return rand(rng,4)
end
function myAlgorithm2(;rng = Random.GLOBAL_RNG)
    return rand(rng,4)
end

myAlgorithm(seed=123)                  # always the same result
myAlgorithm2(rng=FIXEDRNG)             # always the same sequence of results on each run of the script ("pulling" from the same rng object on different calls)
myAlgorithm2(rng=StableRNG(FIXEDSEED)) # always the same result (new rng object on each call)

To expand on flexibility: you can use RandomNumbers.jl package, and choose best generator for your needs. Some could be slower but produce better random streams, some can be faster. There are counter based random generators and they are used in parallel computations. So, using generator instead of a seed, gives much more than just reproducibility. I achieved +20% speedup once, just by using different generator instead of the default MersenneTwister.

1 Like