Return-Path: X-Original-To: apmail-commons-issues-archive@minotaur.apache.org Delivered-To: apmail-commons-issues-archive@minotaur.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 6418580C6 for ; Tue, 16 Aug 2011 22:09:58 +0000 (UTC) Received: (qmail 77656 invoked by uid 500); 16 Aug 2011 22:09:58 -0000 Delivered-To: apmail-commons-issues-archive@commons.apache.org Received: (qmail 77581 invoked by uid 500); 16 Aug 2011 22:09:57 -0000 Mailing-List: contact issues-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: issues@commons.apache.org Delivered-To: mailing list issues@commons.apache.org Received: (qmail 77573 invoked by uid 99); 16 Aug 2011 22:09:57 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 16 Aug 2011 22:09:57 +0000 X-ASF-Spam-Status: No, hits=-2001.1 required=5.0 tests=ALL_TRUSTED,RP_MATCHES_RCVD X-Spam-Check-By: apache.org Received: from [140.211.11.116] (HELO hel.zones.apache.org) (140.211.11.116) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 16 Aug 2011 22:09:54 +0000 Received: from hel.zones.apache.org (hel.zones.apache.org [140.211.11.116]) by hel.zones.apache.org (Postfix) with ESMTP id D5FDDBF1DA for ; Tue, 16 Aug 2011 22:09:32 +0000 (UTC) Date: Tue, 16 Aug 2011 22:09:32 +0000 (UTC) From: "Christian Winter (JIRA)" To: issues@commons.apache.org Message-ID: <1194107483.43019.1313532572868.JavaMail.tomcat@hel.zones.apache.org> Subject: [jira] [Commented] (MATH-364) Make Erf more precise in the tails by providing erfc MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit X-JIRA-FingerPrint: 30527f35849b9dde25b450d4833f0394 X-Virus-Checked: Checked by ClamAV on apache.org [ https://issues.apache.org/jira/browse/MATH-364?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13086014#comment-13086014 ] Christian Winter commented on MATH-364: --------------------------------------- Here's the new suggestion: {code} public static double erf(double x1, double x2) { if(x1 > x2) { return -erf(x2, x1); } /** * The number {@code x_crit} solves {@code erf(x)=0.5} within 1ulp. * More precisely, the current implementations of * {@link #erf(double)} and {@link #erfc(double)} satisfy:
* {@code erf(x_crit) < 0.5},
* {@code erf(Math.nextUp(x_crit) > 0.5},
* {@code erfc(x_crit) = 0.5}, and
* {@code erfc(Math.nextUp(x_crit) < 0.5} */ double x_crit = 0.4769362762044697; return x1 < -x_crit && x2 < 0.0 ? erfc(-x2) - erfc(-x1) : x2 > x_crit && x1 > 0.0 ? erfc(x1) - erfc(x2) : erf(x2) - erf(x1); } {code} Following the idea to keep numbers small during calculation, the stragegies for {{x1,x2 < -x_crit}}, {{x1,x2 > x_crit}}, and {{|x1|,|x2| ≤ x_crit}} are straightforward and mandatory. In the other cases, numbers ≥ 0.5 cannot be avoided and there is some freedom of choice. The suggested code avoids number ≥ 1 where the final result is < 1. > Make Erf more precise in the tails by providing erfc > ---------------------------------------------------- > > Key: MATH-364 > URL: https://issues.apache.org/jira/browse/MATH-364 > Project: Commons Math > Issue Type: Improvement > Affects Versions: 1.1, 1.2, 2.0, 2.1 > Reporter: Christian Winter > Priority: Minor > Fix For: 3.0 > > > First I want to thank Phil Steitz for making Erf stable in the tails through adjusting the choices in calculating the regularized gamma functions, see [Math-282|https://issues.apache.org/jira/browse/MATH-282]. However, the precision of Erf in the tails is limitted to fixed point precision because of the closeness to +/-1.0, although the Gamma class could provide much more accuracy. Thus I propose to add the methods erfc(double) and erf(double, double) to the class Erf: > {code:borderStyle=solid} > /** > * Returns the complementary error function erfc(x). > * @param x the value > * @return the complementary error function erfc(x) > * @throws MathException if the algorithm fails to converge > */ > public static double erfc(double x) throws MathException { > double ret = Gamma.regularizedGammaQ(0.5, x * x, 1.0e-15, 10000); > if (x < 0) { > ret = -ret; > } > return ret; > } > /** > * Returns the difference of the error function values of x1 and x2. > * @param x1 the first bound > * @param x2 the second bound > * @return erf(x2) - erf(x1) > * @throws MathException > */ > public static double erf(double x1, double x2) throws MathException { > if(x1>x2) > return erf(x2, x1); > if(x1==x2) > return 0.0; > > double f1 = erf(x1); > double f2 = erf(x2); > > if(f2 > 0.5) > if(f1 > 0.5) > return erfc(x1) - erfc(x2); > else > return (0.5-erfc(x2)) + (0.5-f1); > else > if(f1 < -0.5) > if(f2 < -0.5) > return erfc(-x2) - erfc(-x1); > else > return (0.5-erfc(-x1)) + (0.5+f2); > else > return f2 - f1; > } > {code} > Further this can be used to improve the NormalDistributionImpl through > {code:borderStyle=solid} > @Override > public double cumulativeProbability(double x0, double x1) throws MathException { > return 0.5 * Erf.erf( > (x0 - getMean()) / (getStandardDeviation() * sqrt2), > (x1 - getMean()) / (getStandardDeviation() * sqrt2) ); > } > {code} -- This message is automatically generated by JIRA. For more information on JIRA, see: http://www.atlassian.com/software/jira