[BACK]Return to specfun.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot

Annotation of OpenXM_contrib/gnuplot/specfun.c, Revision 1.1.1.1

1.1       maekawa     1: #ifndef lint
                      2: static char *RCSid = "$Id: specfun.c,v 1.21 1998/04/14 00:16:20 drd Exp $";
                      3: #endif
                      4:
                      5:
                      6: /* GNUPLOT - specfun.c */
                      7:
                      8: /*[
                      9:  * Copyright 1986 - 1993, 1998   Thomas Williams, Colin Kelley
                     10:  *
                     11:  * Permission to use, copy, and distribute this software and its
                     12:  * documentation for any purpose with or without fee is hereby granted,
                     13:  * provided that the above copyright notice appear in all copies and
                     14:  * that both that copyright notice and this permission notice appear
                     15:  * in supporting documentation.
                     16:  *
                     17:  * Permission to modify the software is granted, but not the right to
                     18:  * distribute the complete modified source code.  Modifications are to
                     19:  * be distributed as patches to the released version.  Permission to
                     20:  * distribute binaries produced by compiling modified sources is granted,
                     21:  * provided you
                     22:  *   1. distribute the corresponding source modifications from the
                     23:  *    released version in the form of a patch file along with the binaries,
                     24:  *   2. add special version identification to distinguish your version
                     25:  *    in addition to the base release version number,
                     26:  *   3. provide your name and address as the primary contact for the
                     27:  *    support of your modified version, and
                     28:  *   4. retain our contact information in regard to use of the base
                     29:  *    software.
                     30:  * Permission to distribute the released version of the source code along
                     31:  * with corresponding source modifications in the form of a patch file is
                     32:  * granted with same provisions 2 through 4 for binary distributions.
                     33:  *
                     34:  * This software is provided "as is" without express or implied warranty
                     35:  * to the extent permitted by applicable law.
                     36: ]*/
                     37:
                     38: /*
                     39:  * AUTHORS
                     40:  *
                     41:  *   Original Software:
                     42:  *   Jos van der Woude, jvdwoude@hut.nl
                     43:  *
                     44:  */
                     45:
                     46: #include "plot.h"
                     47: #include "fnproto.h"
                     48:
                     49:
                     50: extern struct value stack[STACK_DEPTH];
                     51: extern int s_p;
                     52: extern double zero;
                     53:
                     54: #define ITMAX   200
                     55:
                     56: #ifdef FLT_EPSILON
                     57: # define MACHEPS FLT_EPSILON   /* 1.0E-08 */
                     58: #else
                     59: # define MACHEPS 1.0E-08
                     60: #endif
                     61:
                     62: /* AS239 value, e^-88 = 2^-127 */
                     63: #define MINEXP  -88.0
                     64:
                     65: #ifdef FLT_MAX
                     66: # define OFLOW   FLT_MAX               /* 1.0E+37 */
                     67: #else
                     68: # define OFLOW   1.0E+37
                     69: #endif
                     70:
                     71: /* AS239 value for igamma(a,x>=XBIG) = 1.0 */
                     72: #define XBIG    1.0E+08
                     73:
                     74: /*
                     75:  * Mathematical constants
                     76:  */
                     77: #define LNPI 1.14472988584940016
                     78: #define LNSQRT2PI 0.9189385332046727
                     79: #ifdef PI
                     80: # undef PI
                     81: #endif
                     82: #define PI 3.14159265358979323846
                     83: #define PNT68 0.6796875
                     84: #define SQRT_TWO 1.41421356237309504880168872420969809 /* JG */
                     85:
                     86: /* Prefer lgamma */
                     87: #ifndef GAMMA
                     88: # ifdef HAVE_LGAMMA
                     89: #  define GAMMA(x) lgamma (x)
                     90: # elif defined(HAVE_GAMMA)
                     91: #  define GAMMA(x) gamma (x)
                     92: # else
                     93: #  undef GAMMA
                     94: # endif
                     95: #endif
                     96:
                     97: #ifndef GAMMA
                     98: int signgam = 0;
                     99: #else
                    100: extern int signgam;            /* this is not always declared in math.h */
                    101: #endif
                    102:
                    103: /* Global variables, not visible outside this file */
                    104: static long Xm1 = 2147483563L;
                    105: static long Xm2 = 2147483399L;
                    106: static long Xa1 = 40014L;
                    107: static long Xa2 = 40692L;
                    108:
                    109: /* Local function declarations, not visible outside this file */
                    110: static double confrac __PROTO((double a, double b, double x));
                    111: static double ibeta __PROTO((double a, double b, double x));
                    112: static double igamma __PROTO((double a, double x));
                    113: static double ranf __PROTO((double init));
                    114: static double inverse_normal_func __PROTO((double p));
                    115: static double inverse_error_func __PROTO((double p));
                    116:
                    117: #ifndef GAMMA
                    118: /* Provide GAMMA function for those who do not already have one */
                    119: static double lngamma __PROTO((double z));
                    120: static double lgamneg __PROTO((double z));
                    121: static double lgampos __PROTO((double z));
                    122:
                    123: /**
                    124:  * from statlib, Thu Jan 23 15:02:27 EST 1992 ***
                    125:  *
                    126:  * This file contains two algorithms for the logarithm of the gamma function.
                    127:  * Algorithm AS 245 is the faster (but longer) and gives an accuracy of about
                    128:  * 10-12 significant decimal digits except for small regions around X = 1 and
                    129:  * X = 2, where the function goes to zero.
                    130:  * The second algorithm is not part of the AS algorithms.   It is slower but
                    131:  * gives 14 or more significant decimal digits accuracy, except around X = 1
                    132:  * and X = 2.   The Lanczos series from which this algorithm is derived is
                    133:  * interesting in that it is a convergent series approximation for the gamma
                    134:  * function, whereas the familiar series due to De Moivre (and usually wrongly
                    135:  * called Stirling's approximation) is only an asymptotic approximation, as
                    136:  * is the true and preferable approximation due to Stirling.
                    137:  *
                    138:  * Uses Lanczos-type approximation to ln(gamma) for z > 0. Reference: Lanczos,
                    139:  * C. 'A precision approximation of the gamma function', J. SIAM Numer.
                    140:  * Anal., B, 1, 86-96, 1964. Accuracy: About 14 significant digits except for
                    141:  * small regions in the vicinity of 1 and 2.
                    142:  *
                    143:  * Programmer: Alan Miller CSIRO Division of Mathematics & Statistics
                    144:  *
                    145:  * Latest revision - 17 April 1988
                    146:  *
                    147:  * Additions: Translated from fortran to C, code added to handle values z < 0.
                    148:  * The global variable signgam contains the sign of the gamma function.
                    149:  *
                    150:  * IMPORTANT: The signgam variable contains garbage until AFTER the call to
                    151:  * lngamma().
                    152:  *
                    153:  * Permission granted to distribute freely for non-commercial purposes only
                    154:  * Copyright (c) 1992 Jos van der Woude, jvdwoude@hut.nl
                    155:  */
                    156:
                    157: /* Local data, not visible outside this file
                    158:    static double   a[] =
                    159:    {
                    160:    0.9999999999995183E+00,
                    161:    0.6765203681218835E+03,
                    162:    -.1259139216722289E+04,
                    163:    0.7713234287757674E+03,
                    164:    -.1766150291498386E+03,
                    165:    0.1250734324009056E+02,
                    166:    -.1385710331296526E+00,
                    167:    0.9934937113930748E-05,
                    168:    0.1659470187408462E-06,
                    169:    };   */
                    170:
                    171: /* from Ray Toy */
                    172: static double GPFAR a[] =
                    173: {
                    174:     .99999999999980993227684700473478296744476168282198,
                    175:     676.52036812188509856700919044401903816411251975244084,
                    176:     -1259.13921672240287047156078755282840836424300664868028,
                    177:     771.32342877765307884865282588943070775227268469602500,
                    178:     -176.61502916214059906584551353999392943274507608117860,
                    179:     12.50734327868690481445893685327104972970563021816420,
                    180:     -.13857109526572011689554706984971501358032683492780,
                    181:     .00000998436957801957085956266828104544089848531228,
                    182:     .00000015056327351493115583383579667028994545044040,
                    183: };
                    184:
                    185: static double lgamneg(z)
                    186: double z;
                    187: {
                    188:     double tmp;
                    189:
                    190:     /* Use reflection formula, then call lgampos() */
                    191:     tmp = sin(z * PI);
                    192:
                    193:     if (fabs(tmp) < MACHEPS) {
                    194:        tmp = 0.0;
                    195:     } else if (tmp < 0.0) {
                    196:        tmp = -tmp;
                    197:        signgam = -1;
                    198:     }
                    199:     return LNPI - lgampos(1.0 - z) - log(tmp);
                    200:
                    201: }
                    202:
                    203: static double lgampos(z)
                    204: double z;
                    205: {
                    206:     double sum;
                    207:     double tmp;
                    208:     int i;
                    209:
                    210:     sum = a[0];
                    211:     for (i = 1, tmp = z; i < 9; i++) {
                    212:        sum += a[i] / tmp;
                    213:        tmp++;
                    214:     }
                    215:
                    216:     return log(sum) + LNSQRT2PI - z - 6.5 + (z - 0.5) * log(z + 6.5);
                    217: }
                    218:
                    219: static double lngamma(z)
                    220: double z;
                    221: {
                    222:     signgam = 1;
                    223:
                    224:     if (z <= 0.0)
                    225:        return lgamneg(z);
                    226:     else
                    227:        return lgampos(z);
                    228: }
                    229:
                    230: # define GAMMA(x) lngamma ((x))
                    231: #endif /* !GAMMA */
                    232:
                    233: void f_erf()
                    234: {
                    235:     struct value a;
                    236:     double x;
                    237:
                    238:     x = real(pop(&a));
                    239:
                    240: #ifdef HAVE_ERF
                    241:     x = erf(x);
                    242: #else
                    243:     {
                    244:        int fsign;
                    245:        fsign = x >= 0 ? 1 : 0;
                    246:        x = igamma(0.5, (x)*(x));
                    247:        if (x == -1.0) {
                    248:            undefined = TRUE;
                    249:            x = 0.0;
                    250:        } else {
                    251:            if (fsign == 0)
                    252:                x = -x;
                    253:        }
                    254:     }
                    255: #endif
                    256:     push(Gcomplex(&a, x, 0.0));
                    257: }
                    258:
                    259: void f_erfc()
                    260: {
                    261:     struct value a;
                    262:     double x;
                    263:
                    264:     x = real(pop(&a));
                    265: #ifdef HAVE_ERFC
                    266:     x = erfc(x);
                    267: #else
                    268:     {
                    269:        int fsign;
                    270:        fsign = x >= 0 ? 1 : 0;
                    271:        x = igamma(0.5, (x)*(x));
                    272:        if (x == 1.0) {
                    273:            undefined = TRUE;
                    274:            x = 0.0;
                    275:        } else {
                    276:            x = fsign > 0 ? 1.0 - x : 1.0 + x ;
                    277:        }
                    278:     }
                    279: #endif
                    280:     push(Gcomplex(&a, x, 0.0));
                    281: }
                    282:
                    283: void f_ibeta()
                    284: {
                    285:     struct value a;
                    286:     double x;
                    287:     double arg1;
                    288:     double arg2;
                    289:
                    290:     x = real(pop(&a));
                    291:     arg2 = real(pop(&a));
                    292:     arg1 = real(pop(&a));
                    293:
                    294:     x = ibeta(arg1, arg2, x);
                    295:     if (x == -1.0) {
                    296:        undefined = TRUE;
                    297:        push(Ginteger(&a, 0));
                    298:     } else
                    299:        push(Gcomplex(&a, x, 0.0));
                    300: }
                    301:
                    302: void f_igamma()
                    303: {
                    304:     struct value a;
                    305:     double x;
                    306:     double arg1;
                    307:
                    308:     x = real(pop(&a));
                    309:     arg1 = real(pop(&a));
                    310:
                    311:     x = igamma(arg1, x);
                    312:     if (x == -1.0) {
                    313:        undefined = TRUE;
                    314:        push(Ginteger(&a, 0));
                    315:     } else
                    316:        push(Gcomplex(&a, x, 0.0));
                    317: }
                    318:
                    319: void f_gamma()
                    320: {
                    321:     register double y;
                    322:     struct value a;
                    323:
                    324:     y = GAMMA(real(pop(&a)));
                    325:     if (y > 88.0) {
                    326:        undefined = TRUE;
                    327:        push(Ginteger(&a, 0));
                    328:     } else
                    329:        push(Gcomplex(&a, signgam * gp_exp(y), 0.0));
                    330: }
                    331:
                    332: void f_lgamma()
                    333: {
                    334:     struct value a;
                    335:
                    336:     push(Gcomplex(&a, GAMMA(real(pop(&a))), 0.0));
                    337: }
                    338:
                    339: #ifndef BADRAND
                    340:
                    341: void f_rand()
                    342: {
                    343:     struct value a;
                    344:
                    345:     push(Gcomplex(&a, ranf(real(pop(&a))), 0.0));
                    346: }
                    347:
                    348: #else /* BADRAND */
                    349:
                    350: /* Use only to observe the effect of a "bad" random number generator. */
                    351: void f_rand()
                    352: {
                    353:     struct value a;
                    354:
                    355:     static unsigned int y = 0;
                    356:     unsigned int maxran = 1000;
                    357:
                    358:     (void) real(pop(&a));
                    359:     y = (781 * y + 387) % maxran;
                    360:
                    361:     push(Gcomplex(&a, (double) y / maxran, 0.0));
                    362: }
                    363:
                    364: #endif /* BADRAND */
                    365:
                    366: /** ibeta.c
                    367:  *
                    368:  *   DESCRIB   Approximate the incomplete beta function Ix(a, b).
                    369:  *
                    370:  *                           _
                    371:  *                          |(a + b)     /x  (a-1)         (b-1)
                    372:  *             Ix(a, b) = -_-------_--- * |  t     * (1 - t)     dt (a,b > 0)
                    373:  *                        |(a) * |(b)   /0
                    374:  *
                    375:  *
                    376:  *
                    377:  *   CALL      p = ibeta(a, b, x)
                    378:  *
                    379:  *             double    a    > 0
                    380:  *             double    b    > 0
                    381:  *             double    x    [0, 1]
                    382:  *
                    383:  *   WARNING   none
                    384:  *
                    385:  *   RETURN    double    p    [0, 1]
                    386:  *                            -1.0 on error condition
                    387:  *
                    388:  *   XREF      lngamma()
                    389:  *
                    390:  *   BUGS      none
                    391:  *
                    392:  *   REFERENCE The continued fraction expansion as given by
                    393:  *             Abramowitz and Stegun (1964) is used.
                    394:  *
                    395:  * Permission granted to distribute freely for non-commercial purposes only
                    396:  * Copyright (c) 1992 Jos van der Woude, jvdwoude@hut.nl
                    397:  */
                    398:
                    399: static double ibeta(a, b, x)
                    400: double a, b, x;
                    401: {
                    402:     /* Test for admissibility of arguments */
                    403:     if (a <= 0.0 || b <= 0.0)
                    404:        return -1.0;
                    405:     if (x < 0.0 || x > 1.0)
                    406:        return -1.0;;
                    407:
                    408:     /* If x equals 0 or 1, return x as prob */
                    409:     if (x == 0.0 || x == 1.0)
                    410:        return x;
                    411:
                    412:     /* Swap a, b if necessarry for more efficient evaluation */
                    413:     return a < x * (a + b) ? 1.0 - confrac(b, a, 1.0 - x) : confrac(a, b, x);
                    414: }
                    415:
                    416: static double confrac(a, b, x)
                    417: double a, b, x;
                    418: {
                    419:     double Alo = 0.0;
                    420:     double Ahi;
                    421:     double Aev;
                    422:     double Aod;
                    423:     double Blo = 1.0;
                    424:     double Bhi = 1.0;
                    425:     double Bod = 1.0;
                    426:     double Bev = 1.0;
                    427:     double f;
                    428:     double fold;
                    429:     double Apb = a + b;
                    430:     double d;
                    431:     int i;
                    432:     int j;
                    433:
                    434:     /* Set up continued fraction expansion evaluation. */
                    435:     Ahi = gp_exp(GAMMA(Apb) + a * log(x) + b * log(1.0 - x) -
                    436:                 GAMMA(a + 1.0) - GAMMA(b));
                    437:
                    438:     /*
                    439:      * Continued fraction loop begins here. Evaluation continues until
                    440:      * maximum iterations are exceeded, or convergence achieved.
                    441:      */
                    442:     for (i = 0, j = 1, f = Ahi; i <= ITMAX; i++, j++) {
                    443:        d = a + j + i;
                    444:        Aev = -(a + i) * (Apb + i) * x / d / (d - 1.0);
                    445:        Aod = j * (b - j) * x / d / (d + 1.0);
                    446:        Alo = Bev * Ahi + Aev * Alo;
                    447:        Blo = Bev * Bhi + Aev * Blo;
                    448:        Ahi = Bod * Alo + Aod * Ahi;
                    449:        Bhi = Bod * Blo + Aod * Bhi;
                    450:
                    451:        if (fabs(Bhi) < MACHEPS)
                    452:            Bhi = 0.0;
                    453:
                    454:        if (Bhi != 0.0) {
                    455:            fold = f;
                    456:            f = Ahi / Bhi;
                    457:            if (fabs(f - fold) < fabs(f) * MACHEPS)
                    458:                return f;
                    459:        }
                    460:     }
                    461:
                    462:     return -1.0;
                    463: }
                    464:
                    465: /** igamma.c
                    466:  *
                    467:  *   DESCRIB   Approximate the incomplete gamma function P(a, x).
                    468:  *
                    469:  *                         1     /x  -t   (a-1)
                    470:  *             P(a, x) = -_--- * |  e  * t     dt      (a > 0)
                    471:  *                       |(a)   /0
                    472:  *
                    473:  *   CALL      p = igamma(a, x)
                    474:  *
                    475:  *             double    a    >  0
                    476:  *             double    x    >= 0
                    477:  *
                    478:  *   WARNING   none
                    479:  *
                    480:  *   RETURN    double    p    [0, 1]
                    481:  *                            -1.0 on error condition
                    482:  *
                    483:  *   XREF      lngamma()
                    484:  *
                    485:  *   BUGS      Values 0 <= x <= 1 may lead to inaccurate results.
                    486:  *
                    487:  *   REFERENCE ALGORITHM AS239  APPL. STATIST. (1988) VOL. 37, NO. 3
                    488:  *
                    489:  * Permission granted to distribute freely for non-commercial purposes only
                    490:  * Copyright (c) 1992 Jos van der Woude, jvdwoude@hut.nl
                    491:  */
                    492:
                    493: /* Global variables, not visible outside this file */
                    494: static double pn1, pn2, pn3, pn4, pn5, pn6;
                    495:
                    496: static double igamma(a, x)
                    497: double a, x;
                    498: {
                    499:     double arg;
                    500:     double aa;
                    501:     double an;
                    502:     double b;
                    503:     int i;
                    504:
                    505:     /* Check that we have valid values for a and x */
                    506:     if (x < 0.0 || a <= 0.0)
                    507:        return -1.0;
                    508:
                    509:     /* Deal with special cases */
                    510:     if (x == 0.0)
                    511:        return 0.0;
                    512:     if (x > XBIG)
                    513:        return 1.0;
                    514:
                    515:     /* Check value of factor arg */
                    516:     arg = a * log(x) - x - GAMMA(a + 1.0);
                    517:     if (arg < MINEXP)
                    518:        return -1.0;
                    519:     arg = gp_exp(arg);
                    520:
                    521:     /* Choose infinite series or continued fraction. */
                    522:
                    523:     if ((x > 1.0) && (x >= a + 2.0)) {
                    524:        /* Use a continued fraction expansion */
                    525:
                    526:        double rn;
                    527:        double rnold;
                    528:
                    529:        aa = 1.0 - a;
                    530:        b = aa + x + 1.0;
                    531:        pn1 = 1.0;
                    532:        pn2 = x;
                    533:        pn3 = x + 1.0;
                    534:        pn4 = x * b;
                    535:        rnold = pn3 / pn4;
                    536:
                    537:        for (i = 1; i <= ITMAX; i++) {
                    538:
                    539:            aa++;
                    540:            b += 2.0;
                    541:            an = aa * (double) i;
                    542:
                    543:            pn5 = b * pn3 - an * pn1;
                    544:            pn6 = b * pn4 - an * pn2;
                    545:
                    546:            if (pn6 != 0.0) {
                    547:
                    548:                rn = pn5 / pn6;
                    549:                if (fabs(rnold - rn) <= GPMIN(MACHEPS, MACHEPS * rn))
                    550:                    return 1.0 - arg * rn * a;
                    551:
                    552:                rnold = rn;
                    553:            }
                    554:            pn1 = pn3;
                    555:            pn2 = pn4;
                    556:            pn3 = pn5;
                    557:            pn4 = pn6;
                    558:
                    559:            /* Re-scale terms in continued fraction if terms are large */
                    560:            if (fabs(pn5) >= OFLOW) {
                    561:
                    562:                pn1 /= OFLOW;
                    563:                pn2 /= OFLOW;
                    564:                pn3 /= OFLOW;
                    565:                pn4 /= OFLOW;
                    566:            }
                    567:        }
                    568:     } else {
                    569:        /* Use Pearson's series expansion. */
                    570:
                    571:        for (i = 0, aa = a, an = b = 1.0; i <= ITMAX; i++) {
                    572:
                    573:            aa++;
                    574:            an *= x / aa;
                    575:            b += an;
                    576:            if (an < b * MACHEPS)
                    577:                return arg * b;
                    578:        }
                    579:     }
                    580:     return -1.0;
                    581: }
                    582:
                    583: /***********************************************************************
                    584:      double ranf(double init)
                    585:                 RANDom number generator as a Function
                    586:      Returns a random floating point number from a uniform distribution
                    587:      over 0 - 1 (endpoints of this interval are not returned) using a
                    588:      large integer generator.
                    589:      This is a transcription from Pascal to Fortran of routine
                    590:      Uniform_01 from the paper
                    591:      L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
                    592:      with Splitting Facilities." ACM Transactions on Mathematical
                    593:      Software, 17:98-111 (1991)
                    594:
                    595:                GeNerate LarGe Integer
                    596:      Returns a random integer following a uniform distribution over
                    597:      (1, 2147483562) using the generator.
                    598:      This is a transcription from Pascal to Fortran of routine
                    599:      Random from the paper
                    600:      L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package
                    601:      with Splitting Facilities." ACM Transactions on Mathematical
                    602:      Software, 17:98-111 (1991)
                    603: ***********************************************************************/
                    604: static double ranf(init)
                    605: double init;
                    606: {
                    607:
                    608:     long k, z;
                    609:     static int firsttime = 1;
                    610:     static long s1, s2;
                    611:
                    612:     /* (Re)-Initialize seeds if necessary */
                    613:     if (init < 0.0 || firsttime == 1) {
                    614:        firsttime = 0;
                    615:        s1 = 1234567890L;
                    616:        s2 = 1234567890L;
                    617:     }
                    618:     /* Generate pseudo random integers */
                    619:     k = s1 / 53668L;
                    620:     s1 = Xa1 * (s1 - k * 53668L) - k * 12211;
                    621:     if (s1 < 0)
                    622:        s1 += Xm1;
                    623:     k = s2 / 52774L;
                    624:     s2 = Xa2 * (s2 - k * 52774L) - k * 3791;
                    625:     if (s2 < 0)
                    626:        s2 += Xm2;
                    627:     z = s1 - s2;
                    628:     if (z < 1)
                    629:        z += (Xm1 - 1);
                    630:
                    631:     /*
                    632:      * 4.656613057E-10 is 1/Xm1.  Xm1 is set at the top of this file and is
                    633:      * currently 2147483563. If Xm1 changes, change this also.
                    634:      */
                    635:     return (double) 4.656613057E-10 *z;
                    636: }
                    637:
                    638: /* ----------------------------------------------------------------
                    639:    Following to specfun.c made by John Grosh (jgrosh@arl.mil)
                    640:    on 28 OCT 1992.
                    641:    ---------------------------------------------------------------- */
                    642:
                    643: void f_normal()
                    644: {                              /* Normal or Gaussian Probability Function */
                    645:     struct value a;
                    646:     double x;
                    647:
                    648:     /* ref. Abramowitz and Stegun 1964, "Handbook of Mathematical
                    649:        Functions", Applied Mathematics Series, vol 55,
                    650:        Chapter 26, page 934, Eqn. 26.2.29 and Jos van der Woude
                    651:        code found above */
                    652:
                    653:     x = real(pop(&a));
                    654:
                    655:     x = 0.5 * SQRT_TWO * x;
                    656: #ifdef HAVE_ERF
                    657:     x = 0.5 * (1.0 + erf(x));
                    658: #else
                    659:     {
                    660:        int fsign;
                    661:        fsign = x >= 0 ? 1 : 0;
                    662:        x = igamma(0.5, (x)*(x));
                    663:        if (x == 1.0) {
                    664:            undefined = TRUE;
                    665:            x = 0.0;
                    666:        } else {
                    667:            if (fsign == 0)
                    668:                x = -(x);
                    669:            x = 0.5 * (1.0 + x);
                    670:        }
                    671:     }
                    672: #endif
                    673:     push(Gcomplex(&a, x, 0.0));
                    674: }
                    675:
                    676: void f_inverse_normal()
                    677: {                              /* Inverse normal distribution function */
                    678:     struct value a;
                    679:     double x;
                    680:
                    681:     x = real(pop(&a));
                    682:
                    683:     if (x <= 0.0 || x >= 1.0) {
                    684:        undefined = TRUE;
                    685:        push(Gcomplex(&a, 0.0, 0.0));
                    686:     } else {
                    687:        push(Gcomplex(&a, inverse_normal_func(x), 0.0));
                    688:     }
                    689: }
                    690:
                    691:
                    692: void f_inverse_erf()
                    693: {                              /* Inverse error function */
                    694:     struct value a;
                    695:     double x;
                    696:
                    697:     x = real(pop(&a));
                    698:
                    699:     if (fabs(x) >= 1.0) {
                    700:        undefined = TRUE;
                    701:        push(Gcomplex(&a, 0.0, 0.0));
                    702:     } else {
                    703:        push(Gcomplex(&a, inverse_error_func(x), 0.0));
                    704:     }
                    705: }
                    706:
                    707: static double inverse_normal_func(p)
                    708: double p;
                    709: {
                    710:     /*
                    711:        Source: This routine was derived (using f2c) from the
                    712:        FORTRAN subroutine MDNRIS found in
                    713:        ACM Algorithm 602 obtained from netlib.
                    714:
                    715:        MDNRIS code contains the 1978 Copyright
                    716:        by IMSL, INC. .  Since MDNRIS has been
                    717:        submitted to netlib it may be used with
                    718:        the restriction that it may only be
                    719:        used for noncommercial purposes and that
                    720:        IMSL be acknowledged as the copyright-holder
                    721:        of the code.
                    722:      */
                    723:
                    724:     /* Initialized data */
                    725:     static double eps = 1e-10;
                    726:     static double g0 = 1.851159e-4;
                    727:     static double g1 = -.002028152;
                    728:     static double g2 = -.1498384;
                    729:     static double g3 = .01078639;
                    730:     static double h0 = .09952975;
                    731:     static double h1 = .5211733;
                    732:     static double h2 = -.06888301;
                    733:     static double sqrt2 = 1.414213562373095;
                    734:
                    735:     /* Local variables */
                    736:     static double a, w, x;
                    737:     static double sd, wi, sn, y;
                    738:
                    739:     /* Note: 0.0 < p < 1.0 */
                    740:
                    741:     /* p too small, compute y directly */
                    742:     if (p <= eps) {
                    743:        a = p + p;
                    744:        w = sqrt(-(double) log(a + (a - a * a)));
                    745:
                    746:        /* use a rational function in 1.0 / w */
                    747:        wi = 1.0 / w;
                    748:        sn = ((g3 * wi + g2) * wi + g1) * wi;
                    749:        sd = ((wi + h2) * wi + h1) * wi + h0;
                    750:        y = w + w * (g0 + sn / sd);
                    751:        y = -y * sqrt2;
                    752:     } else {
                    753:        x = 1.0 - (p + p);
                    754:        y = inverse_error_func(x);
                    755:        y = -sqrt2 * y;
                    756:     }
                    757:     return (y);
                    758: }
                    759:
                    760:
                    761: static double inverse_error_func(p)
                    762: double p;
                    763: {
                    764:     /*
                    765:        Source: This routine was derived (using f2c) from the
                    766:        FORTRAN subroutine MERFI found in
                    767:        ACM Algorithm 602 obtained from netlib.
                    768:
                    769:        MDNRIS code contains the 1978 Copyright
                    770:        by IMSL, INC. .  Since MERFI has been
                    771:        submitted to netlib, it may be used with
                    772:        the restriction that it may only be
                    773:        used for noncommercial purposes and that
                    774:        IMSL be acknowledged as the copyright-holder
                    775:        of the code.
                    776:      */
                    777:
                    778:
                    779:
                    780:     /* Initialized data */
                    781:     static double a1 = -.5751703;
                    782:     static double a2 = -1.896513;
                    783:     static double a3 = -.05496261;
                    784:     static double b0 = -.113773;
                    785:     static double b1 = -3.293474;
                    786:     static double b2 = -2.374996;
                    787:     static double b3 = -1.187515;
                    788:     static double c0 = -.1146666;
                    789:     static double c1 = -.1314774;
                    790:     static double c2 = -.2368201;
                    791:     static double c3 = .05073975;
                    792:     static double d0 = -44.27977;
                    793:     static double d1 = 21.98546;
                    794:     static double d2 = -7.586103;
                    795:     static double e0 = -.05668422;
                    796:     static double e1 = .3937021;
                    797:     static double e2 = -.3166501;
                    798:     static double e3 = .06208963;
                    799:     static double f0 = -6.266786;
                    800:     static double f1 = 4.666263;
                    801:     static double f2 = -2.962883;
                    802:     static double g0 = 1.851159e-4;
                    803:     static double g1 = -.002028152;
                    804:     static double g2 = -.1498384;
                    805:     static double g3 = .01078639;
                    806:     static double h0 = .09952975;
                    807:     static double h1 = .5211733;
                    808:     static double h2 = -.06888301;
                    809:
                    810:     /* Local variables */
                    811:     static double a, b, f, w, x, y, z, sigma, z2, sd, wi, sn;
                    812:
                    813:     x = p;
                    814:
                    815:     /* determine sign of x */
                    816:     if (x > 0)
                    817:        sigma = 1.0;
                    818:     else
                    819:        sigma = -1.0;
                    820:
                    821:     /* Note: -1.0 < x < 1.0 */
                    822:
                    823:     z = fabs(x);
                    824:
                    825:     /* z between 0.0 and 0.85, approx. f by a
                    826:        rational function in z  */
                    827:
                    828:     if (z <= 0.85) {
                    829:        z2 = z * z;
                    830:        f = z + z * (b0 + a1 * z2 / (b1 + z2 + a2
                    831:                                     / (b2 + z2 + a3 / (b3 + z2))));
                    832:
                    833:        /* z greater than 0.85 */
                    834:     } else {
                    835:        a = 1.0 - z;
                    836:        b = z;
                    837:
                    838:        /* reduced argument is in (0.85,1.0),
                    839:           obtain the transformed variable */
                    840:
                    841:        w = sqrt(-(double) log(a + a * b));
                    842:
                    843:        /* w greater than 4.0, approx. f by a
                    844:           rational function in 1.0 / w */
                    845:
                    846:        if (w >= 4.0) {
                    847:            wi = 1.0 / w;
                    848:            sn = ((g3 * wi + g2) * wi + g1) * wi;
                    849:            sd = ((wi + h2) * wi + h1) * wi + h0;
                    850:            f = w + w * (g0 + sn / sd);
                    851:
                    852:            /* w between 2.5 and 4.0, approx.
                    853:               f by a rational function in w */
                    854:
                    855:        } else if (w < 4.0 && w > 2.5) {
                    856:            sn = ((e3 * w + e2) * w + e1) * w;
                    857:            sd = ((w + f2) * w + f1) * w + f0;
                    858:            f = w + w * (e0 + sn / sd);
                    859:
                    860:            /* w between 1.13222 and 2.5, approx. f by
                    861:               a rational function in w */
                    862:        } else if (w <= 2.5 && w > 1.13222) {
                    863:            sn = ((c3 * w + c2) * w + c1) * w;
                    864:            sd = ((w + d2) * w + d1) * w + d0;
                    865:            f = w + w * (c0 + sn / sd);
                    866:        }
                    867:     }
                    868:     y = sigma * f;
                    869:     return (y);
                    870: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>