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.rng.RandomProviderState;
20 import org.apache.commons.rng.RestorableUniformRandomProvider;
21 import org.apache.commons.rng.simple.RandomSource;
22 import org.junit.Assert;
23 import org.junit.Test;
24
25
26
27
28
29
30 public class PoissonSamplerCacheTest {
31
32
33
34
35 private final int minRange = (int) Math.floor(PoissonSampler.PIVOT - 2);
36
37 private final int maxRange = (int) Math.floor(PoissonSampler.PIVOT + 6);
38
39 private final int midRange = (minRange + maxRange) / 2;
40
41
42
43
44
45
46
47
48 @Test
49 public void testConstructorWithNoCache() {
50 final double min = 0;
51 final double max = PoissonSampler.PIVOT - 2;
52 PoissonSamplerCache cache = createPoissonSamplerCache(min, max);
53 Assert.assertFalse(cache.isValidRange());
54 Assert.assertEquals(0, cache.getMinMean(), 0);
55 Assert.assertEquals(0, cache.getMaxMean(), 0);
56 }
57
58
59
60
61
62
63 @Test
64 public void testConstructorWhenMaxEqualsMin() {
65 final double min = PoissonSampler.PIVOT + 2;
66 final double max = min;
67 PoissonSamplerCache cache = createPoissonSamplerCache(min, max);
68 Assert.assertTrue(cache.isValidRange());
69 Assert.assertEquals(min, cache.getMinMean(), 0);
70 Assert.assertEquals(Math.nextAfter(Math.floor(max) + 1, -1),
71 cache.getMaxMean(), 0);
72 }
73
74
75
76
77
78
79 @Test
80 public void testConstructorWhenMaxAboveMin() {
81 final double min = PoissonSampler.PIVOT + 2;
82 final double max = min + 10;
83 PoissonSamplerCache cache = createPoissonSamplerCache(min, max);
84 Assert.assertTrue(cache.isValidRange());
85 Assert.assertEquals(min, cache.getMinMean(), 0);
86 Assert.assertEquals(Math.nextAfter(Math.floor(max) + 1, -1),
87 cache.getMaxMean(), 0);
88 }
89
90
91
92
93 @Test(expected=IllegalArgumentException.class)
94 public void testConstructorThrowsWhenMaxIsLessThanMin() {
95 final double min = PoissonSampler.PIVOT;
96 final double max = Math.nextAfter(min, -1);
97 createPoissonSamplerCache(min, max);
98 }
99
100
101
102
103
104 @Test
105 public void testConstructorWhenMinBelow0() {
106 final double min = -1;
107 final double max = PoissonSampler.PIVOT + 2;
108 PoissonSamplerCache cache = createPoissonSamplerCache(min, max);
109 Assert.assertTrue(cache.isValidRange());
110 Assert.assertEquals(PoissonSampler.PIVOT, cache.getMinMean(), 0);
111 Assert.assertEquals(Math.nextAfter(Math.floor(max) + 1, -1),
112 cache.getMaxMean(), 0);
113 }
114
115
116
117
118
119 @Test
120 public void testConstructorWhenMaxBelow0() {
121 final double min = -10;
122 final double max = -1;
123 PoissonSamplerCache cache = createPoissonSamplerCache(min, max);
124 Assert.assertFalse(cache.isValidRange());
125 Assert.assertEquals(0, cache.getMinMean(), 0);
126 Assert.assertEquals(0, cache.getMaxMean(), 0);
127 }
128
129
130
131
132
133
134 @Test
135 public void testWithRangeConstructorWithNoCache() {
136 final double min = 0;
137 final double max = PoissonSampler.PIVOT - 2;
138 PoissonSamplerCache cache = createPoissonSamplerCache().withRange(min, max);
139 Assert.assertFalse(cache.isValidRange());
140 Assert.assertEquals(0, cache.getMinMean(), 0);
141 Assert.assertEquals(0, cache.getMaxMean(), 0);
142 }
143
144
145
146
147
148
149 @Test
150 public void testWithRangeConstructorWhenMaxEqualsMin() {
151 final double min = PoissonSampler.PIVOT + 2;
152 final double max = min;
153 PoissonSamplerCache cache = createPoissonSamplerCache().withRange(min, max);
154 Assert.assertTrue(cache.isValidRange());
155 Assert.assertEquals(min, cache.getMinMean(), 0);
156 Assert.assertEquals(Math.nextAfter(Math.floor(max) + 1, -1),
157 cache.getMaxMean(), 0);
158 }
159
160
161
162
163
164
165 @Test
166 public void testWithRangeConstructorWhenMaxAboveMin() {
167 final double min = PoissonSampler.PIVOT + 2;
168 final double max = min + 10;
169 PoissonSamplerCache cache = createPoissonSamplerCache().withRange(min, max);
170 Assert.assertTrue(cache.isValidRange());
171 Assert.assertEquals(min, cache.getMinMean(), 0);
172 Assert.assertEquals(Math.nextAfter(Math.floor(max) + 1, -1),
173 cache.getMaxMean(), 0);
174 }
175
176
177
178
179 @Test(expected=IllegalArgumentException.class)
180 public void testWithRangeConstructorThrowsWhenMaxIsLessThanMin() {
181 final double min = PoissonSampler.PIVOT;
182 final double max = Math.nextAfter(min, -1);
183 createPoissonSamplerCache().withRange(min, max);
184 }
185
186
187
188
189
190 @Test
191 public void testWithRangeConstructorWhenMinBelow0() {
192 final double min = -1;
193 final double max = PoissonSampler.PIVOT + 2;
194 PoissonSamplerCache cache = createPoissonSamplerCache().withRange(min, max);
195 Assert.assertTrue(cache.isValidRange());
196 Assert.assertEquals(PoissonSampler.PIVOT, cache.getMinMean(), 0);
197 Assert.assertEquals(Math.nextAfter(Math.floor(max) + 1, -1),
198 cache.getMaxMean(), 0);
199 }
200
201
202
203
204 @Test
205 public void testWithRangeConstructorWhenCacheHasNoCapcity() {
206 final double min = PoissonSampler.PIVOT + 2;
207 final double max = min + 10;
208 PoissonSamplerCache cache = createPoissonSamplerCache(0, 0).withRange(min, max);
209 Assert.assertTrue(cache.isValidRange());
210 Assert.assertEquals(min, cache.getMinMean(), 0);
211 Assert.assertEquals(Math.nextAfter(Math.floor(max) + 1, -1),
212 cache.getMaxMean(), 0);
213 }
214
215
216
217
218
219 @Test
220 public void testWithinRange() {
221 final double min = PoissonSampler.PIVOT + 10;
222 final double max = PoissonSampler.PIVOT + 20;
223 PoissonSamplerCache cache = createPoissonSamplerCache(min, max);
224
225 Assert.assertTrue(cache.withinRange(PoissonSampler.PIVOT - 1));
226 Assert.assertFalse(cache.withinRange(min - 1));
227 Assert.assertTrue(cache.withinRange(min));
228 Assert.assertTrue(cache.withinRange(max));
229 Assert.assertFalse(cache.withinRange(max + 10));
230 }
231
232
233
234
235
236
237
238
239 @Test(expected=IllegalArgumentException.class)
240 public void testCreatePoissonSamplerThrowsWithZeroMean() {
241 final RestorableUniformRandomProvider rng =
242 RandomSource.create(RandomSource.SPLIT_MIX_64);
243 final PoissonSamplerCache cache = createPoissonSamplerCache();
244 cache.createPoissonSampler(rng, 0);
245 }
246
247
248
249
250 @Test(expected=IllegalArgumentException.class)
251 public void testCreatePoissonSamplerThrowsWithNonIntegerMean() {
252 final RestorableUniformRandomProvider rng =
253 RandomSource.create(RandomSource.SPLIT_MIX_64);
254 final PoissonSamplerCache cache = createPoissonSamplerCache();
255 final double mean = Integer.MAX_VALUE + 1.0;
256 cache.createPoissonSampler(rng, mean);
257 }
258
259
260
261
262
263
264
265 @Test
266 public void testCanComputeSameSamplesAsPoissonSamplerWithFullRangeCache() {
267 checkComputeSameSamplesAsPoissonSampler(minRange,
268 maxRange);
269 }
270
271
272
273
274
275 @Test
276 public void testCanComputeSameSamplesAsPoissonSamplerWithNoCache() {
277 checkComputeSameSamplesAsPoissonSampler(0,
278 minRange - 2);
279 }
280
281
282
283
284
285 @Test
286 public void testCanComputeSameSamplesAsPoissonSamplerWithPartialCacheCoveringLowerRange() {
287 checkComputeSameSamplesAsPoissonSampler(minRange,
288 midRange);
289 }
290
291
292
293
294
295 @Test
296 public void testCanComputeSameSamplesAsPoissonSamplerWithPartialCacheCoveringUpperRange() {
297 checkComputeSameSamplesAsPoissonSampler(midRange,
298 maxRange);
299 }
300
301
302
303
304
305 @Test
306 public void testCanComputeSameSamplesAsPoissonSamplerWithCacheAboveTheUpperRange() {
307 checkComputeSameSamplesAsPoissonSampler(maxRange + 10,
308 maxRange + 20);
309 }
310
311
312
313
314
315
316
317
318 private void checkComputeSameSamplesAsPoissonSampler(int minMean,
319 int maxMean) {
320
321 final RestorableUniformRandomProvider rng1 =
322 RandomSource.create(RandomSource.WELL_19937_C);
323 final RandomProviderState state = rng1.saveState();
324 final RestorableUniformRandomProvider rng2 =
325 RandomSource.create(RandomSource.WELL_19937_C);
326 rng2.restoreState(state);
327
328
329 final PoissonSamplerCache cache =
330 createPoissonSamplerCache(minMean, maxMean);
331
332
333 for (int i = minRange; i <= maxRange; i++) {
334
335 testPoissonSamples(rng1, rng2, cache, i);
336
337 testPoissonSamples(rng1, rng2, cache, i + 0.5);
338 }
339 }
340
341
342
343
344
345
346
347
348 private static PoissonSamplerCache createPoissonSamplerCache(double minMean,
349 double maxMean)
350 {
351 return new PoissonSamplerCache(minMean, maxMean);
352 }
353
354
355
356
357
358
359 private static PoissonSamplerCache createPoissonSamplerCache()
360 {
361 return new PoissonSamplerCache(PoissonSampler.PIVOT,
362 PoissonSampler.PIVOT + 10);
363 }
364
365
366
367
368
369
370
371
372
373
374
375 private static void testPoissonSamples(
376 final RestorableUniformRandomProvider rng1,
377 final RestorableUniformRandomProvider rng2,
378 PoissonSamplerCache cache,
379 double mean) {
380 final DiscreteSampler s1 = new PoissonSampler(rng1, mean);
381 final DiscreteSampler s2 = cache.createPoissonSampler(rng2, mean);
382 for (int j = 0; j < 10; j++)
383 Assert.assertEquals(s1.sample(), s2.sample());
384 }
385
386
387
388
389
390 @Test
391 public void testCanComputeSameSamplesAsPoissonSamplerReusingCacheEntireRange() {
392 checkComputeSameSamplesAsPoissonSamplerReusingCache(midRange,
393 maxRange,
394 midRange,
395 maxRange);
396 }
397
398
399
400
401
402 @Test
403 public void testCanComputeSameSamplesAsPoissonSamplerReusingCacheNoRange() {
404 checkComputeSameSamplesAsPoissonSamplerReusingCache(midRange,
405 maxRange,
406 maxRange + 10,
407 maxRange + 20);
408 }
409
410
411
412
413
414 @Test
415 public void testCanComputeSameSamplesAsPoissonSamplerReusingCacheLowerRange() {
416 checkComputeSameSamplesAsPoissonSamplerReusingCache(midRange,
417 maxRange,
418 minRange,
419 midRange + 1);
420 }
421
422
423
424
425
426 @Test
427 public void testCanComputeSameSamplesAsPoissonSamplerReusingCacheUpperRange() {
428 checkComputeSameSamplesAsPoissonSamplerReusingCache(midRange,
429 maxRange,
430 maxRange - 1,
431 maxRange + 5);
432 }
433
434
435
436
437
438
439
440
441
442
443
444
445
446 private void checkComputeSameSamplesAsPoissonSamplerReusingCache(int minMean,
447 int maxMean,
448 int minMean2,
449 int maxMean2) {
450
451 final RestorableUniformRandomProvider rng1 =
452 RandomSource.create(RandomSource.WELL_19937_C);
453 final RandomProviderState state = rng1.saveState();
454 final RestorableUniformRandomProvider rng2 =
455 RandomSource.create(RandomSource.WELL_19937_C);
456
457
458 final PoissonSamplerCache cache =
459 createPoissonSamplerCache(minMean, maxMean);
460
461
462 for (int i = minMean; i <= maxMean; i++) {
463 cache.createPoissonSampler(rng1, i);
464 }
465
466 final PoissonSamplerCache cache2 = cache.withRange(minMean2, maxMean2);
467 Assert.assertTrue("WithRange cache is the same object", cache != cache2);
468
469 rng1.restoreState(state);
470 rng2.restoreState(state);
471
472
473
474 for (int i = minRange; i <= maxRange; i++) {
475
476 testPoissonSamples(rng1, rng2, cache2, i);
477
478 testPoissonSamples(rng1, rng2, cache2, i + 0.5);
479 }
480 }
481 }