1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.statistics.distribution;
18
19 import org.apache.commons.rng.UniformRandomProvider;
20 import org.apache.commons.rng.simple.RandomSource;
21 import org.junit.jupiter.api.Assertions;
22 import org.junit.jupiter.api.Test;
23 import org.junit.jupiter.params.ParameterizedTest;
24 import org.junit.jupiter.params.provider.CsvSource;
25
26
27
28
29
30 class PoissonDistributionTest extends BaseDiscreteDistributionTest {
31 @Override
32 DiscreteDistribution makeDistribution(Object... parameters) {
33 final double mean = (Double) parameters[0];
34 return PoissonDistribution.of(mean);
35 }
36
37
38 @Override
39 Object[][] makeInvalidParameters() {
40 return new Object[][] {
41 {0.0},
42 {-0.1},
43 };
44 }
45
46 @Override
47 String[] getParameterNames() {
48 return new String[] {"Mean"};
49 }
50
51 @Override
52 protected double getRelativeTolerance() {
53 return 1e-14;
54 }
55
56
57
58 @Test
59 void testLargeMeanCumulativeProbability() {
60 double mean = 1.0;
61 while (mean <= 10000000.0) {
62 final PoissonDistribution dist = PoissonDistribution.of(mean);
63
64 double x = mean * 2.0;
65 final double dx = x / 10.0;
66 final double sigma = Math.sqrt(mean);
67 while (x >= 0) {
68 try {
69 final double p = dist.cumulativeProbability((int) x);
70 Assertions.assertFalse(Double.isNaN(p), "NaN cumulative probability");
71 if (x > mean - 2 * sigma) {
72 Assertions.assertTrue(p > 0, "Zero cumulative probaility");
73 }
74 } catch (final AssertionError ex) {
75 Assertions.fail("mean of " + mean + " and x of " + x + " caused " + ex.getMessage());
76 }
77 x -= dx;
78 }
79
80 mean *= 10.0;
81 }
82 }
83
84
85
86
87 @ParameterizedTest
88 @CsvSource({
89 "9120, 9075",
90 "9120, 9102",
91 "5058, 5044",
92 "6986, 6950",
93 })
94 void testCumulativeProbabilitySpecial(double mean, int x) {
95 final PoissonDistribution dist = PoissonDistribution.of(mean);
96 final double p = dist.cumulativeProbability(x);
97 Assertions.assertFalse(Double.isNaN(p), () -> "NaN cumulative probability returned for mean = " +
98 dist.getMean() + " x = " + x);
99 Assertions.assertTrue(p > 0, () -> "Zero cum probability returned for mean = " +
100 dist.getMean() + " x = " + x);
101 }
102
103 @Test
104 void testLargeMeanInverseCumulativeProbability() {
105 double mean = 1.0;
106 while (mean <= 100000.0) {
107 final PoissonDistribution dist = PoissonDistribution.of(mean);
108 double p = 0.1;
109 final double dp = p;
110 while (p < .99) {
111 try {
112 final int ret = dist.inverseCumulativeProbability(p);
113
114 Assertions.assertTrue(p <= dist.cumulativeProbability(ret));
115 Assertions.assertTrue(p > dist.cumulativeProbability(ret - 1));
116 } catch (final AssertionError ex) {
117 Assertions.fail("mean of " + mean + " and p of " + p + " caused " + ex.getMessage());
118 }
119 p += dp;
120 }
121 mean *= 10.0;
122 }
123 }
124
125 @Test
126 void testAdditionalCumulativeProbabilityHighPrecision() {
127
128 testCumulativeProbabilityHighPrecision(
129 PoissonDistribution.of(100),
130 new int[] {28, 25},
131 new double[] {1.6858675763053070496e-17, 3.184075559619425735e-19},
132 DoubleTolerances.relative(5e-14));
133 }
134
135
136
137
138 @Test
139 void testCreateSamplerWithLargeMean() {
140 final int mean = Integer.MAX_VALUE;
141 final PoissonDistribution dist = PoissonDistribution.of(mean);
142
143 Assertions.assertEquals(0.5, dist.cumulativeProbability(mean), 0.05);
144 final UniformRandomProvider rng = RandomSource.SPLIT_MIX_64.create();
145 dist.createSampler(rng)
146 .samples(50)
147 .forEach(i -> Assertions.assertTrue(i >= 0, () -> "Bad sample: " + i));
148 }
149 }