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