knf.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. /* knf.c
  2. *
  3. * Modified Bessel function, third kind, integer order
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * float x, y, knf();
  10. * int n;
  11. *
  12. * y = knf( n, x );
  13. *
  14. *
  15. *
  16. * DESCRIPTION:
  17. *
  18. * Returns modified Bessel function of the third kind
  19. * of order n of the argument.
  20. *
  21. * The range is partitioned into the two intervals [0,9.55] and
  22. * (9.55, infinity). An ascending power series is used in the
  23. * low range, and an asymptotic expansion in the high range.
  24. *
  25. *
  26. *
  27. * ACCURACY:
  28. *
  29. * Absolute error, relative when function > 1:
  30. * arithmetic domain # trials peak rms
  31. * IEEE 0,30 10000 2.0e-4 3.8e-6
  32. *
  33. * Error is high only near the crossover point x = 9.55
  34. * between the two expansions used.
  35. */
  36. /*
  37. Cephes Math Library Release 2.2: June, 1992
  38. Copyright 1984, 1987, 1988, 1992 by Stephen L. Moshier
  39. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  40. */
  41. /*
  42. Algorithm for Kn.
  43. n-1
  44. -n - (n-k-1)! 2 k
  45. K (x) = 0.5 (x/2) > -------- (-x /4)
  46. n - k!
  47. k=0
  48. inf. 2 k
  49. n n - (x /4)
  50. + (-1) 0.5(x/2) > {p(k+1) + p(n+k+1) - 2log(x/2)} ---------
  51. - k! (n+k)!
  52. k=0
  53. where p(m) is the psi function: p(1) = -EUL and
  54. m-1
  55. -
  56. p(m) = -EUL + > 1/k
  57. -
  58. k=1
  59. For large x,
  60. 2 2 2
  61. u-1 (u-1 )(u-3 )
  62. K (z) = sqrt(pi/2z) exp(-z) { 1 + ------- + ------------ + ...}
  63. v 1 2
  64. 1! (8z) 2! (8z)
  65. asymptotically, where
  66. 2
  67. u = 4 v .
  68. */
  69. #include <math.h>
  70. #define EUL 5.772156649015328606065e-1
  71. #define MAXFAC 31
  72. extern float MACHEPF, MAXNUMF, MAXLOGF, PIF;
  73. #define fabsf(x) ( (x) < 0 ? -(x) : (x) )
  74. float expf(float), logf(float), sqrtf(float);
  75. float knf( int nnn, float xx )
  76. {
  77. float x, k, kf, nk1f, nkf, zn, t, s, z0, z;
  78. float ans, fn, pn, pk, zmn, tlg, tox;
  79. int i, n, nn;
  80. nn = nnn;
  81. x = xx;
  82. if( nn < 0 )
  83. n = -nn;
  84. else
  85. n = nn;
  86. if( n > MAXFAC )
  87. {
  88. overf:
  89. mtherr( "knf", OVERFLOW );
  90. return( MAXNUMF );
  91. }
  92. if( x <= 0.0 )
  93. {
  94. if( x < 0.0 )
  95. mtherr( "knf", DOMAIN );
  96. else
  97. mtherr( "knf", SING );
  98. return( MAXNUMF );
  99. }
  100. if( x > 9.55 )
  101. goto asymp;
  102. ans = 0.0;
  103. z0 = 0.25 * x * x;
  104. fn = 1.0;
  105. pn = 0.0;
  106. zmn = 1.0;
  107. tox = 2.0/x;
  108. if( n > 0 )
  109. {
  110. /* compute factorial of n and psi(n) */
  111. pn = -EUL;
  112. k = 1.0;
  113. for( i=1; i<n; i++ )
  114. {
  115. pn += 1.0/k;
  116. k += 1.0;
  117. fn *= k;
  118. }
  119. zmn = tox;
  120. if( n == 1 )
  121. {
  122. ans = 1.0/x;
  123. }
  124. else
  125. {
  126. nk1f = fn/n;
  127. kf = 1.0;
  128. s = nk1f;
  129. z = -z0;
  130. zn = 1.0;
  131. for( i=1; i<n; i++ )
  132. {
  133. nk1f = nk1f/(n-i);
  134. kf = kf * i;
  135. zn *= z;
  136. t = nk1f * zn / kf;
  137. s += t;
  138. if( (MAXNUMF - fabsf(t)) < fabsf(s) )
  139. goto overf;
  140. if( (tox > 1.0) && ((MAXNUMF/tox) < zmn) )
  141. goto overf;
  142. zmn *= tox;
  143. }
  144. s *= 0.5;
  145. t = fabsf(s);
  146. if( (zmn > 1.0) && ((MAXNUMF/zmn) < t) )
  147. goto overf;
  148. if( (t > 1.0) && ((MAXNUMF/t) < zmn) )
  149. goto overf;
  150. ans = s * zmn;
  151. }
  152. }
  153. tlg = 2.0 * logf( 0.5 * x );
  154. pk = -EUL;
  155. if( n == 0 )
  156. {
  157. pn = pk;
  158. t = 1.0;
  159. }
  160. else
  161. {
  162. pn = pn + 1.0/n;
  163. t = 1.0/fn;
  164. }
  165. s = (pk+pn-tlg)*t;
  166. k = 1.0;
  167. do
  168. {
  169. t *= z0 / (k * (k+n));
  170. pk += 1.0/k;
  171. pn += 1.0/(k+n);
  172. s += (pk+pn-tlg)*t;
  173. k += 1.0;
  174. }
  175. while( fabsf(t/s) > MACHEPF );
  176. s = 0.5 * s / zmn;
  177. if( n & 1 )
  178. s = -s;
  179. ans += s;
  180. return(ans);
  181. /* Asymptotic expansion for Kn(x) */
  182. /* Converges to 1.4e-17 for x > 18.4 */
  183. asymp:
  184. if( x > MAXLOGF )
  185. {
  186. mtherr( "knf", UNDERFLOW );
  187. return(0.0);
  188. }
  189. k = n;
  190. pn = 4.0 * k * k;
  191. pk = 1.0;
  192. z0 = 8.0 * x;
  193. fn = 1.0;
  194. t = 1.0;
  195. s = t;
  196. nkf = MAXNUMF;
  197. i = 0;
  198. do
  199. {
  200. z = pn - pk * pk;
  201. t = t * z /(fn * z0);
  202. nk1f = fabsf(t);
  203. if( (i >= n) && (nk1f > nkf) )
  204. {
  205. goto adone;
  206. }
  207. nkf = nk1f;
  208. s += t;
  209. fn += 1.0;
  210. pk += 2.0;
  211. i += 1;
  212. }
  213. while( fabsf(t/s) > MACHEPF );
  214. adone:
  215. ans = expf(-x) * sqrtf( PIF/(2.0*x) ) * s;
  216. return(ans);
  217. }