Skip to content

Commit 60dbea0

Browse files
authored
Fix tests (#157)
* Make `generic.jl` tests more similar to `rmath.jl` * Try to tune tolerances * Some fixes * Refactor tests * Tune tolerances
1 parent 7217d12 commit 60dbea0

File tree

4 files changed

+35
-26
lines changed

4 files changed

+35
-26
lines changed

test/generic.jl

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,35 @@
11
using StatsFuns
22
using StatsFuns: RFunctions
33
using ForwardDiff: Dual
4+
using Test
5+
6+
include("utils.jl")
47

58
function check_rmath(fname, statsfun, rmathfun, params, aname, a, isprob, rtol)
69
v = @inferred(rmathfun(params..., a))
710
rv = @inferred(statsfun(params..., Dual(a))).value
11+
@test v isa float(Base.promote_typeof(params..., a))
12+
@test rv isa float(Base.promote_typeof(params..., a))
813
if isprob
9-
rd = abs(v / rv - 1.0)
10-
if rd > rtol
11-
error("$fname deviates too much from Rmath at " *
12-
"params = $params, $aname = $a:\n" *
13-
" v = $v (rv = $rv)\n |v/rv - 1| = $rd > $rtol.")
14-
end
14+
@test v rv rtol=rtol nans=true
1515
else
16-
τ = (1.0 + abs(rv)) * rtol
17-
ad = abs(v - rv)
18-
if ad > τ
19-
error("$fname deviates too much from Rmath at " *
20-
"params = $params, $aname = $a:\n" *
21-
" v = $v (rv = $rv)\n |v - rv| = $ad > .")
22-
end
16+
@test v rv atol=rtol rtol=rtol nans=true
2317
end
2418
end
2519

26-
function genericcomp(basename, params, X::AbstractArray, rtol=100eps(float(one(eltype(X)))))
20+
function genericcomp(basename, params, X::AbstractArray, rtol=_default_rtol(params, X))
2721
pdf = string(basename, "pdf")
2822
logpdf = string(basename, "logpdf")
2923
stats_pdf = eval(Symbol(pdf))
3024
stats_logpdf = eval(Symbol(logpdf))
3125
rmath_pdf = eval(Meta.parse(string("RFunctions.", pdf)))
3226
rmath_logpdf = eval(Meta.parse(string("RFunctions.", logpdf)))
33-
for i = 1:length(X)
34-
x = X[i]
27+
28+
@testset "pdf with params=$params, x=$x" for x in X
3529
check_rmath(pdf, stats_pdf, rmath_pdf, params, "x", x, true, rtol)
30+
end
31+
32+
@testset "logpdf with params=$params, x=$x" for x in X
3633
check_rmath(logpdf, stats_logpdf, rmath_logpdf, params, "x", x, false, rtol)
3734
end
3835
end
@@ -121,8 +118,11 @@ end
121118

122119
genericcomp_tests("pois", [
123120
((1.0,), 0:30),
124-
((10.0,), 0:42)
121+
((10.0,), 0:37),
122+
((10.0,), 39:42),
125123
])
124+
# Requires slightly larger tolerance: #157
125+
genericcomp("pois", (10.0,), 38:38, 2.5e-14)
126126

127127
genericcomp_tests("tdist", [
128128
((1,), -5.0:0.1:5.0),

test/misc.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using SpecialFunctions, StatsFuns
2+
using Test
23

34
@testset "logmvgamma" begin
45
@testset "type behavior" for eltya in (Float32, Float64)

test/rmath.jl

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ using StatsFuns
22
using StatsFuns: RFunctions
33
using Test
44

5+
include("utils.jl")
6+
57
function check_rmath(fname, statsfun, rmathfun, params, aname, a, isprob, rtol)
68
v = @inferred(statsfun(params..., a))
79
rv = @inferred(rmathfun(params..., a))
@@ -17,15 +19,7 @@ end
1719
get_statsfun(fname) = eval(Symbol(fname))
1820
get_rmathfun(fname) = eval(Meta.parse(string("RFunctions.", fname)))
1921

20-
function rmathcomp(basename, params, X::AbstractArray)
21-
# compute default tolerance:
22-
# has to take into account `params` as well since otherwise e.g. `X::Array{<:Rational}`
23-
# always uses a tolerance based on `eps(one(Float64))` even when parameters are of type
24-
# Float32
25-
rtol = 100 * eps(float(one(promote_type(Base.promote_typeof(params...), eltype(X)))))
26-
rmathcomp(basename, params, X, rtol)
27-
end
28-
function rmathcomp(basename, params, X::AbstractArray, rtol)
22+
function rmathcomp(basename, params, X::AbstractArray, rtol=_default_rtol(params, X))
2923
# tackle pdf specially
3024
has_pdf = true
3125
if basename == "srdist"

test/utils.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# default relative tolerance for comparisons with Rmath
2+
function _default_rtol(params, X::AbstractArray)
3+
# has to take into account `params` as well since otherwise e.g. `X::Array{<:Rational}`
4+
# always uses a tolerance based on `eps(one(Float64))` even when parameters are of type
5+
# Float32
6+
return _default_rtol(float(promote_type(Base.promote_typeof(params...), eltype(X))))
7+
end
8+
9+
# We use less sharp tolerances for Float16 and Float32 since the proportion of significant
10+
# digits that are equal when evaluating Rmath and StatsFuns is smaller
11+
# eps^(7//8) means requiring equality of about 7/8 of the significant digits, etc.
12+
_default_rtol(::Type{Float64}) = eps(Float64)^(7//8) # ~2.0e-14
13+
_default_rtol(::Type{Float32}) = eps(Float32)^(3//4) # ~6.4e-6
14+
_default_rtol(::Type{Float16}) = eps(Float16)^(2//3) # ~9.9e-3

0 commit comments

Comments
 (0)