From 97a3ed9e21b969e1006f6612ff1ae76b1c79c188 Mon Sep 17 00:00:00 2001 From: Luc Maisonobe Date: Fri, 15 Mar 2013 11:38:23 +0000 Subject: [PATCH] Use erfinv in the normal distribution. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1456906 13f79535-47bb-0310-9956-ffa450edef68 --- src/changes/changes.xml | 6 ++++++ .../commons/math3/distribution/NormalDistribution.java | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 67aa62b6c..635ba1ebc 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -55,6 +55,12 @@ This is a minor release: It combines bug fixes and new features. Changes to existing features were made in a backwards-compatible way such as to allow drop-in replacement of the v3.1[.1] JAR file. "> + + Normal distribution now uses a direct implementation of the + inverse error function to compute inverse cumulative probability + instead of relying on a numerical solver. This is much faster, + more accurate and does not need convergence threshold. + Implementations for inverse error function and inverse complementary error functions have been added. diff --git a/src/main/java/org/apache/commons/math3/distribution/NormalDistribution.java b/src/main/java/org/apache/commons/math3/distribution/NormalDistribution.java index db85902f1..8d2cbd4a8 100644 --- a/src/main/java/org/apache/commons/math3/distribution/NormalDistribution.java +++ b/src/main/java/org/apache/commons/math3/distribution/NormalDistribution.java @@ -19,6 +19,7 @@ package org.apache.commons.math3.distribution; import org.apache.commons.math3.exception.NotStrictlyPositiveException; import org.apache.commons.math3.exception.NumberIsTooLargeException; +import org.apache.commons.math3.exception.OutOfRangeException; import org.apache.commons.math3.exception.util.LocalizedFormats; import org.apache.commons.math3.special.Erf; import org.apache.commons.math3.util.FastMath; @@ -152,6 +153,15 @@ public class NormalDistribution extends AbstractRealDistribution { return 0.5 * (1 + Erf.erf(dev / (standardDeviation * SQRT2))); } + /** {@inheritDoc} */ + @Override + public double inverseCumulativeProbability(final double p) throws OutOfRangeException { + if (p < 0.0 || p > 1.0) { + throw new OutOfRangeException(p, 0, 1); + } + return mean + standardDeviation * SQRT2 * Erf.erfInv(2 * p - 1); + } + /** * {@inheritDoc} *