Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||||||
BinomialDistributionImpl |
|
| 2.1;2.1 |
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 | package org.apache.commons.math.distribution; |
|
17 | ||
18 | import java.io.Serializable; |
|
19 | ||
20 | import org.apache.commons.math.MathException; |
|
21 | import org.apache.commons.math.special.Beta; |
|
22 | import org.apache.commons.math.util.MathUtils; |
|
23 | ||
24 | /** |
|
25 | * The default implementation of {@link BinomialDistribution}. |
|
26 | * |
|
27 | * @version $Revision$ $Date: 2005-06-26 15:20:57 -0700 (Sun, 26 Jun 2005) $ |
|
28 | */ |
|
29 | public class BinomialDistributionImpl |
|
30 | extends AbstractIntegerDistribution |
|
31 | implements BinomialDistribution, Serializable { |
|
32 | ||
33 | /** Serializable version identifier */ |
|
34 | static final long serialVersionUID = 6751309484392813623L; |
|
35 | ||
36 | /** The number of trials. */ |
|
37 | private int numberOfTrials; |
|
38 | ||
39 | /** The probability of success. */ |
|
40 | private double probabilityOfSuccess; |
|
41 | ||
42 | /** |
|
43 | * Create a binomial distribution with the given number of trials and |
|
44 | * probability of success. |
|
45 | * @param trials the number of trials. |
|
46 | * @param p the probability of success. |
|
47 | */ |
|
48 | public BinomialDistributionImpl(int trials, double p) { |
|
49 | 30 | super(); |
50 | 30 | setNumberOfTrials(trials); |
51 | 28 | setProbabilityOfSuccess(p); |
52 | 24 | } |
53 | ||
54 | /** |
|
55 | * Access the number of trials for this distribution. |
|
56 | * @return the number of trials. |
|
57 | */ |
|
58 | public int getNumberOfTrials() { |
|
59 | 540 | return numberOfTrials; |
60 | } |
|
61 | ||
62 | /** |
|
63 | * Access the probability of success for this distribution. |
|
64 | * @return the probability of success. |
|
65 | */ |
|
66 | public double getProbabilityOfSuccess() { |
|
67 | 258 | return probabilityOfSuccess; |
68 | } |
|
69 | ||
70 | /** |
|
71 | * Change the number of trials for this distribution. |
|
72 | * @param trials the new number of trials. |
|
73 | * @throws IllegalArgumentException if <code>trials</code> is not a valid |
|
74 | * number of trials. |
|
75 | */ |
|
76 | public void setNumberOfTrials(int trials) { |
|
77 | 30 | if (trials < 0) { |
78 | 2 | throw new IllegalArgumentException("number of trials must be non-negative."); |
79 | } |
|
80 | 28 | numberOfTrials = trials; |
81 | 28 | } |
82 | ||
83 | /** |
|
84 | * Change the probability of success for this distribution. |
|
85 | * @param p the new probability of success. |
|
86 | * @throws IllegalArgumentException if <code>p</code> is not a valid |
|
87 | * probability. |
|
88 | */ |
|
89 | public void setProbabilityOfSuccess(double p) { |
|
90 | 28 | if (p < 0.0 || p > 1.0) { |
91 | 4 | throw new IllegalArgumentException("probability of success must be between 0.0 and 1.0, inclusive."); |
92 | } |
|
93 | 24 | probabilityOfSuccess = p; |
94 | 24 | } |
95 | ||
96 | /** |
|
97 | * Access the domain value lower bound, based on <code>p</code>, used to |
|
98 | * bracket a PDF root. |
|
99 | * |
|
100 | * @param p the desired probability for the critical value |
|
101 | * @return domain value lower bound, i.e. |
|
102 | * P(X < <i>lower bound</i>) < <code>p</code> |
|
103 | */ |
|
104 | protected int getDomainLowerBound(double p) { |
|
105 | 28 | return -1; |
106 | } |
|
107 | ||
108 | /** |
|
109 | * Access the domain value upper bound, based on <code>p</code>, used to |
|
110 | * bracket a PDF root. |
|
111 | * |
|
112 | * @param p the desired probability for the critical value |
|
113 | * @return domain value upper bound, i.e. |
|
114 | * P(X < <i>upper bound</i>) > <code>p</code> |
|
115 | */ |
|
116 | protected int getDomainUpperBound(double p) { |
|
117 | 28 | return getNumberOfTrials(); |
118 | } |
|
119 | ||
120 | /** |
|
121 | * For this distribution, X, this method returns P(X ≤ x). |
|
122 | * @param x the value at which the PDF is evaluated. |
|
123 | * @return PDF for this distribution. |
|
124 | * @throws MathException if the cumulative probability can not be |
|
125 | * computed due to convergence or other numerical errors. |
|
126 | */ |
|
127 | public double cumulativeProbability(int x) throws MathException { |
|
128 | double ret; |
|
129 | 226 | if (x < 0) { |
130 | 14 | ret = 0.0; |
131 | 212 | } else if (x >= getNumberOfTrials()) { |
132 | 22 | ret = 1.0; |
133 | } else { |
|
134 | 190 | ret = |
135 | 1.0 - Beta.regularizedBeta( |
|
136 | getProbabilityOfSuccess(), |
|
137 | x + 1.0, |
|
138 | getNumberOfTrials() - x); |
|
139 | } |
|
140 | 226 | return ret; |
141 | } |
|
142 | ||
143 | /** |
|
144 | * For this disbution, X, this method returns P(X = x). |
|
145 | * |
|
146 | * @param x the value at which the PMF is evaluated. |
|
147 | * @return PMF for this distribution. |
|
148 | */ |
|
149 | public double probability(int x) { |
|
150 | double ret; |
|
151 | 48 | if (x < 0 || x > getNumberOfTrials()) { |
152 | 14 | ret = 0.0; |
153 | } else { |
|
154 | 34 | ret = MathUtils.binomialCoefficientDouble( |
155 | getNumberOfTrials(), x) * |
|
156 | Math.pow(getProbabilityOfSuccess(), x) * |
|
157 | Math.pow(1.0 - getProbabilityOfSuccess(), |
|
158 | getNumberOfTrials() - x); |
|
159 | } |
|
160 | 48 | return ret; |
161 | } |
|
162 | ||
163 | /** |
|
164 | * For this distribution, X, this method returns the largest x, such |
|
165 | * that P(X ≤ x) ≤ <code>p</code>. |
|
166 | * <p> |
|
167 | * Returns <code>-1</code> for p=0 and <code>Integer.MAX_VALUE</code> for |
|
168 | * p=1. |
|
169 | * |
|
170 | * @param p the desired probability |
|
171 | * @return the largest x such that P(X ≤ x) <= p |
|
172 | * @throws MathException if the inverse cumulative probability can not be |
|
173 | * computed due to convergence or other numerical errors. |
|
174 | * @throws IllegalArgumentException if p < 0 or p > 1 |
|
175 | */ |
|
176 | public int inverseCumulativeProbability(final double p) throws MathException { |
|
177 | // handle extreme values explicitly |
|
178 | 36 | if (p == 0) { |
179 | 2 | return -1; |
180 | } |
|
181 | 34 | if (p == 1) { |
182 | 2 | return Integer.MAX_VALUE; |
183 | } |
|
184 | ||
185 | // use default bisection impl |
|
186 | 32 | return super.inverseCumulativeProbability(p); |
187 | } |
|
188 | } |