psi.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. /* psi.c
  2. *
  3. * Psi (digamma) function
  4. *
  5. *
  6. * SYNOPSIS:
  7. *
  8. * double x, y, psi();
  9. *
  10. * y = psi( x );
  11. *
  12. *
  13. * DESCRIPTION:
  14. *
  15. * d -
  16. * psi(x) = -- ln | (x)
  17. * dx
  18. *
  19. * is the logarithmic derivative of the gamma function.
  20. * For integer x,
  21. * n-1
  22. * -
  23. * psi(n) = -EUL + > 1/k.
  24. * -
  25. * k=1
  26. *
  27. * This formula is used for 0 < n <= 10. If x is negative, it
  28. * is transformed to a positive argument by the reflection
  29. * formula psi(1-x) = psi(x) + pi cot(pi x).
  30. * For general positive x, the argument is made greater than 10
  31. * using the recurrence psi(x+1) = psi(x) + 1/x.
  32. * Then the following asymptotic expansion is applied:
  33. *
  34. * inf. B
  35. * - 2k
  36. * psi(x) = log(x) - 1/2x - > -------
  37. * - 2k
  38. * k=1 2k x
  39. *
  40. * where the B2k are Bernoulli numbers.
  41. *
  42. * ACCURACY:
  43. * Relative error (except absolute when |psi| < 1):
  44. * arithmetic domain # trials peak rms
  45. * DEC 0,30 2500 1.7e-16 2.0e-17
  46. * IEEE 0,30 30000 1.3e-15 1.4e-16
  47. * IEEE -30,0 40000 1.5e-15 2.2e-16
  48. *
  49. * ERROR MESSAGES:
  50. * message condition value returned
  51. * psi singularity x integer <=0 MAXNUM
  52. */
  53. /*
  54. Cephes Math Library Release 2.8: June, 2000
  55. Copyright 1984, 1987, 1992, 2000 by Stephen L. Moshier
  56. */
  57. #include <math.h>
  58. #ifdef UNK
  59. static double A[] = {
  60. 8.33333333333333333333E-2,
  61. -2.10927960927960927961E-2,
  62. 7.57575757575757575758E-3,
  63. -4.16666666666666666667E-3,
  64. 3.96825396825396825397E-3,
  65. -8.33333333333333333333E-3,
  66. 8.33333333333333333333E-2
  67. };
  68. #endif
  69. #ifdef DEC
  70. static unsigned short A[] = {
  71. 0037252,0125252,0125252,0125253,
  72. 0136654,0145314,0126312,0146255,
  73. 0036370,0037017,0101740,0174076,
  74. 0136210,0104210,0104210,0104211,
  75. 0036202,0004040,0101010,0020202,
  76. 0136410,0104210,0104210,0104211,
  77. 0037252,0125252,0125252,0125253
  78. };
  79. #endif
  80. #ifdef IBMPC
  81. static unsigned short A[] = {
  82. 0x5555,0x5555,0x5555,0x3fb5,
  83. 0x5996,0x9599,0x9959,0xbf95,
  84. 0x1f08,0xf07c,0x07c1,0x3f7f,
  85. 0x1111,0x1111,0x1111,0xbf71,
  86. 0x0410,0x1041,0x4104,0x3f70,
  87. 0x1111,0x1111,0x1111,0xbf81,
  88. 0x5555,0x5555,0x5555,0x3fb5
  89. };
  90. #endif
  91. #ifdef MIEEE
  92. static unsigned short A[] = {
  93. 0x3fb5,0x5555,0x5555,0x5555,
  94. 0xbf95,0x9959,0x9599,0x5996,
  95. 0x3f7f,0x07c1,0xf07c,0x1f08,
  96. 0xbf71,0x1111,0x1111,0x1111,
  97. 0x3f70,0x4104,0x1041,0x0410,
  98. 0xbf81,0x1111,0x1111,0x1111,
  99. 0x3fb5,0x5555,0x5555,0x5555
  100. };
  101. #endif
  102. #define EUL 0.57721566490153286061
  103. #ifdef ANSIPROT
  104. extern double floor ( double );
  105. extern double log ( double );
  106. extern double tan ( double );
  107. extern double polevl ( double, void *, int );
  108. #else
  109. double floor(), log(), tan(), polevl();
  110. #endif
  111. extern double PI, MAXNUM;
  112. double psi(x)
  113. double x;
  114. {
  115. double p, q, nz, s, w, y, z;
  116. int i, n, negative;
  117. negative = 0;
  118. nz = 0.0;
  119. if( x <= 0.0 )
  120. {
  121. negative = 1;
  122. q = x;
  123. p = floor(q);
  124. if( p == q )
  125. {
  126. mtherr( "psi", SING );
  127. return( MAXNUM );
  128. }
  129. /* Remove the zeros of tan(PI x)
  130. * by subtracting the nearest integer from x
  131. */
  132. nz = q - p;
  133. if( nz != 0.5 )
  134. {
  135. if( nz > 0.5 )
  136. {
  137. p += 1.0;
  138. nz = q - p;
  139. }
  140. nz = PI/tan(PI*nz);
  141. }
  142. else
  143. {
  144. nz = 0.0;
  145. }
  146. x = 1.0 - x;
  147. }
  148. /* check for positive integer up to 10 */
  149. if( (x <= 10.0) && (x == floor(x)) )
  150. {
  151. y = 0.0;
  152. n = x;
  153. for( i=1; i<n; i++ )
  154. {
  155. w = i;
  156. y += 1.0/w;
  157. }
  158. y -= EUL;
  159. goto done;
  160. }
  161. s = x;
  162. w = 0.0;
  163. while( s < 10.0 )
  164. {
  165. w += 1.0/s;
  166. s += 1.0;
  167. }
  168. if( s < 1.0e17 )
  169. {
  170. z = 1.0/(s * s);
  171. y = z * polevl( z, A, 6 );
  172. }
  173. else
  174. y = 0.0;
  175. y = log(s) - (0.5/s) - y - w;
  176. done:
  177. if( negative )
  178. {
  179. y -= nz;
  180. }
  181. return(y);
  182. }