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 }