| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 | /*							psi.c * *	Psi (digamma) function * * * SYNOPSIS: * * double x, y, psi(); * * y = psi( x ); * * * DESCRIPTION: * *              d      - *   psi(x)  =  -- ln | (x) *              dx * * is the logarithmic derivative of the gamma function. * For integer x, *                   n-1 *                    - * psi(n) = -EUL  +   >  1/k. *                    - *                   k=1 * * This formula is used for 0 < n <= 10.  If x is negative, it * is transformed to a positive argument by the reflection * formula  psi(1-x) = psi(x) + pi cot(pi x). * For general positive x, the argument is made greater than 10 * using the recurrence  psi(x+1) = psi(x) + 1/x. * Then the following asymptotic expansion is applied: * *                           inf.   B *                            -      2k * psi(x) = log(x) - 1/2x -   >   ------- *                            -        2k *                           k=1   2k x * * where the B2k are Bernoulli numbers. * * ACCURACY: *    Relative error (except absolute when |psi| < 1): * arithmetic   domain     # trials      peak         rms *    DEC       0,30         2500       1.7e-16     2.0e-17 *    IEEE      0,30        30000       1.3e-15     1.4e-16 *    IEEE      -30,0       40000       1.5e-15     2.2e-16 * * ERROR MESSAGES: *     message         condition      value returned * psi singularity    x integer <=0      MAXNUM *//*Cephes Math Library Release 2.8:  June, 2000Copyright 1984, 1987, 1992, 2000 by Stephen L. Moshier*/#include <math.h>#ifdef UNKstatic double A[] = { 8.33333333333333333333E-2,-2.10927960927960927961E-2, 7.57575757575757575758E-3,-4.16666666666666666667E-3, 3.96825396825396825397E-3,-8.33333333333333333333E-3, 8.33333333333333333333E-2};#endif#ifdef DECstatic unsigned short A[] = {0037252,0125252,0125252,0125253,0136654,0145314,0126312,0146255,0036370,0037017,0101740,0174076,0136210,0104210,0104210,0104211,0036202,0004040,0101010,0020202,0136410,0104210,0104210,0104211,0037252,0125252,0125252,0125253};#endif#ifdef IBMPCstatic unsigned short A[] = {0x5555,0x5555,0x5555,0x3fb5,0x5996,0x9599,0x9959,0xbf95,0x1f08,0xf07c,0x07c1,0x3f7f,0x1111,0x1111,0x1111,0xbf71,0x0410,0x1041,0x4104,0x3f70,0x1111,0x1111,0x1111,0xbf81,0x5555,0x5555,0x5555,0x3fb5};#endif#ifdef MIEEEstatic unsigned short A[] = {0x3fb5,0x5555,0x5555,0x5555,0xbf95,0x9959,0x9599,0x5996,0x3f7f,0x07c1,0xf07c,0x1f08,0xbf71,0x1111,0x1111,0x1111,0x3f70,0x4104,0x1041,0x0410,0xbf81,0x1111,0x1111,0x1111,0x3fb5,0x5555,0x5555,0x5555};#endif#define EUL 0.57721566490153286061#ifdef ANSIPROTextern double floor ( double );extern double log ( double );extern double tan ( double );extern double polevl ( double, void *, int );#elsedouble floor(), log(), tan(), polevl();#endifextern double PI, MAXNUM;double psi(x)double x;{double p, q, nz, s, w, y, z;int i, n, negative;negative = 0;nz = 0.0;if( x <= 0.0 )	{	negative = 1;	q = x;	p = floor(q);	if( p == q )		{		mtherr( "psi", SING );		return( MAXNUM );		}/* Remove the zeros of tan(PI x) * by subtracting the nearest integer from x */	nz = q - p;	if( nz != 0.5 )		{		if( nz > 0.5 )			{			p += 1.0;			nz = q - p;			}		nz = PI/tan(PI*nz);		}	else		{		nz = 0.0;		}	x = 1.0 - x;	}/* check for positive integer up to 10 */if( (x <= 10.0) && (x == floor(x)) )	{	y = 0.0;	n = x;	for( i=1; i<n; i++ )		{		w = i;		y += 1.0/w;		}	y -= EUL;	goto done;	}s = x;w = 0.0;while( s < 10.0 )	{	w += 1.0/s;	s += 1.0;	}if( s < 1.0e17 )	{	z = 1.0/(s * s);	y = z * polevl( z, A, 6 );	}else	y = 0.0;y = log(s)  -  (0.5/s)  -  y  -  w;done:if( negative )	{	y -= nz;	}return(y);}
 |