1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with this
4  * work for additional information regarding copyright ownership. The ASF
5  * licenses this file to You under the Apache License, Version 2.0 (the
6  * "License"); you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
9  * or agreed to in writing, software distributed under the License is
10  * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
11  * KIND, either express or implied. See the License for the specific language
12  * governing permissions and limitations under the License.
13  */
14 package org.apache.commons.math3.distribution;
15 
16 import org.junit.Assert;
17 import org.junit.Test;
18 
19 /**
20  * Test cases for BinomialDistribution. Extends IntegerDistributionAbstractTest.
21  * See class javadoc for IntegerDistributionAbstractTest for details.
22  *
23  */
24 public class BinomialDistributionTest extends IntegerDistributionAbstractTest {
25 
26     /**
27      * Constructor to override default tolerance.
28      */
BinomialDistributionTest()29     public BinomialDistributionTest() {
30         setTolerance(1e-12);
31     }
32 
33     // -------------- Implementations for abstract methods
34     // -----------------------
35 
36     /** Creates the default discrete distribution instance to use in tests. */
37     @Override
makeDistribution()38     public IntegerDistribution makeDistribution() {
39         return new BinomialDistribution(10, 0.70);
40     }
41 
42     /** Creates the default probability density test input values. */
43     @Override
makeDensityTestPoints()44     public int[] makeDensityTestPoints() {
45         return new int[] { -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
46     }
47 
48     /**
49      * Creates the default probability density test expected values.
50      * Reference values are from R, version 2.15.3.
51      */
52     @Override
makeDensityTestValues()53     public double[] makeDensityTestValues() {
54         return new double[] { 0d, 0.0000059049d, 0.000137781d, 0.0014467005,
55             0.009001692, 0.036756909, 0.1029193452, 0.200120949, 0.266827932,
56             0.2334744405, 0.121060821, 0.0282475249, 0d };
57     }
58 
59     /** Creates the default cumulative probability density test input values */
60     @Override
makeCumulativeTestPoints()61     public int[] makeCumulativeTestPoints() {
62         return makeDensityTestPoints();
63     }
64 
65     /**
66      * Creates the default cumulative probability density test expected values.
67      * Reference values are from R, version 2.15.3.
68      */
69     @Override
makeCumulativeTestValues()70     public double[] makeCumulativeTestValues() {
71         return new double[] { 0d, 5.9049e-06, 0.0001436859, 0.0015903864, 0.0105920784,  0.0473489874,
72             0.1502683326, 0.3503892816, 0.6172172136, 0.8506916541, 0.9717524751, 1d, 1d };
73     }
74 
75     /** Creates the default inverse cumulative probability test input values */
76     @Override
makeInverseCumulativeTestPoints()77     public double[] makeInverseCumulativeTestPoints() {
78         return new double[] { 0, 0.001d, 0.010d, 0.025d, 0.050d, 0.100d,
79                 0.999d, 0.990d, 0.975d, 0.950d, 0.900d, 1 };
80     }
81 
82     /**
83      * Creates the default inverse cumulative probability density test expected
84      * values
85      */
86     @Override
makeInverseCumulativeTestValues()87     public int[] makeInverseCumulativeTestValues() {
88         return new int[] { 0, 2, 3, 4, 5, 5, 10, 10, 10, 9, 9, 10 };
89     }
90 
91     // ----------------- Additional test cases ---------------------------------
92 
93     /** Test degenerate case p = 0 */
94     @Test
testDegenerate0()95     public void testDegenerate0() {
96         BinomialDistribution dist = new BinomialDistribution(5, 0.0d);
97         setDistribution(dist);
98         setCumulativeTestPoints(new int[] { -1, 0, 1, 5, 10 });
99         setCumulativeTestValues(new double[] { 0d, 1d, 1d, 1d, 1d });
100         setDensityTestPoints(new int[] { -1, 0, 1, 10, 11 });
101         setDensityTestValues(new double[] { 0d, 1d, 0d, 0d, 0d });
102         setInverseCumulativeTestPoints(new double[] { 0.1d, 0.5d });
103         setInverseCumulativeTestValues(new int[] { 0, 0 });
104         verifyDensities();
105         verifyCumulativeProbabilities();
106         verifyInverseCumulativeProbabilities();
107         Assert.assertEquals(dist.getSupportLowerBound(), 0);
108         Assert.assertEquals(dist.getSupportUpperBound(), 0);
109     }
110 
111     /** Test degenerate case p = 1 */
112     @Test
testDegenerate1()113     public void testDegenerate1() {
114         BinomialDistribution dist = new BinomialDistribution(5, 1.0d);
115         setDistribution(dist);
116         setCumulativeTestPoints(new int[] { -1, 0, 1, 2, 5, 10 });
117         setCumulativeTestValues(new double[] { 0d, 0d, 0d, 0d, 1d, 1d });
118         setDensityTestPoints(new int[] { -1, 0, 1, 2, 5, 10 });
119         setDensityTestValues(new double[] { 0d, 0d, 0d, 0d, 1d, 0d });
120         setInverseCumulativeTestPoints(new double[] { 0.1d, 0.5d });
121         setInverseCumulativeTestValues(new int[] { 5, 5 });
122         verifyDensities();
123         verifyCumulativeProbabilities();
124         verifyInverseCumulativeProbabilities();
125         Assert.assertEquals(dist.getSupportLowerBound(), 5);
126         Assert.assertEquals(dist.getSupportUpperBound(), 5);
127     }
128 
129     /** Test degenerate case n = 0 */
130     @Test
testDegenerate2()131     public void testDegenerate2() {
132         BinomialDistribution dist = new BinomialDistribution(0, 0.01d);
133         setDistribution(dist);
134         setCumulativeTestPoints(new int[] { -1, 0, 1, 2, 5, 10 });
135         setCumulativeTestValues(new double[] { 0d, 1d, 1d, 1d, 1d, 1d });
136         setDensityTestPoints(new int[] { -1, 0, 1, 2, 5, 10 });
137         setDensityTestValues(new double[] { 0d, 1d, 0d, 0d, 0d, 0d });
138         setInverseCumulativeTestPoints(new double[] { 0.1d, 0.5d });
139         setInverseCumulativeTestValues(new int[] { 0, 0 });
140         verifyDensities();
141         verifyCumulativeProbabilities();
142         verifyInverseCumulativeProbabilities();
143         Assert.assertEquals(dist.getSupportLowerBound(), 0);
144         Assert.assertEquals(dist.getSupportUpperBound(), 0);
145     }
146 
147     @Test
testMoments()148     public void testMoments() {
149         final double tol = 1e-9;
150         BinomialDistribution dist;
151 
152         dist = new BinomialDistribution(10, 0.5);
153         Assert.assertEquals(dist.getNumericalMean(), 10d * 0.5d, tol);
154         Assert.assertEquals(dist.getNumericalVariance(), 10d * 0.5d * 0.5d, tol);
155 
156         dist = new BinomialDistribution(30, 0.3);
157         Assert.assertEquals(dist.getNumericalMean(), 30d * 0.3d, tol);
158         Assert.assertEquals(dist.getNumericalVariance(), 30d * 0.3d * (1d - 0.3d), tol);
159     }
160 
161     @Test
testMath718()162     public void testMath718() {
163         // for large trials the evaluation of ContinuedFraction was inaccurate
164         // do a sweep over several large trials to test if the current implementation is
165         // numerically stable.
166 
167         for (int trials = 500000; trials < 20000000; trials += 100000) {
168             BinomialDistribution dist = new BinomialDistribution(trials, 0.5);
169             int p = dist.inverseCumulativeProbability(0.5);
170             Assert.assertEquals(trials / 2, p);
171         }
172     }
173 }
174