MATH-120: finished review of pascal distribution.

git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/math/trunk@525837 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Brent Worden 2007-04-05 14:48:48 +00:00
parent b87e7190d5
commit 55b2cc8c03
4 changed files with 61 additions and 70 deletions

View File

@ -89,9 +89,12 @@ public abstract class DistributionFactory {
* @param numberOfSuccesses the number of successes.
* @param probabilityOfSuccess the probability of success
* @return a new Pascal distribution
* @since 1.2
*/
public abstract PascalDistribution createPascalDistribution(
int numberOfSuccesses, double probabilityOfSuccess);
public PascalDistribution createPascalDistribution(
int numberOfSuccesses, double probabilityOfSuccess) {
return new PascalDistributionImpl(numberOfSuccesses, probabilityOfSuccess);
}
/**
* Create a new cauchy distribution with the given median and scale.

View File

@ -154,17 +154,4 @@ public class DistributionFactoryImpl extends DistributionFactory {
public PoissonDistribution createPoissonDistribution(double lambda) {
return new PoissonDistributionImpl(lambda);
}
/**
* Create a Pascal distribution with the given number of successes and
* probability of success.
*
* @param numberOfSuccesses the number of successes.
* @param probabilityOfSuccess the probability of success
* @return a new Pascal distribution
*/
public PascalDistribution createPascalDistribution(int numberOfSuccesses, double probabilityOfSuccess) {
return new PascalDistributionImpl(numberOfSuccesses, probabilityOfSuccess);
}
}

View File

