    1   /*
    2    * Copyright 2004-2005 The Apache Software Foundation.
    3    *
    4    * Licensed under the Apache License, Version 2.0 (the "License");
    5    * you may not use this file except in compliance with the License.
    6    * You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   */
    16  package org.apache.commons.math.distribution;
    17
    18  import org.apache.commons.math.MathException;
    19
    20  /***
    21   * <code>PoissonDistributionTest</code>
    22   *
    23   * @version $Revision: 348888 $ $Date: 2005-11-24 23:21:25 -0700 (Thu, 24 Nov 2005) $
    24   */
    25  public class PoissonDistributionTest extends IntegerDistributionAbstractTest {
    26
    27      /***
    28       * Poisson parameter value for the test distribution.
    29       */
    30      private static final double DEFAULT_TEST_POISSON_PARAMETER = 4.0;
    31
    32      /***
    33       * Constructor.
    34       * @param name
    35       */
    36      public PoissonDistributionTest(String name) {
    37          super(name);
    38          setTolerance(1e-12);
    39      }
    40
    41      /***
    42       * Creates the default discrete distribution instance to use in tests.
    43       */
    44      public IntegerDistribution makeDistribution() {
    45          return DistributionFactory.newInstance().createPoissonDistribution
    46              (DEFAULT_TEST_POISSON_PARAMETER);
    47      }
    48
    49      /***
    50       * Creates the default probability density test input values.
    51       */
    52      public int[] makeDensityTestPoints() {
    53          return new int[] { -1, 0, 1, 2, 3, 4, 5, 10, 20};
    54      }
    55
    56      /***
    57       * Creates the default probability density test expected values.
    58       * These and all other test values are generated by R, version 1.8.1
    59       */
    60      public double[] makeDensityTestValues() {
    61          return new double[] { 0d, 0.0183156388887d,  0.073262555555d,
    62                  0.14652511111d, 0.195366814813d, 0.195366814813,
    63                  0.156293451851d, 0.00529247667642d, 8.27746364655e-09};
    64      }
    65
    66      /***
    67       * Creates the default cumulative probability density test input values.
    68       */
    69      public int[] makeCumulativeTestPoints() {
    70          return new int[] { -1, 0, 1, 2, 3, 4, 5, 10, 20 };
    71      }
    72
    73      /***
    74       * Creates the default cumulative probability density test expected values.
    75       */
    76      public double[] makeCumulativeTestValues() {
    77          return new double[] { 0d,  0.0183156388887d, 0.0915781944437d,
    78                  0.238103305554d, 0.433470120367d, 0.62883693518,
    79                  0.78513038703d,  0.99716023388d, 0.999999998077 };
    80      }
    81
    82      /***
    83       * Creates the default inverse cumulative probability test input values.
    84       * Increased 3rd and 7th values slightly as computed cumulative
    85       * probabilities for corresponding values exceeds the target value (still
    86       * within tolerance).
    87       */
    88      public double[] makeInverseCumulativeTestPoints() {
    89          return new double[] { 0d,  0.018315638889d, 0.0915781944437d,
    90                  0.238103305554d, 0.433470120367d, 0.62883693518,
    91                  0.78513038704d,  0.99716023388d, 0.999999998077 };
    92      }
    93
    94      /***
    95       * Creates the default inverse cumulative probability density test expected values.
    96       */
    97      public int[] makeInverseCumulativeTestValues() {
    98          return new int[] { -1, 0, 1, 2, 3, 4, 5, 10, 20};
    99      }
    100
    101     /***
    102      * Test the normal approximation of the Poisson distribution by
    103      * calculating P(90 &le; X &le; 110) for X = Po(100) and
    104      * P(9900 &le; X &le; 10200) for X  = Po(10000)
    105      */
    106     public void testNormalApproximateProbability() throws Exception {
    107         PoissonDistribution dist = DistributionFactory.newInstance().createPoissonDistribution(100);
    108         double result = dist.normalApproximateProbability(110)
    109                 - dist.normalApproximateProbability(89);
    110         assertEquals(0.706281887248, result, 1E-10);
    111         dist.setMean(10000);
    112         result = dist.normalApproximateProbability(10200)
    113         - dist.normalApproximateProbability(9899);
    114         assertEquals(0.820070051552, result, 1E-10);
    115     }
    116
    117     /***
    118      * Test the degenerate cases of a 0.0 and 1.0 inverse cumulative probability.
    119      * @throws Exception
    120      */
    121     public void testDegenerateInverseCumulativeProbability() throws Exception {
    122         PoissonDistribution dist = DistributionFactory.newInstance().createPoissonDistribution(DEFAULT_TEST_POISSON_PARAMETER);
    123         assertEquals(Integer.MAX_VALUE, dist.inverseCumulativeProbability(1.0d));
    124         assertEquals(-1, dist.inverseCumulativeProbability(0d));
    125     }
    126
    127     public void testMean() {
    128         PoissonDistribution dist = DistributionFactory.newInstance().createPoissonDistribution(DEFAULT_TEST_POISSON_PARAMETER);
    129         try {
    130             dist.setMean(-1);
    131             fail("negative mean.  IllegalArgumentException expected");
    132         } catch(IllegalArgumentException ex) {
    133         }
    134
    135         dist.setMean(10.0);
    136         assertEquals(10.0, dist.getMean(), 0.0);
    137     }
    138
    139     public void testLargeMeanCumulativeProbability() {
    140         PoissonDistribution dist = DistributionFactory.newInstance().createPoissonDistribution(1.0);
    141         double mean = 1.0;
    142         while (mean <= 10000000.0) {
    143             dist.setMean(mean);
    144
    145             double x = mean * 2.0;
    146             double dx = x / 10.0;
    147             while (x >= 0) {
    148                 try {
    149                     dist.cumulativeProbability(x);
    150                 } catch (MathException ex) {
    151                     fail("mean of " + mean + " and x of " + x + " caused " + ex.getMessage());
    152                 }
    153                 x -= dx;
    154             }
    155
    156             mean *= 10.0;
    157         }
    158     }
    159
    160     public void testLargeMeanInverseCumulativeProbability() {
    161         PoissonDistribution dist = DistributionFactory.newInstance().createPoissonDistribution(1.0);
    162         double mean = 1.0;
    163         while (mean <= 10000000.0) {
    164             dist.setMean(mean);
    165
    166             double p = 0.1;
    167             double dp = p;
    168             while (p < 1.0) {
    169                 try {
    170                     dist.inverseCumulativeProbability(p);
    171                 } catch (MathException ex) {
    172                     fail("mean of " + mean + " and p of " + p + " caused " + ex.getMessage());
    173                 }
    174                 p += dp;
    175             }
    176
    177             mean *= 10.0;
    178         }
    179     }
    180 }