1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.rng.sampling.distribution;
18
19 import org.apache.commons.math3.distribution.PoissonDistribution;
20 import org.apache.commons.rng.UniformRandomProvider;
21 import org.apache.commons.rng.sampling.RandomAssert;
22 import org.apache.commons.rng.simple.RandomSource;
23 import org.junit.Assert;
24 import org.junit.Test;
25
26
27
28
29
30 public class KempSmallMeanPoissonSamplerTest {
31
32
33
34
35
36
37 private static final double SUPPORTED_UPPER_BOUND = -Math.log(Double.MIN_VALUE);
38
39
40 private final UniformRandomProvider dummyRng = new FixedRNG(0);
41
42
43
44
45 @Test(expected = IllegalArgumentException.class)
46 public void testConstructorThrowsWithMeanLargerThanUpperBound() {
47 final double mean = SUPPORTED_UPPER_BOUND + 1;
48 @SuppressWarnings("unused")
49 SharedStateDiscreteSampler sampler = KempSmallMeanPoissonSampler.of(dummyRng, mean);
50 }
51
52
53
54
55 @Test(expected = IllegalArgumentException.class)
56 public void testConstructorThrowsWithZeroMean() {
57 final double mean = 0;
58 @SuppressWarnings("unused")
59 SharedStateDiscreteSampler sampler = KempSmallMeanPoissonSampler.of(dummyRng, mean);
60 }
61
62
63
64
65 @Test(expected = IllegalArgumentException.class)
66 public void testConstructorThrowsWithNegativeMean() {
67 final double mean = -1;
68 @SuppressWarnings("unused")
69 SharedStateDiscreteSampler sampler = KempSmallMeanPoissonSampler.of(dummyRng, mean);
70 }
71
72
73
74
75 @Test(expected = IllegalArgumentException.class)
76 public void testConstructorWithNaNMean() {
77 final double mean = Double.NaN;
78 @SuppressWarnings("unused")
79 SharedStateDiscreteSampler sampler = KempSmallMeanPoissonSampler.of(dummyRng, mean);
80 }
81
82
83
84
85
86 @Test
87 public void testSummationFrom1AtUpperBound() {
88 final double mean = SUPPORTED_UPPER_BOUND;
89 double u = 1;
90 int x = 0;
91 double p = Math.exp(-mean);
92 while (u > p && p != 0) {
93 u -= p;
94 x = x + 1;
95 p = p * mean / x;
96 }
97 Assert.assertEquals("Summation is not zero", 0, u, 1e-3);
98 Assert.assertTrue("Summation is not greater than zero", u > 0);
99 }
100
101
102
103
104
105 @Test
106 public void testSummationTo1AtUpperBound() {
107 final double mean = SUPPORTED_UPPER_BOUND;
108 double u = 0;
109 int x = 0;
110 double p = Math.exp(-mean);
111 while (p != 0) {
112 u += p;
113 x = x + 1;
114 p = p * mean / x;
115 }
116 Assert.assertEquals("Summation is not one", 1, u, 1e-3);
117 Assert.assertTrue("Summation is not less than one", u < 1);
118 }
119
120
121
122
123 @Test
124 public void testSamplerAtUpperBounds() {
125 final double mean = SUPPORTED_UPPER_BOUND;
126
127
128 final PoissonDistribution pd = new PoissonDistribution(null, mean,
129 PoissonDistribution.DEFAULT_EPSILON, PoissonDistribution.DEFAULT_MAX_ITERATIONS);
130
131 final FixedRNG rng = new FixedRNG(0);
132 final SharedStateDiscreteSampler sampler = KempSmallMeanPoissonSampler.of(rng, mean);
133
134
135 testSample(rng, sampler, 0, 0, 0);
136
137
138 testSample(rng, sampler, 1, pd.inverseCumulativeProbability(0.9999), Integer.MAX_VALUE);
139
140
141 for (int i = 1; i < 10; i++) {
142 final double p = i * 0.1;
143 final int lower = pd.inverseCumulativeProbability(p - 0.01);
144 final int upper = pd.inverseCumulativeProbability(p + 0.01);
145 testSample(rng, sampler, p, lower, upper);
146 }
147 }
148
149
150
151
152 @Test
153 public void testSharedStateSampler() {
154 final UniformRandomProvider rng1 = RandomSource.create(RandomSource.SPLIT_MIX_64, 0L);
155 final UniformRandomProvider rng2 = RandomSource.create(RandomSource.SPLIT_MIX_64, 0L);
156 final double mean = 1.23;
157 final SharedStateDiscreteSampler sampler1 =
158 KempSmallMeanPoissonSampler.of(rng1, mean);
159 final SharedStateDiscreteSampler sampler2 = sampler1.withUniformRandomProvider(rng2);
160 RandomAssert.assertProduceSameSequence(sampler1, sampler2);
161 }
162
163
164
165
166
167
168
169
170
171
172 private static void testSample(FixedRNG rng, SharedStateDiscreteSampler sampler, double cumulativeProbability,
173 int lower, int upper) {
174 rng.setValue(cumulativeProbability);
175 final int sample = sampler.sample();
176 Assert.assertTrue(sample + " sample is not above realistic lower limit: " + lower, sample >= lower);
177 Assert.assertTrue(sample + " sample is not below realistic upper limit: " + upper, sample <= upper);
178 }
179
180
181
182
183 private static class FixedRNG implements UniformRandomProvider {
184
185 private double value;
186
187
188
189
190 FixedRNG(double value) {
191 this.value = value;
192 }
193
194 @Override
195 public double nextDouble() {
196 return value;
197 }
198
199
200
201
202 void setValue(double value) {
203 this.value = value;
204 }
205
206
207 public long nextLong(long n) { return 0; }
208 public long nextLong() { return 0; }
209 public int nextInt(int n) { return 0; }
210 public int nextInt() { return 0; }
211 public float nextFloat() { return 0; }
212 public void nextBytes(byte[] bytes, int start, int len) {}
213 public void nextBytes(byte[] bytes) {}
214 public boolean nextBoolean() { return false; }
215
216 }
217 }