hyp2f1.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. /* hyp2f1.c
  2. *
  3. * Gauss hypergeometric function F
  4. * 2 1
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * double a, b, c, x, y, hyp2f1();
  10. *
  11. * y = hyp2f1( a, b, c, x );
  12. *
  13. *
  14. * DESCRIPTION:
  15. *
  16. *
  17. * hyp2f1( a, b, c, x ) = F ( a, b; c; x )
  18. * 2 1
  19. *
  20. * inf.
  21. * - a(a+1)...(a+k) b(b+1)...(b+k) k+1
  22. * = 1 + > ----------------------------- x .
  23. * - c(c+1)...(c+k) (k+1)!
  24. * k = 0
  25. *
  26. * Cases addressed are
  27. * Tests and escapes for negative integer a, b, or c
  28. * Linear transformation if c - a or c - b negative integer
  29. * Special case c = a or c = b
  30. * Linear transformation for x near +1
  31. * Transformation for x < -0.5
  32. * Psi function expansion if x > 0.5 and c - a - b integer
  33. * Conditionally, a recurrence on c to make c-a-b > 0
  34. *
  35. * |x| > 1 is rejected.
  36. *
  37. * The parameters a, b, c are considered to be integer
  38. * valued if they are within 1.0e-14 of the nearest integer
  39. * (1.0e-13 for IEEE arithmetic).
  40. *
  41. * ACCURACY:
  42. *
  43. *
  44. * Relative error (-1 < x < 1):
  45. * arithmetic domain # trials peak rms
  46. * IEEE -1,7 230000 1.2e-11 5.2e-14
  47. *
  48. * Several special cases also tested with a, b, c in
  49. * the range -7 to 7.
  50. *
  51. * ERROR MESSAGES:
  52. *
  53. * A "partial loss of precision" message is printed if
  54. * the internally estimated relative error exceeds 1^-12.
  55. * A "singularity" message is printed on overflow or
  56. * in cases not addressed (such as x < -1).
  57. */
  58. /* hyp2f1 */
  59. /*
  60. Cephes Math Library Release 2.8: June, 2000
  61. Copyright 1984, 1987, 1992, 2000 by Stephen L. Moshier
  62. */
  63. #include <math.h>
  64. #ifdef DEC
  65. #define EPS 1.0e-14
  66. #define EPS2 1.0e-11
  67. #endif
  68. #ifdef IBMPC
  69. #define EPS 1.0e-13
  70. #define EPS2 1.0e-10
  71. #endif
  72. #ifdef MIEEE
  73. #define EPS 1.0e-13
  74. #define EPS2 1.0e-10
  75. #endif
  76. #ifdef UNK
  77. #define EPS 1.0e-13
  78. #define EPS2 1.0e-10
  79. #endif
  80. #define ETHRESH 1.0e-12
  81. #ifdef ANSIPROT
  82. extern double fabs ( double );
  83. extern double pow ( double, double );
  84. extern double round ( double );
  85. extern double gamma ( double );
  86. extern double log ( double );
  87. extern double exp ( double );
  88. extern double psi ( double );
  89. static double hyt2f1(double, double, double, double, double *);
  90. static double hys2f1(double, double, double, double, double *);
  91. double hyp2f1(double, double, double, double);
  92. #else
  93. double fabs(), pow(), round(), gamma(), log(), exp(), psi();
  94. static double hyt2f1();
  95. static double hys2f1();
  96. double hyp2f1();
  97. #endif
  98. extern double MAXNUM, MACHEP;
  99. double hyp2f1( a, b, c, x )
  100. double a, b, c, x;
  101. {
  102. double d, d1, d2, e;
  103. double p, q, r, s, y, ax;
  104. double ia, ib, ic, id, err;
  105. int flag, i, aid;
  106. err = 0.0;
  107. ax = fabs(x);
  108. s = 1.0 - x;
  109. flag = 0;
  110. ia = round(a); /* nearest integer to a */
  111. ib = round(b);
  112. if( a <= 0 )
  113. {
  114. if( fabs(a-ia) < EPS ) /* a is a negative integer */
  115. flag |= 1;
  116. }
  117. if( b <= 0 )
  118. {
  119. if( fabs(b-ib) < EPS ) /* b is a negative integer */
  120. flag |= 2;
  121. }
  122. if( ax < 1.0 )
  123. {
  124. if( fabs(b-c) < EPS ) /* b = c */
  125. {
  126. y = pow( s, -a ); /* s to the -a power */
  127. goto hypdon;
  128. }
  129. if( fabs(a-c) < EPS ) /* a = c */
  130. {
  131. y = pow( s, -b ); /* s to the -b power */
  132. goto hypdon;
  133. }
  134. }
  135. if( c <= 0.0 )
  136. {
  137. ic = round(c); /* nearest integer to c */
  138. if( fabs(c-ic) < EPS ) /* c is a negative integer */
  139. {
  140. /* check if termination before explosion */
  141. if( (flag & 1) && (ia > ic) )
  142. goto hypok;
  143. if( (flag & 2) && (ib > ic) )
  144. goto hypok;
  145. goto hypdiv;
  146. }
  147. }
  148. if( flag ) /* function is a polynomial */
  149. goto hypok;
  150. if( ax > 1.0 ) /* series diverges */
  151. goto hypdiv;
  152. p = c - a;
  153. ia = round(p); /* nearest integer to c-a */
  154. if( (ia <= 0.0) && (fabs(p-ia) < EPS) ) /* negative int c - a */
  155. flag |= 4;
  156. r = c - b;
  157. ib = round(r); /* nearest integer to c-b */
  158. if( (ib <= 0.0) && (fabs(r-ib) < EPS) ) /* negative int c - b */
  159. flag |= 8;
  160. d = c - a - b;
  161. id = round(d); /* nearest integer to d */
  162. q = fabs(d-id);
  163. /* Thanks to Christian Burger <BURGER@DMRHRZ11.HRZ.Uni-Marburg.DE>
  164. * for reporting a bug here. */
  165. if( fabs(ax-1.0) < EPS ) /* |x| == 1.0 */
  166. {
  167. if( x > 0.0 )
  168. {
  169. if( flag & 12 ) /* negative int c-a or c-b */
  170. {
  171. if( d >= 0.0 )
  172. goto hypf;
  173. else
  174. goto hypdiv;
  175. }
  176. if( d <= 0.0 )
  177. goto hypdiv;
  178. y = gamma(c)*gamma(d)/(gamma(p)*gamma(r));
  179. goto hypdon;
  180. }
  181. if( d <= -1.0 )
  182. goto hypdiv;
  183. }
  184. /* Conditionally make d > 0 by recurrence on c
  185. * AMS55 #15.2.27
  186. */
  187. if( d < 0.0 )
  188. {
  189. /* Try the power series first */
  190. y = hyt2f1( a, b, c, x, &err );
  191. if( err < ETHRESH )
  192. goto hypdon;
  193. /* Apply the recurrence if power series fails */
  194. err = 0.0;
  195. aid = 2 - id;
  196. e = c + aid;
  197. d2 = hyp2f1(a,b,e,x);
  198. d1 = hyp2f1(a,b,e+1.0,x);
  199. q = a + b + 1.0;
  200. for( i=0; i<aid; i++ )
  201. {
  202. r = e - 1.0;
  203. y = (e*(r-(2.0*e-q)*x)*d2 + (e-a)*(e-b)*x*d1)/(e*r*s);
  204. e = r;
  205. d1 = d2;
  206. d2 = y;
  207. }
  208. goto hypdon;
  209. }
  210. if( flag & 12 )
  211. goto hypf; /* negative integer c-a or c-b */
  212. hypok:
  213. y = hyt2f1( a, b, c, x, &err );
  214. hypdon:
  215. if( err > ETHRESH )
  216. {
  217. mtherr( "hyp2f1", PLOSS );
  218. /* printf( "Estimated err = %.2e\n", err ); */
  219. }
  220. return(y);
  221. /* The transformation for c-a or c-b negative integer
  222. * AMS55 #15.3.3
  223. */
  224. hypf:
  225. y = pow( s, d ) * hys2f1( c-a, c-b, c, x, &err );
  226. goto hypdon;
  227. /* The alarm exit */
  228. hypdiv:
  229. mtherr( "hyp2f1", OVERFLOW );
  230. return( MAXNUM );
  231. }
  232. /* Apply transformations for |x| near 1
  233. * then call the power series
  234. */
  235. static double hyt2f1( a, b, c, x, loss )
  236. double a, b, c, x;
  237. double *loss;
  238. {
  239. double p, q, r, s, t, y, d, err, err1;
  240. double ax, id, d1, d2, e, y1;
  241. int i, aid;
  242. err = 0.0;
  243. s = 1.0 - x;
  244. if( x < -0.5 )
  245. {
  246. if( b > a )
  247. y = pow( s, -a ) * hys2f1( a, c-b, c, -x/s, &err );
  248. else
  249. y = pow( s, -b ) * hys2f1( c-a, b, c, -x/s, &err );
  250. goto done;
  251. }
  252. d = c - a - b;
  253. id = round(d); /* nearest integer to d */
  254. if( x > 0.9 )
  255. {
  256. if( fabs(d-id) > EPS ) /* test for integer c-a-b */
  257. {
  258. /* Try the power series first */
  259. y = hys2f1( a, b, c, x, &err );
  260. if( err < ETHRESH )
  261. goto done;
  262. /* If power series fails, then apply AMS55 #15.3.6 */
  263. q = hys2f1( a, b, 1.0-d, s, &err );
  264. q *= gamma(d) /(gamma(c-a) * gamma(c-b));
  265. r = pow(s,d) * hys2f1( c-a, c-b, d+1.0, s, &err1 );
  266. r *= gamma(-d)/(gamma(a) * gamma(b));
  267. y = q + r;
  268. q = fabs(q); /* estimate cancellation error */
  269. r = fabs(r);
  270. if( q > r )
  271. r = q;
  272. err += err1 + (MACHEP*r)/y;
  273. y *= gamma(c);
  274. goto done;
  275. }
  276. else
  277. {
  278. /* Psi function expansion, AMS55 #15.3.10, #15.3.11, #15.3.12 */
  279. if( id >= 0.0 )
  280. {
  281. e = d;
  282. d1 = d;
  283. d2 = 0.0;
  284. aid = id;
  285. }
  286. else
  287. {
  288. e = -d;
  289. d1 = 0.0;
  290. d2 = d;
  291. aid = -id;
  292. }
  293. ax = log(s);
  294. /* sum for t = 0 */
  295. y = psi(1.0) + psi(1.0+e) - psi(a+d1) - psi(b+d1) - ax;
  296. y /= gamma(e+1.0);
  297. p = (a+d1) * (b+d1) * s / gamma(e+2.0); /* Poch for t=1 */
  298. t = 1.0;
  299. do
  300. {
  301. r = psi(1.0+t) + psi(1.0+t+e) - psi(a+t+d1)
  302. - psi(b+t+d1) - ax;
  303. q = p * r;
  304. y += q;
  305. p *= s * (a+t+d1) / (t+1.0);
  306. p *= (b+t+d1) / (t+1.0+e);
  307. t += 1.0;
  308. }
  309. while( fabs(q/y) > EPS );
  310. if( id == 0.0 )
  311. {
  312. y *= gamma(c)/(gamma(a)*gamma(b));
  313. goto psidon;
  314. }
  315. y1 = 1.0;
  316. if( aid == 1 )
  317. goto nosum;
  318. t = 0.0;
  319. p = 1.0;
  320. for( i=1; i<aid; i++ )
  321. {
  322. r = 1.0-e+t;
  323. p *= s * (a+t+d2) * (b+t+d2) / r;
  324. t += 1.0;
  325. p /= t;
  326. y1 += p;
  327. }
  328. nosum:
  329. p = gamma(c);
  330. y1 *= gamma(e) * p / (gamma(a+d1) * gamma(b+d1));
  331. y *= p / (gamma(a+d2) * gamma(b+d2));
  332. if( (aid & 1) != 0 )
  333. y = -y;
  334. q = pow( s, id ); /* s to the id power */
  335. if( id > 0.0 )
  336. y *= q;
  337. else
  338. y1 *= q;
  339. y += y1;
  340. psidon:
  341. goto done;
  342. }
  343. }
  344. /* Use defining power series if no special cases */
  345. y = hys2f1( a, b, c, x, &err );
  346. done:
  347. *loss = err;
  348. return(y);
  349. }
  350. /* Defining power series expansion of Gauss hypergeometric function */
  351. static double hys2f1( a, b, c, x, loss )
  352. double a, b, c, x;
  353. double *loss; /* estimates loss of significance */
  354. {
  355. double f, g, h, k, m, s, u, umax;
  356. int i;
  357. i = 0;
  358. umax = 0.0;
  359. f = a;
  360. g = b;
  361. h = c;
  362. s = 1.0;
  363. u = 1.0;
  364. k = 0.0;
  365. do
  366. {
  367. if( fabs(h) < EPS )
  368. {
  369. *loss = 1.0;
  370. return( MAXNUM );
  371. }
  372. m = k + 1.0;
  373. u = u * ((f+k) * (g+k) * x / ((h+k) * m));
  374. s += u;
  375. k = fabs(u); /* remember largest term summed */
  376. if( k > umax )
  377. umax = k;
  378. k = m;
  379. if( ++i > 10000 ) /* should never happen */
  380. {
  381. *loss = 1.0;
  382. return(s);
  383. }
  384. }
  385. while( fabs(u/s) > MACHEP );
  386. /* return estimated relative error */
  387. *loss = (MACHEP*umax)/fabs(s) + (MACHEP*i);
  388. return(s);
  389. }