Sindbad~EG File Manager
/* digamma and first polygamma function
Adapted and CORRECTED! from: C Mathematical Function Handbook by Louis Baker
Modified by M. Beeson for use in Mathpert, 9.17.92
In particular, 'abs' has to be changed to 'fabs' or you compute
very wrong values.
*/
#include <math.h>
#define BADVAL 2.0E300
#define pi 3.141592653589793238462643383279
#define Egamma 0.577215664901532860606512090082402431
double pg1(double x)
{ int i;
double sum,z,u,y;
double b[10]={.4041138064,.1471100206,.0500956643,
.0160671426,.004941886,.0014725602,.0004282353,
.0001221952,.000034347,.0000095387};
if( x<=0. && fabs((int)(x)-x) <1.e-8)
return BADVAL;
u=x-1.;
if(u>0. && u<=.5)
{ sum=b[9];
y=u*u;
for(i=8;i>=0;i--)
{ sum= sum*y+b[i];
}
sum*=u;
/*printf(" omega=%e\n",sum);*/
z=1./(u+1.); /* z=1/x */
sum-=.5*z*z;
z=1./(1.-u);
sum+=.5*z*z;
z=sin(u*pi);
return pi*pi*.5/(z*z)-sum-.5/(u*u);
}
if(x>=2.)
{ /* printf(" asymptotic x=%e\n",x);*/
y=1./x;
z=y*y;
/*printf(" asymptotic z,y=%e %e\n",y,z);*/
/* desmet blows up on underflow*/
return(y+z*(.5+y*(1./6.+z*(-1./30./*+z*(1./42.-z/30.)*/))));
}
if(x<0.)
{ z=sin(pi*x);
return (-pg1(1.-x)-pi*pi/(z*z));
}
/* .5<=x<2.*/
/*if(x>1.)*/
return(pg1(x+1.)+1./(x*x));
}
/*_________________________________________________________________*/
double digamma(double x)
{
static double digammin;
double q,y,z,sum;
q=x;
sum=0.;
if(q==0.)
return BADVAL;
if(digammin<=0.)
digammin=30.;
if(q<0.)
{ if( fabs((int)(q)-q) <1.e-8)
return BADVAL;
q=1.-x;sum=pi/tan(pi*x); /*note sum subtracted from final result*/
}
while(q<digammin)
{ if(q==0.)
return BADVAL;
sum+=1./q;
q++;
}
y=1/q;
z=y*y;
/* logx-1/2x- sum n=1 to inf of B[2n]z^-2n/2n*/
return log(q)-sum-.5*y-z*(1./12.-z*(1/120.-z*(1/252.-z/240.)));
}
#undef pi
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists