gonum.org/v1/gonum@v0.14.0/stat/distuv/binomial_test.go (about)

     1  // Copyright ©2018 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  	"sort"
     9  	"testing"
    10  
    11  	"golang.org/x/exp/rand"
    12  
    13  	"gonum.org/v1/gonum/floats/scalar"
    14  )
    15  
    16  func TestBinomialProb(t *testing.T) {
    17  	t.Parallel()
    18  	const tol = 1e-10
    19  	for i, tt := range []struct {
    20  		k    float64
    21  		n    float64
    22  		p    float64
    23  		want float64
    24  	}{
    25  		// Probabilities computed with Wolfram|Alpha (http://wwww.wolframalpha.com)
    26  		{0, 10, 0.5, 0.0009765625},
    27  		{1, 10, 0.5, 0.009765625},
    28  		{2, 10, 0.5, 0.0439453125},
    29  		{3, 10, 0.5, 0.1171875},
    30  		{4, 10, 0.5, 0.205078125},
    31  		{5, 10, 0.75, 5.839920043945313e-02},
    32  		{6, 10, 0.75, 0.1459980010986328},
    33  		{7, 10, 0.75, 0.2502822875976563},
    34  		{8, 10, 0.75, 0.2815675735473633},
    35  		{9, 10, 0.75, 0.1877117156982422},
    36  		{10, 10, 0.75, 5.6313514709472656e-02},
    37  
    38  		{0, 25, 0.25, 7.525434581650003e-04},
    39  		{2, 25, 0.25, 2.508478193883334e-02},
    40  		{5, 25, 0.25, 0.1645375881987921},
    41  		{7, 25, 0.25, 0.1654081574485211},
    42  		{10, 25, 0.25, 4.165835076481272e-02},
    43  		{12, 25, 0.01, 4.563372575901533e-18},
    44  		{15, 25, 0.01, 2.956207951505780e-24},
    45  		{17, 25, 0.01, 9.980175928758777e-29},
    46  		{20, 25, 0.99, 4.345539559454088e-06},
    47  		{22, 25, 0.99, 1.843750355939806e-03},
    48  		{25, 25, 0.99, 0.7778213593991468},
    49  
    50  		{0.5, 25, 0.5, 0},
    51  		{1.5, 25, 0.5, 0},
    52  		{2.5, 25, 0.5, 0},
    53  		{3.5, 25, 0.5, 0},
    54  		{4.5, 25, 0.5, 0},
    55  		{5.5, 25, 0.5, 0},
    56  		{6.5, 25, 0.5, 0},
    57  		{7.5, 25, 0.5, 0},
    58  		{8.5, 25, 0.5, 0},
    59  		{9.5, 25, 0.5, 0},
    60  	} {
    61  		b := Binomial{N: tt.n, P: tt.p}
    62  		got := b.Prob(tt.k)
    63  		if !scalar.EqualWithinRel(got, tt.want, tol) {
    64  			t.Errorf("test-%d: got=%e. want=%e\n", i, got, tt.want)
    65  		}
    66  	}
    67  }
    68  
    69  func TestBinomialCDF(t *testing.T) {
    70  	t.Parallel()
    71  	const tol = 1e-10
    72  	for i, tt := range []struct {
    73  		k    float64
    74  		n    float64
    75  		p    float64
    76  		want float64
    77  	}{
    78  		// Cumulative probabilities computed with SciPy
    79  		{-1, 10, 0.5, 0},
    80  		{0, 10, 0.5, 9.765625e-04},
    81  		{1, 10, 0.5, 1.0742187499999998e-02},
    82  		{2, 10, 0.5, 5.468749999999999e-02},
    83  		{3, 10, 0.5, 1.7187499999999994e-01},
    84  		{4, 10, 0.5, 3.769531249999999e-01},
    85  		{5, 10, 0.25, 9.802722930908203e-01},
    86  		{6, 10, 0.25, 9.964942932128906e-01},
    87  		{7, 10, 0.25, 9.995841979980469e-01},
    88  		{8, 10, 0.25, 9.999704360961914e-01},
    89  		{9, 10, 0.25, 9.999990463256836e-01},
    90  		{10, 10, 0.25, 1.0},
    91  
    92  		{0, 25, 0.75, 8.881784197001252e-16},
    93  		{2.5, 25, 0.75, 2.4655832930875472e-12},
    94  		{5, 25, 0.75, 1.243460090449844e-08},
    95  		{7.5, 25, 0.75, 1.060837565347583e-06},
    96  		{10, 25, 0.75, 2.1451240486669576e-04},
    97  		{12.5, 25, 0.01, 9.999999999999999e-01},
    98  		{15, 25, 0.01, 9.999999999999999e-01},
    99  		{17.5, 25, 0.01, 9.999999999999999e-01},
   100  		{20, 25, 0.99, 4.495958469027147e-06},
   101  		{22.5, 25, 0.99, 1.9506768897388268e-03},
   102  		{25, 25, 0.99, 1.0},
   103  	} {
   104  		b := Binomial{N: tt.n, P: tt.p}
   105  		got := b.CDF(tt.k)
   106  		if !scalar.EqualWithinRel(got, tt.want, tol) {
   107  			t.Errorf("test-%d: got=%e. want=%e\n", i, got, tt.want)
   108  		}
   109  		got = b.Survival(tt.k)
   110  		want := 1 - tt.want
   111  		if !scalar.EqualWithinRel(got, want, tol) {
   112  			t.Errorf("test-%d: got=%e. want=%e\n", i, got, tt.want)
   113  		}
   114  	}
   115  }
   116  
   117  func TestBinomial(t *testing.T) {
   118  	t.Parallel()
   119  	src := rand.New(rand.NewSource(1))
   120  	for i, b := range []Binomial{
   121  		{100, 0.5, src},
   122  		{15, 0.25, src},
   123  		{10, 0.75, src},
   124  		{9000, 0.102, src},
   125  		{1e6, 0.001, src},
   126  		{25, 0.02, src},
   127  		{25, 0.99, src},
   128  		{25, 0.46, src},
   129  		{25, 0.55, src},
   130  		{3, 0.8, src},
   131  	} {
   132  		testBinomial(t, b, i)
   133  	}
   134  }
   135  
   136  func testBinomial(t *testing.T, b Binomial, i int) {
   137  	const (
   138  		tol = 1e-2
   139  		n   = 1e6
   140  	)
   141  	x := make([]float64, n)
   142  	generateSamples(x, b)
   143  	sort.Float64s(x)
   144  
   145  	checkMean(t, i, x, b, tol)
   146  	checkVarAndStd(t, i, x, b, tol)
   147  	checkExKurtosis(t, i, x, b, 7e-2)
   148  	checkSkewness(t, i, x, b, tol)
   149  
   150  	if b.NumParameters() != 2 {
   151  		t.Errorf("Wrong number of parameters")
   152  	}
   153  }