gsl_specfunc__gamma_inc.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. /* specfunc/gamma_inc.c
  2. *
  3. * Copyright (C) 2007 Brian Gough
  4. * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 3 of the License, or (at
  9. * your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. /* Author: G. Jungman */
  21. #include "gsl__config.h"
  22. #include "gsl_math.h"
  23. #include "gsl_errno.h"
  24. #include "gsl_sf_erf.h"
  25. #include "gsl_sf_exp.h"
  26. #include "gsl_sf_log.h"
  27. #include "gsl_sf_gamma.h"
  28. #include "gsl_sf_expint.h"
  29. #include "gsl_specfunc__error.h"
  30. /* The dominant part,
  31. * D(a,x) := x^a e^(-x) / Gamma(a+1)
  32. */
  33. static
  34. int
  35. gamma_inc_D(const double a, const double x, gsl_sf_result * result)
  36. {
  37. if(a < 10.0) {
  38. double lnr;
  39. gsl_sf_result lg;
  40. gsl_sf_lngamma_e(a+1.0, &lg);
  41. lnr = a * log(x) - x - lg.val;
  42. result->val = exp(lnr);
  43. result->err = 2.0 * GSL_DBL_EPSILON * (fabs(lnr) + 1.0) * fabs(result->val);
  44. return GSL_SUCCESS;
  45. }
  46. else {
  47. gsl_sf_result gstar;
  48. gsl_sf_result ln_term;
  49. double term1;
  50. if (x < 0.5*a) {
  51. double u = x/a;
  52. double ln_u = log(u);
  53. ln_term.val = ln_u - u + 1.0;
  54. ln_term.err = (fabs(ln_u) + fabs(u) + 1.0) * GSL_DBL_EPSILON;
  55. } else {
  56. double mu = (x-a)/a;
  57. gsl_sf_log_1plusx_mx_e(mu, &ln_term); /* log(1+mu) - mu */
  58. };
  59. gsl_sf_gammastar_e(a, &gstar);
  60. term1 = exp(a*ln_term.val)/sqrt(2.0*M_PI*a);
  61. result->val = term1/gstar.val;
  62. result->err = 2.0 * GSL_DBL_EPSILON * (fabs(a*ln_term.val) + 1.0) * fabs(result->val);
  63. result->err += gstar.err/fabs(gstar.val) * fabs(result->val);
  64. return GSL_SUCCESS;
  65. }
  66. }
  67. /* P series representation.
  68. */
  69. static
  70. int
  71. gamma_inc_P_series(const double a, const double x, gsl_sf_result * result)
  72. {
  73. const int nmax = 5000;
  74. gsl_sf_result D;
  75. int stat_D = gamma_inc_D(a, x, &D);
  76. double sum = 1.0;
  77. double term = 1.0;
  78. int n;
  79. for(n=1; n<nmax; n++) {
  80. term *= x/(a+n);
  81. sum += term;
  82. if(fabs(term/sum) < GSL_DBL_EPSILON) break;
  83. }
  84. result->val = D.val * sum;
  85. result->err = D.err * fabs(sum);
  86. result->err += (1.0 + n) * GSL_DBL_EPSILON * fabs(result->val);
  87. if(n == nmax)
  88. GSL_ERROR ("error", GSL_EMAXITER);
  89. else
  90. return stat_D;
  91. }
  92. /* Q large x asymptotic
  93. */
  94. static
  95. int
  96. gamma_inc_Q_large_x(const double a, const double x, gsl_sf_result * result)
  97. {
  98. const int nmax = 5000;
  99. gsl_sf_result D;
  100. const int stat_D = gamma_inc_D(a, x, &D);
  101. double sum = 1.0;
  102. double term = 1.0;
  103. double last = 1.0;
  104. int n;
  105. for(n=1; n<nmax; n++) {
  106. term *= (a-n)/x;
  107. if(fabs(term/last) > 1.0) break;
  108. if(fabs(term/sum) < GSL_DBL_EPSILON) break;
  109. sum += term;
  110. last = term;
  111. }
  112. result->val = D.val * (a/x) * sum;
  113. result->err = D.err * fabs((a/x) * sum);
  114. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  115. if(n == nmax)
  116. GSL_ERROR ("error in large x asymptotic", GSL_EMAXITER);
  117. else
  118. return stat_D;
  119. }
  120. /* Uniform asymptotic for x near a, a and x large.
  121. * See [Temme, p. 285]
  122. */
  123. static
  124. int
  125. gamma_inc_Q_asymp_unif(const double a, const double x, gsl_sf_result * result)
  126. {
  127. const double rta = sqrt(a);
  128. const double eps = (x-a)/a;
  129. gsl_sf_result ln_term;
  130. const int stat_ln = gsl_sf_log_1plusx_mx_e(eps, &ln_term); /* log(1+eps) - eps */
  131. const double eta = GSL_SIGN(eps) * sqrt(-2.0*ln_term.val);
  132. gsl_sf_result erfc;
  133. double R;
  134. double c0, c1;
  135. /* This used to say erfc(eta*M_SQRT2*rta), which is wrong.
  136. * The sqrt(2) is in the denominator. Oops.
  137. * Fixed: [GJ] Mon Nov 15 13:25:32 MST 2004
  138. */
  139. gsl_sf_erfc_e(eta*rta/M_SQRT2, &erfc);
  140. if(fabs(eps) < GSL_ROOT5_DBL_EPSILON) {
  141. c0 = -1.0/3.0 + eps*(1.0/12.0 - eps*(23.0/540.0 - eps*(353.0/12960.0 - eps*589.0/30240.0)));
  142. c1 = -1.0/540.0 - eps/288.0;
  143. }
  144. else {
  145. const double rt_term = sqrt(-2.0 * ln_term.val/(eps*eps));
  146. const double lam = x/a;
  147. c0 = (1.0 - 1.0/rt_term)/eps;
  148. c1 = -(eta*eta*eta * (lam*lam + 10.0*lam + 1.0) - 12.0 * eps*eps*eps) / (12.0 * eta*eta*eta*eps*eps*eps);
  149. }
  150. R = exp(-0.5*a*eta*eta)/(M_SQRT2*M_SQRTPI*rta) * (c0 + c1/a);
  151. result->val = 0.5 * erfc.val + R;
  152. result->err = GSL_DBL_EPSILON * fabs(R * 0.5 * a*eta*eta) + 0.5 * erfc.err;
  153. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  154. return stat_ln;
  155. }
  156. /* Continued fraction which occurs in evaluation
  157. * of Q(a,x) or Gamma(a,x).
  158. *
  159. * 1 (1-a)/x 1/x (2-a)/x 2/x (3-a)/x
  160. * F(a,x) = ---- ------- ----- -------- ----- -------- ...
  161. * 1 + 1 + 1 + 1 + 1 + 1 +
  162. *
  163. * Hans E. Plesser, 2002-01-22 (hans dot plesser at itf dot nlh dot no).
  164. *
  165. * Split out from gamma_inc_Q_CF() by GJ [Tue Apr 1 13:16:41 MST 2003].
  166. * See gamma_inc_Q_CF() below.
  167. *
  168. */
  169. static int
  170. gamma_inc_F_CF(const double a, const double x, gsl_sf_result * result)
  171. {
  172. const int nmax = 5000;
  173. const double small = gsl_pow_3 (GSL_DBL_EPSILON);
  174. double hn = 1.0; /* convergent */
  175. double Cn = 1.0 / small;
  176. double Dn = 1.0;
  177. int n;
  178. /* n == 1 has a_1, b_1, b_0 independent of a,x,
  179. so that has been done by hand */
  180. for ( n = 2 ; n < nmax ; n++ )
  181. {
  182. double an;
  183. double delta;
  184. if(GSL_IS_ODD(n))
  185. an = 0.5*(n-1)/x;
  186. else
  187. an = (0.5*n-a)/x;
  188. Dn = 1.0 + an * Dn;
  189. if ( fabs(Dn) < small )
  190. Dn = small;
  191. Cn = 1.0 + an/Cn;
  192. if ( fabs(Cn) < small )
  193. Cn = small;
  194. Dn = 1.0 / Dn;
  195. delta = Cn * Dn;
  196. hn *= delta;
  197. if(fabs(delta-1.0) < GSL_DBL_EPSILON) break;
  198. }
  199. result->val = hn;
  200. result->err = 2.0*GSL_DBL_EPSILON * fabs(hn);
  201. result->err += GSL_DBL_EPSILON * (2.0 + 0.5*n) * fabs(result->val);
  202. if(n == nmax)
  203. GSL_ERROR ("error in CF for F(a,x)", GSL_EMAXITER);
  204. else
  205. return GSL_SUCCESS;
  206. }
  207. /* Continued fraction for Q.
  208. *
  209. * Q(a,x) = D(a,x) a/x F(a,x)
  210. *
  211. * Hans E. Plesser, 2002-01-22 (hans dot plesser at itf dot nlh dot no):
  212. *
  213. * Since the Gautschi equivalent series method for CF evaluation may lead
  214. * to singularities, I have replaced it with the modified Lentz algorithm
  215. * given in
  216. *
  217. * I J Thompson and A R Barnett
  218. * Coulomb and Bessel Functions of Complex Arguments and Order
  219. * J Computational Physics 64:490-509 (1986)
  220. *
  221. * In consequence, gamma_inc_Q_CF_protected() is now obsolete and has been
  222. * removed.
  223. *
  224. * Identification of terms between the above equation for F(a, x) and
  225. * the first equation in the appendix of Thompson&Barnett is as follows:
  226. *
  227. * b_0 = 0, b_n = 1 for all n > 0
  228. *
  229. * a_1 = 1
  230. * a_n = (n/2-a)/x for n even
  231. * a_n = (n-1)/(2x) for n odd
  232. *
  233. */
  234. static
  235. int
  236. gamma_inc_Q_CF(const double a, const double x, gsl_sf_result * result)
  237. {
  238. gsl_sf_result D;
  239. gsl_sf_result F;
  240. const int stat_D = gamma_inc_D(a, x, &D);
  241. const int stat_F = gamma_inc_F_CF(a, x, &F);
  242. result->val = D.val * (a/x) * F.val;
  243. result->err = D.err * fabs((a/x) * F.val) + fabs(D.val * a/x * F.err);
  244. return GSL_ERROR_SELECT_2(stat_F, stat_D);
  245. }
  246. /* Useful for small a and x. Handles the subtraction analytically.
  247. */
  248. static
  249. int
  250. gamma_inc_Q_series(const double a, const double x, gsl_sf_result * result)
  251. {
  252. double term1; /* 1 - x^a/Gamma(a+1) */
  253. double sum; /* 1 + (a+1)/(a+2)(-x)/2! + (a+1)/(a+3)(-x)^2/3! + ... */
  254. int stat_sum;
  255. double term2; /* a temporary variable used at the end */
  256. {
  257. /* Evaluate series for 1 - x^a/Gamma(a+1), small a
  258. */
  259. const double pg21 = -2.404113806319188570799476; /* PolyGamma[2,1] */
  260. const double lnx = log(x);
  261. const double el = M_EULER+lnx;
  262. const double c1 = -el;
  263. const double c2 = M_PI*M_PI/12.0 - 0.5*el*el;
  264. const double c3 = el*(M_PI*M_PI/12.0 - el*el/6.0) + pg21/6.0;
  265. const double c4 = -0.04166666666666666667
  266. * (-1.758243446661483480 + lnx)
  267. * (-0.764428657272716373 + lnx)
  268. * ( 0.723980571623507657 + lnx)
  269. * ( 4.107554191916823640 + lnx);
  270. const double c5 = -0.0083333333333333333
  271. * (-2.06563396085715900 + lnx)
  272. * (-1.28459889470864700 + lnx)
  273. * (-0.27583535756454143 + lnx)
  274. * ( 1.33677371336239618 + lnx)
  275. * ( 5.17537282427561550 + lnx);
  276. const double c6 = -0.0013888888888888889
  277. * (-2.30814336454783200 + lnx)
  278. * (-1.65846557706987300 + lnx)
  279. * (-0.88768082560020400 + lnx)
  280. * ( 0.17043847751371778 + lnx)
  281. * ( 1.92135970115863890 + lnx)
  282. * ( 6.22578557795474900 + lnx);
  283. const double c7 = -0.00019841269841269841
  284. * (-2.5078657901291800 + lnx)
  285. * (-1.9478900888958200 + lnx)
  286. * (-1.3194837322612730 + lnx)
  287. * (-0.5281322700249279 + lnx)
  288. * ( 0.5913834939078759 + lnx)
  289. * ( 2.4876819633378140 + lnx)
  290. * ( 7.2648160783762400 + lnx);
  291. const double c8 = -0.00002480158730158730
  292. * (-2.677341544966400 + lnx)
  293. * (-2.182810448271700 + lnx)
  294. * (-1.649350342277400 + lnx)
  295. * (-1.014099048290790 + lnx)
  296. * (-0.191366955370652 + lnx)
  297. * ( 0.995403817918724 + lnx)
  298. * ( 3.041323283529310 + lnx)
  299. * ( 8.295966556941250 + lnx);
  300. const double c9 = -2.75573192239859e-6
  301. * (-2.8243487670469080 + lnx)
  302. * (-2.3798494322701120 + lnx)
  303. * (-1.9143674728689960 + lnx)
  304. * (-1.3814529102920370 + lnx)
  305. * (-0.7294312810261694 + lnx)
  306. * ( 0.1299079285269565 + lnx)
  307. * ( 1.3873333251885240 + lnx)
  308. * ( 3.5857258865210760 + lnx)
  309. * ( 9.3214237073814600 + lnx);
  310. const double c10 = -2.75573192239859e-7
  311. * (-2.9540329644556910 + lnx)
  312. * (-2.5491366926991850 + lnx)
  313. * (-2.1348279229279880 + lnx)
  314. * (-1.6741881076349450 + lnx)
  315. * (-1.1325949616098420 + lnx)
  316. * (-0.4590034650618494 + lnx)
  317. * ( 0.4399352987435699 + lnx)
  318. * ( 1.7702236517651670 + lnx)
  319. * ( 4.1231539047474080 + lnx)
  320. * ( 10.342627908148680 + lnx);
  321. term1 = a*(c1+a*(c2+a*(c3+a*(c4+a*(c5+a*(c6+a*(c7+a*(c8+a*(c9+a*c10)))))))));
  322. }
  323. {
  324. /* Evaluate the sum.
  325. */
  326. const int nmax = 5000;
  327. double t = 1.0;
  328. int n;
  329. sum = 1.0;
  330. for(n=1; n<nmax; n++) {
  331. t *= -x/(n+1.0);
  332. sum += (a+1.0)/(a+n+1.0)*t;
  333. if(fabs(t/sum) < GSL_DBL_EPSILON) break;
  334. }
  335. if(n == nmax)
  336. stat_sum = GSL_EMAXITER;
  337. else
  338. stat_sum = GSL_SUCCESS;
  339. }
  340. term2 = (1.0 - term1) * a/(a+1.0) * x * sum;
  341. result->val = term1 + term2;
  342. result->err = GSL_DBL_EPSILON * (fabs(term1) + 2.0*fabs(term2));
  343. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  344. return stat_sum;
  345. }
  346. /* series for small a and x, but not defined for a == 0 */
  347. static int
  348. gamma_inc_series(double a, double x, gsl_sf_result * result)
  349. {
  350. gsl_sf_result Q;
  351. gsl_sf_result G;
  352. const int stat_Q = gamma_inc_Q_series(a, x, &Q);
  353. const int stat_G = gsl_sf_gamma_e(a, &G);
  354. result->val = Q.val * G.val;
  355. result->err = fabs(Q.val * G.err) + fabs(Q.err * G.val);
  356. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  357. return GSL_ERROR_SELECT_2(stat_Q, stat_G);
  358. }
  359. static int
  360. gamma_inc_a_gt_0(double a, double x, gsl_sf_result * result)
  361. {
  362. /* x > 0 and a > 0; use result for Q */
  363. gsl_sf_result Q;
  364. gsl_sf_result G;
  365. const int stat_Q = gsl_sf_gamma_inc_Q_e(a, x, &Q);
  366. const int stat_G = gsl_sf_gamma_e(a, &G);
  367. result->val = G.val * Q.val;
  368. result->err = fabs(G.val * Q.err) + fabs(G.err * Q.val);
  369. result->err += 2.0*GSL_DBL_EPSILON * fabs(result->val);
  370. return GSL_ERROR_SELECT_2(stat_G, stat_Q);
  371. }
  372. static int
  373. gamma_inc_CF(double a, double x, gsl_sf_result * result)
  374. {
  375. gsl_sf_result F;
  376. gsl_sf_result pre;
  377. const double am1lgx = (a-1.0)*log(x);
  378. const int stat_F = gamma_inc_F_CF(a, x, &F);
  379. const int stat_E = gsl_sf_exp_err_e(am1lgx - x, GSL_DBL_EPSILON*fabs(am1lgx), &pre);
  380. result->val = F.val * pre.val;
  381. result->err = fabs(F.err * pre.val) + fabs(F.val * pre.err);
  382. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  383. return GSL_ERROR_SELECT_2(stat_F, stat_E);
  384. }
  385. /* evaluate Gamma(0,x), x > 0 */
  386. #define GAMMA_INC_A_0(x, result) gsl_sf_expint_E1_e(x, result)
  387. /*-*-*-*-*-*-*-*-*-*-*-* Functions with Error Codes *-*-*-*-*-*-*-*-*-*-*-*/
  388. int
  389. gsl_sf_gamma_inc_Q_e(const double a, const double x, gsl_sf_result * result)
  390. {
  391. if(a < 0.0 || x < 0.0) {
  392. DOMAIN_ERROR(result);
  393. }
  394. else if(x == 0.0) {
  395. result->val = 1.0;
  396. result->err = 0.0;
  397. return GSL_SUCCESS;
  398. }
  399. else if(a == 0.0)
  400. {
  401. result->val = 0.0;
  402. result->err = 0.0;
  403. return GSL_SUCCESS;
  404. }
  405. else if(x <= 0.5*a) {
  406. /* If the series is quick, do that. It is
  407. * robust and simple.
  408. */
  409. gsl_sf_result P;
  410. int stat_P = gamma_inc_P_series(a, x, &P);
  411. result->val = 1.0 - P.val;
  412. result->err = P.err;
  413. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  414. return stat_P;
  415. }
  416. else if(a >= 1.0e+06 && (x-a)*(x-a) < a) {
  417. /* Then try the difficult asymptotic regime.
  418. * This is the only way to do this region.
  419. */
  420. return gamma_inc_Q_asymp_unif(a, x, result);
  421. }
  422. else if(a < 0.2 && x < 5.0) {
  423. /* Cancellations at small a must be handled
  424. * analytically; x should not be too big
  425. * either since the series terms grow
  426. * with x and log(x).
  427. */
  428. return gamma_inc_Q_series(a, x, result);
  429. }
  430. else if(a <= x) {
  431. if(x <= 1.0e+06) {
  432. /* Continued fraction is excellent for x >~ a.
  433. * We do not let x be too large when x > a since
  434. * it is somewhat pointless to try this there;
  435. * the function is rapidly decreasing for
  436. * x large and x > a, and it will just
  437. * underflow in that region anyway. We
  438. * catch that case in the standard
  439. * large-x method.
  440. */
  441. return gamma_inc_Q_CF(a, x, result);
  442. }
  443. else {
  444. return gamma_inc_Q_large_x(a, x, result);
  445. }
  446. }
  447. else {
  448. if(x > a - sqrt(a)) {
  449. /* Continued fraction again. The convergence
  450. * is a little slower here, but that is fine.
  451. * We have to trade that off against the slow
  452. * convergence of the series, which is the
  453. * only other option.
  454. */
  455. return gamma_inc_Q_CF(a, x, result);
  456. }
  457. else {
  458. gsl_sf_result P;
  459. int stat_P = gamma_inc_P_series(a, x, &P);
  460. result->val = 1.0 - P.val;
  461. result->err = P.err;
  462. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  463. return stat_P;
  464. }
  465. }
  466. }
  467. int
  468. gsl_sf_gamma_inc_P_e(const double a, const double x, gsl_sf_result * result)
  469. {
  470. if(a <= 0.0 || x < 0.0) {
  471. DOMAIN_ERROR(result);
  472. }
  473. else if(x == 0.0) {
  474. result->val = 0.0;
  475. result->err = 0.0;
  476. return GSL_SUCCESS;
  477. }
  478. else if(x < 20.0 || x < 0.5*a) {
  479. /* Do the easy series cases. Robust and quick.
  480. */
  481. return gamma_inc_P_series(a, x, result);
  482. }
  483. else if(a > 1.0e+06 && (x-a)*(x-a) < a) {
  484. /* Crossover region. Note that Q and P are
  485. * roughly the same order of magnitude here,
  486. * so the subtraction is stable.
  487. */
  488. gsl_sf_result Q;
  489. int stat_Q = gamma_inc_Q_asymp_unif(a, x, &Q);
  490. result->val = 1.0 - Q.val;
  491. result->err = Q.err;
  492. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  493. return stat_Q;
  494. }
  495. else if(a <= x) {
  496. /* Q <~ P in this area, so the
  497. * subtractions are stable.
  498. */
  499. gsl_sf_result Q;
  500. int stat_Q;
  501. if(a > 0.2*x) {
  502. stat_Q = gamma_inc_Q_CF(a, x, &Q);
  503. }
  504. else {
  505. stat_Q = gamma_inc_Q_large_x(a, x, &Q);
  506. }
  507. result->val = 1.0 - Q.val;
  508. result->err = Q.err;
  509. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  510. return stat_Q;
  511. }
  512. else {
  513. if((x-a)*(x-a) < a) {
  514. /* This condition is meant to insure
  515. * that Q is not very close to 1,
  516. * so the subtraction is stable.
  517. */
  518. gsl_sf_result Q;
  519. int stat_Q = gamma_inc_Q_CF(a, x, &Q);
  520. result->val = 1.0 - Q.val;
  521. result->err = Q.err;
  522. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  523. return stat_Q;
  524. }
  525. else {
  526. return gamma_inc_P_series(a, x, result);
  527. }
  528. }
  529. }
  530. int
  531. gsl_sf_gamma_inc_e(const double a, const double x, gsl_sf_result * result)
  532. {
  533. if(x < 0.0) {
  534. DOMAIN_ERROR(result);
  535. }
  536. else if(x == 0.0) {
  537. return gsl_sf_gamma_e(a, result);
  538. }
  539. else if(a == 0.0)
  540. {
  541. return GAMMA_INC_A_0(x, result);
  542. }
  543. else if(a > 0.0)
  544. {
  545. return gamma_inc_a_gt_0(a, x, result);
  546. }
  547. else if(x > 0.25)
  548. {
  549. /* continued fraction seems to fail for x too small; otherwise
  550. it is ok, independent of the value of |x/a|, because of the
  551. non-oscillation in the expansion, i.e. the CF is
  552. un-conditionally convergent for a < 0 and x > 0
  553. */
  554. return gamma_inc_CF(a, x, result);
  555. }
  556. else if(fabs(a) < 0.5)
  557. {
  558. return gamma_inc_series(a, x, result);
  559. }
  560. else
  561. {
  562. /* a = fa + da; da >= 0 */
  563. const double fa = floor(a);
  564. const double da = a - fa;
  565. gsl_sf_result g_da;
  566. const int stat_g_da = ( da > 0.0 ? gamma_inc_a_gt_0(da, x, &g_da)
  567. : GAMMA_INC_A_0(x, &g_da));
  568. double alpha = da;
  569. double gax = g_da.val;
  570. /* Gamma(alpha-1,x) = 1/(alpha-1) (Gamma(a,x) - x^(alpha-1) e^-x) */
  571. do
  572. {
  573. const double shift = exp(-x + (alpha-1.0)*log(x));
  574. gax = (gax - shift) / (alpha - 1.0);
  575. alpha -= 1.0;
  576. } while(alpha > a);
  577. result->val = gax;
  578. result->err = 2.0*(1.0 + fabs(a))*GSL_DBL_EPSILON*fabs(gax);
  579. return stat_g_da;
  580. }
  581. }
  582. /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/
  583. #include "gsl_specfunc__eval.h"
  584. double gsl_sf_gamma_inc_P(const double a, const double x)
  585. {
  586. EVAL_RESULT(gsl_sf_gamma_inc_P_e(a, x, &result));
  587. }
  588. double gsl_sf_gamma_inc_Q(const double a, const double x)
  589. {
  590. EVAL_RESULT(gsl_sf_gamma_inc_Q_e(a, x, &result));
  591. }
  592. double gsl_sf_gamma_inc(const double a, const double x)
  593. {
  594. EVAL_RESULT(gsl_sf_gamma_inc_e(a, x, &result));
  595. }