rgammaf.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /* rgammaf.c
  2. *
  3. * Reciprocal gamma function
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * float x, y, rgammaf();
  10. *
  11. * y = rgammaf( x );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Returns one divided by the gamma function of the argument.
  18. *
  19. * The function is approximated by a Chebyshev expansion in
  20. * the interval [0,1]. Range reduction is by recurrence
  21. * for arguments between -34.034 and +34.84425627277176174.
  22. * 1/MAXNUMF is returned for positive arguments outside this
  23. * range.
  24. *
  25. * The reciprocal gamma function has no singularities,
  26. * but overflow and underflow may occur for large arguments.
  27. * These conditions return either MAXNUMF or 1/MAXNUMF with
  28. * appropriate sign.
  29. *
  30. * ACCURACY:
  31. *
  32. * Relative error:
  33. * arithmetic domain # trials peak rms
  34. * IEEE -34,+34 100000 8.9e-7 1.1e-7
  35. */
  36. /*
  37. Cephes Math Library Release 2.2: June, 1992
  38. Copyright 1985, 1987, 1992 by Stephen L. Moshier
  39. Direct inquiries to 30 Frost Street, Cambridge, MA 02140
  40. */
  41. #include <math.h>
  42. /* Chebyshev coefficients for reciprocal gamma function
  43. * in interval 0 to 1. Function is 1/(x gamma(x)) - 1
  44. */
  45. static float R[] = {
  46. 1.08965386454418662084E-9,
  47. -3.33964630686836942556E-8,
  48. 2.68975996440595483619E-7,
  49. 2.96001177518801696639E-6,
  50. -8.04814124978471142852E-5,
  51. 4.16609138709688864714E-4,
  52. 5.06579864028608725080E-3,
  53. -6.41925436109158228810E-2,
  54. -4.98558728684003594785E-3,
  55. 1.27546015610523951063E-1
  56. };
  57. static char name[] = "rgammaf";
  58. extern float PIF, MAXLOGF, MAXNUMF;
  59. float chbevlf(float, float *, int);
  60. float expf(float), logf(float), sinf(float), lgamf(float);
  61. float rgammaf(float xx)
  62. {
  63. float x, w, y, z;
  64. int sign;
  65. x = xx;
  66. if( x > 34.84425627277176174)
  67. {
  68. mtherr( name, UNDERFLOW );
  69. return(1.0/MAXNUMF);
  70. }
  71. if( x < -34.034 )
  72. {
  73. w = -x;
  74. z = sinf( PIF*w );
  75. if( z == 0.0 )
  76. return(0.0);
  77. if( z < 0.0 )
  78. {
  79. sign = 1;
  80. z = -z;
  81. }
  82. else
  83. sign = -1;
  84. y = logf( w * z / PIF ) + lgamf(w);
  85. if( y < -MAXLOGF )
  86. {
  87. mtherr( name, UNDERFLOW );
  88. return( sign * 1.0 / MAXNUMF );
  89. }
  90. if( y > MAXLOGF )
  91. {
  92. mtherr( name, OVERFLOW );
  93. return( sign * MAXNUMF );
  94. }
  95. return( sign * expf(y));
  96. }
  97. z = 1.0;
  98. w = x;
  99. while( w > 1.0 ) /* Downward recurrence */
  100. {
  101. w -= 1.0;
  102. z *= w;
  103. }
  104. while( w < 0.0 ) /* Upward recurrence */
  105. {
  106. z /= w;
  107. w += 1.0;
  108. }
  109. if( w == 0.0 ) /* Nonpositive integer */
  110. return(0.0);
  111. if( w == 1.0 ) /* Other integer */
  112. return( 1.0/z );
  113. y = w * ( 1.0 + chbevlf( 4.0*w-2.0, R, 10 ) ) / z;
  114. return(y);
  115. }