Skip to content

Commit

Permalink
Random: make statistical uniform tests fail less often (JuliaLang#52165)
Browse files Browse the repository at this point in the history
We have a very basic test to check that a distribution might be uniform:
all the sampled elements should be unique, under certain conditions. But
these conditions allowed the tests to fail too often. So allow one
collision if the probability of such an event is too high.

Fix JuliaLang#52156.

---------

Co-authored-by: Kristoffer Carlsson <kcarlsson89@gmail.com>
  • Loading branch information
rfourquet and KristofferC committed Feb 15, 2024
1 parent 2c0098e commit 7fcf9c8
Showing 1 changed file with 20 additions and 5 deletions.
25 changes: 20 additions & 5 deletions stdlib/Random/test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,30 @@ using Random: jump_128, jump_192, jump_128!, jump_192!
import Future # randjump

function test_uniform(xs::AbstractArray{T}) where {T<:AbstractFloat}
if precision(T) >= precision(Float32) # TODO: refine
@test allunique(xs)
# TODO: refine
prec = isempty(xs) ? precision(T) : precision(first(xs))
proba_nocollision = prod((1.0 - i/2.0^prec for i=1:length(xs)-1), init=1.0) # rough estimate
xsu = Set(xs)
if (1.0 - proba_nocollision) < 2.0^-64
@test length(xsu) == length(xs)
elseif prec > 52 && length(xs) < 3000
# if proba of collisions is high enough, allow at most one collision;
# with the constraints on precision and length, more than one collision would happen
# with proba less than 2.0^-62
@test length(xsu) >= length(xs)-1
end
@test all(x -> zero(x) <= x < one(x), xs)
end

function test_uniform(xs::AbstractArray{T}) where {T<:Integer}
if !Base.hastypemax(T) || widen(typemax(T)) - widen(typemin(T)) >= 2^30 # TODO: refine
@test allunique(xs)
function test_uniform(xs::AbstractArray{T}) where {T<:Base.BitInteger}
# TODO: refine
prec = 8*sizeof(T)
proba_nocollision = prod((1.0 - i/2.0^prec for i=1:length(xs)-1), init=1.0)
xsu = Set(xs)
if (1.0 - proba_nocollision) < 2.0^-64
@test length(xsu) == length(xs)
elseif prec > 52 && length(xs) < 3000
@test length(xsu) >= length(xs)-1
end
end

Expand Down

0 comments on commit 7fcf9c8

Please sign in to comment.