Sindbad~EG File Manager

Current Path : /usr/home/beeson/Otter-Lambda/yyy/deval/
Upload File :
Current File : /usr/home/beeson/Otter-Lambda/yyy/deval/gamma.c

/* M. Beeson, following ideas in Numerical Recipes pp. 108-109
  compute factorials, Gamma function, binomial coefficients
  producing decimal answers
  12.17.91 original date
  3.24.95  modified
  1.7.97  modified dbinomial to avoid warnings in VC
*/
#include <math.h>
#include <assert.h>
#define DEVAL_DLL
#include "export.h"
#include "terms.h"
#include "deval.h"
#include "baker.h"  /* for PI_DECIMAL */


#define BADVAL 2.0E300
double gammln(double);
int gamma2(double, double *);   /* called by deval.c */
int dfactorial(double, double *);
int dbinomial(double,double, double *);
/*_____________________________________________________________________*/
#define TABLEDIM 33
int dfactorial(double x, double *ansp)
/* compute factorial of x if x > 0 -- integer or not */
/* if isn't an int, but is very close to an int k, will not fail but
will compute k factorial */
/* return 0 to indicate success */
/* return 18 if factorial would overflow a double */

{ static int ntop = 4;
  long k;
  static double a[TABLEDIM] = {1.0, 1.0, 2.0, 6.0, 24.0}; /* fill in as needed */
  int j;
  if(x<0)
     return 19;
  if(x > 170 )  /* determined by exact calculation of 170! */
     return 18;
  if(x > 32)
     { *ansp = exp(gammln(x + 1.0));
       return 0;
     }
  if(nearint(x,&k) && ((k >> 17) == 0))
     { x = (double) k;  /* fix a slight deviation from an integer,
                      which would probably be due to roundoff error.  */
       if(k < TABLEDIM)  /* fill in the static lookup table */
          { while(ntop < k)
               { j = ntop++;
                 a[ntop] = a[j]*ntop;
               }
            *ansp = a[(int) k];
            return 0;
          }
     }
  *ansp = exp(gammln(x+1.0));
  return 0;
}
/*___________________________________________________________________*/
#define NFTABLE 25  /* small to save space -- was 100 in Numerical Recipes */
double factln(int n)
/* returns ln(n!) */
/* never overflows */
/* n is assumed to be positive */
{  static double a[NFTABLE];  /* table of function values */
   if(n <= 1)
      return 0.0;
   if(n < NFTABLE)  /* use or add to the table */
      return a[n] ? a[n] : (a[n]=gammln(n+1.0));
   return gammln(n+1.0);  /* out of range of the table */
}
#undef NFTABLE
/*___________________________________________________________________*/
int dbinomial( double x, double y, double *ansp)

/*  compute x choose y  if y is actually an integer */
/*  x isn't required even to be close to an integer */

{ double arg;
  long xx,yy;
  if(x <= 0.0 || y <= 0.0 )
     return 1;
  if( x-y < y)
     y = x-y;
  if (!nearint(y,&xx))
     return 17;  /* error value wanted by deval */
  if (nearint(x,&xx) && (xx >> 17) == 0  /* x converts to an int */
      && nearint(y,&yy) && (yy >> 17) == 0
     )
     { arg = factln((int)x) - factln((int)yy) - factln((int)(xx-yy));
       if(arg >= 709)   /* 308 ln 10 */
          { *ansp = BADVAL;
            return 16;
          }
       *ansp = floor(0.5 + exp(arg));
       return 0;
     }
  else
     { arg = gammln(x+1.0) - gammln(y+1.0) - gammln(x-y+1.0);
       if(arg >= 709)   /* 308 ln 10 */
          { *ansp = BADVAL;
            return 16;
          }
       *ansp = exp(arg);
       return 0;
     }
}
/*______________________________________________________________*/
double gammln(double xx)
/* computes ln of the gamma function for arguments > 1 */
{ double x,tmp,ser;
  static double cof[6]={76.18009173,-86.50532033,24.01409822,
                -1.231739516,0.120858003e-2,-0.536382e-5};
  int j;
  x=xx-1.0;
  tmp=x+5.5;
  tmp -= (x+0.5)*log(tmp);
  ser=1.0;
  for (j=0;j<=5;j++)
     { x += 1.0;
       ser += cof[j]/x;
     }
  return -tmp+log(2.50662827465*ser);
}
/*_____________________________________________________________*/
int gamma2 (double x, double *ansp)
{ long k;
  double y;
  if( x > 1.0)
     { *ansp = exp(gammln(x));
       return 0;
     }
  if(nearint(x,&k) && k==1)
     { *ansp = 1.0;
       return 0;
     }
      /* and now for x<1 : Gamma(x) = �x/(Gamma(2-x)sin(�x))
                                   or �/(Gamma(1-x)sin(�x))
             (p. 167 Numerical Recipes)  */
  y = sin(PI_DECIMAL*x);
  if(nearint(y,&k) && k==0)
     { *ansp = BADVAL;
       return 26;
     }
  if(x > 0.0)
     *ansp = (1.0-x) * PI_DECIMAL * exp(- gammln(2.0-x))/y;
  else /* x < 0.0 */
     *ansp = PI_DECIMAL * exp(- gammln(1.0-x))/y;
  return 0;
}

Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists