2
* Licensed to the Apache Software Foundation (ASF) under one or more
3
* contributor license agreements. See the NOTICE file distributed with
4
* this work for additional information regarding copyright ownership.
5
* The ASF licenses this file to You under the Apache License, Version 2.0
6
* (the "License"); you may not use this file except in compliance with
7
* the License. You may obtain a copy of the License at
9
* http://www.apache.org/licenses/LICENSE-2.0
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
17
package org.apache.commons.math.distribution;
19
import java.io.Serializable;
21
import org.apache.commons.math.MathException;
22
import org.apache.commons.math.MathRuntimeException;
26
* Base class for integer-valued discrete distributions. Default
27
* implementations are provided for some of the methods that do not vary
28
* from distribution to distribution.
30
* @version $Revision: 772119 $ $Date: 2009-05-06 05:43:28 -0400 (Wed, 06 May 2009) $
32
public abstract class AbstractIntegerDistribution extends AbstractDistribution
33
implements IntegerDistribution, Serializable {
35
/** Serializable version identifier */
36
private static final long serialVersionUID = -1146319659338487221L;
39
* Default constructor.
41
protected AbstractIntegerDistribution() {
46
* For a random variable X whose values are distributed according
47
* to this distribution, this method returns P(X ≤ x). In other words,
48
* this method represents the (cumulative) distribution function, or
49
* CDF, for this distribution.
51
* If <code>x</code> does not represent an integer value, the CDF is
52
* evaluated at the greatest integer less than x.
54
* @param x the value at which the distribution function is evaluated.
55
* @return cumulative probability that a random variable with this
56
* distribution takes a value less than or equal to <code>x</code>
57
* @throws MathException if the cumulative probability can not be
58
* computed due to convergence or other numerical errors.
60
public double cumulativeProbability(double x) throws MathException {
61
return cumulativeProbability((int) Math.floor(x));
65
* For a random variable X whose values are distributed according
66
* to this distribution, this method returns P(x0 ≤ X ≤ x1).
68
* @param x0 the (inclusive) lower bound
69
* @param x1 the (inclusive) upper bound
70
* @return the probability that a random variable with this distribution
71
* will take a value between <code>x0</code> and <code>x1</code>,
72
* including the endpoints.
73
* @throws MathException if the cumulative probability can not be
74
* computed due to convergence or other numerical errors.
75
* @throws IllegalArgumentException if <code>x0 > x1</code>
78
public double cumulativeProbability(double x0, double x1)
79
throws MathException {
81
throw MathRuntimeException.createIllegalArgumentException(
82
"lower endpoint ({0}) must be less than or equal to upper endpoint ({1})",
85
if (Math.floor(x0) < x0) {
86
return cumulativeProbability(((int) Math.floor(x0)) + 1,
87
(int) Math.floor(x1)); // don't want to count mass below x0
88
} else { // x0 is mathematical integer, so use as is
89
return cumulativeProbability((int) Math.floor(x0),
90
(int) Math.floor(x1));
95
* For a random variable X whose values are distributed according
96
* to this distribution, this method returns P(X ≤ x). In other words,
97
* this method represents the probability distribution function, or PDF,
98
* for this distribution.
100
* @param x the value at which the PDF is evaluated.
101
* @return PDF for this distribution.
102
* @throws MathException if the cumulative probability can not be
103
* computed due to convergence or other numerical errors.
105
abstract public double cumulativeProbability(int x) throws MathException;
108
* For a random variable X whose values are distributed according
109
* to this distribution, this method returns P(X = x). In other words, this
110
* method represents the probability mass function, or PMF, for the distribution.
112
* If <code>x</code> does not represent an integer value, 0 is returned.
114
* @param x the value at which the probability density function is evaluated
115
* @return the value of the probability density function at x
117
public double probability(double x) {
118
double fl = Math.floor(x);
120
return this.probability((int) x);
127
* For a random variable X whose values are distributed according
128
* to this distribution, this method returns P(x0 ≤ X ≤ x1).
130
* @param x0 the inclusive, lower bound
131
* @param x1 the inclusive, upper bound
132
* @return the cumulative probability.
133
* @throws MathException if the cumulative probability can not be
134
* computed due to convergence or other numerical errors.
135
* @throws IllegalArgumentException if x0 > x1
137
public double cumulativeProbability(int x0, int x1) throws MathException {
139
throw MathRuntimeException.createIllegalArgumentException(
140
"lower endpoint ({0}) must be less than or equal to upper endpoint ({1})",
143
return cumulativeProbability(x1) - cumulativeProbability(x0 - 1);
147
* For a random variable X whose values are distributed according
148
* to this distribution, this method returns the largest x, such
149
* that P(X ≤ x) ≤ <code>p</code>.
151
* @param p the desired probability
152
* @return the largest x such that P(X ≤ x) <= p
153
* @throws MathException if the inverse cumulative probability can not be
154
* computed due to convergence or other numerical errors.
155
* @throws IllegalArgumentException if p < 0 or p > 1
157
public int inverseCumulativeProbability(final double p) throws MathException{
158
if (p < 0.0 || p > 1.0) {
159
throw MathRuntimeException.createIllegalArgumentException(
160
"{0} out of [{1}, {2}] range", p, 0.0, 1.0);
163
// by default, do simple bisection.
164
// subclasses can override if there is a better method.
165
int x0 = getDomainLowerBound(p);
166
int x1 = getDomainUpperBound(p);
169
int xm = x0 + (x1 - x0) / 2;
170
pm = cumulativeProbability(xm);
174
// this can happen with integer division
175
// simply decrement x1
178
// update x1 normally
184
// this can happen with integer division
185
// simply increment x0
188
// update x0 normally
194
// insure x0 is the correct critical point
195
pm = cumulativeProbability(x0);
198
pm = cumulativeProbability(x0);
205
* Access the domain value lower bound, based on <code>p</code>, used to
206
* bracket a PDF root. This method is used by
207
* {@link #inverseCumulativeProbability(double)} to find critical values.
209
* @param p the desired probability for the critical value
210
* @return domain value lower bound, i.e.
211
* P(X < <i>lower bound</i>) < <code>p</code>
213
protected abstract int getDomainLowerBound(double p);
216
* Access the domain value upper bound, based on <code>p</code>, used to
217
* bracket a PDF root. This method is used by
218
* {@link #inverseCumulativeProbability(double)} to find critical values.
220
* @param p the desired probability for the critical value
221
* @return domain value upper bound, i.e.
222
* P(X < <i>upper bound</i>) > <code>p</code>
224
protected abstract int getDomainUpperBound(double p);