hypergf.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /* hypergf.c
  2. *
  3. * Confluent hypergeometric function
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * float a, b, x, y, hypergf();
  10. *
  11. * y = hypergf( a, b, x );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Computes the confluent hypergeometric function
  18. *
  19. * 1 2
  20. * a x a(a+1) x
  21. * F ( a,b;x ) = 1 + ---- + --------- + ...
  22. * 1 1 b 1! b(b+1) 2!
  23. *
  24. * Many higher transcendental functions are special cases of
  25. * this power series.
  26. *
  27. * As is evident from the formula, b must not be a negative
  28. * integer or zero unless a is an integer with 0 >= a > b.
  29. *
  30. * The routine attempts both a direct summation of the series
  31. * and an asymptotic expansion. In each case error due to
  32. * roundoff, cancellation, and nonconvergence is estimated.
  33. * The result with smaller estimated error is returned.
  34. *
  35. *
  36. *
  37. * ACCURACY:
  38. *
  39. * Tested at random points (a, b, x), all three variables
  40. * ranging from 0 to 30.
  41. * Relative error:
  42. * arithmetic domain # trials peak rms
  43. * IEEE 0,5 10000 6.6e-7 1.3e-7
  44. * IEEE 0,30 30000 1.1e-5 6.5e-7
  45. *
  46. * Larger errors can be observed when b is near a negative
  47. * integer or zero. Certain combinations of arguments yield
  48. * serious cancellation error in the power series summation
  49. * and also are not in the region of near convergence of the
  50. * asymptotic series. An error message is printed if the
  51. * self-estimated relative error is greater than 1.0e-3.
  52. *
  53. */
  54. /* hyperg.c */
  55. /*
  56. Cephes Math Library Release 2.1: November, 1988
  57. Copyright 1984, 1987, 1988 by Stephen L. Moshier
  58. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  59. */
  60. #include <math.h>
  61. extern float MAXNUMF, MACHEPF;
  62. #define fabsf(x) ( (x) < 0 ? -(x) : (x) )
  63. #ifdef ANSIC
  64. float expf(float);
  65. float hyp2f0f(float, float, float, int, float *);
  66. static float hy1f1af(float, float, float, float *);
  67. static float hy1f1pf(float, float, float, float *);
  68. float logf(float), gammaf(float), lgamf(float);
  69. #else
  70. float expf(), hyp2f0f();
  71. float logf(), gammaf(), lgamf();
  72. static float hy1f1pf(), hy1f1af();
  73. #endif
  74. float hypergf( float aa, float bb, float xx )
  75. {
  76. float a, b, x, asum, psum, acanc, pcanc, temp;
  77. a = aa;
  78. b = bb;
  79. x = xx;
  80. /* See if a Kummer transformation will help */
  81. temp = b - a;
  82. if( fabsf(temp) < 0.001 * fabsf(a) )
  83. return( expf(x) * hypergf( temp, b, -x ) );
  84. psum = hy1f1pf( a, b, x, &pcanc );
  85. if( pcanc < 1.0e-6 )
  86. goto done;
  87. /* try asymptotic series */
  88. asum = hy1f1af( a, b, x, &acanc );
  89. /* Pick the result with less estimated error */
  90. if( acanc < pcanc )
  91. {
  92. pcanc = acanc;
  93. psum = asum;
  94. }
  95. done:
  96. if( pcanc > 1.0e-3 )
  97. mtherr( "hyperg", PLOSS );
  98. return( psum );
  99. }
  100. /* Power series summation for confluent hypergeometric function */
  101. static float hy1f1pf( float aa, float bb, float xx, float *err )
  102. {
  103. float a, b, x, n, a0, sum, t, u, temp;
  104. float an, bn, maxt, pcanc;
  105. a = aa;
  106. b = bb;
  107. x = xx;
  108. /* set up for power series summation */
  109. an = a;
  110. bn = b;
  111. a0 = 1.0;
  112. sum = 1.0;
  113. n = 1.0;
  114. t = 1.0;
  115. maxt = 0.0;
  116. while( t > MACHEPF )
  117. {
  118. if( bn == 0 ) /* check bn first since if both */
  119. {
  120. mtherr( "hypergf", SING );
  121. return( MAXNUMF ); /* an and bn are zero it is */
  122. }
  123. if( an == 0 ) /* a singularity */
  124. return( sum );
  125. if( n > 200 )
  126. goto pdone;
  127. u = x * ( an / (bn * n) );
  128. /* check for blowup */
  129. temp = fabsf(u);
  130. if( (temp > 1.0 ) && (maxt > (MAXNUMF/temp)) )
  131. {
  132. pcanc = 1.0; /* estimate 100% error */
  133. goto blowup;
  134. }
  135. a0 *= u;
  136. sum += a0;
  137. t = fabsf(a0);
  138. if( t > maxt )
  139. maxt = t;
  140. /*
  141. if( (maxt/fabsf(sum)) > 1.0e17 )
  142. {
  143. pcanc = 1.0;
  144. goto blowup;
  145. }
  146. */
  147. an += 1.0;
  148. bn += 1.0;
  149. n += 1.0;
  150. }
  151. pdone:
  152. /* estimate error due to roundoff and cancellation */
  153. if( sum != 0.0 )
  154. maxt /= fabsf(sum);
  155. maxt *= MACHEPF; /* this way avoids multiply overflow */
  156. pcanc = fabsf( MACHEPF * n + maxt );
  157. blowup:
  158. *err = pcanc;
  159. return( sum );
  160. }
  161. /* hy1f1a() */
  162. /* asymptotic formula for hypergeometric function:
  163. *
  164. * ( -a
  165. * -- ( |z|
  166. * | (b) ( -------- 2f0( a, 1+a-b, -1/x )
  167. * ( --
  168. * ( | (b-a)
  169. *
  170. *
  171. * x a-b )
  172. * e |x| )
  173. * + -------- 2f0( b-a, 1-a, 1/x ) )
  174. * -- )
  175. * | (a) )
  176. */
  177. static float hy1f1af( float aa, float bb, float xx, float *err )
  178. {
  179. float a, b, x, h1, h2, t, u, temp, acanc, asum, err1, err2;
  180. a = aa;
  181. b = bb;
  182. x = xx;
  183. if( x == 0 )
  184. {
  185. acanc = 1.0;
  186. asum = MAXNUMF;
  187. goto adone;
  188. }
  189. temp = logf( fabsf(x) );
  190. t = x + temp * (a-b);
  191. u = -temp * a;
  192. if( b > 0 )
  193. {
  194. temp = lgamf(b);
  195. t += temp;
  196. u += temp;
  197. }
  198. h1 = hyp2f0f( a, a-b+1, -1.0/x, 1, &err1 );
  199. temp = expf(u) / gammaf(b-a);
  200. h1 *= temp;
  201. err1 *= temp;
  202. h2 = hyp2f0f( b-a, 1.0-a, 1.0/x, 2, &err2 );
  203. if( a < 0 )
  204. temp = expf(t) / gammaf(a);
  205. else
  206. temp = expf( t - lgamf(a) );
  207. h2 *= temp;
  208. err2 *= temp;
  209. if( x < 0.0 )
  210. asum = h1;
  211. else
  212. asum = h2;
  213. acanc = fabsf(err1) + fabsf(err2);
  214. if( b < 0 )
  215. {
  216. temp = gammaf(b);
  217. asum *= temp;
  218. acanc *= fabsf(temp);
  219. }
  220. if( asum != 0.0 )
  221. acanc /= fabsf(asum);
  222. acanc *= 30.0; /* fudge factor, since error of asymptotic formula
  223. * often seems this much larger than advertised */
  224. adone:
  225. *err = acanc;
  226. return( asum );
  227. }
  228. /* hyp2f0() */
  229. float hyp2f0f(float aa, float bb, float xx, int type, float *err)
  230. {
  231. float a, b, x, a0, alast, t, tlast, maxt;
  232. float n, an, bn, u, sum, temp;
  233. a = aa;
  234. b = bb;
  235. x = xx;
  236. an = a;
  237. bn = b;
  238. a0 = 1.0;
  239. alast = 1.0;
  240. sum = 0.0;
  241. n = 1.0;
  242. t = 1.0;
  243. tlast = 1.0e9;
  244. maxt = 0.0;
  245. do
  246. {
  247. if( an == 0 )
  248. goto pdone;
  249. if( bn == 0 )
  250. goto pdone;
  251. u = an * (bn * x / n);
  252. /* check for blowup */
  253. temp = fabsf(u);
  254. if( (temp > 1.0 ) && (maxt > (MAXNUMF/temp)) )
  255. goto error;
  256. a0 *= u;
  257. t = fabsf(a0);
  258. /* terminating condition for asymptotic series */
  259. if( t > tlast )
  260. goto ndone;
  261. tlast = t;
  262. sum += alast; /* the sum is one term behind */
  263. alast = a0;
  264. if( n > 200 )
  265. goto ndone;
  266. an += 1.0;
  267. bn += 1.0;
  268. n += 1.0;
  269. if( t > maxt )
  270. maxt = t;
  271. }
  272. while( t > MACHEPF );
  273. pdone: /* series converged! */
  274. /* estimate error due to roundoff and cancellation */
  275. *err = fabsf( MACHEPF * (n + maxt) );
  276. alast = a0;
  277. goto done;
  278. ndone: /* series did not converge */
  279. /* The following "Converging factors" are supposed to improve accuracy,
  280. * but do not actually seem to accomplish very much. */
  281. n -= 1.0;
  282. x = 1.0/x;
  283. switch( type ) /* "type" given as subroutine argument */
  284. {
  285. case 1:
  286. alast *= ( 0.5 + (0.125 + 0.25*b - 0.5*a + 0.25*x - 0.25*n)/x );
  287. break;
  288. case 2:
  289. alast *= 2.0/3.0 - b + 2.0*a + x - n;
  290. break;
  291. default:
  292. ;
  293. }
  294. /* estimate error due to roundoff, cancellation, and nonconvergence */
  295. *err = MACHEPF * (n + maxt) + fabsf( a0 );
  296. done:
  297. sum += alast;
  298. return( sum );
  299. /* series blew up: */
  300. error:
  301. *err = MAXNUMF;
  302. mtherr( "hypergf", TLOSS );
  303. return( sum );
  304. }