Modified NormalDistributionImpl.cumulativeProbablity to catch

MaxIterationsExceededException and return 0 or 1, resp. if the argument
is more than 20 standard deviations from the mean.

JIRA: MATH-167


git-svn-id: https://svn.apache.org/repos/asf/jakarta/commons/proper/math/trunk@558450 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Phil Steitz 2007-07-22 02:33:08 +00:00
parent 13eb8cca17
commit b8b6c66e1c
3 changed files with 43 additions and 3 deletions

View File

@ -20,6 +20,7 @@ package org.apache.commons.math.distribution;
import java.io.Serializable;
import org.apache.commons.math.MathException;
import org.apache.commons.math.MaxIterationsExceededException;
import org.apache.commons.math.special.Erf;
/**
@ -100,11 +101,23 @@ public class NormalDistributionImpl extends AbstractContinuousDistribution
* For this disbution, X, this method returns P(X &lt; <code>x</code>).
* @param x the value at which the CDF is evaluated.
* @return CDF evaluted at <code>x</code>.
* @throws MathException if the algorithm fails to converge.
* @throws MathException if the algorithm fails to converge; unless
* x is more than 20 standard deviations from the mean, in which case the
* convergence exception is caught and 0 or 1 is returned.
*/
public double cumulativeProbability(double x) throws MathException {
return 0.5 * (1.0 + Erf.erf((x - mean) /
(standardDeviation * Math.sqrt(2.0))));
try {
return 0.5 * (1.0 + Erf.erf((x - mean) /
(standardDeviation * Math.sqrt(2.0))));
} catch (MaxIterationsExceededException ex) {
if (x < (mean - 20 * standardDeviation)) { // JDK 1.5 blows at 38
return 0.0d;
} else if (x > (mean + 20 * standardDeviation)) {
return 1.0d;
} else {
throw ex;
}
}
}
/**

View File

@ -120,4 +120,26 @@ public class NormalDistributionTest extends ContinuousDistributionAbstractTest
// Expected
}
}
/**
* Check to make sure top-coding of extreme values works correctly.
* Verifies fix for JIRA MATH-167
*/
public void testExtremeValues() throws Exception {
NormalDistribution distribution = (NormalDistribution) getDistribution();
distribution.setMean(0);
distribution.setStandardDeviation(1);
for (int i = 0; i < 100; i+=5) { // make sure no convergence exception
double lowerTail = distribution.cumulativeProbability((double)-i);
double upperTail = distribution.cumulativeProbability((double) i);
if (i < 10) { // make sure not top-coded
assertTrue(lowerTail > 0.0d);
assertTrue(upperTail < 1.0d);
}
else { // make sure top coding not reversed
assertTrue(lowerTail < 0.00001);
assertTrue(upperTail > 0.99999);
}
}
}
}

View File

@ -87,6 +87,11 @@ Commons Math Release Notes</title>
<action dev="psteitz" type="update" issue="MATH-160" due-to "Matthias Hummel">
Added two sample (binned comparison) ChiSquare test.
</action>
<action dev="psteitz" type="fix" issue="MATH-167">
Modified NormalDistributionImpl.cumulativeProbablity to catch
MaxIterationsExceededException and return 0 or 1, resp. if the argument
is more than 20 standard deviations from the mean.
</action>
</release>
<release version="1.1" date="2005-12-17"
description="This is a maintenance release containing bug fixes and enhancements.