@ -17,20 +17,29 @@
package org.apache.commons.math.distribution;
/**
* The Pascal Distribution.
* The Pascal distribution. The Pascal distribution is a special case of the
* Negative Binomial distribution where the number of successes parameter is an
* integer.
*
* There are various ways to express the probability mass and distribution
* functions for the Pascal distribution. The convention employed by the
* library is to express these functions in terms of the number of failures in
* a Bernoulli experiment [2].
*
* Instances of PascalDistribution objects should be created using
* {@link DistributionFactory#createPascalDistribution(int, double)}.
*
* <p>
* References:
* <ul>
* <ol>
* <li><a href="http://mathworld.wolfram.com/NegativeBinomialDistribution.html">
* Negative Binomial Distribution</a></li>
* <oi><a href="http://en.wikipedia.org/wiki/Negative_binomial_distribution#Waiting_time_in_a_Bernoulli_process">Waiting Time in a Bernoulli Process</a></li>
* </ul>
* </p>
*
* @version $Revision:$
* @since 1.2
*/
public interface PascalDistribution extends IntegerDistribution {
/**

View File

@ -24,17 +24,16 @@ import org.apache.commons.math.util.MathUtils;
/**
* The default implementation of {@link PascalDistribution}.
*
* @version $Revision:$
* @since 1.2
*/
public class PascalDistributionImpl
extends AbstractIntegerDistribution
public class PascalDistributionImpl extends AbstractIntegerDistribution
implements PascalDistribution, Serializable {
/** Serializable version identifier */
private static final long serialVersionUID = 6751309484392813623L;
/** The number of trials */
/** The number of successes */
private int numberOfSuccesses;
/** The probability of success */
@ -43,7 +42,6 @@ public class PascalDistributionImpl
/**
* Create a binomial distribution with the given number of trials and
* probability of success.
*
* @param r the number of successes
* @param p the probability of success
*/
@ -54,9 +52,8 @@ public class PascalDistributionImpl
}
/**
* Access the number of trials for this distribution.
*
* @return the number of trials
* Access the number of successes for this distribution.
* @return the number of successes
*/
public int getNumberOfSuccesses() {
return numberOfSuccesses;
@ -64,7 +61,6 @@ public class PascalDistributionImpl
/**
* Access the probability of success for this distribution.
*
* @return the probability of success
*/
public double getProbabilityOfSuccess() {
@ -72,28 +68,29 @@ public class PascalDistributionImpl
}
/**
* Change the number of trials for this distribution.
*
* @param successes the new number of trials
* @throws IllegalArgumentException if <code>trials</code> is not positive.
* Change the number of successes for this distribution.
* @param successes the new number of successes
* @throws IllegalArgumentException if <code>successes</code> is not
* positive.
*/
public void setNumberOfSuccesses(int successes) {
if (successes < 0) {
throw new IllegalArgumentException("number of trials must be non-negative.");
throw new IllegalArgumentException(
"number of successes must be non-negative.");
}
numberOfSuccesses = successes;
}
/**
* Change the probability of success for this distribution.
*
* @param p the new probability of success
* @throws IllegalArgumentException if <code>p</code> is not a valid
* probability.
*/
public void setProbabilityOfSuccess(double p) {
if (p < 0.0 || p > 1.0) {
throw new IllegalArgumentException("probability of success must be between 0.0 and 1.0, inclusive.");
throw new IllegalArgumentException(
"probability of success must be between 0.0 and 1.0, inclusive.");
}
probabilityOfSuccess = p;
}
@ -101,10 +98,9 @@ public class PascalDistributionImpl
/**
* Access the domain value lower bound, based on <code>p</code>, used to
* bracket a PDF root.
*
* @param p the desired probability for the critical value
* @return domain value lower bound, i.e.
* P(X &lt; <i>lower bound</i>) &lt; <code>p</code>
* @return domain value lower bound, i.e. P(X &lt; <i>lower bound</i>) &lt;
* <code>p</code>
*/
protected int getDomainLowerBound(double p) {
return -1;
@ -113,80 +109,76 @@ public class PascalDistributionImpl
/**
* Access the domain value upper bound, based on <code>p</code>, used to
* bracket a PDF root.
*
* @param p the desired probability for the critical value
* @return domain value upper bound, i.e.
* P(X &lt; <i>upper bound</i>) &gt; <code>p</code>
* @return domain value upper bound, i.e. P(X &lt; <i>upper bound</i>) &gt;
* <code>p</code>
*/
protected int getDomainUpperBound(double p) {
// use MAX - 1 because MAX causes loop
return Integer.MAX_VALUE - 1;
// use MAX - 1 because MAX causes loop
return Integer.MAX_VALUE - 1;
}
/**
* For this distribution, X, this method returns P(X &le; x).
*
* @param x the value at which the PDF is evaluated
* @return PDF for this distribution
* @throws MathException if the cumulative probability can not be
* computed due to convergence or other numerical errors
* @throws MathException if the cumulative probability can not be computed
* due to convergence or other numerical errors
*/
public double cumulativeProbability(int x) throws MathException {
double ret;
if (x < 0) {
ret = 0.0;
} else {
ret = Beta.regularizedBeta(
getProbabilityOfSuccess(),
getNumberOfSuccesses(),
x + 1);
ret = Beta.regularizedBeta(getProbabilityOfSuccess(),
getNumberOfSuccesses(), x + 1);
}
return ret;
}
/**
* For this distribution, X, this method returns P(X = x).
*
* @param x the value at which the PMF is evaluated
* @return PMF for this distribution
* @return PMF for this distribution
*/
public double probability(int x) {
double ret;
if (x < 0) {
ret = 0.0;
} else {
ret = MathUtils.binomialCoefficientDouble(x + getNumberOfSuccesses() - 1,
getNumberOfSuccesses() - 1) *
Math.pow(getProbabilityOfSuccess(), getNumberOfSuccesses()) *
Math.pow(1.0 - getProbabilityOfSuccess(),
x);
ret = MathUtils.binomialCoefficientDouble(x
+ getNumberOfSuccesses() - 1, getNumberOfSuccesses() - 1)
* Math.pow(getProbabilityOfSuccess(), getNumberOfSuccesses())
* Math.pow(1.0 - getProbabilityOfSuccess(), x);
}
return ret;
}
/**
* For this distribution, X, this method returns the largest x, such
* that P(X &le; x) &le; <code>p</code>.
* For this distribution, X, this method returns the largest x, such that
* P(X &le; x) &le; <code>p</code>.
* <p>
* Returns <code>-1</code> for p=0 and <code>Integer.MAX_VALUE</code> for
* p=1.
*
* Returns <code>-1</code> for p=0 and <code>Integer.MAX_VALUE</code>
* for p=1.
* @param p the desired probability
* @return the largest x such that P(X &le; x) <= p
* @throws MathException if the inverse cumulative probability can not be
* computed due to convergence or other numerical errors.
* computed due to convergence or other numerical errors.
* @throws IllegalArgumentException if p < 0 or p > 1
*/
public int inverseCumulativeProbability(final double p) throws MathException {
public int inverseCumulativeProbability(final double p)
throws MathException {
int ret;
// handle extreme values explicitly
if (p == 0) {
return -1;
}
if (p == 1) {
return Integer.MAX_VALUE;
ret = -1;
} else if (p == 1) {
ret = Integer.MAX_VALUE;
} else {
ret = super.inverseCumulativeProbability(p);
}
// use default bisection impl
return super.inverseCumulativeProbability(p);
return ret;
}
}