From b60859bebbe6fb8b708cdcd867a7a1f18eb9b638 Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Fri, 12 Sep 2014 19:50:18 +0530 Subject: [PATCH 1/2] make the seed of a MersenneTwister be always a Vector{Uint32} MersenneTwister's constructor making an instance with an Uint32 seed were removed in commit 4fb4622f5c. But a subsequent call to srand(r::MersenneTwister, seed) would only accept an Uint32 as a seed, and would always make r.seed an Uint32; this was not consistent. --- base/random.jl | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/base/random.jl b/base/random.jl index fee039d6fe9db..b845b780eabf6 100644 --- a/base/random.jl +++ b/base/random.jl @@ -13,21 +13,14 @@ abstract AbstractRNG type MersenneTwister <: AbstractRNG state::DSFMT_state - seed::Union(Uint32,Vector{Uint32}) + seed::Vector{Uint32} - function MersenneTwister(seed::Vector{Uint32}) + function MersenneTwister(seed::Union(Integer,Vector{Uint32})) state = DSFMT_state() - dsfmt_init_by_array(state, seed) - return new(state, seed) + return srand(new(state), seed) end - MersenneTwister(seed=0) = MersenneTwister(make_seed(seed)) -end - -function srand(r::MersenneTwister, seed) - r.seed = seed - dsfmt_init_gen_rand(r.state, seed) - return r + MersenneTwister() = MersenneTwister(make_seed(0)) end ## initialization @@ -59,11 +52,18 @@ __init__() = srand() ## srand() -function srand(seed::Vector{Uint32}) - global RANDOM_SEED = seed - dsfmt_gv_init_by_array(seed) +function srand(seed::Union(Integer, Vector{Uint32})) + global RANDOM_SEED = make_seed(seed) + dsfmt_gv_init_by_array(RANDOM_SEED) end -srand(n::Integer) = srand(make_seed(n)) + +function srand(r::MersenneTwister, seed::Union(Integer, Vector{Uint32})) + r.seed = make_seed(seed) + dsfmt_init_by_array(r.state, r.seed) + return r +end + +make_seed(seed::Vector{Uint32}) = seed function make_seed(n::Integer) n < 0 && throw(DomainError()) From 20ef5673551821b111c2c54b049a02fd7ec4992b Mon Sep 17 00:00:00 2001 From: Rafael Fourquet Date: Fri, 12 Sep 2014 20:23:12 +0530 Subject: [PATCH 2/2] make srand behave as the manual pretended The srand methods working on a MersenneTwister instance did not catch up with those working on the global RNG. They are now made similar thanks to the make_seed function, which implements the different logics. Also, the manual is more precise on the types of valid seeds. --- base/random.jl | 55 ++++++++++++++++++++++++++------------------- doc/stdlib/base.rst | 2 +- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/base/random.jl b/base/random.jl index b845b780eabf6..6aa87aa50ff00 100644 --- a/base/random.jl +++ b/base/random.jl @@ -20,16 +20,20 @@ type MersenneTwister <: AbstractRNG return srand(new(state), seed) end - MersenneTwister() = MersenneTwister(make_seed(0)) + MersenneTwister() = MersenneTwister(0) end ## initialization -function srand() +__init__() = srand() + +## make_seed() + +function make_seed() @unix_only begin try - srand("/dev/urandom") + return make_seed("/dev/urandom", 4) catch println(STDERR, "Entropy pool not available to seed RNG; using ad-hoc entropy sources.") seed = reinterpret(Uint64, time()) @@ -37,30 +41,15 @@ function srand() try seed = hash(seed, parseint(Uint64, readall(`ifconfig` |> `sha1sum`)[1:40], 16)) end - srand(seed) + return make_seed(seed) end end @windows_only begin a = zeros(Uint32, 2) win32_SystemFunction036!(a) - srand(a) -end -end - -__init__() = srand() - -## srand() - -function srand(seed::Union(Integer, Vector{Uint32})) - global RANDOM_SEED = make_seed(seed) - dsfmt_gv_init_by_array(RANDOM_SEED) + return make_seed(a) end - -function srand(r::MersenneTwister, seed::Union(Integer, Vector{Uint32})) - r.seed = make_seed(seed) - dsfmt_init_by_array(r.state, r.seed) - return r end make_seed(seed::Vector{Uint32}) = seed @@ -77,14 +66,34 @@ function make_seed(n::Integer) end end -function srand(filename::String, n::Integer) +function make_seed(filename::String, n::Integer) open(filename) do io a = Array(Uint32, int(n)) read!(io, a) - srand(a) + a end end -srand(filename::String) = srand(filename, 4) + +## srand() + +srand() = srand(make_seed()) + +srand(r::MersenneTwister) = srand(r, make_seed()) + +function srand(seed::Union(Integer, Vector{Uint32})) + global RANDOM_SEED = make_seed(seed) + dsfmt_gv_init_by_array(RANDOM_SEED) +end + +function srand(r::MersenneTwister, seed::Union(Integer, Vector{Uint32})) + r.seed = make_seed(seed) + dsfmt_init_by_array(r.state, r.seed) + return r +end + +srand(filename::String, n::Integer=4) = srand(make_seed(filename, n)) + +srand(r::MersenneTwister, filename::String, n::Integer=4) = srand(r, make_seed(filename, n)) ## random floating point values diff --git a/doc/stdlib/base.rst b/doc/stdlib/base.rst index e237f0af810dc..e3b8521fbcb72 100644 --- a/doc/stdlib/base.rst +++ b/doc/stdlib/base.rst @@ -3929,7 +3929,7 @@ Random number generation in Julia uses the `Mersenne Twister library