gonum.org/v1/gonum@v0.14.0/stat/distuv/f_test.go (about) 1 // Copyright ©2017 The Gonum Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package distuv 6 7 import ( 8 "math" 9 "sort" 10 "testing" 11 12 "golang.org/x/exp/rand" 13 14 "gonum.org/v1/gonum/floats/scalar" 15 ) 16 17 func TestFProb(t *testing.T) { 18 t.Parallel() 19 for _, test := range []struct { 20 x, d1, d2, want float64 21 }{ 22 // Values calculated with scipy.stats.f 23 {0.0001, 4, 6, 0.00053315559110558126}, 24 {0.1, 1, 1, 0.91507658371794609}, 25 {0.5, 11, 7, 0.66644660411410883}, 26 {0.9, 20, 15, 0.88293424959522437}, 27 {1, 1, 1, 0.15915494309189535}, 28 {2, 15, 12, 0.16611971273429088}, 29 {5, 4, 8, 0.013599775603702537}, 30 {10, 12, 9, 0.00032922887567957289}, 31 {100, 7, 7, 6.08037637806889e-08}, 32 {1000, 2, 1, 1.1171959870312232e-05}, 33 } { 34 pdf := F{test.d1, test.d2, nil}.Prob(test.x) 35 if !scalar.EqualWithinAbsOrRel(pdf, test.want, 1e-10, 1e-10) { 36 t.Errorf("Prob mismatch, x = %v, d1 = %v, d2 = %v. Got %v, want %v", test.x, test.d1, test.d2, pdf, test.want) 37 } 38 } 39 } 40 41 func TestFCDF(t *testing.T) { 42 t.Parallel() 43 for _, test := range []struct { 44 x, d1, d2, want float64 45 }{ 46 // Values calculated with scipy.stats.f 47 {0.0001, 4, 6, 2.6660741629519019e-08}, 48 {0.1, 1, 1, 0.19498222904213672}, 49 {0.5, 11, 7, 0.14625028471336987}, 50 {0.9, 20, 15, 0.40567939897287852}, 51 {1, 1, 1, 0.50000000000000011}, 52 {2, 15, 12, 0.8839384428956264}, 53 {5, 4, 8, 0.97429642410900219}, 54 {10, 12, 9, 0.99915733385467187}, 55 {100, 7, 7, 0.99999823560259171}, 56 {1000, 2, 1, 0.97764490829950534}, 57 } { 58 cdf := F{test.d1, test.d2, nil}.CDF(test.x) 59 if !scalar.EqualWithinAbsOrRel(cdf, test.want, 1e-10, 1e-10) { 60 t.Errorf("CDF mismatch, x = %v, d1 = %v, d2 = %v. Got %v, want %v", test.x, test.d1, test.d2, cdf, test.want) 61 } 62 } 63 } 64 65 func TestF(t *testing.T) { 66 t.Parallel() 67 src := rand.New(rand.NewSource(1)) 68 for i, f := range []F{ 69 {13, 16, src}, 70 {42, 31, src}, 71 {77, 92, src}, 72 } { 73 testF(t, f, i) 74 } 75 } 76 77 func testF(t *testing.T, f F, i int) { 78 const ( 79 tol = 1e-2 80 n = 1e6 81 bins = 50 82 ) 83 x := make([]float64, n) 84 generateSamples(x, f) 85 sort.Float64s(x) 86 87 testRandLogProbContinuous(t, i, 0, x, f, tol, bins) 88 checkProbContinuous(t, i, x, 0, math.Inf(1), f, 1e-4) 89 checkMean(t, i, x, f, tol) 90 checkVarAndStd(t, i, x, f, tol) 91 checkExKurtosis(t, i, x, f, 1e-1) 92 checkSkewness(t, i, x, f, 5e-2) 93 checkQuantileCDFSurvival(t, i, x, f, 5e-3) 94 checkMode(t, i, x, f, 2e-2, 3e-2) 95 96 if f.NumParameters() != 2 { 97 t.Errorf("Wrong number of parameters. Got %v, want 2", f.NumParameters()) 98 } 99 } 100 101 func TestFUndefined(t *testing.T) { 102 t.Parallel() 103 for _, d1 := range []float64{1, 100} { 104 for _, d2 := range []float64{4, 8} { 105 f := F{d1, d2, nil} 106 exKurt := f.ExKurtosis() 107 if !math.IsNaN(exKurt) { 108 t.Errorf("Expected NaN excess kurtosis for D1 = %g and D2 = %g, got %v", d1, d2, exKurt) 109 } 110 } 111 } 112 for _, d1 := range []float64{1, 100} { 113 for _, d2 := range []float64{1, 2} { 114 f := F{d1, d2, nil} 115 mean := f.Mean() 116 if !math.IsNaN(mean) { 117 t.Errorf("Expected NaN mean for D1 = %g and D2 = %g, got %v", d1, d2, mean) 118 } 119 } 120 } 121 for _, d1 := range []float64{1, 2} { 122 for _, d2 := range []float64{1, 100} { 123 f := F{d1, d2, nil} 124 mode := f.Mode() 125 if !math.IsNaN(mode) { 126 t.Errorf("Expected NaN mode for D1 = %g and D2 = %g, got %v", d1, d2, mode) 127 } 128 } 129 } 130 for _, d1 := range []float64{1, 100} { 131 for _, d2 := range []float64{3, 6} { 132 f := F{d1, d2, nil} 133 skewness := f.Skewness() 134 if !math.IsNaN(skewness) { 135 t.Errorf("Expected NaN skewness for D1 = %g and D2 = %g, got %v", d1, d2, skewness) 136 } 137 } 138 } 139 for _, d1 := range []float64{1, 100} { 140 for _, d2 := range []float64{2, 4} { 141 f := F{d1, d2, nil} 142 variance := f.Variance() 143 if !math.IsNaN(variance) { 144 t.Errorf("Expected NaN variance for D1 = %g and D2 = %g, got %v", d1, d2, variance) 145 } 146 stdDev := f.StdDev() 147 if !math.IsNaN(stdDev) { 148 t.Errorf("Expected NaN standard deviation for D1 = %g and D2 = %g, got %v", d1, d2, variance) 149 } 150 } 151 } 152 }