1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.apache.commons.math.distribution;
18
19 import junit.framework.TestCase;
20
21 /**
22 * Abstract base class for {@link IntegerDistribution} tests.
23 * <p>
24 * To create a concrete test class for an integer distribution implementation,
25 * implement makeDistribution() to return a distribution instance to use in
26 * tests and each of the test data generation methods below. In each case, the
27 * test points and test values arrays returned represent parallel arrays of
28 * inputs and expected values for the distribution returned by makeDistribution().
29 * <p>
30 * makeDensityTestPoints() -- arguments used to test probability density calculation
31 * makeDensityTestValues() -- expected probability densities
32 * makeCumulativeTestPoints() -- arguments used to test cumulative probabilities
33 * makeCumulativeTestValues() -- expected cumulative probabilites
34 * makeInverseCumulativeTestPoints() -- arguments used to test inverse cdf evaluation
35 * makeInverseCumulativeTestValues() -- expected inverse cdf values
36 * <p>
37 * To implement additional test cases with different distribution instances and test data,
38 * use the setXxx methods for the instance data in test cases and call the verifyXxx methods
39 * to verify results.
40 *
41 * @version $Revision: 620368 $ $Date: 2008-02-10 18:04:48 -0700 (Sun, 10 Feb 2008) $
42 */
43 public abstract class IntegerDistributionAbstractTest extends TestCase {
44
45 //-------------------- Private test instance data -------------------------
46 /** Discrete distribution instance used to perform tests */
47 private IntegerDistribution distribution;
48
49 /** Tolerance used in comparing expected and returned values */
50 private double tolerance = 1E-4;
51
52 /** Arguments used to test probability density calculations */
53 private int[] densityTestPoints;
54
55 /** Values used to test probability density calculations */
56 private double[] densityTestValues;
57
58 /** Arguments used to test cumulative probability density calculations */
59 private int[] cumulativeTestPoints;
60
61 /** Values used to test cumulative probability density calculations */
62 private double[] cumulativeTestValues;
63
64 /** Arguments used to test inverse cumulative probability density calculations */
65 private double[] inverseCumulativeTestPoints;
66
67 /** Values used to test inverse cumulative probability density calculations */
68 private int[] inverseCumulativeTestValues;
69
70 //-------------------------------------------------------------------------
71
72 /**
73 * Constructor for IntegerDistributionAbstractTest.
74 * @param name
75 */
76 public IntegerDistributionAbstractTest(String name) {
77 super(name);
78 }
79
80 //-------------------- Abstract methods -----------------------------------
81
82 /** Creates the default discrete distribution instance to use in tests. */
83 public abstract IntegerDistribution makeDistribution();
84
85 /** Creates the default probability density test input values */
86 public abstract int[] makeDensityTestPoints();
87
88 /** Creates the default probability density test expected values */
89 public abstract double[] makeDensityTestValues();
90
91 /** Creates the default cumulative probability density test input values */
92 public abstract int[] makeCumulativeTestPoints();
93
94 /** Creates the default cumulative probability density test expected values */
95 public abstract double[] makeCumulativeTestValues();
96
97 /** Creates the default inverse cumulative probability test input values */
98 public abstract double[] makeInverseCumulativeTestPoints();
99
100 /** Creates the default inverse cumulative probability density test expected values */
101 public abstract int[] makeInverseCumulativeTestValues();
102
103 //-------------------- Setup / tear down ----------------------------------
104
105 /**
106 * Setup sets all test instance data to default values
107 */
108 protected void setUp() throws Exception {
109 super.setUp();
110 distribution = makeDistribution();
111 densityTestPoints = makeDensityTestPoints();
112 densityTestValues = makeDensityTestValues();
113 cumulativeTestPoints = makeCumulativeTestPoints();
114 cumulativeTestValues = makeCumulativeTestValues();
115 inverseCumulativeTestPoints = makeInverseCumulativeTestPoints();
116 inverseCumulativeTestValues = makeInverseCumulativeTestValues();
117 }
118
119 /**
120 * Cleans up test instance data
121 */
122 protected void tearDown() throws Exception {
123 super.tearDown();
124 distribution = null;
125 densityTestPoints = null;
126 densityTestValues = null;
127 cumulativeTestPoints = null;
128 cumulativeTestValues = null;
129 inverseCumulativeTestPoints = null;
130 inverseCumulativeTestValues = null;
131 }
132
133 //-------------------- Verification methods -------------------------------
134
135 /**
136 * Verifies that probability density calculations match expected values
137 * using current test instance data
138 */
139 protected void verifyDensities() throws Exception {
140 for (int i = 0; i < densityTestPoints.length; i++) {
141 assertEquals("Incorrect density value returned for " + densityTestPoints[i],
142 densityTestValues[i],
143 distribution.probability(densityTestPoints[i]), tolerance);
144 }
145 }
146
147 /**
148 * Verifies that cumulative probability density calculations match expected values
149 * using current test instance data
150 */
151 protected void verifyCumulativeProbabilities() throws Exception {
152 for (int i = 0; i < cumulativeTestPoints.length; i++) {
153 assertEquals("Incorrect cumulative probability value returned for " + cumulativeTestPoints[i],
154 cumulativeTestValues[i],
155 distribution.cumulativeProbability(cumulativeTestPoints[i]), tolerance);
156 }
157 }
158
159
160 /**
161 * Verifies that inverse cumulative probability density calculations match expected values
162 * using current test instance data
163 */
164 protected void verifyInverseCumulativeProbabilities() throws Exception {
165 for (int i = 0; i < inverseCumulativeTestPoints.length; i++) {
166 assertEquals("Incorrect inverse cumulative probability value returned for "
167 + inverseCumulativeTestPoints[i], inverseCumulativeTestValues[i],
168 distribution.inverseCumulativeProbability(inverseCumulativeTestPoints[i]));
169 }
170 }
171
172 //------------------------ Default test cases -----------------------------
173
174 /**
175 * Verifies that probability density calculations match expected values
176 * using default test instance data
177 */
178 public void testDensities() throws Exception {
179 verifyDensities();
180 }
181
182 /**
183 * Verifies that cumulative probability density calculations match expected values
184 * using default test instance data
185 */
186 public void testCumulativeProbabilities() throws Exception {
187 verifyCumulativeProbabilities();
188 }
189
190 /**
191 * Verifies that floating point arguments are correctly handled by
192 * cumulativeProbablility(-,-)
193 * JIRA: MATH-184
194 */
195 public void testFloatingPointArguments() throws Exception {
196 for (int i = 0; i < cumulativeTestPoints.length; i++) {
197 double arg = (double) cumulativeTestPoints[i];
198 assertEquals(
199 "Incorrect cumulative probability value returned for " +
200 cumulativeTestPoints[i],
201 cumulativeTestValues[i],
202 distribution.cumulativeProbability(arg), tolerance);
203 if (i < cumulativeTestPoints.length - 1) {
204 double arg2 = (double) cumulativeTestPoints[i + 1];
205 assertEquals("Inconsistent probability for discrete range " +
206 "[ " + arg + "," + arg2 + " ]",
207 distribution.cumulativeProbability(
208 cumulativeTestPoints[i],
209 cumulativeTestPoints[i + 1]),
210 distribution.cumulativeProbability(arg, arg2), tolerance);
211 arg = arg - Math.random();
212 arg2 = arg2 + Math.random();
213 assertEquals("Inconsistent probability for discrete range " +
214 "[ " + arg + "," + arg2 + " ]",
215 distribution.cumulativeProbability(
216 cumulativeTestPoints[i],
217 cumulativeTestPoints[i + 1]),
218 distribution.cumulativeProbability(arg, arg2), tolerance);
219 }
220 }
221 int one = 1;
222 int ten = 10;
223 int two = 2;
224 double oned = (double) one;
225 double twod = (double) two;
226 double tend = (double) ten;
227 assertEquals(distribution.cumulativeProbability(one, two),
228 distribution.cumulativeProbability(oned, twod), tolerance);
229 assertEquals(distribution.cumulativeProbability(one, two),
230 distribution.cumulativeProbability(oned - tolerance,
231 twod + 0.9), tolerance);
232 assertEquals(distribution.cumulativeProbability(two, ten),
233 distribution.cumulativeProbability(twod, tend), tolerance);
234 assertEquals(distribution.cumulativeProbability(two, ten),
235 distribution.cumulativeProbability(twod - tolerance,
236 tend + 0.9), tolerance);
237 }
238
239 /**
240 * Verifies that inverse cumulative probability density calculations match expected values
241 * using default test instance data
242 */
243 public void testInverseCumulativeProbabilities() throws Exception {
244 verifyInverseCumulativeProbabilities();
245 }
246
247 /**
248 * Verifies that illegal arguments are correctly handled
249 */
250 public void testIllegalArguments() throws Exception {
251 try {
252 distribution.cumulativeProbability(1, 0);
253 fail("Expecting IllegalArgumentException for bad cumulativeProbability interval");
254 } catch (IllegalArgumentException ex) {
255 // expected
256 }
257 try {
258 distribution.inverseCumulativeProbability(-1);
259 fail("Expecting IllegalArgumentException for p = -1");
260 } catch (IllegalArgumentException ex) {
261 // expected
262 }
263 try {
264 distribution.inverseCumulativeProbability(2);
265 fail("Expecting IllegalArgumentException for p = 2");
266 } catch (IllegalArgumentException ex) {
267 // expected
268 }
269 }
270
271 //------------------ Getters / Setters for test instance data -----------
272 /**
273 * @return Returns the cumulativeTestPoints.
274 */
275 protected int[] getCumulativeTestPoints() {
276 return cumulativeTestPoints;
277 }
278
279 /**
280 * @param cumulativeTestPoints The cumulativeTestPoints to set.
281 */
282 protected void setCumulativeTestPoints(int[] cumulativeTestPoints) {
283 this.cumulativeTestPoints = cumulativeTestPoints;
284 }
285
286 /**
287 * @return Returns the cumulativeTestValues.
288 */
289 protected double[] getCumulativeTestValues() {
290 return cumulativeTestValues;
291 }
292
293 /**
294 * @param cumulativeTestValues The cumulativeTestValues to set.
295 */
296 protected void setCumulativeTestValues(double[] cumulativeTestValues) {
297 this.cumulativeTestValues = cumulativeTestValues;
298 }
299
300 /**
301 * @return Returns the densityTestPoints.
302 */
303 protected int[] getDensityTestPoints() {
304 return densityTestPoints;
305 }
306
307 /**
308 * @param densityTestPoints The densityTestPoints to set.
309 */
310 protected void setDensityTestPoints(int[] densityTestPoints) {
311 this.densityTestPoints = densityTestPoints;
312 }
313
314 /**
315 * @return Returns the densityTestValues.
316 */
317 protected double[] getDensityTestValues() {
318 return densityTestValues;
319 }
320
321 /**
322 * @param densityTestValues The densityTestValues to set.
323 */
324 protected void setDensityTestValues(double[] densityTestValues) {
325 this.densityTestValues = densityTestValues;
326 }
327
328 /**
329 * @return Returns the distribution.
330 */
331 protected IntegerDistribution getDistribution() {
332 return distribution;
333 }
334
335 /**
336 * @param distribution The distribution to set.
337 */
338 protected void setDistribution(IntegerDistribution distribution) {
339 this.distribution = distribution;
340 }
341
342 /**
343 * @return Returns the inverseCumulativeTestPoints.
344 */
345 protected double[] getInverseCumulativeTestPoints() {
346 return inverseCumulativeTestPoints;
347 }
348
349 /**
350 * @param inverseCumulativeTestPoints The inverseCumulativeTestPoints to set.
351 */
352 protected void setInverseCumulativeTestPoints(double[] inverseCumulativeTestPoints) {
353 this.inverseCumulativeTestPoints = inverseCumulativeTestPoints;
354 }
355
356 /**
357 * @return Returns the inverseCumulativeTestValues.
358 */
359 protected int[] getInverseCumulativeTestValues() {
360 return inverseCumulativeTestValues;
361 }
362
363 /**
364 * @param inverseCumulativeTestValues The inverseCumulativeTestValues to set.
365 */
366 protected void setInverseCumulativeTestValues(int[] inverseCumulativeTestValues) {
367 this.inverseCumulativeTestValues = inverseCumulativeTestValues;
368 }
369
370 /**
371 * @return Returns the tolerance.
372 */
373 protected double getTolerance() {
374 return tolerance;
375 }
376
377 /**
378 * @param tolerance The tolerance to set.
379 */
380 protected void setTolerance(double tolerance) {
381 this.tolerance = tolerance;
382 }
383
384 }