/* erf.c * * Error function * * * * SYNOPSIS: * * double x, y, erf(); * * y = erf( x ); * * * * DESCRIPTION: * * The integral is * * x * - * 2 | | 2 * erf(x) = -------- | exp( - t ) dt. * sqrt(pi) | | * - * 0 * * The magnitude of x is limited to 9.231948545 for DEC * arithmetic; 1 or -1 is returned outside this range. * * For 0 <= |x| < 1, erf(x) = x * P6(x^2)/Q6(x^2); otherwise * erf(x) = 1 - erfc(x). * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE 0,1 3000 1.8e-19 6.5e-20 * */ /* erfc.c * * Complementary error function * * * * SYNOPSIS: * * double x, y, erfc(); * * y = erfc( x ); * * * * DESCRIPTION: * * * 1 - erf(x) = * * inf. * - * 2 | | 2 * erfc(x) = -------- | exp( - t ) dt * sqrt(pi) | | * - * x * * * For small x, erfc(x) = 1 - erf(x); otherwise rational * approximations are computed. * * * * ACCURACY: * * Relative error: * arithmetic domain # trials peak rms * IEEE 0,8 1000 1.8e-18 6.1e-19 * For x > 1, error is dominated by the calculation of exp(-x^2) * and is of order 3e-19 x. * * * ERROR MESSAGES: * * message condition value returned * erfc underflow x > sqrt(MAXLOGL) 0.0 * * */ /* ndtr.c * * Normal distribution function * * * * SYNOPSIS: * * double x, y, ndtr(); * * y = ndtr( x ); * * * * DESCRIPTION: * * Returns the area under the Gaussian probability density * function, integrated from minus infinity to x: * * x * - * 1 | | 2 * ndtr(x) = --------- | exp( - t /2 ) dt * sqrt(2pi) | | * - * -inf. * * = ( 1 + erf(z) ) / 2 * = erfc(z) / 2 * * where z = x/sqrt(2). Computation is via the functions * erf and erfc. * * * ACCURACY: * * See erfl, erfc. * * ERROR MESSAGES: * * message condition value returned * erfc underflow x > sqrt(MAXLOGL) 0.0 * */ /* Cephes Math Library Release 2.2: June, 1992 Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier Direct inquiries to 30 Frost Street, Cambridge, MA 02140 */ #include "mathl.h" extern long double __polevll ( long double, long double *, int ); extern long double __p1evll ( long double, long double *, int ); #define SQRTH 7.07106781186547524401E-1L #define MAXLOGL 1.1356523406294143949492E4L /* erfc(x) = exp(-x^2) P(z)/Q(z) z(x) = 1/x Relative error n=9, d=10 Peak error = 7.761600916141239627567679213879910992123E-21 Relative error spread = 1.023351469044268241908780645010281568783E0 */ static long double P[] = { 1.257754157740948157833312785512722262237E9L, 2.544170037359209505076053758183547658874E9L, 2.546959074195068787444430942851029462365E9L, 1.605230257662887752768505542850382838437E9L, 6.899137924684927504585242368865475647796E8L, 2.066152777382002343549858319788089708173E8L, 4.227432144169649646138430076248102333111E7L, 5.463192951525719736944609969792412137906E6L, 3.509752864577976833796176700600960407890E5L, -1.071020848327048365754654097516174838747E-5L, }; static long double Q[] = { /* 1.000000000000000000000000000000000000000E0 */ 1.257754146471137811029618866219716318753E9L, 3.963393686787501126271033323119385984564E9L, 5.761415509088700168863599482318704228527E9L, 5.089047658881201390929483867868625212361E9L, 3.023468726254039362316680583964735625632E9L, 1.259993446190802606495833425577455019099E9L, 3.710577088683661371497272954319350172686E8L, 7.524032571027728454099705963391636990057E7L, 9.683257455518460133999913804480458079007E6L, 6.220874963793103874137444426727337364012E5L }; /* erfc(x) = exp(-x^2) z P(z**2)/Q(z**2) z(x) = 1/x x >= 8 Relative error n=4, d=5 Peak error = 1.82e-21 Relative error spread = 3.9e-3 */ static long double R[] = { 3.621771504143418323727691824727645990561E0L, 7.176028075353789451273277986715563076155E0L, 3.446811092743012309113505238337669421091E0L, 5.541324340261065929875426053951866015250E-1L, 2.699905677541423267238580904507582955709E-2L }; static long double S[] = { /* 1.000000000000000000000000000000000000000E0 */ 1.073074561751358600517229966140297947840E1L, 1.534256653809200505130664147433856235472E1L, 6.576473386900615376978244623190582091578E0L, 1.006101457677419240008726711451145446254E0L, 4.785458215239962067727484634993830260306E-2L }; /* erf(x) z P(z**2)/Q(z**2) 0 <= x <= 1 z(x) = x Relative error n=6, d=6 Peak error = 7.640688643888757419028899590163681314010E-23 Relative error spread = 9.108314657350825251106158661154911170107E-3 */ static long double T[] = { 1.097461701666048418572764102524978668857E-1L, 5.403114568277600506272199159607654730741E0L, 2.871755797503643801098000314688440010017E2L, 2.677455035557940040284806618777105723130E3L, 4.825836895686958085365801683371047641820E4L, 1.549871261553367266536226453640515782388E5L, 1.104347959782514112319886330985904796384E6L }; static long double U[] = { /* 1.000000000000000000000000000000000000000E0 */ 4.525736349514749653000420739995094197946E1L, 9.715176200212976593594958594375455394272E2L, 1.245878656969449881132817817129763145725E4L, 9.942693068079099139656602031366763195331E4L, 4.635880633067639826809494193933792409347E5L, 9.787028970280835391789815008496258590638E5L }; #define UTHRESH 37.519379347 /* double ndtr(a) double a; { double x, y, z; double fabs(), erf(), erfc(); x = a * SQRTH; z = fabs(x); if( z < SQRTH ) y = 0.5 + 0.5 * erf(x); else { y = 0.5 * erfc(z); if( x > 0 ) y = 1.0 - y; } return(y); } */ long double erfcl(long double a) { long double p,q,x,y,z; if( a < 0.0L ) x = -a; else x = a; if( x < 1.0L ) return( 1.0L - erfl(a) ); z = -a * a; if( z < -MAXLOGL ) { under: /* Some kind of error flagging needed. */ /* mtherr( "erfcl", UNDERFLOW ); */ if( a < 0 ) return( 2.0L ); else return( 0.0L ); } z = expl(z); if( x < 8.0L ) { y = 1.0/a; p = __polevll( y, P, 9 ); q = __p1evll( y, Q, 10 ); } else { y = 1.0/(a*a); p = __polevll( y, R, 4 ) / a; q = __p1evll( y, S, 5 ); } y = (z * p)/q; if( a < 0 ) y = 2.0L - y; if( y == 0.0L ) goto under; return(y); } long double erfl(long double x) { long double y, z; if( fabsl(x) > 1.0L ) return( 1.0L - erfcl(x) ); z = x * x; y = x * __polevll( z, T, 6 ) / __p1evll( z, U, 6 ); return( y ); }