Skip to content

Commit 2d4d096

Browse files
authored
unify shuffle and randperm (JuliaLang#50318)
1 parent 680e3b3 commit 2d4d096

File tree

1 file changed

+26
-23
lines changed

1 file changed

+26
-23
lines changed

stdlib/Random/src/misc.jl

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -201,34 +201,35 @@ julia> rng = MersenneTwister(1234);
201201
202202
julia> shuffle!(rng, Vector(1:16))
203203
16-element Vector{Int64}:
204-
2
205-
15
206-
5
207-
14
204+
16
208205
1
209-
9
206+
14
207+
12
208+
5
210209
10
211-
6
212-
11
210+
4
211+
15
212+
13
213213
3
214-
16
215214
7
216-
4
217-
12
215+
9
216+
6
217+
11
218218
8
219-
13
219+
2
220220
```
221221
"""
222222
function shuffle!(r::AbstractRNG, a::AbstractArray)
223+
# keep it consistent with `randperm!` and `randcycle!` if possible
223224
require_one_based_indexing(a)
224225
n = length(a)
225-
n <= 1 && return a # nextpow below won't work with n == 0
226226
@assert n <= Int64(2)^52
227-
mask = nextpow(2, n) - 1
228-
for i = n:-1:2
229-
(mask >> 1) == i && (mask >>= 1)
227+
n == 0 && return a
228+
mask = 3
229+
@inbounds for i = 2:n
230230
j = 1 + rand(r, ltm52(i, mask))
231231
a[i], a[j] = a[j], a[i]
232+
i == 1 + mask && (mask = 2 * mask + 1)
232233
end
233234
return a
234235
end
@@ -249,16 +250,16 @@ julia> rng = MersenneTwister(1234);
249250
250251
julia> shuffle(rng, Vector(1:10))
251252
10-element Vector{Int64}:
252-
6
253-
1
254-
10
255253
2
256-
3
254+
1
255+
7
257256
9
258257
5
259-
7
258+
10
260259
4
261260
8
261+
6
262+
3
262263
```
263264
"""
264265
shuffle(r::AbstractRNG, a::AbstractArray) = shuffle!(r, copymutable(a))
@@ -315,6 +316,7 @@ julia> randperm!(MersenneTwister(1234), Vector{Int}(undef, 4))
315316
```
316317
"""
317318
function randperm!(r::AbstractRNG, a::Array{<:Integer})
319+
# keep it consistent with `shuffle!` and `randcycle!` if possible
318320
n = length(a)
319321
@assert n <= Int64(2)^52
320322
n == 0 && return a
@@ -326,7 +328,7 @@ function randperm!(r::AbstractRNG, a::Array{<:Integer})
326328
a[i] = a[j]
327329
end
328330
a[j] = i
329-
i == 1+mask && (mask = 2mask + 1)
331+
i == 1 + mask && (mask = 2 * mask + 1)
330332
end
331333
return a
332334
end
@@ -382,16 +384,17 @@ julia> randcycle!(MersenneTwister(1234), Vector{Int}(undef, 6))
382384
```
383385
"""
384386
function randcycle!(r::AbstractRNG, a::Array{<:Integer})
387+
# keep it consistent with `shuffle!` and `randperm!` if possible
385388
n = length(a)
386-
n == 0 && return a
387389
@assert n <= Int64(2)^52
390+
n == 0 && return a
388391
a[1] = 1
389392
mask = 3
390393
@inbounds for i = 2:n
391394
j = 1 + rand(r, ltm52(i-1, mask))
392395
a[i] = a[j]
393396
a[j] = i
394-
i == 1+mask && (mask = 2mask + 1)
397+
i == 1 + mask && (mask = 2 * mask + 1)
395398
end
396399
return a
397400
end

0 commit comments

Comments
 (0)