Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add rand(::IntSet) #21960

Merged
merged 3 commits into from
May 30, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
complete the rand API with Dict, Set, IntSet
  • Loading branch information
rfourquet committed May 29, 2017
commit 99f207d3a6701bba422ac23beccf4aa99f44c923
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))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is not a doctest perhaps the MersenneTwister(0) is unnecessary

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes right.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I think I wanted to illustrate different combinations of arguments and show the use of an explicit RNG (and MersenneTwister is the most likely to be used, but doesn't accept for now no-argument), so I would rather keep it as is.

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