Skip to content

Commit

Permalink
implement randn!(::Array{Float32}) etc. (fix JuliaLang#9836)
Browse files Browse the repository at this point in the history
  • Loading branch information
rfourquet committed Jun 9, 2016
1 parent 8479012 commit e6a767c
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 85 deletions.
31 changes: 0 additions & 31 deletions base/docs/helpdb/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -938,14 +938,6 @@ references in `r` are replaced with the corresponding matched text.
"""
replace

"""
randexp([rng], [dims...])
Generate a random number according to the exponential distribution with scale 1. Optionally
generate an array of such random numbers.
"""
randexp

"""
chop(string)
Expand Down Expand Up @@ -1964,14 +1956,6 @@ Kronecker tensor product of two vectors or two matrices.
"""
kron

"""
randn([rng], [dims...])
Generate a normally-distributed random number with mean 0 and standard deviation 1.
Optionally generate an array of normally-distributed random numbers.
"""
randn

"""
process_exited(p::Process)
Expand Down Expand Up @@ -6412,13 +6396,6 @@ the topmost backend that does not throw a `MethodError`).
"""
pushdisplay

"""
randexp!([rng], A::Array{Float64,N})
Fill the array `A` with random numbers following the exponential distribution (with scale 1).
"""
randexp!

"""
prevind(str, i)
Expand Down Expand Up @@ -9433,14 +9410,6 @@ no effect outside of compilation.
"""
include_dependency

"""
randn!([rng], A::Array{Float64,N})
Fill the array `A` with normally-distributed (mean 0, standard deviation 1) random numbers.
Also see the rand function.
"""
randn!

"""
ldexp(x, n)
Expand Down
79 changes: 56 additions & 23 deletions base/random.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1096,7 +1096,14 @@ const ziggurat_nor_r = 3.6541528853610087963519472518
const ziggurat_nor_inv_r = inv(ziggurat_nor_r)
const ziggurat_exp_r = 7.6971174701310497140446280481

"""
randn([rng], [T=Float64], [dims...])
Generate a normally-distributed random number of type `T` with mean 0 and standard deviation 1.
Optionally generate an array of normally-distributed random numbers.
The `Base` module currently provides an implementation for the types
`Float16`, `Float32`, and `Float64` (the default).
"""
@inline function randn(rng::AbstractRNG=GLOBAL_RNG)
@inbounds begin
r = rand_ui52(rng)
Expand All @@ -1123,19 +1130,14 @@ function randn_unlikely(rng, idx, rabs, x)
end
end

function randn!(rng::AbstractRNG, A::AbstractArray{Float64})
for i in eachindex(A)
@inbounds A[i] = randn(rng)
end
A
end

randn!(A::AbstractArray{Float64}) = randn!(GLOBAL_RNG, A)
randn(dims::Dims) = randn!(Array{Float64}(dims))
randn(dims::Integer...) = randn!(Array{Float64}(dims...))
randn(rng::AbstractRNG, dims::Dims) = randn!(rng, Array{Float64}(dims))
randn(rng::AbstractRNG, dims::Integer...) = randn!(rng, Array{Float64}(dims...))
"""
randexp([rng], [T=Float64], [dims...])
Generate a random number of type `T` according to the exponential distribution with scale 1.
Optionally generate an array of such random numbers.
The `Base` module currently provides an implementation for the types
`Float16`, `Float32`, and `Float64` (the default).
"""
@inline function randexp(rng::AbstractRNG=GLOBAL_RNG)
@inbounds begin
ri = rand_ui52(rng)
Expand All @@ -1156,20 +1158,51 @@ function randexp_unlikely(rng, idx, x)
end
end

function randexp!(rng::AbstractRNG, A::Array{Float64})
for i in eachindex(A)
@inbounds A[i] = randexp(rng)
end
A
end
"""
randn!([rng], A::AbstractArray) -> A
randexp!(A::Array{Float64}) = randexp!(GLOBAL_RNG, A)
randexp(dims::Dims) = randexp!(Array{Float64}(dims))
randexp(dims::Int...) = randexp!(Array{Float64}(dims))
randexp(rng::AbstractRNG, dims::Dims) = randexp!(rng, Array{Float64}(dims))
randexp(rng::AbstractRNG, dims::Int...) = randexp!(rng, Array{Float64}(dims))
Fill the array `A` with normally-distributed (mean 0, standard deviation 1) random numbers.
Also see the `rand` function.
"""
function randn! end

"""
randexp!([rng], A::AbstractArray) -> A
Fill the array `A` with random numbers following the exponential distribution (with scale 1).
"""
function randexp! end

let Floats = Union{Float16,Float32,Float64}
for randfun in [:randn, :randexp]
randfun! = Symbol(randfun, :!)
@eval begin
# scalars
$randfun{T<:$Floats}(rng::AbstractRNG, ::Type{T}) = convert(T, $randfun(rng))
$randfun{T<:$Floats}(::Type{T}) = $randfun(GLOBAL_RNG, T)

# filling arrays
function $randfun!{T}(rng::AbstractRNG, A::AbstractArray{T})
for i in eachindex(A)
@inbounds A[i] = $randfun(rng, T)
end
A
end

$randfun!(A::AbstractArray) = $randfun!(GLOBAL_RNG, A)

