Skip to content

Commit 8696d51

Browse files
devmotionararslan
andauthored
Use default_rng() instead of GLOBAL_RNG on Julia >= 1.3 (#878)
* Use `default_rng()` instead of `GLOBAL_RNG` on Julia >= 1.3 * Improve version check Co-authored-by: Alex Arslan <[email protected]> * Update test/sampling.jl --------- Co-authored-by: Alex Arslan <[email protected]>
1 parent eac9bb8 commit 8696d51

File tree

3 files changed

+56
-44
lines changed

3 files changed

+56
-44
lines changed

docs/src/sampling.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ Here are a list of algorithms implemented in the package. The functions below ar
3232
- `wv`: the weight vector (of type `AbstractWeights`), for weighted sampling
3333
- `n`: the length of `a`
3434
- `k`: the length of `x`. For sampling without replacement, `k` must not exceed `n`.
35-
- `rng`: optional random number generator (defaults to `Random.GLOBAL_RNG`)
35+
- `rng`: optional random number generator (defaults to `Random.default_rng()` on Julia >= 1.3 and `Random.GLOBAL_RNG` on Julia < 1.3)
3636

3737
All following functions write results to `x` (pre-allocated) and return `x`.
3838

src/sampling.jl

Lines changed: 48 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@
55
#
66
###########################################################
77

8-
using Random: Sampler, Random.GLOBAL_RNG
8+
using Random: Sampler
9+
10+
if VERSION < v"1.3.0-DEV.565"
11+
default_rng() = Random.GLOBAL_RNG
12+
else
13+
using Random: default_rng
14+
end
915

1016
### Algorithms for sampling with replacement
1117

@@ -25,7 +31,7 @@ function direct_sample!(rng::AbstractRNG, a::UnitRange, x::AbstractArray)
2531
end
2632
return x
2733
end
28-
direct_sample!(a::UnitRange, x::AbstractArray) = direct_sample!(Random.GLOBAL_RNG, a, x)
34+
direct_sample!(a::UnitRange, x::AbstractArray) = direct_sample!(default_rng(), a, x)
2935

3036
"""
3137
direct_sample!([rng], a::AbstractArray, x::AbstractArray)
@@ -46,7 +52,7 @@ function direct_sample!(rng::AbstractRNG, a::AbstractArray, x::AbstractArray)
4652
end
4753
return x
4854
end
49-
direct_sample!(a::AbstractArray, x::AbstractArray) = direct_sample!(Random.GLOBAL_RNG, a, x)
55+
direct_sample!(a::AbstractArray, x::AbstractArray) = direct_sample!(default_rng(), a, x)
5056

5157
# check whether we can use T to store indices 1:n exactly, and
5258
# use some heuristics to decide whether it is beneficial for k samples
@@ -103,28 +109,28 @@ sample_ordered!(sampler!, rng::AbstractRNG, a::AbstractArray,
103109
Draw a pair of distinct integers between 1 and `n` without replacement.
104110
105111
Optionally specify a random number generator `rng` as the first argument
106-
(defaults to `Random.GLOBAL_RNG`).
112+
(defaults to `Random.$(VERSION < v"1.3" ? "GLOBAL_RNG" : "default_rng()")`).
107113
"""
108114
function samplepair(rng::AbstractRNG, n::Integer)
109115
i1 = rand(rng, one(n):n)
110116
i2 = rand(rng, one(n):(n - one(n)))
111117
return (i1, ifelse(i2 == i1, n, i2))
112118
end
113-
samplepair(n::Integer) = samplepair(Random.GLOBAL_RNG, n)
119+
samplepair(n::Integer) = samplepair(default_rng(), n)
114120

115121
"""
116122
samplepair([rng], a)
117123
118124
Draw a pair of distinct elements from the array `a` without replacement.
119125
120126
Optionally specify a random number generator `rng` as the first argument
121-
(defaults to `Random.GLOBAL_RNG`).
127+
(defaults to `Random.$(VERSION < v"1.3" ? "GLOBAL_RNG" : "default_rng()")`).
122128
"""
123129
function samplepair(rng::AbstractRNG, a::AbstractArray)
124130
i1, i2 = samplepair(rng, length(a))
125131
return a[i1], a[i2]
126132
end
127-
samplepair(a::AbstractArray) = samplepair(Random.GLOBAL_RNG, a)
133+
samplepair(a::AbstractArray) = samplepair(default_rng(), a)
128134

129135
### Algorithm for sampling without replacement
130136

@@ -173,7 +179,7 @@ function knuths_sample!(rng::AbstractRNG, a::AbstractArray, x::AbstractArray;
173179
return x
174180
end
175181
knuths_sample!(a::AbstractArray, x::AbstractArray; initshuffle::Bool=true) =
176-
knuths_sample!(Random.GLOBAL_RNG, a, x; initshuffle=initshuffle)
182+
knuths_sample!(default_rng(), a, x; initshuffle=initshuffle)
177183

178184
"""
179185
fisher_yates_sample!([rng], a::AbstractArray, x::AbstractArray)
@@ -223,7 +229,7 @@ function fisher_yates_sample!(rng::AbstractRNG, a::AbstractArray, x::AbstractArr
223229
return x
224230
end
225231
fisher_yates_sample!(a::AbstractArray, x::AbstractArray) =
226-
fisher_yates_sample!(Random.GLOBAL_RNG, a, x)
232+
fisher_yates_sample!(default_rng(), a, x)
227233

228234
"""
229235
self_avoid_sample!([rng], a::AbstractArray, x::AbstractArray)
@@ -269,7 +275,7 @@ function self_avoid_sample!(rng::AbstractRNG, a::AbstractArray, x::AbstractArray
269275
return x
270276
end
271277
self_avoid_sample!(a::AbstractArray, x::AbstractArray) =
272-
self_avoid_sample!(Random.GLOBAL_RNG, a, x)
278+
self_avoid_sample!(default_rng(), a, x)
273279

274280
"""
275281
seqsample_a!([rng], a::AbstractArray, x::AbstractArray)
@@ -311,7 +317,7 @@ function seqsample_a!(rng::AbstractRNG, a::AbstractArray, x::AbstractArray)
311317
end
312318
return x
313319
end
314-
seqsample_a!(a::AbstractArray, x::AbstractArray) = seqsample_a!(Random.GLOBAL_RNG, a, x)
320+
seqsample_a!(a::AbstractArray, x::AbstractArray) = seqsample_a!(default_rng(), a, x)
315321

316322
"""
317323
seqsample_c!([rng], a::AbstractArray, x::AbstractArray)
@@ -357,7 +363,7 @@ function seqsample_c!(rng::AbstractRNG, a::AbstractArray, x::AbstractArray)
357363
end
358364
return x
359365
end
360-
seqsample_c!(a::AbstractArray, x::AbstractArray) = seqsample_c!(Random.GLOBAL_RNG, a, x)
366+
seqsample_c!(a::AbstractArray, x::AbstractArray) = seqsample_c!(default_rng(), a, x)
361367

362368
"""
363369
seqsample_d!([rng], a::AbstractArray, x::AbstractArray)
@@ -449,7 +455,7 @@ function seqsample_d!(rng::AbstractRNG, a::AbstractArray, x::AbstractArray)
449455
end
450456
end
451457

452-
seqsample_d!(a::AbstractArray, x::AbstractArray) = seqsample_d!(Random.GLOBAL_RNG, a, x)
458+
seqsample_d!(a::AbstractArray, x::AbstractArray) = seqsample_d!(default_rng(), a, x)
453459

454460

455461
### Interface functions (poly-algorithms)
@@ -460,10 +466,10 @@ Select a single random element of `a`. Sampling probabilities are proportional t
460466
the weights given in `wv`, if provided.
461467
462468
Optionally specify a random number generator `rng` as the first argument
463-
(defaults to `Random.GLOBAL_RNG`).
469+
(defaults to `Random.$(VERSION < v"1.3" ? "GLOBAL_RNG" : "default_rng()")`).
464470
"""
465471
sample(rng::AbstractRNG, a::AbstractArray) = a[rand(rng, 1:length(a))]
466-
sample(a::AbstractArray) = sample(Random.GLOBAL_RNG, a)
472+
sample(a::AbstractArray) = sample(default_rng(), a)
467473

468474

469475
"""
@@ -478,7 +484,7 @@ an ordered sample (also called a sequential sample, i.e. a sample where
478484
items appear in the same order as in `a`) should be taken.
479485
480486
Optionally specify a random number generator `rng` as the first argument
481-
(defaults to `Random.GLOBAL_RNG`).
487+
(defaults to `Random.$(VERSION < v"1.3" ? "GLOBAL_RNG" : "default_rng()")`).
482488
483489
Output array `a` must not be the same object as `x` or `wv`
484490
nor share memory with them, or the result may be incorrect.
@@ -522,7 +528,7 @@ function sample!(rng::AbstractRNG, a::AbstractArray, x::AbstractArray;
522528
return x
523529
end
524530
sample!(a::AbstractArray, x::AbstractArray; replace::Bool=true, ordered::Bool=false) =
525-
sample!(Random.GLOBAL_RNG, a, x; replace=replace, ordered=ordered)
531+
sample!(default_rng(), a, x; replace=replace, ordered=ordered)
526532

527533

528534
"""
@@ -536,14 +542,14 @@ an ordered sample (also called a sequential sample, i.e. a sample where
536542
items appear in the same order as in `a`) should be taken.
537543
538544
Optionally specify a random number generator `rng` as the first argument
539-
(defaults to `Random.GLOBAL_RNG`).
545+
(defaults to `Random.$(VERSION < v"1.3" ? "GLOBAL_RNG" : "default_rng()")`).
540546
"""
541547
function sample(rng::AbstractRNG, a::AbstractArray{T}, n::Integer;
542548
replace::Bool=true, ordered::Bool=false) where T
543549
sample!(rng, a, Vector{T}(undef, n); replace=replace, ordered=ordered)
544550
end
545551
sample(a::AbstractArray, n::Integer; replace::Bool=true, ordered::Bool=false) =
546-
sample(Random.GLOBAL_RNG, a, n; replace=replace, ordered=ordered)
552+
sample(default_rng(), a, n; replace=replace, ordered=ordered)
547553

548554

549555
"""
@@ -557,14 +563,14 @@ an ordered sample (also called a sequential sample, i.e. a sample where
557563
items appear in the same order as in `a`) should be taken.
558564
559565
Optionally specify a random number generator `rng` as the first argument
560-
(defaults to `Random.GLOBAL_RNG`).
566+
(defaults to `Random.$(VERSION < v"1.3" ? "GLOBAL_RNG" : "default_rng()")`).
561567
"""
562568
function sample(rng::AbstractRNG, a::AbstractArray{T}, dims::Dims;
563569
replace::Bool=true, ordered::Bool=false) where T
564570
sample!(rng, a, Array{T}(undef, dims); replace=replace, ordered=ordered)
565571
end
566572
sample(a::AbstractArray, dims::Dims; replace::Bool=true, ordered::Bool=false) =
567-
sample(Random.GLOBAL_RNG, a, dims; replace=replace, ordered=ordered)
573+
sample(default_rng(), a, dims; replace=replace, ordered=ordered)
568574

569575
################################################################
570576
#
@@ -579,7 +585,7 @@ Select a single random integer in `1:length(wv)` with probabilities
579585
proportional to the weights given in `wv`.
580586
581587
Optionally specify a random number generator `rng` as the first argument
582-
(defaults to `Random.GLOBAL_RNG`).
588+
(defaults to `Random.$(VERSION < v"1.3" ? "GLOBAL_RNG" : "default_rng()")`).
583589
"""
584590
function sample(rng::AbstractRNG, wv::AbstractWeights)
585591
1 == firstindex(wv) ||
@@ -594,10 +600,10 @@ function sample(rng::AbstractRNG, wv::AbstractWeights)
594600
end
595601
return i
596602
end
597-
sample(wv::AbstractWeights) = sample(Random.GLOBAL_RNG, wv)
603+
sample(wv::AbstractWeights) = sample(default_rng(), wv)
598604

599605
sample(rng::AbstractRNG, a::AbstractArray, wv::AbstractWeights) = a[sample(rng, wv)]
600-
sample(a::AbstractArray, wv::AbstractWeights) = sample(Random.GLOBAL_RNG, a, wv)
606+
sample(a::AbstractArray, wv::AbstractWeights) = sample(default_rng(), a, wv)
601607

602608
"""
603609
direct_sample!([rng], a::AbstractArray, wv::AbstractWeights, x::AbstractArray)
@@ -627,7 +633,7 @@ function direct_sample!(rng::AbstractRNG, a::AbstractArray,
627633
return x
628634
end
629635
direct_sample!(a::AbstractArray, wv::AbstractWeights, x::AbstractArray) =
630-
direct_sample!(Random.GLOBAL_RNG, a, wv, x)
636+
direct_sample!(default_rng(), a, wv, x)
631637

632638
function make_alias_table!(w::AbstractVector, wsum,
633639
a::AbstractVector{Float64},
@@ -725,7 +731,7 @@ function alias_sample!(rng::AbstractRNG, a::AbstractArray, wv::AbstractWeights,
725731
return x
726732
end
727733
alias_sample!(a::AbstractArray, wv::AbstractWeights, x::AbstractArray) =
728-
alias_sample!(Random.GLOBAL_RNG, a, wv, x)
734+
alias_sample!(default_rng(), a, wv, x)
729735

730736
"""
731737
naive_wsample_norep!([rng], a::AbstractArray, wv::AbstractWeights, x::AbstractArray)
@@ -769,7 +775,7 @@ function naive_wsample_norep!(rng::AbstractRNG, a::AbstractArray,
769775
return x
770776
end
771777
naive_wsample_norep!(a::AbstractArray, wv::AbstractWeights, x::AbstractArray) =
772-
naive_wsample_norep!(Random.GLOBAL_RNG, a, wv, x)
778+
naive_wsample_norep!(default_rng(), a, wv, x)
773779

774780
# Weighted sampling without replacement
775781
# Instead of keys u^(1/w) where u = random(0,1) keys w/v where v = randexp(1) are used.
@@ -810,7 +816,7 @@ function efraimidis_a_wsample_norep!(rng::AbstractRNG, a::AbstractArray,
810816
return x
811817
end
812818
efraimidis_a_wsample_norep!(a::AbstractArray, wv::AbstractWeights, x::AbstractArray) =
813-
efraimidis_a_wsample_norep!(Random.GLOBAL_RNG, a, wv, x)
819+
efraimidis_a_wsample_norep!(default_rng(), a, wv, x)
814820

815821
# Weighted sampling without replacement
816822
# Instead of keys u^(1/w) where u = random(0,1) keys w/v where v = randexp(1) are used.
@@ -882,7 +888,7 @@ function efraimidis_ares_wsample_norep!(rng::AbstractRNG, a::AbstractArray,
882888
return x
883889
end
884890
efraimidis_ares_wsample_norep!(a::AbstractArray, wv::AbstractWeights, x::AbstractArray) =
885-
efraimidis_ares_wsample_norep!(Random.GLOBAL_RNG, a, wv, x)
891+
efraimidis_ares_wsample_norep!(default_rng(), a, wv, x)
886892

887893
# Weighted sampling without replacement
888894
# Instead of keys u^(1/w) where u = random(0,1) keys w/v where v = randexp(1) are used.
@@ -964,7 +970,7 @@ function efraimidis_aexpj_wsample_norep!(rng::AbstractRNG, a::AbstractArray,
964970
end
965971
efraimidis_aexpj_wsample_norep!(a::AbstractArray, wv::AbstractWeights, x::AbstractArray;
966972
ordered::Bool=false) =
967-
efraimidis_aexpj_wsample_norep!(Random.GLOBAL_RNG, a, wv, x; ordered=ordered)
973+
efraimidis_aexpj_wsample_norep!(default_rng(), a, wv, x; ordered=ordered)
968974

969975
function sample!(rng::AbstractRNG, a::AbstractArray, wv::AbstractWeights, x::AbstractArray;
970976
replace::Bool=true, ordered::Bool=false)
@@ -998,21 +1004,21 @@ function sample!(rng::AbstractRNG, a::AbstractArray, wv::AbstractWeights, x::Abs
9981004
end
9991005
sample!(a::AbstractArray, wv::AbstractWeights, x::AbstractArray;
10001006
replace::Bool=true, ordered::Bool=false) =
1001-
sample!(Random.GLOBAL_RNG, a, wv, x; replace=replace, ordered=ordered)
1007+
sample!(default_rng(), a, wv, x; replace=replace, ordered=ordered)
10021008

10031009
sample(rng::AbstractRNG, a::AbstractArray{T}, wv::AbstractWeights, n::Integer;
10041010
replace::Bool=true, ordered::Bool=false) where {T} =
10051011
sample!(rng, a, wv, Vector{T}(undef, n); replace=replace, ordered=ordered)
10061012
sample(a::AbstractArray, wv::AbstractWeights, n::Integer;
10071013
replace::Bool=true, ordered::Bool=false) =
1008-
sample(Random.GLOBAL_RNG, a, wv, n; replace=replace, ordered=ordered)
1014+
sample(default_rng(), a, wv, n; replace=replace, ordered=ordered)
10091015

10101016
sample(rng::AbstractRNG, a::AbstractArray{T}, wv::AbstractWeights, dims::Dims;
10111017
replace::Bool=true, ordered::Bool=false) where {T} =
10121018
sample!(rng, a, wv, Array{T}(undef, dims); replace=replace, ordered=ordered)
10131019
sample(a::AbstractArray, wv::AbstractWeights, dims::Dims;
10141020
replace::Bool=true, ordered::Bool=false) =
1015-
sample(Random.GLOBAL_RNG, a, wv, dims; replace=replace, ordered=ordered)
1021+
sample(default_rng(), a, wv, dims; replace=replace, ordered=ordered)
10161022

10171023
# wsample interface
10181024

@@ -1026,14 +1032,14 @@ an ordered sample (also called a sequential sample, i.e. a sample where
10261032
items appear in the same order as in `a`) should be taken.
10271033
10281034
Optionally specify a random number generator `rng` as the first argument
1029-
(defaults to `Random.GLOBAL_RNG`).
1035+
(defaults to `Random.$(VERSION < v"1.3" ? "GLOBAL_RNG" : "default_rng()")`).
10301036
"""
10311037
wsample!(rng::AbstractRNG, a::AbstractArray, w::AbstractVector{<:Real}, x::AbstractArray;
10321038
replace::Bool=true, ordered::Bool=false) =
10331039
sample!(rng, a, weights(w), x; replace=replace, ordered=ordered)
10341040
wsample!(a::AbstractArray, w::AbstractVector{<:Real}, x::AbstractArray;
10351041
replace::Bool=true, ordered::Bool=false) =
1036-
sample!(Random.GLOBAL_RNG, a, weights(w), x; replace=replace, ordered=ordered)
1042+
sample!(default_rng(), a, weights(w), x; replace=replace, ordered=ordered)
10371043

10381044
"""
10391045
wsample([rng], [a], w)
@@ -1042,12 +1048,12 @@ Select a weighted random sample of size 1 from `a` with probabilities proportion
10421048
to the weights given in `w`. If `a` is not present, select a random weight from `w`.
10431049
10441050
Optionally specify a random number generator `rng` as the first argument
1045-
(defaults to `Random.GLOBAL_RNG`).
1051+
(defaults to `Random.$(VERSION < v"1.3" ? "GLOBAL_RNG" : "default_rng()")`).
10461052
"""
10471053
wsample(rng::AbstractRNG, w::AbstractVector{<:Real}) = sample(rng, weights(w))
1048-
wsample(w::AbstractVector{<:Real}) = wsample(Random.GLOBAL_RNG, w)
1054+
wsample(w::AbstractVector{<:Real}) = wsample(default_rng(), w)
10491055
wsample(rng::AbstractRNG, a::AbstractArray, w::AbstractVector{<:Real}) = sample(rng, a, weights(w))
1050-
wsample(a::AbstractArray, w::AbstractVector{<:Real}) = wsample(Random.GLOBAL_RNG, a, w)
1056+
wsample(a::AbstractArray, w::AbstractVector{<:Real}) = wsample(default_rng(), a, w)
10511057

10521058

10531059
"""
@@ -1061,14 +1067,14 @@ an ordered sample (also called a sequential sample, i.e. a sample where
10611067
items appear in the same order as in `a`) should be taken.
10621068
10631069
Optionally specify a random number generator `rng` as the first argument
1064-
(defaults to `Random.GLOBAL_RNG`).
1070+
(defaults to `Random.$(VERSION < v"1.3" ? "GLOBAL_RNG" : "default_rng()")`).
10651071
"""
10661072
wsample(rng::AbstractRNG, a::AbstractArray{T}, w::AbstractVector{<:Real}, n::Integer;
10671073
replace::Bool=true, ordered::Bool=false) where {T} =
10681074
wsample!(rng, a, w, Vector{T}(undef, n); replace=replace, ordered=ordered)
10691075
wsample(a::AbstractArray, w::AbstractVector{<:Real}, n::Integer;
10701076
replace::Bool=true, ordered::Bool=false) =
1071-
wsample(Random.GLOBAL_RNG, a, w, n; replace=replace, ordered=ordered)
1077+
wsample(default_rng(), a, w, n; replace=replace, ordered=ordered)
10721078

10731079
"""
10741080
wsample([rng], [a], w, dims::Dims; replace=true, ordered=false)
@@ -1078,11 +1084,11 @@ weights given in `w` if `a` is present, otherwise select a random sample of size
10781084
`n` of the weights given in `w`. The dimensions of the output are given by `dims`.
10791085
10801086
Optionally specify a random number generator `rng` as the first argument
1081-
(defaults to `Random.GLOBAL_RNG`).
1087+
(defaults to `Random.$(VERSION < v"1.3" ? "GLOBAL_RNG" : "default_rng()")`).
10821088
"""
10831089
wsample(rng::AbstractRNG, a::AbstractArray{T}, w::AbstractVector{<:Real}, dims::Dims;
10841090
replace::Bool=true, ordered::Bool=false) where {T} =
10851091
wsample!(rng, a, w, Array{T}(undef, dims); replace=replace, ordered=ordered)
10861092
wsample(a::AbstractArray, w::AbstractVector{<:Real}, dims::Dims;
10871093
replace::Bool=true, ordered::Bool=false) =
1088-
wsample(Random.GLOBAL_RNG, a, w, dims; replace=replace, ordered=ordered)
1094+
wsample(default_rng(), a, w, dims; replace=replace, ordered=ordered)

test/sampling.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ n = 100000
99
# a) if the same rng is passed to a sample function twice,
1010
# the results should be the same (repeatability)
1111
# b) not specifying a rng should be the same as specifying Random.GLOBAL_RNG
12+
# and Random.default_rng() on Julia >= 1.3
1213
function test_rng_use(func, non_rng_args...)
1314
# some sampling methods mutate a passed array and return it
1415
# so that the tests don't pass trivially, we need to copy those
@@ -17,12 +18,17 @@ function test_rng_use(func, non_rng_args...)
1718
# repeatability
1819
@test func(MersenneTwister(1), deepcopy(non_rng_args)...) ==
1920
func(MersenneTwister(1), deepcopy(non_rng_args)...)
20-
# default RNG is Random.GLOBAL_RNG
21+
# default RNG is Random.GLOBAL_RNG/Random.default_rng()
2122
Random.seed!(47)
2223
x = func(deepcopy(non_rng_args)...)
2324
Random.seed!(47)
2425
y = func(Random.GLOBAL_RNG, deepcopy(non_rng_args)...)
2526
@test x == y
27+
if VERSION >= v"1.3.0-DEV.565"
28+
Random.seed!(47)
29+
y = func(Random.default_rng(), deepcopy(non_rng_args)...)
30+
@test x == y
31+
end
2632
end
2733

2834
#### sample with replacement

0 commit comments

Comments
 (0)