mirror of
https://github.com/gonum/gonum.git
synced 2025-12-24 13:47:56 +08:00
272 lines
5.2 KiB
Go
272 lines
5.2 KiB
Go
// Copyright ©2014 The Gonum Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package distuv
|
|
|
|
import (
|
|
"math"
|
|
"math/rand/v2"
|
|
"sort"
|
|
"testing"
|
|
)
|
|
|
|
func TestHalfKStandardWeibullProb(t *testing.T) {
|
|
t.Parallel()
|
|
pts := []univariateProbPoint{
|
|
{
|
|
loc: 0,
|
|
prob: math.Inf(1),
|
|
cumProb: 0,
|
|
logProb: math.Inf(1),
|
|
},
|
|
{
|
|
loc: -1,
|
|
prob: 0,
|
|
cumProb: 0,
|
|
logProb: math.Inf(-1),
|
|
},
|
|
{
|
|
loc: 1,
|
|
prob: 0.183939720585721,
|
|
cumProb: 0.632120558828558,
|
|
logProb: -1.693147180559950,
|
|
},
|
|
{
|
|
loc: 20,
|
|
prob: 0.001277118038048,
|
|
cumProb: 0.988577109006533,
|
|
logProb: -6.663149272336520,
|
|
},
|
|
}
|
|
testDistributionProbs(t, Weibull{K: 0.5, Lambda: 1}, "0.5K Standard Weibull", pts)
|
|
}
|
|
|
|
func TestExponentialStandardWeibullProb(t *testing.T) {
|
|
t.Parallel()
|
|
pts := []univariateProbPoint{
|
|
{
|
|
loc: 0,
|
|
prob: 1,
|
|
cumProb: 0,
|
|
logProb: 0,
|
|
},
|
|
{
|
|
loc: -1,
|
|
prob: 0,
|
|
cumProb: 0,
|
|
logProb: math.Inf(-1),
|
|
},
|
|
{
|
|
loc: 1,
|
|
prob: 0.367879441171442,
|
|
cumProb: 0.632120558828558,
|
|
logProb: -1.0,
|
|
},
|
|
{
|
|
loc: 20,
|
|
prob: 0.000000002061154,
|
|
cumProb: 0.999999997938846,
|
|
logProb: -20.0,
|
|
},
|
|
}
|
|
testDistributionProbs(t, Weibull{K: 1, Lambda: 1}, "1K (Exponential) Standard Weibull", pts)
|
|
}
|
|
|
|
func TestRayleighStandardWeibullProb(t *testing.T) {
|
|
t.Parallel()
|
|
pts := []univariateProbPoint{
|
|
{
|
|
loc: 0,
|
|
prob: 0,
|
|
cumProb: 0,
|
|
logProb: math.Inf(-1),
|
|
},
|
|
{
|
|
loc: -1,
|
|
prob: 0,
|
|
cumProb: 0,
|
|
logProb: math.Inf(-1),
|
|
},
|
|
{
|
|
loc: 1,
|
|
prob: 0.735758882342885,
|
|
cumProb: 0.632120558828558,
|
|
logProb: -0.306852819440055,
|
|
},
|
|
{
|
|
loc: 20,
|
|
prob: 0,
|
|
cumProb: 1,
|
|
logProb: -396.31112054588607,
|
|
},
|
|
}
|
|
testDistributionProbs(t, Weibull{K: 2, Lambda: 1}, "2K (Rayleigh) Standard Weibull", pts)
|
|
}
|
|
|
|
func TestFiveKStandardWeibullProb(t *testing.T) {
|
|
t.Parallel()
|
|
pts := []univariateProbPoint{
|
|
{
|
|
loc: 0,
|
|
prob: 0,
|
|
cumProb: 0,
|
|
logProb: math.Inf(-1),
|
|
},
|
|
{
|
|
loc: -1,
|
|
prob: 0,
|
|
cumProb: 0,
|
|
logProb: math.Inf(-1),
|
|
},
|
|
{
|
|
loc: 1,
|
|
prob: 1.839397205857210,
|
|
cumProb: 0.632120558828558,
|
|
logProb: 0.609437912434100,
|
|
},
|
|
{
|
|
loc: 20,
|
|
prob: 0,
|
|
cumProb: 1,
|
|
logProb: -3199986.4076329935,
|
|
},
|
|
}
|
|
testDistributionProbs(t, Weibull{K: 5, Lambda: 1}, "5K Standard Weibull", pts)
|
|
}
|
|
|
|
func TestScaledUpHalfKStandardWeibullProb(t *testing.T) {
|
|
t.Parallel()
|
|
pts := []univariateProbPoint{
|
|
{
|
|
loc: 0,
|
|
prob: math.Inf(1),
|
|
cumProb: 0,
|
|
logProb: math.Inf(1),
|
|
},
|
|
{
|
|
loc: -1,
|
|
prob: 0,
|
|
cumProb: 0,
|
|
logProb: math.Inf(-1),
|
|
},
|
|
{
|
|
loc: 1,
|
|
prob: 0.180436508682207,
|
|
cumProb: 0.558022622759326,
|
|
logProb: -1.712376315541750,
|
|
},
|
|
{
|
|
loc: 20,
|
|
prob: 0.002369136850928,
|
|
cumProb: 0.974047406098605,
|
|
logProb: -6.045229588092130,
|
|
},
|
|
}
|
|
testDistributionProbs(t, Weibull{K: 0.5, Lambda: 1.5}, "0.5K 1.5λ Weibull", pts)
|
|
}
|
|
|
|
func TestScaledDownHalfKStandardWeibullProb(t *testing.T) {
|
|
t.Parallel()
|
|
pts := []univariateProbPoint{
|
|
{
|
|
loc: 0,
|
|
prob: math.Inf(1),
|
|
cumProb: 0,
|
|
logProb: math.Inf(1),
|
|
},
|
|
{
|
|
loc: -1,
|
|
prob: 0,
|
|
cumProb: 0,
|
|
logProb: math.Inf(-1),
|
|
},
|
|
{
|
|
loc: 1,
|
|
prob: 0.171909491538362,
|
|
cumProb: 0.756883265565786,
|
|
logProb: -1.760787152653070,
|
|
},
|
|
{
|
|
loc: 20,
|
|
prob: 0.000283302579100,
|
|
cumProb: 0.998208237166091,
|
|
logProb: -8.168995047393730,
|
|
},
|
|
}
|
|
testDistributionProbs(t, Weibull{K: 0.5, Lambda: 0.5}, "0.5K 0.5λ Weibull", pts)
|
|
}
|
|
|
|
func TestWeibullScores(t *testing.T) {
|
|
t.Parallel()
|
|
for i, test := range []*Weibull{
|
|
{
|
|
K: 1,
|
|
Lambda: 1,
|
|
},
|
|
{
|
|
K: 2,
|
|
Lambda: 3.6,
|
|
},
|
|
{
|
|
K: 3.4,
|
|
Lambda: 8,
|
|
},
|
|
} {
|
|
testDerivParam(t, test)
|
|
for _, x := range []float64{0, -0.0001} {
|
|
score := test.Score(nil, 0)
|
|
if !math.IsNaN(score[0]) || !math.IsNaN(score[1]) {
|
|
t.Errorf("Score mismatch for case %d and x == %g: got %v, want [NaN, NaN]", i, x, score)
|
|
}
|
|
scoreInput := test.ScoreInput(0)
|
|
if !math.IsNaN(scoreInput) {
|
|
t.Errorf("ScoreInput mismatch for case %d and x == %g: got %v, want NaN", i, x, score)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestWeibull(t *testing.T) {
|
|
t.Parallel()
|
|
src := rand.New(rand.NewPCG(1, 1))
|
|
for i, dist := range []Weibull{
|
|
{K: 0.75, Lambda: 1, Src: src},
|
|
{K: 1, Lambda: 1, Src: src},
|
|
{K: 2, Lambda: 3.6, Src: src},
|
|
{K: 3.4, Lambda: 8, Src: src},
|
|
} {
|
|
testWeibull(t, dist, i)
|
|
}
|
|
}
|
|
|
|
func testWeibull(t *testing.T, dist Weibull, i int) {
|
|
const (
|
|
tol = 1e-2
|
|
n = 3e6
|
|
bins = 50
|
|
)
|
|
x := make([]float64, n)
|
|
generateSamples(x, dist)
|
|
sort.Float64s(x)
|
|
|
|
checkMean(t, i, x, dist, tol)
|
|
checkVarAndStd(t, i, x, dist, tol)
|
|
checkEntropy(t, i, x, dist, tol)
|
|
checkExKurtosis(t, i, x, dist, 3e-2)
|
|
checkSkewness(t, i, x, dist, tol)
|
|
checkMedian(t, i, x, dist, tol)
|
|
checkQuantileCDFSurvival(t, i, x, dist, tol)
|
|
// Weibull distribution PDF has a singularity at 0 for K < 1,
|
|
// so we need higher tolerance.
|
|
var probTol float64
|
|
if dist.K >= 1 {
|
|
probTol = 1e-10
|
|
} else {
|
|
probTol = 1e-8
|
|
}
|
|
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)
|
|
}
|