psi.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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 "mconf.h"
  58. #ifdef UNK
  59. static double A[] = {8.33333333333333333333E-2, -2.10927960927960927961E-2,
  60. 7.57575757575757575758E-3, -4.16666666666666666667E-3,
  61. 3.96825396825396825397E-3, -8.33333333333333333333E-3,
  62. 8.33333333333333333333E-2};
  63. #endif
  64. #ifdef DEC
  65. static unsigned short A[] = {
  66. 0037252, 0125252, 0125252, 0125253, 0136654, 0145314, 0126312,
  67. 0146255, 0036370, 0037017, 0101740, 0174076, 0136210, 0104210,
  68. 0104210, 0104211, 0036202, 0004040, 0101010, 0020202, 0136410,
  69. 0104210, 0104210, 0104211, 0037252, 0125252, 0125252, 0125253};
  70. #endif
  71. #ifdef IBMPC
  72. static unsigned short A[] = {0x5555, 0x5555, 0x5555, 0x3fb5, 0x5996, 0x9599,
  73. 0x9959, 0xbf95, 0x1f08, 0xf07c, 0x07c1, 0x3f7f,
  74. 0x1111, 0x1111, 0x1111, 0xbf71, 0x0410, 0x1041,
  75. 0x4104, 0x3f70, 0x1111, 0x1111, 0x1111, 0xbf81,
  76. 0x5555, 0x5555, 0x5555, 0x3fb5};
  77. #endif
  78. #ifdef MIEEE
  79. static unsigned short A[] = {0x3fb5, 0x5555, 0x5555, 0x5555, 0xbf95, 0x9959,
  80. 0x9599, 0x5996, 0x3f7f, 0x07c1, 0xf07c, 0x1f08,
  81. 0xbf71, 0x1111, 0x1111, 0x1111, 0x3f70, 0x4104,
  82. 0x1041, 0x0410, 0xbf81, 0x1111, 0x1111, 0x1111,
  83. 0x3fb5, 0x5555, 0x5555, 0x5555};
  84. #endif
  85. #define EUL 0.57721566490153286061
  86. #ifdef ANSIPROT
  87. extern double floor(double);
  88. extern double log(double);
  89. extern double tan(double);
  90. extern double polevl(double, void *, int);
  91. #else
  92. double floor(), log(), tan(), polevl();
  93. #endif
  94. extern double PI, MAXNUM;
  95. double psi(x) double x;
  96. {
  97. double p, q, nz, s, w, y, z;
  98. int i, n, negative;
  99. negative = 0;
  100. nz = 0.0;
  101. if (x <= 0.0) {
  102. negative = 1;
  103. q = x;
  104. p = floor(q);
  105. if (p == q) {
  106. mtherr("psi", SING);
  107. return (MAXNUM);
  108. }
  109. /* Remove the zeros of tan(PI x)
  110. * by subtracting the nearest integer from x
  111. */
  112. nz = q - p;
  113. if (nz != 0.5) {
  114. if (nz > 0.5) {
  115. p += 1.0;
  116. nz = q - p;
  117. }
  118. nz = PI / tan(PI * nz);
  119. } else {
  120. nz = 0.0;
  121. }
  122. x = 1.0 - x;
  123. }
  124. /* check for positive integer up to 10 */
  125. if ((x <= 10.0) && (x == floor(x))) {
  126. y = 0.0;
  127. n = x;
  128. for (i = 1; i < n; i++) {
  129. w = i;
  130. y += 1.0 / w;
  131. }
  132. y -= EUL;
  133. goto done;
  134. }
  135. s = x;
  136. w = 0.0;
  137. while (s < 10.0) {
  138. w += 1.0 / s;
  139. s += 1.0;
  140. }
  141. if (s < 1.0e17) {
  142. z = 1.0 / (s * s);
  143. y = z * polevl(z, A, 6);
  144. } else
  145. y = 0.0;
  146. y = log(s) - (0.5 / s) - y - w;
  147. done:
  148. if (negative) {
  149. y -= nz;
  150. }
  151. return (y);
  152. }