Skip to content

Commit 355b66a

Browse files
authored
add Xoshiro(seed) constructor, and extend some tests to Xoshiro (#41105)
Usually, a seed should be equally valid for an RNG constructor or for a call to `seed!`, as `seed!`'s docstring mentions: > After the call to seed!, rng is equivalent to a newly created object > initialized with the same seed.
1 parent 612cbe8 commit 355b66a

File tree

2 files changed

+21
-12
lines changed

2 files changed

+21
-12
lines changed

stdlib/Random/src/Xoshiro.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ mutable struct Xoshiro <: AbstractRNG
2323
s1::UInt64
2424
s2::UInt64
2525
s3::UInt64
26+
27+
Xoshiro(s0::Integer, s1::Integer, s2::Integer, s3::Integer) = new(s0, s1, s2, s3)
28+
Xoshiro(seed) = seed!(new(), seed)
2629
end
2730

2831
Xoshiro(::Nothing) = Xoshiro()

stdlib/Random/test/runtests.jl

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ let a = [rand(RandomDevice(), UInt128) for i=1:10]
308308
end
309309

310310
# test all rand APIs
311-
for rng in ([], [MersenneTwister(0)], [RandomDevice()])
311+
for rng in ([], [MersenneTwister(0)], [RandomDevice()], [Xoshiro()])
312312
ftypes = [Float16, Float32, Float64]
313313
cftypes = [ComplexF16, ComplexF32, ComplexF64, ftypes...]
314314
types = [Bool, Char, BigFloat, Base.BitInteger_types..., ftypes...]
@@ -433,7 +433,7 @@ function hist(X, n)
433433
end
434434

435435
# test uniform distribution of floats
436-
for rng in [MersenneTwister(), RandomDevice()],
436+
for rng in [MersenneTwister(), RandomDevice(), Xoshiro()],
437437
T in [Float16, Float32, Float64, BigFloat],
438438
prec in (T == BigFloat ? [3, 53, 64, 100, 256, 1000] : [256])
439439
setprecision(BigFloat, prec) do
@@ -454,7 +454,7 @@ end
454454
# but also for 3 linear combinations of positions (for the array version)
455455
lcs = unique!.([rand(1:n, 2), rand(1:n, 3), rand(1:n, 5)])
456456
aslcs = zeros(Int, 3)
457-
for rng = (MersenneTwister(), RandomDevice())
457+
for rng = (MersenneTwister(), RandomDevice(), Xoshiro())
458458
for scalar = [false, true]
459459
fill!(a, 0)
460460
fill!(as, 0)
@@ -478,8 +478,8 @@ end
478478
end
479479
end
480480

481-
# test reproducility of methods
482-
let mta = MersenneTwister(42), mtb = MersenneTwister(42)
481+
@testset "reproducility of methods for $RNG" for RNG=(MersenneTwister,Xoshiro)
482+
mta, mtb = RNG(42), RNG(42)
483483

484484
@test rand(mta) == rand(mtb)
485485
@test rand(mta,10) == rand(mtb,10)
@@ -664,7 +664,7 @@ end
664664
# this shouldn't crash (#22403)
665665
@test_throws ArgumentError rand!(Union{UInt,Int}[1, 2, 3])
666666

667-
@testset "$RNG() & Random.seed!(rng::$RNG) initializes randomly" for RNG in (MersenneTwister, RandomDevice)
667+
@testset "$RNG() & Random.seed!(rng::$RNG) initializes randomly" for RNG in (MersenneTwister, RandomDevice, Xoshiro)
668668
m = RNG()
669669
a = rand(m, Int)
670670
m = RNG()
@@ -685,11 +685,17 @@ end
685685
@test rand(m, Int) (a, b, c, d)
686686
end
687687

688-
@testset "MersenneTwister($seed) & Random.seed!(m::MersenneTwister, $seed) produce the same stream" for seed in [0:5; 10000:10005]
689-
m = MersenneTwister(seed)
690-
a = [rand(m) for _=1:100]
691-
Random.seed!(m, seed)
692-
@test a == [rand(m) for _=1:100]
688+
@testset "$RNG(seed) & Random.seed!(m::$RNG, seed) produce the same stream" for RNG=(MersenneTwister,Xoshiro)
689+
seeds = Any[0, 1, 2, 10000, 10001, rand(UInt32, 8), rand(UInt128, 3)...]
690+
if RNG == Xoshiro
691+
push!(seeds, rand(UInt64, rand(1:4)), Tuple(rand(UInt64, 4)))
692+
end
693+
for seed=seeds
694+
m = RNG(seed)
695+
a = [rand(m) for _=1:100]
696+
Random.seed!(m, seed)
697+
@test a == [rand(m) for _=1:100]
698+
end
693699
end
694700

695701
struct RandomStruct23964 end
@@ -698,7 +704,7 @@ struct RandomStruct23964 end
698704
@test_throws ArgumentError rand(RandomStruct23964())
699705
end
700706

701-
@testset "rand(::$(typeof(RNG)), ::UnitRange{$T}" for RNG (MersenneTwister(rand(UInt128)), RandomDevice()),
707+
@testset "rand(::$(typeof(RNG)), ::UnitRange{$T}" for RNG (MersenneTwister(rand(UInt128)), RandomDevice(), Xoshiro()),
702708
T (Int8, Int16, Int32, UInt32, Int64, Int128, UInt128)
703709
for S in (SamplerRangeInt, SamplerRangeFast, SamplerRangeNDL)
704710
S == SamplerRangeNDL && sizeof(T) > 8 && continue

0 commit comments

Comments
 (0)