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 org.apache.commons.math.MathException;
020
021 /**
022 * <code>PoissonDistributionTest</code>
023 *
024 * @version $Revision: 762087 $ $Date: 2009-04-05 10:20:18 -0400 (Sun, 05 Apr 2009) $
025 */
026 public class PoissonDistributionTest extends IntegerDistributionAbstractTest {
027
028 /**
029 * Poisson parameter value for the test distribution.
030 */
031 private static final double DEFAULT_TEST_POISSON_PARAMETER = 4.0;
032
033 /**
034 * Constructor.
035 * @param name
036 */
037 public PoissonDistributionTest(String name) {
038 super(name);
039 setTolerance(1e-12);
040 }
041
042 /**
043 * Creates the default discrete distribution instance to use in tests.
044 */
045 @Override
046 public IntegerDistribution makeDistribution() {
047 return new PoissonDistributionImpl(DEFAULT_TEST_POISSON_PARAMETER);
048 }
049
050 /**
051 * Creates the default probability density test input values.
052 */
053 @Override
054 public int[] makeDensityTestPoints() {
055 return new int[] { -1, 0, 1, 2, 3, 4, 5, 10, 20};
056 }
057
058 /**
059 * Creates the default probability density test expected values.
060 * These and all other test values are generated by R, version 1.8.1
061 */
062 @Override
063 public double[] makeDensityTestValues() {
064 return new double[] { 0d, 0.0183156388887d, 0.073262555555d,
065 0.14652511111d, 0.195366814813d, 0.195366814813,
066 0.156293451851d, 0.00529247667642d, 8.27746364655e-09};
067 }
068
069 /**
070 * Creates the default cumulative probability density test input values.
071 */
072 @Override
073 public int[] makeCumulativeTestPoints() {
074 return new int[] { -1, 0, 1, 2, 3, 4, 5, 10, 20 };
075 }
076
077 /**
078 * Creates the default cumulative probability density test expected values.
079 */
080 @Override
081 public double[] makeCumulativeTestValues() {
082 return new double[] { 0d, 0.0183156388887d, 0.0915781944437d,
083 0.238103305554d, 0.433470120367d, 0.62883693518,
084 0.78513038703d, 0.99716023388d, 0.999999998077 };
085 }
086
087 /**
088 * Creates the default inverse cumulative probability test input values.
089 * Increased 3rd and 7th values slightly as computed cumulative
090 * probabilities for corresponding values exceeds the target value (still
091 * within tolerance).
092 */
093 @Override
094 public double[] makeInverseCumulativeTestPoints() {
095 return new double[] { 0d, 0.018315638889d, 0.0915781944437d,
096 0.238103305554d, 0.433470120367d, 0.62883693518,
097 0.78513038704d, 0.99716023388d, 0.999999998077 };
098 }
099
100 /**
101 * Creates the default inverse cumulative probability density test expected values.
102 */
103 @Override
104 public int[] makeInverseCumulativeTestValues() {
105 return new int[] { -1, 0, 1, 2, 3, 4, 5, 10, 20};
106 }
107
108 /**
109 * Test the normal approximation of the Poisson distribution by
110 * calculating P(90 ≤ X ≤ 110) for X = Po(100) and
111 * P(9900 ≤ X ≤ 10200) for X = Po(10000)
112 */
113 public void testNormalApproximateProbability() throws Exception {
114 PoissonDistribution dist = new PoissonDistributionImpl(100);
115 double result = dist.normalApproximateProbability(110)
116 - dist.normalApproximateProbability(89);
117 assertEquals(0.706281887248, result, 1E-10);
118 dist.setMean(10000);
119 result = dist.normalApproximateProbability(10200)
120 - dist.normalApproximateProbability(9899);
121 assertEquals(0.820070051552, result, 1E-10);
122 }
123
124 /**
125 * Test the degenerate cases of a 0.0 and 1.0 inverse cumulative probability.
126 * @throws Exception
127 */
128 public void testDegenerateInverseCumulativeProbability() throws Exception {
129 PoissonDistribution dist = new PoissonDistributionImpl(DEFAULT_TEST_POISSON_PARAMETER);
130 assertEquals(Integer.MAX_VALUE, dist.inverseCumulativeProbability(1.0d));
131 assertEquals(-1, dist.inverseCumulativeProbability(0d));
132 }
133
134 public void testMean() {
135 PoissonDistribution dist = new PoissonDistributionImpl(DEFAULT_TEST_POISSON_PARAMETER);
136 try {
137 dist.setMean(-1);
138 fail("negative mean. IllegalArgumentException expected");
139 } catch(IllegalArgumentException ex) {
140 }
141
142 dist.setMean(10.0);
143 assertEquals(10.0, dist.getMean(), 0.0);
144 }
145
146 public void testLargeMeanCumulativeProbability() {
147 PoissonDistribution dist = new PoissonDistributionImpl(1.0);
148 double mean = 1.0;
149 while (mean <= 10000000.0) {
150 dist.setMean(mean);
151
152 double x = mean * 2.0;
153 double dx = x / 10.0;
154 while (x >= 0) {
155 try {
156 dist.cumulativeProbability(x);
157 } catch (MathException ex) {
158 fail("mean of " + mean + " and x of " + x + " caused " + ex.getMessage());
159 }
160 x -= dx;
161 }
162
163 mean *= 10.0;
164 }
165 }
166
167 public void testLargeMeanInverseCumulativeProbability() {
168 PoissonDistribution dist = new PoissonDistributionImpl(1.0);
169 double mean = 1.0;
170 while (mean <= 10000000.0) {
171 dist.setMean(mean);
172
173 double p = 0.1;
174 double dp = p;
175 while (p < 1.0) {
176 try {
177 dist.inverseCumulativeProbability(p);
178 } catch (MathException ex) {
179 fail("mean of " + mean + " and p of " + p + " caused " + ex.getMessage());
180 }
181 p += dp;
182 }
183
184 mean *= 10.0;
185 }
186 }
187 }