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:
parent
b87e7190d5
commit
55b2cc8c03
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
/**
|
||||
|
|
|
@ -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 < <i>lower bound</i>) < <code>p</code>
|
||||
* @return domain value lower bound, i.e. P(X < <i>lower bound</i>) <
|
||||
* <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 < <i>upper bound</i>) > <code>p</code>
|
||||
* @return domain value upper bound, i.e. P(X < <i>upper bound</i>) >
|
||||
* <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 ≤ 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 ≤ x) ≤ <code>p</code>.
|
||||
* For this distribution, X, this method returns the largest x, such that
|
||||
* P(X ≤ x) ≤ <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 ≤ 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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue