1: #ifndef lint
   2: static char sccsid[] = "@(#)lgamma.c	4.4 (Berkeley) 9/11/85";
   3: #endif not lint
   4: 
   5: /*
   6: 	C program for floating point log Gamma function
   7: 
   8: 	lgamma(x) computes the log of the absolute
   9: 	value of the Gamma function.
  10: 	The sign of the Gamma function is returned in the
  11: 	external quantity signgam.
  12: 
  13: 	The coefficients for expansion around zero
  14: 	are #5243 from Hart & Cheney; for expansion
  15: 	around infinity they are #5404.
  16: 
  17: 	Calls log, floor and sin.
  18: */
  19: 
  20: #include <math.h>
  21: #ifdef VAX
  22: #include <errno.h>
  23: #endif
  24: int signgam = 0;
  25: static double goobie    = 0.9189385332046727417803297;  /* log(2*pi)/2 */
  26: static double pi    = 3.1415926535897932384626434;
  27: 
  28: #define M 6
  29: #define N 8
  30: static double p1[] = {
  31:     0.83333333333333101837e-1,
  32:     -.277777777735865004e-2,
  33:     0.793650576493454e-3,
  34:     -.5951896861197e-3,
  35:     0.83645878922e-3,
  36:     -.1633436431e-2,
  37: };
  38: static double p2[] = {
  39:     -.42353689509744089647e5,
  40:     -.20886861789269887364e5,
  41:     -.87627102978521489560e4,
  42:     -.20085274013072791214e4,
  43:     -.43933044406002567613e3,
  44:     -.50108693752970953015e2,
  45:     -.67449507245925289918e1,
  46:     0.0,
  47: };
  48: static double q2[] = {
  49:     -.42353689509744090010e5,
  50:     -.29803853309256649932e4,
  51:     0.99403074150827709015e4,
  52:     -.15286072737795220248e4,
  53:     -.49902852662143904834e3,
  54:     0.18949823415702801641e3,
  55:     -.23081551524580124562e2,
  56:     0.10000000000000000000e1,
  57: };
  58: 
  59: double
  60: lgamma(arg)
  61: double arg;
  62: {
  63:     double log(), pos(), neg(), asym();
  64: 
  65:     signgam = 1.;
  66:     if(arg <= 0.) return(neg(arg));
  67:     if(arg > 8.) return(asym(arg));
  68:     return(log(pos(arg)));
  69: }
  70: 
  71: static double
  72: asym(arg)
  73: double arg;
  74: {
  75:     double log();
  76:     double n, argsq;
  77:     int i;
  78: 
  79:     argsq = 1./(arg*arg);
  80:     for(n=0,i=M-1; i>=0; i--){
  81:         n = n*argsq + p1[i];
  82:     }
  83:     return((arg-.5)*log(arg) - arg + goobie + n/arg);
  84: }
  85: 
  86: static double
  87: neg(arg)
  88: double arg;
  89: {
  90:     double t;
  91:     double log(), sin(), floor(), pos();
  92: 
  93:     arg = -arg;
  94:      /*
  95:       * to see if arg were a true integer, the old code used the
  96:       * mathematically correct observation:
  97:       * sin(n*pi) = 0 <=> n is an integer.
  98:       * but in finite precision arithmetic, sin(n*PI) will NEVER
  99:       * be zero simply because n*PI is a rational number.  hence
 100:       *	it failed to work with our newer, more accurate sin()
 101:       * which uses true pi to do the argument reduction...
 102:       *	temp = sin(pi*arg);
 103:       */
 104:     t = floor(arg);
 105:     if (arg - t  > 0.5e0)
 106:         t += 1.e0;              /* t := integer nearest arg */
 107: #ifdef VAX
 108:     if (arg == t) {
 109:         extern double infnan();
 110:         return(infnan(ERANGE));     /* +INF */
 111:     }
 112: #endif
 113:     signgam = (int) (t - 2*floor(t/2)); /* signgam =  1 if t was odd, */
 114:                         /*            0 if t was even */
 115:     signgam = signgam - 1 + signgam;    /* signgam =  1 if t was odd, */
 116:                         /*           -1 if t was even */
 117:     t = arg - t;                /*  -0.5 <= t <= 0.5 */
 118:     if (t < 0.e0) {
 119:         t = -t;
 120:         signgam = -signgam;
 121:     }
 122:     return(-log(arg*pos(arg)*sin(pi*t)/pi));
 123: }
 124: 
 125: static double
 126: pos(arg)
 127: double arg;
 128: {
 129:     double n, d, s;
 130:     register i;
 131: 
 132:     if(arg < 2.) return(pos(arg+1.)/arg);
 133:     if(arg > 3.) return((arg-1.)*pos(arg-1.));
 134: 
 135:     s = arg - 2.;
 136:     for(n=0,d=0,i=N-1; i>=0; i--){
 137:         n = n*s + p2[i];
 138:         d = d*s + q2[i];
 139:     }
 140:     return(n/d);
 141: }

Defined functions

asym defined in line 71; used 2 times
lgamma defined in line 59; used 2 times
neg defined in line 86; used 2 times
pos defined in line 125; used 6 times

Defined variables

goobie defined in line 25; used 1 times
  • in line 83
p1 defined in line 30; used 1 times
  • in line 81
p2 defined in line 38; used 1 times
pi defined in line 26; used 2 times
  • in line 122(2)
q2 defined in line 48; used 1 times
sccsid defined in line 2; never used
signgam defined in line 24; used 7 times

Defined macros

M defined in line 28; used 1 times
  • in line 80
N defined in line 29; used 1 times
Last modified: 1985-09-12
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1336
Valid CSS Valid XHTML 1.0 Strict