1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  package org.hipparchus.distribution.discrete;
23  
24  import org.hipparchus.distribution.IntegerDistribution;
25  import org.hipparchus.exception.MathIllegalArgumentException;
26  import org.hipparchus.util.FastMath;
27  import org.junit.jupiter.api.Test;
28  
29  import static org.junit.jupiter.api.Assertions.assertEquals;
30  import static org.junit.jupiter.api.Assertions.assertFalse;
31  import static org.junit.jupiter.api.Assertions.assertThrows;
32  import static org.junit.jupiter.api.Assertions.assertTrue;
33  import static org.junit.jupiter.api.Assertions.fail;
34  
35  
36  
37  
38  public class PoissonDistributionTest extends IntegerDistributionAbstractTest {
39  
40      
41  
42  
43      private static final double DEFAULT_TEST_POISSON_PARAMETER = 4.0;
44  
45      
46  
47  
48      public PoissonDistributionTest() {
49          setTolerance(1e-12);
50      }
51  
52      
53  
54  
55      @Override
56      public IntegerDistribution makeDistribution() {
57          return new PoissonDistribution(DEFAULT_TEST_POISSON_PARAMETER);
58      }
59  
60      
61  
62  
63      @Override
64      public int[] makeDensityTestPoints() {
65          return new int[] { -1, 0, 1, 2, 3, 4, 5, 10, 20};
66      }
67  
68      
69  
70  
71  
72      @Override
73      public double[] makeDensityTestValues() {
74          return new double[] { 0d, 0.0183156388887d,  0.073262555555d,
75                  0.14652511111d, 0.195366814813d, 0.195366814813,
76                  0.156293451851d, 0.00529247667642d, 8.27746364655e-09};
77      }
78  
79      
80  
81  
82  
83      @Override
84      public double[] makeLogDensityTestValues() {
85          return new double[] { Double.NEGATIVE_INFINITY, -4.000000000000d,
86                  -2.613705638880d, -1.920558458320d, -1.632876385868d,
87                  -1.632876385868d, -1.856019937183d, -5.241468961877d,
88                  -18.609729238356d};
89      }
90  
91      
92  
93  
94      @Override
95      public int[] makeCumulativeTestPoints() {
96          return new int[] { -1, 0, 1, 2, 3, 4, 5, 10, 20 };
97      }
98  
99      
100 
101 
102     @Override
103     public double[] makeCumulativeTestValues() {
104         return new double[] { 0d,  0.0183156388887d, 0.0915781944437d,
105                 0.238103305554d, 0.433470120367d, 0.62883693518,
106                 0.78513038703d,  0.99716023388d, 0.999999998077 };
107     }
108 
109     
110 
111 
112     @Override
113     public double[] makeInverseCumulativeTestPoints() {
114         IntegerDistribution dist = getDistribution();
115         return new double[] { 0d, 0.018315638886d, 0.018315638890d,
116                 0.091578194441d, 0.091578194445d, 0.238103305552d,
117                 0.238103305556d, dist.cumulativeProbability(3),
118                 dist.cumulativeProbability(4), dist.cumulativeProbability(5),
119                 dist.cumulativeProbability(10), dist.cumulativeProbability(20)};
120     }
121 
122     
123 
124 
125     @Override
126     public int[] makeInverseCumulativeTestValues() {
127         return new int[] { 0, 0, 1, 1, 2, 2, 3, 3, 4, 5, 10, 20};
128     }
129 
130     
131 
132 
133 
134 
135     @Test
136     void testNormalApproximateProbability() {
137         PoissonDistribution dist = new PoissonDistribution(100);
138         double result = dist.normalApproximateProbability(110)
139                 - dist.normalApproximateProbability(89);
140         assertEquals(0.706281887248, result, 1E-10);
141 
142         dist = new PoissonDistribution(10000);
143         result = dist.normalApproximateProbability(10200)
144         - dist.normalApproximateProbability(9899);
145         assertEquals(0.820070051552, result, 1E-10);
146     }
147 
148     
149 
150 
151     @Test
152     void testDegenerateInverseCumulativeProbability() {
153         PoissonDistribution dist = new PoissonDistribution(DEFAULT_TEST_POISSON_PARAMETER);
154         assertEquals(Integer.MAX_VALUE, dist.inverseCumulativeProbability(1.0d));
155         assertEquals(0, dist.inverseCumulativeProbability(0d));
156     }
157 
158     @Test
159     void testNegativeMean() {
160         assertThrows(MathIllegalArgumentException.class, () -> {
161             new PoissonDistribution(-1);
162         });
163     }
164 
165     @Test
166     void testMean() {
167         PoissonDistribution dist = new PoissonDistribution(10.0);
168         assertEquals(10.0, dist.getMean(), 0.0);
169     }
170 
171     @Test
172     void testLargeMeanCumulativeProbability() {
173         double mean = 1.0;
174         while (mean <= 10000000.0) {
175             PoissonDistribution dist = new PoissonDistribution(mean);
176 
177             double x = mean * 2.0;
178             double dx = x / 10.0;
179             double p = Double.NaN;
180             double sigma = FastMath.sqrt(mean);
181             while (x >= 0) {
182                 try {
183                     p = dist.cumulativeProbability((int) x);
184                     assertFalse(Double.isNaN(p),"NaN cumulative probability returned for mean = " +
185                             mean + " x = " + x);
186                     if (x > mean - 2 * sigma) {
187                         assertTrue(p > 0, "Zero cum probaility returned for mean = " +
188                                 mean + " x = " + x);
189                     }
190                 } catch (Exception ex) {
191                     fail("mean of " + mean + " and x of " + x + " caused " + ex.getMessage());
192                 }
193                 x -= dx;
194             }
195 
196             mean *= 10.0;
197         }
198     }
199 
200     
201 
202 
203     @Test
204     void testCumulativeProbabilitySpecial() {
205         PoissonDistribution dist;
206         dist = new PoissonDistribution(9120);
207         checkProbability(dist, 9075);
208         checkProbability(dist, 9102);
209         dist = new PoissonDistribution(5058);
210         checkProbability(dist, 5044);
211         dist = new PoissonDistribution(6986);
212         checkProbability(dist, 6950);
213     }
214 
215     private void checkProbability(PoissonDistribution dist, int x) {
216         double p = dist.cumulativeProbability(x);
217         assertFalse(Double.isNaN(p), "NaN cumulative probability returned for mean = " +
218                 dist.getMean() + " x = " + x);
219         assertTrue(p > 0, "Zero cum probability returned for mean = " +
220                 dist.getMean() + " x = " + x);
221     }
222 
223     @Test
224     void testLargeMeanInverseCumulativeProbability() {
225         double mean = 1.0;
226         while (mean <= 100000.0) { 
227             PoissonDistribution dist = new PoissonDistribution(mean);
228             double p = 0.1;
229             double dp = p;
230             while (p < .99) {
231                 try {
232                     int ret = dist.inverseCumulativeProbability(p);
233                     
234                     assertTrue(p <= dist.cumulativeProbability(ret));
235                     assertTrue(p > dist.cumulativeProbability(ret - 1));
236                 } catch (Exception ex) {
237                     fail("mean of " + mean + " and p of " + p + " caused " + ex.getMessage());
238                 }
239                 p += dp;
240             }
241             mean *= 10.0;
242         }
243     }
244 
245     @Test
246     void testMoments() {
247         final double tol = 1e-9;
248         PoissonDistribution dist;
249 
250         dist = new PoissonDistribution(1);
251         assertEquals(1, dist.getNumericalMean(), tol);
252         assertEquals(1, dist.getNumericalVariance(), tol);
253 
254         dist = new PoissonDistribution(11.23);
255         assertEquals(11.23, dist.getNumericalMean(), tol);
256         assertEquals(11.23, dist.getNumericalVariance(), tol);
257     }
258 }