Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 24 Aug 2013 19:30:29 -0700
From:      Steve Kargl <sgk@troutmask.apl.washington.edu>
To:        Bruce Evans <brde@optusnet.com.au>
Cc:        freebsd-numerics@FreeBSD.org
Subject:   Re: (2nd time) tweaks to erff() threshold values
Message-ID:  <20130825023029.GA56772@troutmask.apl.washington.edu>
In-Reply-To: <20130824202102.GA54981@troutmask.apl.washington.edu>
References:  <20130822213315.GA6708@troutmask.apl.washington.edu> <20130823202257.Q1593@besplex.bde.org> <20130823165744.GA47369@troutmask.apl.washington.edu> <20130824202102.GA54981@troutmask.apl.washington.edu>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, Aug 24, 2013 at 01:21:02PM -0700, Steve Kargl wrote:
> On Fri, Aug 23, 2013 at 09:57:44AM -0700, Steve Kargl wrote:
> > On Fri, Aug 23, 2013 at 09:12:33PM +1000, Bruce Evans wrote:
> > 
> >> The whole erf implementation is probably not the best way for
> >> float precision, but is good for understanding higher precisions.
> > 
> > I'm fairly certain that the implementation of erff() is not very
> > efficient.  The polynomials, used in the rational approximations,
> > are the same order as those used in the double precision approximation.
> > I'll check the polys when update my P(x)/Q(x) remes algorithm for
> > erfl and erfcl.
> 
> I seem to be right (although I haven't iterated on the P's and Q's).
> 

Now, with pretty testing and (perhaps) better coefficients:

         | usec/call | Max ULP | X Max ULP
---------+-----------+---------+---------------------------------
new erfc |  0.02757  | 0.65947 | 8.19824636e-01, 0x1.a3c00ep-1
old erfc |  0.03348  | 0.68218 | 8.43257010e-01, 0x1.afbf62p-1
---------+-----------+---------+---------------------------------
new erf  |  0.02302  | 0.62437 | 1.04175471e-38, 0x1.c5bf88p-127
old erf  |  0.03028  | 0.62437 | 1.04175471e-38, 0x1.c5bf88p-127

OK to commit?

-- 
Steve

Index: src/s_erff.c
===================================================================
--- src/s_erff.c	(revision 1361)
+++ src/s_erff.c	(working copy)
@@ -31,16 +31,16 @@ erx =  8.4506291151e-01, /* 0x3f58560b *
  */
 efx =  1.2837916613e-01, /* 0x3e0375d4 */
 efx8=  1.0270333290e+00, /* 0x3f8375d4 */
-pp0  =  1.2837916613e-01, /* 0x3e0375d4 */
-pp1  = -3.2504209876e-01, /* 0xbea66beb */
-pp2  = -2.8481749818e-02, /* 0xbce9528f */
-pp3  = -5.7702702470e-03, /* 0xbbbd1489 */
-pp4  = -2.3763017452e-05, /* 0xb7c756b1 */
-qq1  =  3.9791721106e-01, /* 0x3ecbbbce */
-qq2  =  6.5022252500e-02, /* 0x3d852a63 */
-qq3  =  5.0813062117e-03, /* 0x3ba68116 */
-qq4  =  1.3249473704e-04, /* 0x390aee49 */
-qq5  = -3.9602282413e-06, /* 0xb684e21a */
+/*
+ *  Domain [0, 0.84375], range ~[-5.4446e-10,5.5197e-10]:
+ *  |(erf(x) - x)/x - p(x)/q(x)| < 2**-31.
+ */
+pp0  =  1.28379166e-01F,	/*  0x1.06eba8p-3 */
+pp1  = -3.36030394e-01F,	/* -0x1.58185ap-2 */
+pp2  = -1.86260219e-03F,	/* -0x1.e8451ep-10 */
+qq1  =  3.12324286e-01F,	/*  0x1.3fd1f0p-2 */
+qq2  =  2.16070302e-02F,	/*  0x1.620274p-6 */
+qq3  = -1.98859419e-03F, 	/* -0x1.04a626p-9 */
 /*
  * Coefficients for approximation to  erf  in [0.84375,1.25]
  */
@@ -114,8 +114,8 @@ erff(float x)
 		return x + efx*x;
 	    }
 	    z = x*x;
-	    r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
-	    s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+	    r = pp0+z*(pp1+z*pp2);
+	    s = one+z*(qq1+z*(qq2+z*qq3));
 	    y = r/s;
 	    return x + x*y;
 	}
@@ -163,8 +163,8 @@ erfcf(float x)
 	    if(ix < 0x23800000)  	/* |x|<2**-56 */
 		return one-x;
 	    z = x*x;
-	    r = pp0+z*(pp1+z*(pp2+z*(pp3+z*pp4)));
-	    s = one+z*(qq1+z*(qq2+z*(qq3+z*(qq4+z*qq5))));
+	    r = pp0+z*(pp1+z*pp2);
+	    s = one+z*(qq1+z*(qq2+z*qq3));
 	    y = r/s;
 	    if(hx < 0x3e800000) {  	/* x<1/4 */
 		return one-(x+x*y);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130825023029.GA56772>