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:
parent
13eb8cca17
commit
b8b6c66e1c
|
@ -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 < <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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue