Skip to content

Commit

Permalink
complete the rand API with Dict, Set, IntSet
Browse files Browse the repository at this point in the history
  • Loading branch information
rfourquet committed May 29, 2017
1 parent 9770290 commit 99f207d
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 12 deletions.
29 changes: 28 additions & 1 deletion base/random.jl
Original file line number Diff line number Diff line change
Expand Up @@ -257,11 +257,22 @@ globalRNG() = GLOBAL_RNG
Pick a random element or array of random elements from the set of values specified by `S`; `S` can be
* an indexable collection (for example `1:n` or `['x','y','z']`), or
* a `Dict`, a `Set` or an `IntSet`, or
* a type: the set of values to pick from is then equivalent to `typemin(S):typemax(S)` for
integers (this is not applicable to [`BigInt`](@ref)), and to ``[0, 1)`` for floating
point numbers;
`S` defaults to [`Float64`](@ref).
```julia-repl
julia> rand(Int, 2)
2-element Array{Int64,1}:
1339893410598768192
1575814717733606317
julia> rand(MersenneTwister(0), Dict(1=>2, 3=>4))
1=>2
```
"""
@inline rand() = rand(GLOBAL_RNG, CloseOpen)
@inline rand(T::Type) = rand(GLOBAL_RNG, T)
Expand All @@ -276,7 +287,7 @@ rand(r::AbstractArray) = rand(GLOBAL_RNG, r)
"""
rand!([rng=GLOBAL_RNG], A, [coll])
Populate the array `A` with random values. If the indexable collection `coll` is specified,
Populate the array `A` with random values. If the collection `coll` is specified,
the values are picked randomly from `coll`. This is equivalent to `copy!(A, rand(rng, coll, size(A)))`
or `copy!(A, rand(rng, eltype(A), size(A)))` but without allocating a new array.
"""
Expand Down Expand Up @@ -384,6 +395,22 @@ function rand!{T}(r::AbstractRNG, A::AbstractArray{T})
A
end

function rand!(r::AbstractRNG, A::AbstractArray, s::Union{Dict,Set,IntSet})
for i in eachindex(A)
@inbounds A[i] = rand(r, s)
end
A
end

rand!(A::AbstractArray, s::Union{Dict,Set,IntSet}) = rand!(GLOBAL_RNG, A, s)

rand(r::AbstractRNG, s::Dict{K,V}, dims::Dims) where {K,V} = rand!(r, Array{Pair{K,V}}(dims), s)
rand(r::AbstractRNG, s::Set{T}, dims::Dims) where {T} = rand!(r, Array{T}(dims), s)
rand(r::AbstractRNG, s::IntSet, dims::Dims) = rand!(r, Array{Int}(dims), s)
rand(r::AbstractRNG, s::Union{Dict,Set,IntSet}, dims::Integer...) = rand(r, s, convert(Dims, dims))
rand(s::Union{Dict,Set,IntSet}, dims::Integer...) = rand(GLOBAL_RNG, s, dims)
rand(s::Union{Dict,Set,IntSet}, dims::Dims) = rand(GLOBAL_RNG, s, dims)

# MersenneTwister

function rand_AbstractArray_Float64!{I<:FloatInterval}(r::MersenneTwister, A::AbstractArray{Float64}, n=length(A), ::Type{I}=CloseOpen)
Expand Down
30 changes: 19 additions & 11 deletions test/random.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,6 @@ let mt = MersenneTwister(0)
rand(coll, 2, 3)
end

# rand using Dict, Set, IntSet
adict = Dict(1=>2, 3=>4, 5=>6)
@test rand(adict) in adict
@test_throws ArgumentError rand(Dict())
aset = Set(1:10)
@test rand(aset) in aset
@test_throws ArgumentError rand(Set())
anintset = IntSet(1:10)
@test rand(anintset) in anintset
@test_throws ArgumentError rand(IntSet())

# randn
@test randn(MersenneTwister(42)) == -0.5560268761463861
A = zeros(2, 2)
Expand Down Expand Up @@ -320,6 +309,11 @@ for rng in ([], [MersenneTwister(0)], [RandomDevice()])
ftypes = [Float16, Float32, Float64]
cftypes = [Complex32, Complex64, Complex128, ftypes...]
types = [Bool, Char, Base.BitInteger_types..., ftypes...]
collections = [(IntSet(rand(1:100, 20)), Int),
(Set(rand(Int, 20)), Int),
(Dict(zip(rand(Int,10), rand(Int, 10))), Pair{Int,Int}),
(1:100, Int),
(rand(Int, 100), Int)]
b2 = big(2)
u3 = UInt(3)
for f in [rand, randn, randexp]
Expand All @@ -341,6 +335,20 @@ for rng in ([], [MersenneTwister(0)], [RandomDevice()])
end
end
end
for (C, T) in collections
a0 = rand(rng..., C) ::T
a1 = rand(rng..., C, 5) ::Vector{T}
a2 = rand(rng..., C, 2, 3) ::Array{T, 2}
a3 = rand!(rng..., Array{T}(5), C) ::Vector{T}
a4 = rand!(rng..., Array{T}(2, 3), C) ::Array{T, 2}
for a in [a0, a1..., a2..., a3..., a4...]
@test a in C
end
end
for C in [1:0, Dict(), Set(), IntSet(), Int[]]
@test_throws ArgumentError rand(rng..., C)
@test_throws ArgumentError rand(rng..., C, 5)
end
for f! in [rand!, randn!, randexp!]
for T in (f! === rand! ? types : f! === randn! ? cftypes : ftypes)
X = T == Bool ? T[0,1] : T[0,1,2]
Expand Down

0 comments on commit 99f207d

Please sign in to comment.