hyp2f1.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  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 "mconf.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) double a, b, c, x;
  100. {
  101. double d, d1, d2, e;
  102. double p, q, r, s, y, ax;
  103. double ia, ib, ic, id, err;
  104. int flag, i, aid;
  105. err = 0.0;
  106. ax = fabs(x);
  107. s = 1.0 - x;
  108. flag = 0;
  109. ia = round(a); /* nearest integer to a */
  110. ib = round(b);
  111. if (a <= 0) {
  112. if (fabs(a - ia) < EPS) /* a is a negative integer */
  113. flag |= 1;
  114. }
  115. if (b <= 0) {
  116. if (fabs(b - ib) < EPS) /* b is a negative integer */
  117. flag |= 2;
  118. }
  119. if (ax < 1.0) {
  120. if (fabs(b - c) < EPS) /* b = c */
  121. {
  122. y = pow(s, -a); /* s to the -a power */
  123. goto hypdon;
  124. }
  125. if (fabs(a - c) < EPS) /* a = c */
  126. {
  127. y = pow(s, -b); /* s to the -b power */
  128. goto hypdon;
  129. }
  130. }
  131. if (c <= 0.0) {
  132. ic = round(c); /* nearest integer to c */
  133. if (fabs(c - ic) < EPS) /* c is a negative integer */
  134. {
  135. /* check if termination before explosion */
  136. if ((flag & 1) && (ia > ic))
  137. goto hypok;
  138. if ((flag & 2) && (ib > ic))
  139. goto hypok;
  140. goto hypdiv;
  141. }
  142. }
  143. if (flag) /* function is a polynomial */
  144. goto hypok;
  145. if (ax > 1.0) /* series diverges */
  146. goto hypdiv;
  147. p = c - a;
  148. ia = round(p); /* nearest integer to c-a */
  149. if ((ia <= 0.0) && (fabs(p - ia) < EPS)) /* negative int c - a */
  150. flag |= 4;
  151. r = c - b;
  152. ib = round(r); /* nearest integer to c-b */
  153. if ((ib <= 0.0) && (fabs(r - ib) < EPS)) /* negative int c - b */
  154. flag |= 8;
  155. d = c - a - b;
  156. id = round(d); /* nearest integer to d */
  157. q = fabs(d - id);
  158. /* Thanks to Christian Burger <BURGER@DMRHRZ11.HRZ.Uni-Marburg.DE>
  159. * for reporting a bug here. */
  160. if (fabs(ax - 1.0) < EPS) /* |x| == 1.0 */
  161. {
  162. if (x > 0.0) {
  163. if (flag & 12) /* negative int c-a or c-b */
  164. {
  165. if (d >= 0.0)
  166. goto hypf;
  167. else
  168. goto hypdiv;
  169. }
  170. if (d <= 0.0)
  171. goto hypdiv;
  172. y = gamma(c) * gamma(d) / (gamma(p) * gamma(r));
  173. goto hypdon;
  174. }
  175. if (d <= -1.0)
  176. goto hypdiv;
  177. }
  178. /* Conditionally make d > 0 by recurrence on c
  179. * AMS55 #15.2.27
  180. */
  181. if (d < 0.0) {
  182. /* Try the power series first */
  183. y = hyt2f1(a, b, c, x, &err);
  184. if (err < ETHRESH)
  185. goto hypdon;
  186. /* Apply the recurrence if power series fails */
  187. err = 0.0;
  188. aid = 2 - id;
  189. e = c + aid;
  190. d2 = hyp2f1(a, b, e, x);
  191. d1 = hyp2f1(a, b, e + 1.0, x);
  192. q = a + b + 1.0;
  193. for (i = 0; i < aid; i++) {
  194. r = e - 1.0;
  195. y = (e * (r - (2.0 * e - q) * x) * d2 + (e - a) * (e - b) * x * d1) /
  196. (e * r * s);
  197. e = r;
  198. d1 = d2;
  199. d2 = y;
  200. }
  201. goto hypdon;
  202. }
  203. if (flag & 12)
  204. goto hypf; /* negative integer c-a or c-b */
  205. hypok:
  206. y = hyt2f1(a, b, c, x, &err);
  207. hypdon:
  208. if (err > ETHRESH) {
  209. mtherr("hyp2f1", PLOSS);
  210. /* printf( "Estimated err = %.2e\n", err ); */
  211. }
  212. return (y);
  213. /* The transformation for c-a or c-b negative integer
  214. * AMS55 #15.3.3
  215. */
  216. hypf:
  217. y = pow(s, d) * hys2f1(c - a, c - b, c, x, &err);
  218. goto hypdon;
  219. /* The alarm exit */
  220. hypdiv:
  221. mtherr("hyp2f1", OVERFLOW);
  222. return (MAXNUM);
  223. }
  224. /* Apply transformations for |x| near 1
  225. * then call the power series
  226. */
  227. static double hyt2f1(a, b, c, x, loss) double a, b, c, x;
  228. double *loss;
  229. {
  230. double p, q, r, s, t, y, d, err, err1;
  231. double ax, id, d1, d2, e, y1;
  232. int i, aid;
  233. err = 0.0;
  234. s = 1.0 - x;
  235. if (x < -0.5) {
  236. if (b > a)
  237. y = pow(s, -a) * hys2f1(a, c - b, c, -x / s, &err);
  238. else
  239. y = pow(s, -b) * hys2f1(c - a, b, c, -x / s, &err);
  240. goto done;
  241. }
  242. d = c - a - b;
  243. id = round(d); /* nearest integer to d */
  244. if (x > 0.9) {
  245. if (fabs(d - id) > EPS) /* test for integer c-a-b */
  246. {
  247. /* Try the power series first */
  248. y = hys2f1(a, b, c, x, &err);
  249. if (err < ETHRESH)
  250. goto done;
  251. /* If power series fails, then apply AMS55 #15.3.6 */
  252. q = hys2f1(a, b, 1.0 - d, s, &err);
  253. q *= gamma(d) / (gamma(c - a) * gamma(c - b));
  254. r = pow(s, d) * hys2f1(c - a, c - b, d + 1.0, s, &err1);
  255. r *= gamma(-d) / (gamma(a) * gamma(b));
  256. y = q + r;
  257. q = fabs(q); /* estimate cancellation error */
  258. r = fabs(r);
  259. if (q > r)
  260. r = q;
  261. err += err1 + (MACHEP * r) / y;
  262. y *= gamma(c);
  263. goto done;
  264. } else {
  265. /* Psi function expansion, AMS55 #15.3.10, #15.3.11, #15.3.12 */
  266. if (id >= 0.0) {
  267. e = d;
  268. d1 = d;
  269. d2 = 0.0;
  270. aid = id;
  271. } else {
  272. e = -d;
  273. d1 = 0.0;
  274. d2 = d;
  275. aid = -id;
  276. }
  277. ax = log(s);
  278. /* sum for t = 0 */
  279. y = psi(1.0) + psi(1.0 + e) - psi(a + d1) - psi(b + d1) - ax;
  280. y /= gamma(e + 1.0);
  281. p = (a + d1) * (b + d1) * s / gamma(e + 2.0); /* Poch for t=1 */
  282. t = 1.0;
  283. do {
  284. r = psi(1.0 + t) + psi(1.0 + t + e) - psi(a + t + d1) -
  285. psi(b + t + d1) - ax;
  286. q = p * r;
  287. y += q;
  288. p *= s * (a + t + d1) / (t + 1.0);
  289. p *= (b + t + d1) / (t + 1.0 + e);
  290. t += 1.0;
  291. } while (fabs(q / y) > EPS);
  292. if (id == 0.0) {
  293. y *= gamma(c) / (gamma(a) * gamma(b));
  294. goto psidon;
  295. }
  296. y1 = 1.0;
  297. if (aid == 1)
  298. goto nosum;
  299. t = 0.0;
  300. p = 1.0;
  301. for (i = 1; i < aid; i++) {
  302. r = 1.0 - e + t;
  303. p *= s * (a + t + d2) * (b + t + d2) / r;
  304. t += 1.0;
  305. p /= t;
  306. y1 += p;
  307. }
  308. nosum:
  309. p = gamma(c);
  310. y1 *= gamma(e) * p / (gamma(a + d1) * gamma(b + d1));
  311. y *= p / (gamma(a + d2) * gamma(b + d2));
  312. if ((aid & 1) != 0)
  313. y = -y;
  314. q = pow(s, id); /* s to the id power */
  315. if (id > 0.0)
  316. y *= q;
  317. else
  318. y1 *= q;
  319. y += y1;
  320. psidon:
  321. goto done;
  322. }
  323. }
  324. /* Use defining power series if no special cases */
  325. y = hys2f1(a, b, c, x, &err);
  326. done:
  327. *loss = err;
  328. return (y);
  329. }
  330. /* Defining power series expansion of Gauss hypergeometric function */
  331. static double hys2f1(a, b, c, x, loss) double a, b, c, x;
  332. double *loss; /* estimates loss of significance */
  333. {
  334. double f, g, h, k, m, s, u, umax;
  335. int i;
  336. i = 0;
  337. umax = 0.0;
  338. f = a;
  339. g = b;
  340. h = c;
  341. s = 1.0;
  342. u = 1.0;
  343. k = 0.0;
  344. do {
  345. if (fabs(h) < EPS) {
  346. *loss = 1.0;
  347. return (MAXNUM);
  348. }
  349. m = k + 1.0;
  350. u = u * ((f + k) * (g + k) * x / ((h + k) * m));
  351. s += u;
  352. k = fabs(u); /* remember largest term summed */
  353. if (k > umax)
  354. umax = k;
  355. k = m;
  356. if (++i > 10000) /* should never happen */
  357. {
  358. *loss = 1.0;
  359. return (s);
  360. }
  361. } while (fabs(u / s) > MACHEP);
  362. /* return estimated relative error */
  363. *loss = (MACHEP * umax) / fabs(s) + (MACHEP * i);
  364. return (s);
  365. }