Skip to content

Commit 7fcf9c8

Browse files
Random: make statistical uniform tests fail less often (#52165)
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 #52156. --------- Co-authored-by: Kristoffer Carlsson <[email protected]>
1 parent 2c0098e commit 7fcf9c8

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

stdlib/Random/test/runtests.jl

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,30 @@ using Random: jump_128, jump_192, jump_128!, jump_192!
1616
import Future # randjump
1717

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

25-
function test_uniform(xs::AbstractArray{T}) where {T<:Integer}
26-
if !Base.hastypemax(T) || widen(typemax(T)) - widen(typemin(T)) >= 2^30 # TODO: refine
27-
@test allunique(xs)
34+
function test_uniform(xs::AbstractArray{T}) where {T<:Base.BitInteger}
35+
# TODO: refine
36+
prec = 8*sizeof(T)
37+
proba_nocollision = prod((1.0 - i/2.0^prec for i=1:length(xs)-1), init=1.0)
38+
xsu = Set(xs)
39+
if (1.0 - proba_nocollision) < 2.0^-64
40+
@test length(xsu) == length(xs)
41+
elseif prec > 52 && length(xs) < 3000
42+
@test length(xsu) >= length(xs)-1
2843
end
2944
end
3045

0 commit comments

Comments
 (0)