KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > math > distribution > HypergeometricDistributionImpl


1 /*
2  * Copyright 2003-2004 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
17 package org.apache.commons.math.distribution;
18
19 import java.io.Serializable JavaDoc;
20
21 import org.apache.commons.math.MathException;
22 import org.apache.commons.math.util.MathUtils;
23
24 /**
25  * The default implementation of {@link HypergeometricDistribution}.
26  *
27  * @version $Revision$ $Date: 2005-02-26 05:11:52 -0800 (Sat, 26 Feb 2005) $
28  */

29 public class HypergeometricDistributionImpl extends AbstractIntegerDistribution
30     implements HypergeometricDistribution, Serializable JavaDoc
31 {
32
33     /** Serializable version identifier */
34     static final long serialVersionUID = -436928820673516179L;
35
36     /** The number of successes in the population. */
37     private int numberOfSuccesses;
38     
39     /** The population size. */
40     private int populationSize;
41     
42     /** The sample size. */
43     private int sampleSize;
44     
45     /**
46      * Construct a new hypergeometric distribution with the given the population
47      * size, the number of successes in the population, and the sample size.
48      * @param populationSize the population size.
49      * @param numberOfSuccesses number of successes in the population.
50      * @param sampleSize the sample size.
51      */

52     public HypergeometricDistributionImpl(int populationSize,
53         int numberOfSuccesses, int sampleSize) {
54         super();
55         if (numberOfSuccesses > populationSize) {
56             throw new IllegalArgumentException JavaDoc(
57             "number of successes must be less than or equal to population size");
58         }
59         if (sampleSize > populationSize) {
60             throw new IllegalArgumentException JavaDoc(
61             "sample size must be less than or equal to population size");
62         }
63         setPopulationSize(populationSize);
64         setSampleSize(sampleSize);
65         setNumberOfSuccesses(numberOfSuccesses);
66     }
67
68     /**
69      * For this disbution, X, this method returns P(X ≤ x).
70      * @param x the value at which the PDF is evaluated.
71      * @return PDF for this distribution.
72      * @throws MathException if the cumulative probability can not be
73      * computed due to convergence or other numerical errors.
74      */

75     public double cumulativeProbability(int x) throws MathException{
76         double ret;
77         
78         int n = getPopulationSize();
79         int m = getNumberOfSuccesses();
80         int k = getSampleSize();
81
82         int[] domain = getDomain(n, m, k);
83         if (x < domain[0]) {
84             ret = 0.0;
85         } else if(x >= domain[1]) {
86             ret = 1.0;
87         } else {
88             ret = 0.0;
89             for (int i = domain[0]; i <= x; ++i){
90                 ret += probability(n, m, k, i);
91             }
92         }
93         
94         return ret;
95     }
96
97     /**
98      * Return the domain for the given hypergeometric distribution parameters.
99      * @param n the population size.
100      * @param m number of successes in the population.
101      * @param k the sample size.
102      * @return a two element array containing the lower and upper bounds of the
103      * hypergeometric distribution.
104      */

105     private int[] getDomain(int n, int m, int k){
106         return new int[]{
107             getLowerDomain(n, m, k),
108             getUpperDomain(m, k)
109         };
110     }
111     
112     /**
113      * Access the domain value lower bound, based on <code>p</code>, used to
114      * bracket a PDF root.
115      *
116      * @param p the desired probability for the critical value
117      * @return domain value lower bound, i.e.
118      * P(X &lt; <i>lower bound</i>) &lt; <code>p</code>
119      */

120     protected int getDomainLowerBound(double p) {
121         return getLowerDomain(getPopulationSize(), getNumberOfSuccesses(),
122             getSampleSize());
123     }
124     
125     /**
126      * Access the domain value upper bound, based on <code>p</code>, used to
127      * bracket a PDF root.
128      *
129      * @param p the desired probability for the critical value
130      * @return domain value upper bound, i.e.
131      * P(X &lt; <i>upper bound</i>) &gt; <code>p</code>
132      */

133     protected int getDomainUpperBound(double p) {
134         return getUpperDomain(getSampleSize(), getNumberOfSuccesses());
135     }
136
137     /**
138      * Return the lowest domain value for the given hypergeometric distribution
139      * parameters.
140      * @param n the population size.
141      * @param m number of successes in the population.
142      * @param k the sample size.
143      * @return the lowest domain value of the hypergeometric distribution.
144      */

145     private int getLowerDomain(int n, int m, int k) {
146         return Math.max(0, m - (n - k));
147     }
148
149     /**
150      * Access the number of successes.
151      * @return the number of successes.
152      */

153     public int getNumberOfSuccesses() {
154         return numberOfSuccesses;
155     }
156
157     /**
158      * Access the population size.
159      * @return the population size.
160      */

161     public int getPopulationSize() {
162         return populationSize;
163     }
164
165     /**
166      * Access the sample size.
167      * @return the sample size.
168      */

169     public int getSampleSize() {
170         return sampleSize;
171     }
172
173     /**
174      * Return the highest domain value for the given hypergeometric distribution
175      * parameters.
176      * @param m number of successes in the population.
177      * @param k the sample size.
178      * @return the highest domain value of the hypergeometric distribution.
179      */

180     private int getUpperDomain(int m, int k){
181         return Math.min(k, m);
182     }
183
184     /**
185      * For this disbution, X, this method returns P(X = x).
186      *
187      * @param x the value at which the PMF is evaluated.
188      * @return PMF for this distribution.
189      */

190     public double probability(int x) {
191         double ret;
192         
193         int n = getPopulationSize();
194         int m = getNumberOfSuccesses();
195         int k = getSampleSize();
196
197         int[] domain = getDomain(n, m, k);
198         if(x < domain[0] || x > domain[1]){
199             ret = 0.0;
200         } else {
201             ret = probability(n, m, k, x);
202         }
203         
204         return ret;
205     }
206
207     /**
208      * For the disbution, X, defined by the given hypergeometric distribution
209      * parameters, this method returns P(X = x).
210      *
211      * @param n the population size.
212      * @param m number of successes in the population.
213      * @param k the sample size.
214      * @param x the value at which the PMF is evaluated.
215      * @return PMF for the distribution.
216      */

217     private double probability(int n, int m, int k, int x) {
218         return Math.exp(MathUtils.binomialCoefficientLog(m, x) +
219             MathUtils.binomialCoefficientLog(n - m, k - x) -
220             MathUtils.binomialCoefficientLog(n, k));
221     }
222     
223     /**
224      * Modify the number of successes.
225      * @param num the new number of successes.
226      * @throws IllegalArgumentException if <code>num</code> is negative.
227      */

228     public void setNumberOfSuccesses(int num) {
229         if(num < 0){
230             throw new IllegalArgumentException JavaDoc(
231                 "number of successes must be non-negative.");
232         }
233         numberOfSuccesses = num;
234     }
235
236     /**
237      * Modify the population size.
238      * @param size the new population size.
239      * @throws IllegalArgumentException if <code>size</code> is not positive.
240      */

241     public void setPopulationSize(int size) {
242         if(size <= 0){
243             throw new IllegalArgumentException JavaDoc(
244                 "population size must be positive.");
245         }
246         populationSize = size;
247     }
248
249     /**
250      * Modify the sample size.
251      * @param size the new sample size.
252      * @throws IllegalArgumentException if <code>size</code> is negative.
253      */

254     public void setSampleSize(int size) {
255         if (size < 0) {
256             throw new IllegalArgumentException JavaDoc(
257                 "sample size must be non-negative.");
258         }
259         sampleSize = size;
260     }
261 }
262
Popular Tags