Skip to content

Commit

Permalink
RFC: Restricts parameter type for randn & randexp to Float types for J…
Browse files Browse the repository at this point in the history
…uliaLang#17608. (JuliaLang#17627)

* Fixes infinite recursion in randn for non-floats; fixes JuliaLang#17608.

The functions already only supported Float types
(Float16,Float32,Float64), but could be called with non-float types.
Calling with Non-Float types, e.g. `Int`, could cause an infinite loop.

Also adds tests verifying that randn throws a MethodError for types
besides Float types.

* s/dim0/dim1/

* removed other dimensions, fixed randn(T), added comment.
  • Loading branch information
NHDaly authored and mfasi committed Sep 5, 2016
1 parent 990171c commit 2203061
Showing 2 changed files with 27 additions and 9 deletions.
19 changes: 10 additions & 9 deletions base/random.jl
Original file line number Diff line number Diff line change
@@ -1200,7 +1200,7 @@ let Floats = Union{Float16,Float32,Float64}
@eval begin
# scalars
$randfun{T<:$Floats}(rng::AbstractRNG, ::Type{T}) = convert(T, $randfun(rng))
$randfun{T<:$Floats}(::Type{T}) = $randfun(GLOBAL_RNG, T)
$randfun{T}(::Type{T}) = $randfun(GLOBAL_RNG, T)

# filling arrays
function $randfun!{T}(rng::AbstractRNG, A::AbstractArray{T})
@@ -1213,14 +1213,15 @@ let Floats = Union{Float16,Float32,Float64}
$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...)
$randfun{T}(rng::AbstractRNG, ::Type{T}, dims::Dims ) = $randfun!(rng, Array{T}(dims))
# Note that this method explicitly does not define $randfun(rng, T), in order to prevent an infinite recursion.
$randfun{T}(rng::AbstractRNG, ::Type{T}, dim1::Integer, dims::Integer...) = $randfun!(rng, Array{T}(dim1, 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
17 changes: 17 additions & 0 deletions test/random.jl
Original file line number Diff line number Diff line change
@@ -343,6 +343,23 @@ for rng in ([], [MersenneTwister()], [RandomDevice()])
bitrand(rng..., 2, 3) ::BitArray{2}
rand!(rng..., BitArray(5)) ::BitArray{1}
rand!(rng..., BitArray(2, 3)) ::BitArray{2}

# Test that you cannot call randn or randexp with non-Float types.
for r in [randn, randexp, randn!, randexp!]
@test_throws MethodError r(Int)
@test_throws MethodError r(Int32)
@test_throws MethodError r(Bool)
@test_throws MethodError r(String)
@test_throws MethodError r(AbstractFloat)
# TODO(#17627): Consider adding support for randn(BigFloat) and removing this test.
@test_throws MethodError r(BigFloat)

@test_throws MethodError r(Int64, (2,3))
@test_throws MethodError r(String, 1)

@test_throws MethodError r(rng..., Number, (2,3))
@test_throws MethodError r(rng..., Any, 1)
end
end

function hist(X,n)

0 comments on commit 2203061

Please sign in to comment.