@@ -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)
5456end
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
6269end
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
6673function 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
6976end
7077
7178function == (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
7380end
7481
7582rng_native_52 (:: Xoshiro ) = UInt64
@@ -116,7 +123,7 @@ rng_native_52(::TaskLocalRNG) = UInt64
116123function setstate! (
117124 x:: TaskLocalRNG ,
118125 s0:: UInt64 , s1:: UInt64 , s2:: UInt64 , s3:: UInt64 , # xoshiro256 state
119- s4:: UInt64 = 1 s0 + 3 s1 + 5 s2 + 7 s3 , # internal splitmix state
126+ s4:: UInt64 , # internal splitmix state
120127)
121128 t = current_task ()
122129 t. rngState0 = s0
@@ -148,14 +155,20 @@ end
148155function 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 = 1 s0 + 3 s1 + 5 s2 + 7 s3
163+ setstate! (rng, s0, s1, s2, s3, s4)
152164end
153165
154166function 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 = 1 s0 + 3 s1 + 5 s2 + 7 s3
171+ setstate! (rng, s0, s1, s2, s3, s4)
159172end
160173
161174seed! (rng:: Union{TaskLocalRNG, Xoshiro} , seed:: Integer ) = seed! (rng, make_seed (seed))
@@ -178,24 +191,30 @@ end
178191
179192function 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 )
182195end
183196
184197function 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
188201end
189202
190203function 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
194207end
195208
196209function == (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+ )
199218end
200219
201220== (a:: TaskLocalRNG , b:: Xoshiro ) = b == a
0 commit comments