diff --git a/base/random/RNGs.jl b/base/random/RNGs.jl index ff33d5c3f46e7..8959e830d7a96 100644 --- a/base/random/RNGs.jl +++ b/base/random/RNGs.jl @@ -45,10 +45,10 @@ RandomDevice ### generation of floats -rand(rng::RandomDevice, ::Type{Close1Open2}) = +rand(rng::RandomDevice, ::Close1Open2_64) = reinterpret(Float64, 0x3ff0000000000000 | rand(rng, UInt64) & 0x000fffffffffffff) -rand(rng::RandomDevice, ::Type{CloseOpen}) = rand(rng, Close1Open2) - 1.0 +rand(rng::RandomDevice, ::CloseOpen_64) = rand(rng, Close1Open2()) - 1.0 @inline rand(r::RandomDevice, T::BitFloatType) = rand_generic(r, T) @@ -198,13 +198,13 @@ const GLOBAL_RNG = MersenneTwister(0) #### helper functions # precondition: !mt_empty(r) -@inline rand_inbounds(r::MersenneTwister, ::Type{Close1Open2}) = mt_pop!(r) -@inline rand_inbounds(r::MersenneTwister, ::Type{CloseOpen}) = - rand_inbounds(r, Close1Open2) - 1.0 -@inline rand_inbounds(r::MersenneTwister) = rand_inbounds(r, CloseOpen) +@inline rand_inbounds(r::MersenneTwister, ::Close1Open2_64) = mt_pop!(r) +@inline rand_inbounds(r::MersenneTwister, ::CloseOpen_64) = + rand_inbounds(r, Close1Open2()) - 1.0 +@inline rand_inbounds(r::MersenneTwister) = rand_inbounds(r, CloseOpen()) @inline rand_ui52_raw_inbounds(r::MersenneTwister) = - reinterpret(UInt64, rand_inbounds(r, Close1Open2)) + reinterpret(UInt64, rand_inbounds(r, Close1Open2())) @inline rand_ui52_raw(r::MersenneTwister) = (reserve_1(r); rand_ui52_raw_inbounds(r)) @inline function rand_ui2x52_raw(r::MersenneTwister) @@ -222,8 +222,7 @@ rand_ui23_raw(r::MersenneTwister) = rand_ui52_raw(r) #### floats -@inline rand(r::MersenneTwister, ::Type{I}) where {I<:FloatInterval} = - (reserve_1(r); rand_inbounds(r, I)) +@inline rand(r::MersenneTwister, I::FloatInterval_64) = (reserve_1(r); rand_inbounds(r, I)) @inline rand(r::MersenneTwister, T::BitFloatType) = rand_generic(r, T) @@ -251,8 +250,7 @@ rand(r::MersenneTwister, ::Type{Int128}) = reinterpret(Int128, rand(r, UInt128)) #### arrays of floats function rand_AbstractArray_Float64!(r::MersenneTwister, A::AbstractArray{Float64}, - n=length(A), - ::Type{I}=CloseOpen) where I<:FloatInterval + n=length(A), I::FloatInterval_64=CloseOpen()) # what follows is equivalent to this simple loop but more efficient: # for i=1:n # @inbounds A[i] = rand(r, I) @@ -275,14 +273,14 @@ end rand!(r::MersenneTwister, A::AbstractArray{Float64}) = rand_AbstractArray_Float64!(r, A) -fill_array!(s::DSFMT_state, A::Ptr{Float64}, n::Int, ::Type{CloseOpen}) = +fill_array!(s::DSFMT_state, A::Ptr{Float64}, n::Int, ::CloseOpen_64) = dsfmt_fill_array_close_open!(s, A, n) -fill_array!(s::DSFMT_state, A::Ptr{Float64}, n::Int, ::Type{Close1Open2}) = +fill_array!(s::DSFMT_state, A::Ptr{Float64}, n::Int, ::Close1Open2_64) = dsfmt_fill_array_close1_open2!(s, A, n) function rand!(r::MersenneTwister, A::Array{Float64}, n::Int=length(A), - ::Type{I}=CloseOpen) where I<:FloatInterval + I::FloatInterval_64=CloseOpen()) # depending on the alignment of A, the data written by fill_array! may have # to be left-shifted by up to 15 bytes (cf. unsafe_copy! below) for # reproducibility purposes; @@ -319,12 +317,12 @@ end (u & 0x007fffff007fffff007fffff007fffff) | 0x3f8000003f8000003f8000003f800000 function rand!(r::MersenneTwister, A::Union{Array{Float16},Array{Float32}}, - ::Type{Close1Open2}) + ::Close1Open2_64) T = eltype(A) n = length(A) n128 = n * sizeof(T) รท 16 rand!(r, unsafe_wrap(Array, convert(Ptr{Float64}, pointer(A)), 2*n128), - 2*n128, Close1Open2) + 2*n128, Close1Open2()) A128 = unsafe_wrap(Array, convert(Ptr{UInt128}, pointer(A)), n128) @inbounds for i in 1:n128 u = A128[i] @@ -347,9 +345,8 @@ function rand!(r::MersenneTwister, A::Union{Array{Float16},Array{Float32}}, A end -function rand!(r::MersenneTwister, A::Union{Array{Float16},Array{Float32}}, - ::Type{CloseOpen}) - rand!(r, A, Close1Open2) +function rand!(r::MersenneTwister, A::Union{Array{Float16},Array{Float32}}, ::CloseOpen_64) + rand!(r, A, Close1Open2()) I32 = one(Float32) for i in eachindex(A) @inbounds A[i] = Float32(A[i])-I32 # faster than "A[i] -= one(T)" for T==Float16 @@ -357,7 +354,8 @@ function rand!(r::MersenneTwister, A::Union{Array{Float16},Array{Float32}}, A end -rand!(r::MersenneTwister, A::Union{Array{Float16},Array{Float32}}) = rand!(r, A, CloseOpen) +rand!(r::MersenneTwister, A::Union{Array{Float16},Array{Float32}}) = + rand!(r, A, CloseOpen()) #### arrays of integers @@ -368,7 +366,7 @@ function rand!(r::MersenneTwister, A::Array{UInt128}, n::Int=length(A)) Af = unsafe_wrap(Array, convert(Ptr{Float64}, pointer(A)), 2n) i = n while true - rand!(r, Af, 2i, Close1Open2) + rand!(r, Af, 2i, Close1Open2()) n < 5 && break i = 0 @inbounds while n-i >= 5 diff --git a/base/random/generation.jl b/base/random/generation.jl index 14cde41b37b95..c534410a66e6c 100644 --- a/base/random/generation.jl +++ b/base/random/generation.jl @@ -10,11 +10,11 @@ ### random floats -@inline rand(r::AbstractRNG=GLOBAL_RNG) = rand(r, CloseOpen) +@inline rand(r::AbstractRNG=GLOBAL_RNG) = rand(r, CloseOpen()) # 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) +@inline rand_generic(r::AbstractRNG, ::Type{Float64}) = rand(r, CloseOpen()) rand_generic(r::AbstractRNG, ::Type{Float16}) = Float16(reinterpret(Float32, @@ -28,7 +28,7 @@ rand_generic(r::AbstractRNG, ::Type{Float32}) = rand_ui10_raw(r::AbstractRNG) = rand(r, UInt16) rand_ui23_raw(r::AbstractRNG) = rand(r, UInt32) -@inline rand_ui52_raw(r::AbstractRNG) = reinterpret(UInt64, rand(r, Close1Open2)) +@inline rand_ui52_raw(r::AbstractRNG) = reinterpret(UInt64, rand(r, Close1Open2())) @inline rand_ui52(r::AbstractRNG) = rand_ui52_raw(r) & 0x000fffffffffffff ### random complex numbers diff --git a/base/random/random.jl b/base/random/random.jl index 7d88cbd5cb388..988bc925003a3 100644 --- a/base/random/random.jl +++ b/base/random/random.jl @@ -22,9 +22,17 @@ export srand, abstract type AbstractRNG end -abstract type FloatInterval end -mutable struct CloseOpen <: FloatInterval end -mutable struct Close1Open2 <: FloatInterval end +abstract type FloatInterval{T<:AbstractFloat} end + +struct CloseOpen{ T<:AbstractFloat} <: FloatInterval{T} end # interval [0,1) +struct Close1Open2{T<:AbstractFloat} <: FloatInterval{T} end # interval [1,2) + +const FloatInterval_64 = FloatInterval{Float64} +const CloseOpen_64 = CloseOpen{Float64} +const Close1Open2_64 = Close1Open2{Float64} + +CloseOpen() = CloseOpen{Float64}() +Close1Open2() = Close1Open2{Float64}() const BitFloatType = Union{Type{Float16},Type{Float32},Type{Float64}}