Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make srand work similarly for global RNG and MersenneTwister instance #8331

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 36 additions & 27 deletions base/random.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,57 +13,46 @@ 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(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())
seed = hash(seed, uint64(getpid()))
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)
return make_seed(a)
end
end

__init__() = srand()

## srand()

function srand(seed::Vector{Uint32})
global RANDOM_SEED = seed
dsfmt_gv_init_by_array(seed)
end
srand(n::Integer) = srand(make_seed(n))
make_seed(seed::Vector{Uint32}) = seed

function make_seed(n::Integer)
n < 0 && throw(DomainError())
Expand All @@ -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

Expand Down
2 changes: 1 addition & 1 deletion doc/stdlib/base.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3929,7 +3929,7 @@ Random number generation in Julia uses the `Mersenne Twister library <http://www

.. function:: srand([rng], [seed])

Reseed the random number generator. If a ``seed`` is provided, the RNG will give a reproducible sequence of numbers, otherwise Julia will get entropy from the system. The ``seed`` may be an unsigned integer, a vector of unsigned integers or a filename, in which case the seed is read from a file. If the argument ``rng`` is not provided, the default global RNG is seeded.
Reseed the random number generator. If a ``seed`` is provided, the RNG will give a reproducible sequence of numbers, otherwise Julia will get entropy from the system. The ``seed`` may be a non-negative integer, a vector of ``Uint32`` integers or a filename, in which case the seed is read from a file. If the argument ``rng`` is not provided, the default global RNG is seeded.

.. function:: MersenneTwister([seed])

Expand Down