Skip to content

Commit dab7b33

Browse files
committed
add s4 to Xoshiro
1 parent b5feb45 commit dab7b33

File tree

1 file changed

+31
-12
lines changed

1 file changed

+31
-12
lines changed

stdlib/Random/src/Xoshiro.jl

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -48,28 +48,35 @@ mutable struct Xoshiro <: AbstractRNG
4848
s1::UInt64
4949
s2::UInt64
5050
s3::UInt64
51+
s4::UInt64 # internal splitmix state
5152

52-
Xoshiro(s0::Integer, s1::Integer, s2::Integer, s3::Integer) = new(s0, s1, s2, s3)
53+
Xoshiro(s0::Integer, s1::Integer, s2::Integer, s3::Integer, s4::Integer) = new(s0, s1, s2, s3, s4)
54+
Xoshiro(s0::Integer, s1::Integer, s2::Integer, s3::Integer) = new(s0, s1, s2, s3, UInt64(0))
5355
Xoshiro(seed=nothing) = seed!(new(), seed)
5456
end
5557

56-
function setstate!(x::Xoshiro, s0::UInt64, s1::UInt64, s2::UInt64, s3::UInt64)
58+
function setstate!(
59+
x::Xoshiro,
60+
s0::UInt64, s1::UInt64, s2::UInt64, s3::UInt64, # xoshiro256 state
61+
s4::UInt64, # internal splitmix state
62+
)
5763
x.s0 = s0
5864
x.s1 = s1
5965
x.s2 = s2
6066
x.s3 = s3
67+
x.s4 = s4
6168
x
6269
end
6370

64-
copy(rng::Xoshiro) = Xoshiro(rng.s0, rng.s1, rng.s2, rng.s3)
71+
copy(rng::Xoshiro) = Xoshiro(rng.s0, rng.s1, rng.s2, rng.s3, rng.s4)
6572

6673
function copy!(dst::Xoshiro, src::Xoshiro)
67-
dst.s0, dst.s1, dst.s2, dst.s3 = src.s0, src.s1, src.s2, src.s3
74+
dst.s0, dst.s1, dst.s2, dst.s3, dst.s4 = src.s0, src.s1, src.s2, src.s3, src.s4
6875
dst
6976
end
7077

7178
function ==(a::Xoshiro, b::Xoshiro)
72-
a.s0 == b.s0 && a.s1 == b.s1 && a.s2 == b.s2 && a.s3 == b.s3
79+
a.s0 == b.s0 && a.s1 == b.s1 && a.s2 == b.s2 && a.s3 == b.s3 && a.s4 == b.s4
7380
end
7481

7582
rng_native_52(::Xoshiro) = UInt64
@@ -116,7 +123,7 @@ rng_native_52(::TaskLocalRNG) = UInt64
116123
function setstate!(
117124
x::TaskLocalRNG,
118125
s0::UInt64, s1::UInt64, s2::UInt64, s3::UInt64, # xoshiro256 state
119-
s4::UInt64 = 1s0 + 3s1 + 5s2 + 7s3, # internal splitmix state
126+
s4::UInt64, # internal splitmix state
120127
)
121128
t = current_task()
122129
t.rngState0 = s0
@@ -148,14 +155,20 @@ end
148155
function seed!(rng::Union{TaskLocalRNG,Xoshiro})
149156
# as we get good randomness from RandomDevice, we can skip hashing
150157
rd = RandomDevice()
151-
setstate!(rng, rand(rd, UInt64), rand(rd, UInt64), rand(rd, UInt64), rand(rd, UInt64))
158+
s0 = rand(rd, UInt64)
159+
s1 = rand(rd, UInt64)
160+
s2 = rand(rd, UInt64)
161+
s3 = rand(rd, UInt64)
162+
s4 = 1s0 + 3s1 + 5s2 + 7s3
163+
setstate!(rng, s0, s1, s2, s3, s4)
152164
end
153165

154166
function seed!(rng::Union{TaskLocalRNG,Xoshiro}, seed::Union{Vector{UInt32}, Vector{UInt64}})
155167
c = SHA.SHA2_256_CTX()
156168
SHA.update!(c, reinterpret(UInt8, seed))
157169
s0, s1, s2, s3 = reinterpret(UInt64, SHA.digest!(c))
158-
setstate!(rng, s0, s1, s2, s3)
170+
s4 = 1s0 + 3s1 + 5s2 + 7s3
171+
setstate!(rng, s0, s1, s2, s3, s4)
159172
end
160173

161174
seed!(rng::Union{TaskLocalRNG, Xoshiro}, seed::Integer) = seed!(rng, make_seed(seed))
@@ -178,24 +191,30 @@ end
178191

179192
function copy(rng::TaskLocalRNG)
180193
t = current_task()
181-
Xoshiro(t.rngState0, t.rngState1, t.rngState2, t.rngState3)
194+
Xoshiro(t.rngState0, t.rngState1, t.rngState2, t.rngState3, t.rngState4)
182195
end
183196

184197
function copy!(dst::TaskLocalRNG, src::Xoshiro)
185198
t = current_task()
186-
setstate!(dst, src.s0, src.s1, src.s2, src.s3)
199+
setstate!(dst, src.s0, src.s1, src.s2, src.s3, src.s4)
187200
return dst
188201
end
189202

190203
function copy!(dst::Xoshiro, src::TaskLocalRNG)
191204
t = current_task()
192-
setstate!(dst, t.rngState0, t.rngState1, t.rngState2, t.rngState3)
205+
setstate!(dst, t.rngState0, t.rngState1, t.rngState2, t.rngState3, t.rngState4)
193206
return dst
194207
end
195208

196209
function ==(a::Xoshiro, b::TaskLocalRNG)
197210
t = current_task()
198-
a.s0 == t.rngState0 && a.s1 == t.rngState1 && a.s2 == t.rngState2 && a.s3 == t.rngState3
211+
(
212+
a.s0 == t.rngState0 &&
213+
a.s1 == t.rngState1 &&
214+
a.s2 == t.rngState2 &&
215+
a.s3 == t.rngState3 &&
216+
a.s4 == t.rngState4
217+
)
199218
end
200219

201220
==(a::TaskLocalRNG, b::Xoshiro) = b == a

0 commit comments

Comments
 (0)