Skip to content

Commit

Permalink
Random: reorganize some generic fallback methods for floats
Browse files Browse the repository at this point in the history
  • Loading branch information
rfourquet committed Aug 21, 2017
1 parent d3ba26e commit 379f032
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 13 deletions.
9 changes: 2 additions & 7 deletions base/random/RNGs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,7 @@ RandomDevice

### generation of floats

rand(rng::RandomDevice, ::Close1Open2_64) =
reinterpret(Float64, 0x3ff0000000000000 | rand(rng, UInt64) & 0x000fffffffffffff)

rand(rng::RandomDevice, ::CloseOpen_64) = rand(rng, Close1Open2()) - 1.0

@inline rand(r::RandomDevice, T::BitFloatType) = rand_generic(r, T)
@inline rand(r::RandomDevice, I::FloatInterval) = rand_generic(r, I)


## MersenneTwister
Expand Down Expand Up @@ -224,7 +219,7 @@ rand_ui23_raw(r::MersenneTwister) = rand_ui52_raw(r)

@inline rand(r::MersenneTwister, I::FloatInterval_64) = (reserve_1(r); rand_inbounds(r, I))

@inline rand(r::MersenneTwister, T::BitFloatType) = rand_generic(r, T)
@inline rand(r::MersenneTwister, I::FloatInterval) = rand_generic(r, I)

#### integers

Expand Down
27 changes: 23 additions & 4 deletions base/random/generation.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,25 @@

### random floats

@inline rand(r::AbstractRNG=GLOBAL_RNG) = rand(r, CloseOpen())
# CloseOpen(T) is the fallback for an AbstractFloat T
@inline rand(r::AbstractRNG=GLOBAL_RNG, ::Type{T}=Float64) where {T<:AbstractFloat} =
rand(r, CloseOpen(T))

# generic random generation function which can be used by RNG implementors
# it is not defined as a fallback rand method as this could create ambiguities
@inline rand_generic(r::AbstractRNG, ::Type{Float64}) = rand(r, CloseOpen())

rand_generic(r::AbstractRNG, ::Type{Float16}) =
rand_generic(r::AbstractRNG, ::CloseOpen{Float16}) =
Float16(reinterpret(Float32,
(rand_ui10_raw(r) % UInt32 << 13) & 0x007fe000 | 0x3f800000) - 1)

rand_generic(r::AbstractRNG, ::Type{Float32}) =
rand_generic(r::AbstractRNG, ::CloseOpen{Float32}) =
reinterpret(Float32, rand_ui23_raw(r) % UInt32 & 0x007fffff | 0x3f800000) - 1

rand_generic(r::AbstractRNG, ::Close1Open2_64) =
reinterpret(Float64, 0x3ff0000000000000 | rand(r, UInt64) & 0x000fffffffffffff)

rand_generic(r::AbstractRNG, ::CloseOpen_64) = rand(r, Close1Open2()) - 1.0

### random integers

rand_ui10_raw(r::AbstractRNG) = rand(r, UInt16)
Expand Down Expand Up @@ -72,6 +78,19 @@ rand( T::Type, d::Integer, dims::Integer...) = rand(T, Dims((d, d
# rand(r, ()) would match both this method and rand(r, dims::Dims)
# moreover, a call like rand(r, NotImplementedType()) would be an infinite loop

#### arrays of floats

rand!(r::AbstractRNG, A::AbstractArray, ::Type{T}) where {T<:AbstractFloat} =
rand!(r, A, CloseOpen{T}())

function rand!(r::AbstractRNG, A::AbstractArray, I::FloatInterval)
for i in eachindex(A)
@inbounds A[i] = rand(r, I)
end
A
end

rand!(A::AbstractArray, I::FloatInterval) = rand!(GLOBAL_RNG, A, I)

## Generate random integer within a range

Expand Down
4 changes: 2 additions & 2 deletions base/random/random.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ const FloatInterval_64 = FloatInterval{Float64}
const CloseOpen_64 = CloseOpen{Float64}
const Close1Open2_64 = Close1Open2{Float64}

CloseOpen() = CloseOpen{Float64}()
Close1Open2() = Close1Open2{Float64}()
CloseOpen( ::Type{T}=Float64) where {T<:AbstractFloat} = CloseOpen{T}()
Close1Open2(::Type{T}=Float64) where {T<:AbstractFloat} = Close1Open2{T}()

const BitFloatType = Union{Type{Float16},Type{Float32},Type{Float64}}

Expand Down

0 comments on commit 379f032

Please sign in to comment.