igaml.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /* igaml.c
  2. *
  3. * Incomplete gamma integral
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * long double a, x, y, igaml();
  10. *
  11. * y = igaml( a, x );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * The function is defined by
  18. *
  19. * x
  20. * -
  21. * 1 | | -t a-1
  22. * igam(a,x) = ----- | e t dt.
  23. * - | |
  24. * | (a) -
  25. * 0
  26. *
  27. *
  28. * In this implementation both arguments must be positive.
  29. * The integral is evaluated by either a power series or
  30. * continued fraction expansion, depending on the relative
  31. * values of a and x.
  32. *
  33. *
  34. *
  35. * ACCURACY:
  36. *
  37. * Relative error:
  38. * arithmetic domain # trials peak rms
  39. * DEC 0,30 4000 4.4e-15 6.3e-16
  40. * IEEE 0,30 10000 3.6e-14 5.1e-15
  41. *
  42. */
  43. /* igamcl()
  44. *
  45. * Complemented incomplete gamma integral
  46. *
  47. *
  48. *
  49. * SYNOPSIS:
  50. *
  51. * long double a, x, y, igamcl();
  52. *
  53. * y = igamcl( a, x );
  54. *
  55. *
  56. *
  57. * DESCRIPTION:
  58. *
  59. * The function is defined by
  60. *
  61. *
  62. * igamc(a,x) = 1 - igam(a,x)
  63. *
  64. * inf.
  65. * -
  66. * 1 | | -t a-1
  67. * = ----- | e t dt.
  68. * - | |
  69. * | (a) -
  70. * x
  71. *
  72. *
  73. * In this implementation both arguments must be positive.
  74. * The integral is evaluated by either a power series or
  75. * continued fraction expansion, depending on the relative
  76. * values of a and x.
  77. *
  78. *
  79. *
  80. * ACCURACY:
  81. *
  82. * Relative error:
  83. * arithmetic domain # trials peak rms
  84. * DEC 0,30 2000 2.7e-15 4.0e-16
  85. * IEEE 0,30 60000 1.4e-12 6.3e-15
  86. *
  87. */
  88. /*
  89. Cephes Math Library Release 2.3: March, 1995
  90. Copyright 1985, 1995 by Stephen L. Moshier
  91. */
  92. #include <math.h>
  93. #ifdef ANSIPROT
  94. extern long double lgaml ( long double );
  95. extern long double expl ( long double );
  96. extern long double logl ( long double );
  97. extern long double fabsl ( long double );
  98. extern long double gammal ( long double );
  99. long double igaml ( long double, long double );
  100. long double igamcl ( long double, long double );
  101. #else
  102. long double lgaml(), expl(), logl(), fabsl(), igaml(), gammal();
  103. long double igamcl();
  104. #endif
  105. #define BIG 9.223372036854775808e18L
  106. #define MAXGAML 1755.455L
  107. extern long double MACHEPL, MINLOGL;
  108. long double igamcl( a, x )
  109. long double a, x;
  110. {
  111. long double ans, c, yc, ax, y, z, r, t;
  112. long double pk, pkm1, pkm2, qk, qkm1, qkm2;
  113. if( (x <= 0.0L) || ( a <= 0.0L) )
  114. return( 1.0L );
  115. if( (x < 1.0L) || (x < a) )
  116. return( 1.0L - igaml(a,x) );
  117. ax = a * logl(x) - x - lgaml(a);
  118. if( ax < MINLOGL )
  119. {
  120. mtherr( "igamcl", UNDERFLOW );
  121. return( 0.0L );
  122. }
  123. ax = expl(ax);
  124. /* continued fraction */
  125. y = 1.0L - a;
  126. z = x + y + 1.0L;
  127. c = 0.0L;
  128. pkm2 = 1.0L;
  129. qkm2 = x;
  130. pkm1 = x + 1.0L;
  131. qkm1 = z * x;
  132. ans = pkm1/qkm1;
  133. do
  134. {
  135. c += 1.0L;
  136. y += 1.0L;
  137. z += 2.0L;
  138. yc = y * c;
  139. pk = pkm1 * z - pkm2 * yc;
  140. qk = qkm1 * z - qkm2 * yc;
  141. if( qk != 0.0L )
  142. {
  143. r = pk/qk;
  144. t = fabsl( (ans - r)/r );
  145. ans = r;
  146. }
  147. else
  148. t = 1.0L;
  149. pkm2 = pkm1;
  150. pkm1 = pk;
  151. qkm2 = qkm1;
  152. qkm1 = qk;
  153. if( fabsl(pk) > BIG )
  154. {
  155. pkm2 /= BIG;
  156. pkm1 /= BIG;
  157. qkm2 /= BIG;
  158. qkm1 /= BIG;
  159. }
  160. }
  161. while( t > MACHEPL );
  162. return( ans * ax );
  163. }
  164. /* left tail of incomplete gamma function:
  165. *
  166. * inf. k
  167. * a -x - x
  168. * x e > ----------
  169. * - -
  170. * k=0 | (a+k+1)
  171. *
  172. */
  173. long double igaml( a, x )
  174. long double a, x;
  175. {
  176. long double ans, ax, c, r;
  177. if( (x <= 0.0L) || ( a <= 0.0L) )
  178. return( 0.0L );
  179. if( (x > 1.0L) && (x > a ) )
  180. return( 1.0L - igamcl(a,x) );
  181. ax = a * logl(x) - x - lgaml(a);
  182. if( ax < MINLOGL )
  183. {
  184. mtherr( "igaml", UNDERFLOW );
  185. return( 0.0L );
  186. }
  187. ax = expl(ax);
  188. /* power series */
  189. r = a;
  190. c = 1.0L;
  191. ans = 1.0L;
  192. do
  193. {
  194. r += 1.0L;
  195. c *= x/r;
  196. ans += c;
  197. }
  198. while( c/ans > MACHEPL );
  199. return( ans * ax/a );
  200. }