View Javadoc
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    * https://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.hipparchus.distribution.discrete;
15  
16  import org.hipparchus.distribution.IntegerDistribution;
17  import org.junit.jupiter.api.Test;
18  
19  import static org.junit.jupiter.api.Assertions.assertEquals;
20  
21  /**
22   * Test cases for BinomialDistribution.
23   */
24  public class BinomialDistributionTest extends IntegerDistributionAbstractTest {
25  
26      /**
27       * Constructor to override default tolerance.
28       */
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
38      public IntegerDistribution makeDistribution() {
39          return new BinomialDistribution(10, 0.70);
40      }
41  
42      /** Creates the default probability density test input values. */
43      @Override
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
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
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
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
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
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
95      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         assertEquals(0, dist.getSupportLowerBound());
108         assertEquals(0, dist.getSupportUpperBound());
109     }
110 
111     /** Test degenerate case p = 1 */
112     @Test
113     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         assertEquals(5, dist.getSupportLowerBound());
126         assertEquals(5, dist.getSupportUpperBound());
127     }
128 
129     /** Test degenerate case n = 0 */
130     @Test
131     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         assertEquals(0, dist.getSupportLowerBound());
144         assertEquals(0, dist.getSupportUpperBound());
145     }
146 
147     @Test
148     void testMoments() {
149         final double tol = 1e-9;
150         BinomialDistribution dist;
151 
152         dist = new BinomialDistribution(10, 0.5);
153         assertEquals(dist.getNumericalMean(), 10d * 0.5d, tol);
154         assertEquals(dist.getNumericalVariance(), 10d * 0.5d * 0.5d, tol);
155 
156         dist = new BinomialDistribution(30, 0.3);
157         assertEquals(dist.getNumericalMean(), 30d * 0.3d, tol);
158         assertEquals(dist.getNumericalVariance(), 30d * 0.3d * (1d - 0.3d), tol);
159     }
160 
161     @Test
162     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             assertEquals(trials / 2, p);
171         }
172     }
173 }