stat/distuv: tighten test tolerances and refactor integration checks
MODIFY
stat/distuv/beta_test.go
stat/distuv/beta_test.go
@@ -61,7 +61,7 @@ func testBeta(t *testing.T, b Beta, i int) {
checkVarAndStd(t, i, x, b, tol)
checkExKurtosis(t, i, x, b, 5e-2)
checkEntropy(t, i, x, b, 5e-3)
- checkProbContinuous(t, i, x, b, 1e-3)
+ checkProbContinuous(t, i, x, 0, 1, b, 1e-6)
checkQuantileCDFSurvival(t, i, x, b, tol)
checkProbQuantContinuous(t, i, x, b, tol)

MODIFY
stat/distuv/chisquared_test.go
stat/distuv/chisquared_test.go
@@ -80,7 +80,7 @@ func testChiSquared(t *testing.T, c ChiSquared, i int) {
checkMean(t, i, x, c, tol)
checkVarAndStd(t, i, x, c, tol)
checkExKurtosis(t, i, x, c, 7e-2)
- checkProbContinuous(t, i, x, c, 1e-3)
+ checkProbContinuous(t, i, x, 0, math.Inf(1), c, 1e-5)
checkQuantileCDFSurvival(t, i, x, c, 1e-2)
expectedMode := math.Max(c.K-2, 0)

MODIFY
stat/distuv/distribution_test.go
stat/distuv/distribution_test.go
@@ -157,13 +157,9 @@ func checkQuantileCDFSurvival(t *testing.T, i int, xs []float64, c cumulanter, t
}
}
-func checkProbContinuous(t *testing.T, i int, x []float64, p probLogprober, tol float64) {
- checkProbContinuousWithBounds(t, i, x, math.Inf(-1), math.Inf(1), p, tol)
-}
-
-// checkProbContinuousWithBounds checks that the PDF is consistent
-// with LogPDF and integrates to 1 from the lower to upper bound.
-func checkProbContinuousWithBounds(t *testing.T, i int, x []float64, lower float64, upper float64, p probLogprober, tol float64) {
+// checkProbContinuous checks that the PDF is consistent with LogPDF
+// and integrates to 1 from the lower to upper bound.
+func checkProbContinuous(t *testing.T, i int, x []float64, lower float64, upper float64, p probLogprober, tol float64) {
q := quad.Fixed(p.Prob, lower, upper, 1000000, nil, 0)
if math.Abs(q-1) > tol {
t.Errorf("Probability distribution doesn't integrate to 1. Case %v: Got %v", i, q)

MODIFY
stat/distuv/exponential_test.go
stat/distuv/exponential_test.go
@@ -77,7 +77,7 @@ func testExponential(t *testing.T, dist Exponential, i int) {
checkSkewness(t, i, x, dist, tol)
checkMedian(t, i, x, dist, tol)
checkQuantileCDFSurvival(t, i, x, dist, tol)
- checkProbContinuous(t, i, x, dist, 1e-10)
+ checkProbContinuous(t, i, x, 0, math.Inf(1), dist, 1e-10)
checkProbQuantContinuous(t, i, x, dist, tol)
if dist.Mode() != 0 {

MODIFY
stat/distuv/f_test.go
stat/distuv/f_test.go
@@ -85,7 +85,7 @@ func testF(t *testing.T, f F, i int) {
sort.Float64s(x)
testRandLogProbContinuous(t, i, 0, x, f, tol, bins)
- checkProbContinuous(t, i, x, f, 1e-3)
+ checkProbContinuous(t, i, x, 0, math.Inf(1), f, 1e-4)
checkMean(t, i, x, f, tol)
checkVarAndStd(t, i, x, f, tol)
checkExKurtosis(t, i, x, f, 1e-1)

MODIFY
stat/distuv/gamma_test.go
stat/distuv/gamma_test.go
@@ -61,7 +61,8 @@ func testGamma(t *testing.T, f Gamma, i int) {
var quadTol float64
if f.Alpha < 0.3 {
- // Gamma PDF has a singularity at 0 for alpha < 1.
+ // Gamma PDF has a singularity at 0 for alpha < 1,
+ // which gets sharper as alpha -> 0.
quadTol = 0.2
} else {
quadTol = tol
@@ -70,12 +71,15 @@ func testGamma(t *testing.T, f Gamma, i int) {
checkMean(t, i, x, f, tol)
checkVarAndStd(t, i, x, f, 2e-2)
checkExKurtosis(t, i, x, f, 2e-1)
- if f.Alpha < 0.3 {
+ switch {
+ case f.Alpha < 0.3:
quadTol = 0.1
- } else {
+ case f.Alpha < 1:
quadTol = 1e-3
+ default:
+ quadTol = 1e-10
}
- checkProbContinuousWithBounds(t, i, x, 0, math.Inf(1), f, quadTol)
+ checkProbContinuous(t, i, x, 0, math.Inf(1), f, quadTol)
checkQuantileCDFSurvival(t, i, x, f, 5e-2)
if f.Alpha < 1 {
if !math.IsNaN(f.Mode()) {

MODIFY
stat/distuv/gumbel_test.go
stat/distuv/gumbel_test.go
@@ -65,7 +65,7 @@ func testGumbelRight(t *testing.T, g GumbelRight, i int) {
min := math.Inf(-1)
testRandLogProbContinuous(t, i, min, x, g, tol, bins)
- checkProbContinuous(t, i, x, g, 1e-3)
+ checkProbContinuous(t, i, x, math.Inf(-1), math.Inf(1), g, 1e-10)
checkMean(t, i, x, g, tol)
checkVarAndStd(t, i, x, g, tol)
checkExKurtosis(t, i, x, g, 1e-1)

MODIFY
stat/distuv/inversegamma_test.go
stat/distuv/inversegamma_test.go
package distuv
import (
+ "math"
"sort"
"testing"
@@ -52,7 +53,7 @@ func testInverseGamma(t *testing.T, f InverseGamma, i int) {
checkMean(t, i, x, f, tol)
checkVarAndStd(t, i, x, f, 2e-2)
checkExKurtosis(t, i, x, f, 2e-1)
- checkProbContinuous(t, i, x, f, 1e-3)
+ checkProbContinuous(t, i, x, 0, math.Inf(1), f, 1e-10)
checkQuantileCDFSurvival(t, i, x, f, 5e-2)
checkMode(t, i, x, f, 1e-2, 1e-2)
}

MODIFY
stat/distuv/laplace_test.go
stat/distuv/laplace_test.go
@@ -91,7 +91,7 @@ func testLaplace(t *testing.T, dist Laplace, i int) {
checkSkewness(t, i, x, dist, tol)
checkMedian(t, i, x, dist, tol)
checkQuantileCDFSurvival(t, i, x, dist, tol)
- checkProbContinuous(t, i, x, dist, 1e-10)
+ checkProbContinuous(t, i, x, math.Inf(-1), math.Inf(1), dist, 1e-10)
checkProbQuantContinuous(t, i, x, dist, tol)
if dist.Mu != dist.Mode() {

MODIFY
stat/distuv/lognormal_test.go
stat/distuv/lognormal_test.go
package distuv
import (
+ "math"
"sort"
"testing"
@@ -34,7 +35,7 @@ func TestLognormal(t *testing.T) {
checkSkewness(t, i, x, dist, 5e-2)
checkMedian(t, i, x, dist, tol)
checkQuantileCDFSurvival(t, i, x, dist, tol)
- checkProbContinuous(t, i, x, dist, 1e-10)
+ checkProbContinuous(t, i, x, 0, math.Inf(1), dist, 1e-10)
checkProbQuantContinuous(t, i, x, dist, tol)
checkMode(t, i, x, dist, 1e-2, 1e-2)
}

MODIFY
stat/distuv/norm_test.go
stat/distuv/norm_test.go
@@ -114,7 +114,7 @@ func testNormal(t *testing.T, dist Normal, i int) {
checkSkewness(t, i, x, dist, tol)
checkMedian(t, i, x, dist, tol)
checkQuantileCDFSurvival(t, i, x, dist, tol)
- checkProbContinuous(t, i, x, dist, 1e-10)
+ checkProbContinuous(t, i, x, math.Inf(-1), math.Inf(1), dist, 1e-10)
checkProbQuantContinuous(t, i, x, dist, tol)
if dist.Mu != dist.Mode() {

MODIFY
stat/distuv/pareto_test.go
stat/distuv/pareto_test.go
package distuv
import (
+ "math"
"sort"
"testing"
@@ -163,7 +164,7 @@ func testPareto(t *testing.T, p Pareto, i int) {
checkMean(t, i, x, p, tol)
checkVarAndStd(t, i, x, p, tol)
checkExKurtosis(t, i, x, p, 7e-2)
- checkProbContinuous(t, i, x, p, 1e-3)
+ checkProbContinuous(t, i, x, p.Xm, math.Inf(1), p, 1e-10)
if p.Xm != p.Mode() {
t.Errorf("Mismatch in mode value: got %v, want %g", p.Mode(), p.Xm)

MODIFY
stat/distuv/studentst_test.go
stat/distuv/studentst_test.go
@@ -61,7 +61,7 @@ func testStudentsT(t *testing.T, c StudentsT, i int) {
if c.Nu > 2 {
checkVarAndStd(t, i, x, c, 5e-2)
}
- checkProbContinuous(t, i, x, c, 1e-3)
+ checkProbContinuous(t, i, x, math.Inf(-1), math.Inf(1), c, 1e-10)
checkQuantileCDFSurvival(t, i, x, c, tol)
checkProbQuantContinuous(t, i, x, c, tol)
if c.Mu != c.Mode() {

MODIFY
stat/distuv/triangle_test.go
stat/distuv/triangle_test.go
@@ -69,7 +69,7 @@ func TestTriangle(t *testing.T) {
checkSkewness(t, i, x, f, 5e-2)
checkMedian(t, i, x, f, tol)
checkQuantileCDFSurvival(t, i, x, f, tol)
- checkProbContinuous(t, i, x, f, 1e-10)
+ checkProbContinuous(t, i, x, f.a, f.b, f, 1e-10)
checkProbQuantContinuous(t, i, x, f, tol)
if f.c != f.Mode() {

MODIFY
stat/distuv/uniform_test.go
stat/distuv/uniform_test.go
@@ -74,6 +74,6 @@ func testUniform(t *testing.T, u Uniform, i int) {
checkMean(t, i, x, u, tol)
checkVarAndStd(t, i, x, u, tol)
checkExKurtosis(t, i, x, u, 7e-2)
- checkProbContinuous(t, i, x, u, 1e-3)
+ checkProbContinuous(t, i, x, u.Min, u.Max, u, 1e-10)
checkQuantileCDFSurvival(t, i, x, u, 1e-2)
}

MODIFY
stat/distuv/weibull_test.go
stat/distuv/weibull_test.go
@@ -254,9 +254,9 @@ func testWeibull(t *testing.T, dist Weibull, i int) {
if dist.K >= 1 {
probTol = 1e-10
} else {
- probTol = 1e-5
+ probTol = 1e-8
}
- checkProbContinuous(t, i, x, dist, probTol)
+ checkProbContinuous(t, i, x, 0, math.Inf(1), dist, probTol)
checkProbQuantContinuous(t, i, x, dist, tol)
checkMode(t, i, x, dist, 1e-1, 2e-1)
}

stat/distuv: tighten test tolerances and refactor integration checks