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: 762118 $ $Date: 2009-04-05 12:55:59 -0400 (Sun, 05 Apr 2009) $
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 @Override
109 protected void setUp() throws Exception {
110 super.setUp();
111 distribution = makeDistribution();
112 densityTestPoints = makeDensityTestPoints();
113 densityTestValues = makeDensityTestValues();
114 cumulativeTestPoints = makeCumulativeTestPoints();
115 cumulativeTestValues = makeCumulativeTestValues();
116 inverseCumulativeTestPoints = makeInverseCumulativeTestPoints();
117 inverseCumulativeTestValues = makeInverseCumulativeTestValues();
118 }
119
120 /**
121 * Cleans up test instance data
122 */
123 @Override
124 protected void tearDown() throws Exception {
125 super.tearDown();
126 distribution = null;
127 densityTestPoints = null;
128 densityTestValues = null;
129 cumulativeTestPoints = null;
130 cumulativeTestValues = null;
131 inverseCumulativeTestPoints = null;
132 inverseCumulativeTestValues = null;
133 }
134
135 //-------------------- Verification methods -------------------------------
136
137 /**
138 * Verifies that probability density calculations match expected values
139 * using current test instance data
140 */
141 protected void verifyDensities() throws Exception {
142 for (int i = 0; i < densityTestPoints.length; i++) {
143 assertEquals("Incorrect density value returned for " + densityTestPoints[i],
144 densityTestValues[i],
145 distribution.probability(densityTestPoints[i]), tolerance);
146 }
147 }
148
149 /**
150 * Verifies that cumulative probability density calculations match expected values
151 * using current test instance data
152 */
153 protected void verifyCumulativeProbabilities() throws Exception {
154 for (int i = 0; i < cumulativeTestPoints.length; i++) {
155 assertEquals("Incorrect cumulative probability value returned for " + cumulativeTestPoints[i],
156 cumulativeTestValues[i],
157 distribution.cumulativeProbability(cumulativeTestPoints[i]), tolerance);
158 }
159 }
160
161
162 /**
163 * Verifies that inverse cumulative probability density calculations match expected values
164 * using current test instance data
165 */
166 protected void verifyInverseCumulativeProbabilities() throws Exception {
167 for (int i = 0; i < inverseCumulativeTestPoints.length; i++) {
168 assertEquals("Incorrect inverse cumulative probability value returned for "
169 + inverseCumulativeTestPoints[i], inverseCumulativeTestValues[i],
170 distribution.inverseCumulativeProbability(inverseCumulativeTestPoints[i]));
171 }
172 }
173
174 //------------------------ Default test cases -----------------------------
175
176 /**
177 * Verifies that probability density calculations match expected values
178 * using default test instance data
179 */
180 public void testDensities() throws Exception {
181 verifyDensities();
182 }
183
184 /**
185 * Verifies that cumulative probability density calculations match expected values
186 * using default test instance data
187 */
188 public void testCumulativeProbabilities() throws Exception {
189 verifyCumulativeProbabilities();
190 }
191
192 /**
193 * Verifies that floating point arguments are correctly handled by
194 * cumulativeProbablility(-,-)
195 * JIRA: MATH-184
196 */
197 public void testFloatingPointArguments() throws Exception {
198 for (int i = 0; i < cumulativeTestPoints.length; i++) {
199 double arg = cumulativeTestPoints[i];
200 assertEquals(
201 "Incorrect cumulative probability value returned for " +
202 cumulativeTestPoints[i],
203 cumulativeTestValues[i],
204 distribution.cumulativeProbability(arg), tolerance);
205 if (i < cumulativeTestPoints.length - 1) {
206 double arg2 = cumulativeTestPoints[i + 1];
207 assertEquals("Inconsistent probability for discrete range " +
208 "[ " + arg + "," + arg2 + " ]",
209 distribution.cumulativeProbability(
210 cumulativeTestPoints[i],
211 cumulativeTestPoints[i + 1]),
212 distribution.cumulativeProbability(arg, arg2), tolerance);
213 arg = arg - Math.random();
214 arg2 = arg2 + Math.random();
215 assertEquals("Inconsistent probability for discrete range " +
216 "[ " + arg + "," + arg2 + " ]",
217 distribution.cumulativeProbability(
218 cumulativeTestPoints[i],
219 cumulativeTestPoints[i + 1]),
220 distribution.cumulativeProbability(arg, arg2), tolerance);
221 }
222 }
223 int one = 1;
224 int ten = 10;
225 int two = 2;
226 double oned = one;
227 double twod = two;
228 double tend = ten;
229 assertEquals(distribution.cumulativeProbability(one, two),
230 distribution.cumulativeProbability(oned, twod), tolerance);
231 assertEquals(distribution.cumulativeProbability(one, two),
232 distribution.cumulativeProbability(oned - tolerance,
233 twod + 0.9), tolerance);
234 assertEquals(distribution.cumulativeProbability(two, ten),
235 distribution.cumulativeProbability(twod, tend), tolerance);
236 assertEquals(distribution.cumulativeProbability(two, ten),
237 distribution.cumulativeProbability(twod - tolerance,
238 tend + 0.9), tolerance);
239 }
240
241 /**
242 * Verifies that inverse cumulative probability density calculations match expected values
243 * using default test instance data
244 */
245 public void testInverseCumulativeProbabilities() throws Exception {
246 verifyInverseCumulativeProbabilities();
247 }
248
249 /**
250 * Verifies that illegal arguments are correctly handled
251 */
252 public void testIllegalArguments() throws Exception {
253 try {
254 distribution.cumulativeProbability(1, 0);
255 fail("Expecting IllegalArgumentException for bad cumulativeProbability interval");
256 } catch (IllegalArgumentException ex) {
257 // expected
258 }
259 try {
260 distribution.inverseCumulativeProbability(-1);
261 fail("Expecting IllegalArgumentException for p = -1");
262 } catch (IllegalArgumentException ex) {
263 // expected
264 }
265 try {
266 distribution.inverseCumulativeProbability(2);
267 fail("Expecting IllegalArgumentException for p = 2");
268 } catch (IllegalArgumentException ex) {
269 // expected
270 }
271 }
272
273 //------------------ Getters / Setters for test instance data -----------
274 /**
275 * @return Returns the cumulativeTestPoints.
276 */
277 protected int[] getCumulativeTestPoints() {
278 return cumulativeTestPoints;
279 }
280
281 /**
282 * @param cumulativeTestPoints The cumulativeTestPoints to set.
283 */
284 protected void setCumulativeTestPoints(int[] cumulativeTestPoints) {
285 this.cumulativeTestPoints = cumulativeTestPoints;
286 }
287
288 /**
289 * @return Returns the cumulativeTestValues.
290 */
291 protected double[] getCumulativeTestValues() {
292 return cumulativeTestValues;
293 }
294
295 /**
296 * @param cumulativeTestValues The cumulativeTestValues to set.
297 */
298 protected void setCumulativeTestValues(double[] cumulativeTestValues) {
299 this.cumulativeTestValues = cumulativeTestValues;
300 }
301
302 /**
303 * @return Returns the densityTestPoints.
304 */
305 protected int[] getDensityTestPoints() {
306 return densityTestPoints;
307 }
308
309 /**
310 * @param densityTestPoints The densityTestPoints to set.
311 */
312 protected void setDensityTestPoints(int[] densityTestPoints) {
313 this.densityTestPoints = densityTestPoints;
314 }
315
316 /**
317 * @return Returns the densityTestValues.
318 */
319 protected double[] getDensityTestValues() {
320 return densityTestValues;
321 }
322
323 /**
324 * @param densityTestValues The densityTestValues to set.
325 */
326 protected void setDensityTestValues(double[] densityTestValues) {
327 this.densityTestValues = densityTestValues;
328 }
329
330 /**
331 * @return Returns the distribution.
332 */
333 protected IntegerDistribution getDistribution() {
334 return distribution;
335 }
336
337 /**
338 * @param distribution The distribution to set.
339 */
340 protected void setDistribution(IntegerDistribution distribution) {
341 this.distribution = distribution;
342 }
343
344 /**
345 * @return Returns the inverseCumulativeTestPoints.
346 */
347 protected double[] getInverseCumulativeTestPoints() {
348 return inverseCumulativeTestPoints;
349 }
350
351 /**
352 * @param inverseCumulativeTestPoints The inverseCumulativeTestPoints to set.
353 */
354 protected void setInverseCumulativeTestPoints(double[] inverseCumulativeTestPoints) {
355 this.inverseCumulativeTestPoints = inverseCumulativeTestPoints;
356 }
357
358 /**
359 * @return Returns the inverseCumulativeTestValues.
360 */
361 protected int[] getInverseCumulativeTestValues() {
362 return inverseCumulativeTestValues;
363 }
364
365 /**
366 * @param inverseCumulativeTestValues The inverseCumulativeTestValues to set.
367 */
368 protected void setInverseCumulativeTestValues(int[] inverseCumulativeTestValues) {
369 this.inverseCumulativeTestValues = inverseCumulativeTestValues;
370 }
371
372 /**
373 * @return Returns the tolerance.
374 */
375 protected double getTolerance() {
376 return tolerance;
377 }
378
379 /**
380 * @param tolerance The tolerance to set.
381 */
382 protected void setTolerance(double tolerance) {
383 this.tolerance = tolerance;
384 }
385
386 }