001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.commons.math.distribution; 018 019 import junit.framework.TestCase; 020 021 /** 022 * Abstract base class for {@link IntegerDistribution} tests. 023 * <p> 024 * To create a concrete test class for an integer distribution implementation, 025 * implement makeDistribution() to return a distribution instance to use in 026 * tests and each of the test data generation methods below. In each case, the 027 * test points and test values arrays returned represent parallel arrays of 028 * inputs and expected values for the distribution returned by makeDistribution(). 029 * <p> 030 * makeDensityTestPoints() -- arguments used to test probability density calculation 031 * makeDensityTestValues() -- expected probability densities 032 * makeCumulativeTestPoints() -- arguments used to test cumulative probabilities 033 * makeCumulativeTestValues() -- expected cumulative probabilites 034 * makeInverseCumulativeTestPoints() -- arguments used to test inverse cdf evaluation 035 * makeInverseCumulativeTestValues() -- expected inverse cdf values 036 * <p> 037 * To implement additional test cases with different distribution instances and test data, 038 * use the setXxx methods for the instance data in test cases and call the verifyXxx methods 039 * to verify results. 040 * 041 * @version $Revision: 762118 $ $Date: 2009-04-05 12:55:59 -0400 (Sun, 05 Apr 2009) $ 042 */ 043 public abstract class IntegerDistributionAbstractTest extends TestCase { 044 045 //-------------------- Private test instance data ------------------------- 046 /** Discrete distribution instance used to perform tests */ 047 private IntegerDistribution distribution; 048 049 /** Tolerance used in comparing expected and returned values */ 050 private double tolerance = 1E-4; 051 052 /** Arguments used to test probability density calculations */ 053 private int[] densityTestPoints; 054 055 /** Values used to test probability density calculations */ 056 private double[] densityTestValues; 057 058 /** Arguments used to test cumulative probability density calculations */ 059 private int[] cumulativeTestPoints; 060 061 /** Values used to test cumulative probability density calculations */ 062 private double[] cumulativeTestValues; 063 064 /** Arguments used to test inverse cumulative probability density calculations */ 065 private double[] inverseCumulativeTestPoints; 066 067 /** Values used to test inverse cumulative probability density calculations */ 068 private int[] inverseCumulativeTestValues; 069 070 //------------------------------------------------------------------------- 071 072 /** 073 * Constructor for IntegerDistributionAbstractTest. 074 * @param name 075 */ 076 public IntegerDistributionAbstractTest(String name) { 077 super(name); 078 } 079 080 //-------------------- Abstract methods ----------------------------------- 081 082 /** Creates the default discrete distribution instance to use in tests. */ 083 public abstract IntegerDistribution makeDistribution(); 084 085 /** Creates the default probability density test input values */ 086 public abstract int[] makeDensityTestPoints(); 087 088 /** Creates the default probability density test expected values */ 089 public abstract double[] makeDensityTestValues(); 090 091 /** Creates the default cumulative probability density test input values */ 092 public abstract int[] makeCumulativeTestPoints(); 093 094 /** Creates the default cumulative probability density test expected values */ 095 public abstract double[] makeCumulativeTestValues(); 096 097 /** Creates the default inverse cumulative probability test input values */ 098 public abstract double[] makeInverseCumulativeTestPoints(); 099 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 }