# generating arrays
$randfun{T}(rng::AbstractRNG, ::Type{T}, dims::Dims) = $randfun!(rng, Array{T}(dims))
$randfun{T}(rng::AbstractRNG, ::Type{T}, dims::Integer...) = $randfun!(rng, Array{T}(dims...))
$randfun{T}( ::Type{T}, dims::Dims) = $randfun(GLOBAL_RNG, T, dims)
$randfun{T}( ::Type{T}, dims::Integer...) = $randfun(GLOBAL_RNG, T, dims...)
$randfun( rng::AbstractRNG, dims::Dims) = $randfun(rng, Float64, dims)
$randfun( rng::AbstractRNG, dims::Integer...) = $randfun(rng, Float64, dims...)
$randfun( dims::Dims) = $randfun(GLOBAL_RNG, Float64, dims)
$randfun( dims::Integer...) = $randfun(GLOBAL_RNG, Float64, dims...)
end
end
end
## random UUID generation

immutable UUID
Expand Down
14 changes: 7 additions & 7 deletions doc/stdlib/numbers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -568,25 +568,25 @@ As ``BigInt`` represents unbounded integers, the interval must be specified (e.g
Generate a ``BitArray`` of random boolean values.

.. function:: randn([rng], [dims...])
.. function:: randn([rng], [T=Float64], [dims...])

.. Docstring generated from Julia source
Generate a normally-distributed random number with mean 0 and standard deviation 1. Optionally generate an array of normally-distributed random numbers.
Generate a normally-distributed random number of type ``T`` with mean 0 and standard deviation 1. Optionally generate an array of normally-distributed random numbers. The ``Base`` module currently provides an implementation for the types ``Float16``\ , ``Float32``\ , and ``Float64`` (the default).

.. function:: randn!([rng], A::Array{Float64,N})
.. function:: randn!([rng], A::AbstractArray) -> A

.. Docstring generated from Julia source
Fill the array ``A`` with normally-distributed (mean 0, standard deviation 1) random numbers. Also see the rand function.
Fill the array ``A`` with normally-distributed (mean 0, standard deviation 1) random numbers. Also see the ``rand`` function.

.. function:: randexp([rng], [dims...])
.. function:: randexp([rng], [T=Float64], [dims...])

.. Docstring generated from Julia source
Generate a random number according to the exponential distribution with scale 1. Optionally generate an array of such random numbers.
Generate a random number of type ``T`` according to the exponential distribution with scale 1. Optionally generate an array of such random numbers. The ``Base`` module currently provides an implementation for the types ``Float16``\ , ``Float32``\ , and ``Float64`` (the default).

.. function:: randexp!([rng], A::Array{Float64,N})
.. function:: randexp!([rng], A::AbstractArray) -> A

.. Docstring generated from Julia source
Expand Down
57 changes: 33 additions & 24 deletions test/random.jl
Original file line number Diff line number Diff line change
Expand Up @@ -300,38 +300,47 @@ end

# test all rand APIs
for rng in ([], [MersenneTwister()], [RandomDevice()])
types = [Base.BitInteger_types..., Bool, Float16, Float32, Float64]
ftypes = [Float16, Float32, Float64]
b2 = big(2)
u3 = UInt(3)
for f in [rand, randn, randexp]
f(rng...) ::Float64
f(rng..., 5) ::Vector{Float64}
f(rng..., 2, 3) ::Array{Float64, 2}
f(rng...) ::Float64
f(rng..., 5) ::Vector{Float64}
f(rng..., 2, 3) ::Array{Float64, 2}
f(rng..., b2, u3) ::Array{Float64, 2}
f(rng..., (2, 3)) ::Array{Float64, 2}
for T in (f === rand ? types : ftypes)
a0 = f(rng..., T) ::T
a1 = f(rng..., T, 5) ::Vector{T}
a2 = f(rng..., T, 2, 3) ::Array{T, 2}
a3 = f(rng..., T, b2, u3) ::Array{T, 2}
a4 = f(rng..., T, (2, 3)) ::Array{T, 2}
if T <: AbstractFloat && f === rand
for a in [a0, a1..., a2..., a3..., a4...]
@test 0.0 <= a < 1.0
end
end
end
end
for f! in [randn!, randexp!]
f!(rng..., Array{Float64}(5)) ::Vector{Float64}
f!(rng..., Array{Float64}(2, 3)) ::Array{Float64, 2}
for f! in [rand!, randn!, randexp!]
for T in (f! === rand! ? types : ftypes)
X = T == Bool ? T[0,1] : T[0,1,2]
for A in (Array{T}(5), Array{T}(2, 3))
f!(rng..., A) ::typeof(A)
if f! === rand!
f!(rng..., A, X) ::typeof(A)
f!(rng..., sparse(A)) ::typeof(sparse(A))
f!(rng..., sparse(A), X) ::typeof(sparse(A))
end
end
end
end

bitrand(rng..., 5) ::BitArray{1}
bitrand(rng..., 2, 3) ::BitArray{2}
rand!(rng..., BitArray(5)) ::BitArray{1}
rand!(rng..., BitArray(2, 3)) ::BitArray{2}

for T in [Base.BitInteger_types..., Bool, Float16, Float32, Float64]
a0 = rand(rng..., T) ::T
a1 = rand(rng..., T, 5) ::Vector{T}
a2 = rand(rng..., T, 2, 3) ::Array{T, 2}
if T <: AbstractFloat
for a in [a0, a1..., a2...]
@test 0.0 <= a < 1.0
end
end
for A in (Array{T}(5), Array{T}(2, 3))
X = T == Bool ? T[0,1] : T[0,1,2]
rand!(rng..., A) ::typeof(A)
rand!(rng..., A, X) ::typeof(A)
rand!(rng..., sparse(A)) ::typeof(sparse(A))
rand!(rng..., sparse(A), X) ::typeof(sparse(A))
end
end
end

function hist(X,n)
Expand Down

0 comments on commit e6a767c

Please sign in to comment.