1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.math4.legacy.distribution;
18
19 import org.apache.commons.statistics.distribution.DiscreteDistribution;
20 import org.apache.commons.math4.legacy.TestUtils;
21 import org.apache.commons.math4.legacy.exception.MathIllegalArgumentException;
22 import org.apache.commons.rng.simple.RandomSource;
23 import org.apache.commons.math4.core.jdkmath.JdkMath;
24 import org.junit.After;
25 import org.junit.Assert;
26 import org.junit.Before;
27 import org.junit.Test;
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 public abstract class IntegerDistributionAbstractTest {
51
52
53
54 private DiscreteDistribution distribution;
55
56
57 private double tolerance = 1E-12;
58
59
60 private int[] densityTestPoints;
61
62
63 private double[] densityTestValues;
64
65
66 private double[] logDensityTestValues;
67
68
69 private int[] cumulativeTestPoints;
70
71
72 private double[] cumulativeTestValues;
73
74
75 private double[] inverseCumulativeTestPoints;
76
77
78 private int[] inverseCumulativeTestValues;
79
80
81
82
83 public abstract DiscreteDistribution makeDistribution();
84
85
86 public abstract int[] makeDensityTestPoints();
87
88
89 public abstract double[] makeDensityTestValues();
90
91
92
93
94
95
96
97
98 public double[] makeLogDensityTestValues() {
99 final double[] densityTestValues = makeDensityTestValues();
100 final double[] logDensityTestValues = new double[densityTestValues.length];
101 for (int i = 0; i < densityTestValues.length; i++) {
102 logDensityTestValues[i] = JdkMath.log(densityTestValues[i]);
103 }
104 return logDensityTestValues;
105 }
106
107
108 public abstract int[] makeCumulativeTestPoints();
109
110
111 public abstract double[] makeCumulativeTestValues();
112
113
114 public abstract double[] makeInverseCumulativeTestPoints();
115
116
117 public abstract int[] makeInverseCumulativeTestValues();
118
119
120
121
122
123
124 @Before
125 public void setUp() {
126 distribution = makeDistribution();
127 densityTestPoints = makeDensityTestPoints();
128 densityTestValues = makeDensityTestValues();
129 logDensityTestValues = makeLogDensityTestValues();
130 cumulativeTestPoints = makeCumulativeTestPoints();
131 cumulativeTestValues = makeCumulativeTestValues();
132 inverseCumulativeTestPoints = makeInverseCumulativeTestPoints();
133 inverseCumulativeTestValues = makeInverseCumulativeTestValues();
134 }
135
136
137
138
139 @After
140 public void tearDown() {
141 distribution = null;
142 densityTestPoints = null;
143 densityTestValues = null;
144 logDensityTestValues = null;
145 cumulativeTestPoints = null;
146 cumulativeTestValues = null;
147 inverseCumulativeTestPoints = null;
148 inverseCumulativeTestValues = null;
149 }
150
151
152
153
154
155
156
157 protected void verifyDensities() {
158 for (int i = 0; i < densityTestPoints.length; i++) {
159 Assert.assertEquals("Incorrect density value returned for " + densityTestPoints[i],
160 densityTestValues[i],
161 distribution.probability(densityTestPoints[i]), getTolerance());
162 }
163 }
164
165
166
167
168
169 protected void verifyLogDensities() {
170 for (int i = 0; i < densityTestPoints.length; i++) {
171 Assert.assertEquals("Incorrect log density value returned for " + densityTestPoints[i],
172 logDensityTestValues[i],
173 distribution.logProbability(densityTestPoints[i]), tolerance);
174 }
175 }
176
177
178
179
180
181 protected void verifyCumulativeProbabilities() {
182 for (int i = 0; i < cumulativeTestPoints.length; i++) {
183 Assert.assertEquals("Incorrect cumulative probability value returned for " + cumulativeTestPoints[i],
184 cumulativeTestValues[i],
185 distribution.cumulativeProbability(cumulativeTestPoints[i]), getTolerance());
186 }
187 }
188
189
190
191
192
193
194 protected void verifyInverseCumulativeProbabilities() {
195 for (int i = 0; i < inverseCumulativeTestPoints.length; i++) {
196 Assert.assertEquals("Incorrect inverse cumulative probability value returned for "
197 + inverseCumulativeTestPoints[i], inverseCumulativeTestValues[i],
198 distribution.inverseCumulativeProbability(inverseCumulativeTestPoints[i]));
199 }
200 }
201
202
203
204
205
206
207
208 @Test
209 public void testDensities() {
210 verifyDensities();
211 }
212
213
214
215
216
217 @Test
218 public void testLogDensities() {
219 verifyLogDensities();
220 }
221
222
223
224
225
226 @Test
227 public void testCumulativeProbabilities() {
228 verifyCumulativeProbabilities();
229 }
230
231
232
233
234
235 @Test
236 public void testInverseCumulativeProbabilities() {
237 verifyInverseCumulativeProbabilities();
238 }
239
240 @Test
241 public void testConsistencyAtSupportBounds() {
242 final int lower = distribution.getSupportLowerBound();
243 Assert.assertEquals("Cumulative probability must be 0 below support lower bound.",
244 0.0, distribution.cumulativeProbability(lower - 1), 0.0);
245 Assert.assertEquals("Cumulative probability of support lower bound must be equal to probability mass at this point.",
246 distribution.probability(lower), distribution.cumulativeProbability(lower), getTolerance());
247 Assert.assertEquals("Inverse cumulative probability of 0 must be equal to support lower bound.",
248 lower, distribution.inverseCumulativeProbability(0.0));
249
250 final int upper = distribution.getSupportUpperBound();
251 if (upper != Integer.MAX_VALUE) {
252 Assert.assertEquals("Cumulative probability of support upper bound must be equal to 1.",
253 1.0, distribution.cumulativeProbability(upper), 0.0);
254 }
255 Assert.assertEquals("Inverse cumulative probability of 1 must be equal to support upper bound.",
256 upper, distribution.inverseCumulativeProbability(1.0));
257 }
258
259
260
261
262 @Test
263 public void testIllegalArguments() {
264 try {
265 distribution.probability(1, 0);
266 Assert.fail("Expecting MathIllegalArgumentException for bad cumulativeProbability interval");
267 } catch (MathIllegalArgumentException ex) {
268
269 }
270 try {
271 distribution.inverseCumulativeProbability(-1);
272 Assert.fail("Expecting MathIllegalArgumentException for p = -1");
273 } catch (MathIllegalArgumentException ex) {
274
275 }
276 try {
277 distribution.inverseCumulativeProbability(2);
278 Assert.fail("Expecting MathIllegalArgumentException for p = 2");
279 } catch (MathIllegalArgumentException ex) {
280
281 }
282 }
283
284
285
286
287 @Test
288 public void testSampling() {
289 int[] densityPoints = makeDensityTestPoints();
290 double[] densityValues = makeDensityTestValues();
291 int sampleSize = 1000;
292 int length = TestUtils.eliminateZeroMassPoints(densityPoints, densityValues);
293 AbstractIntegerDistribution distribution = (AbstractIntegerDistribution) makeDistribution();
294 double[] expectedCounts = new double[length];
295 long[] observedCounts = new long[length];
296 for (int i = 0; i < length; i++) {
297 expectedCounts[i] = sampleSize * densityValues[i];
298 }
299
300 final DiscreteDistribution.Sampler sampler =
301 distribution.createSampler(RandomSource.WELL_512_A.create(1000));
302 int[] sample = AbstractIntegerDistribution.sample(sampleSize, sampler);
303 for (int i = 0; i < sampleSize; i++) {
304 for (int j = 0; j < length; j++) {
305 if (sample[i] == densityPoints[j]) {
306 observedCounts[j]++;
307 }
308 }
309 }
310 TestUtils.assertChiSquareAccept(densityPoints, expectedCounts, observedCounts, .001);
311 }
312
313
314
315
316
317 protected int[] getCumulativeTestPoints() {
318 return cumulativeTestPoints;
319 }
320
321
322
323
324 protected void setCumulativeTestPoints(int[] cumulativeTestPoints) {
325 this.cumulativeTestPoints = cumulativeTestPoints;
326 }
327
328
329
330
331 protected double[] getCumulativeTestValues() {
332 return cumulativeTestValues;
333 }
334
335
336
337
338 protected void setCumulativeTestValues(double[] cumulativeTestValues) {
339 this.cumulativeTestValues = cumulativeTestValues;
340 }
341
342
343
344
345 protected int[] getDensityTestPoints() {
346 return densityTestPoints;
347 }
348
349
350
351
352 protected void setDensityTestPoints(int[] densityTestPoints) {
353 this.densityTestPoints = densityTestPoints;
354 }
355
356
357
358
359 protected double[] getDensityTestValues() {
360 return densityTestValues;
361 }
362
363
364
365
366 protected void setDensityTestValues(double[] densityTestValues) {
367 this.densityTestValues = densityTestValues;
368 }
369
370
371
372
373 protected DiscreteDistribution getDistribution() {
374 return distribution;
375 }
376
377
378
379
380 protected void setDistribution(DiscreteDistribution distribution) {
381 this.distribution = distribution;
382 }
383
384
385
386
387 protected double[] getInverseCumulativeTestPoints() {
388 return inverseCumulativeTestPoints;
389 }
390
391
392
393
394 protected void setInverseCumulativeTestPoints(double[] inverseCumulativeTestPoints) {
395 this.inverseCumulativeTestPoints = inverseCumulativeTestPoints;
396 }
397
398
399
400
401 protected int[] getInverseCumulativeTestValues() {
402 return inverseCumulativeTestValues;
403 }
404
405
406
407
408 protected void setInverseCumulativeTestValues(int[] inverseCumulativeTestValues) {
409 this.inverseCumulativeTestValues = inverseCumulativeTestValues;
410 }
411
412
413
414
415 protected double getTolerance() {
416 return tolerance;
417 }
418
419
420
421
422 protected void setTolerance(double tolerance) {
423 this.tolerance = tolerance;
424 }
425 }