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 }