OSDN Git Service

Fix no pic
[uclinux-h8/uClinux-dist.git] / lib / libm / igamif.c
1 /*                                                      igamif()
2  *
3  *      Inverse of complemented imcomplete gamma integral
4  *
5  *
6  *
7  * SYNOPSIS:
8  *
9  * float a, x, y, igamif();
10  *
11  * x = igamif( a, y );
12  *
13  *
14  *
15  * DESCRIPTION:
16  *
17  * Given y, the function finds x such that
18  *
19  *  igamc( a, x ) = y.
20  *
21  * Starting with the approximate value
22  *
23  *         3
24  *  x = a t
25  *
26  *  where
27  *
28  *  t = 1 - d - ndtri(y) sqrt(d)
29  * 
30  * and
31  *
32  *  d = 1/9a,
33  *
34  * the routine performs up to 10 Newton iterations to find the
35  * root of igamc(a,x) - y = 0.
36  *
37  *
38  * ACCURACY:
39  *
40  * Tested for a ranging from 0 to 100 and x from 0 to 1.
41  *
42  *                      Relative error:
43  * arithmetic   domain     # trials      peak         rms
44  *    IEEE      0,100         5000       1.0e-5      1.5e-6
45  *
46  */
47 \f
48 /*
49 Cephes Math Library Release 2.2:  July, 1992
50 Copyright 1984, 1987, 1992 by Stephen L. Moshier
51 Direct inquiries to 30 Frost Street, Cambridge, MA 02140
52 */
53
54 #include "mconf.h"
55
56 extern float MACHEPF, MAXLOGF;
57
58 #define fabsf(x) ( (x) < 0 ? -(x) : (x) )
59
60 #ifdef ANSIC
61 float igamcf(float, float);
62 float ndtrif(float), expf(float), logf(float), sqrtf(float), lgamf(float);
63 #else
64 float igamcf();
65 float ndtrif(), expf(), logf(), sqrtf(), lgamf();
66 #endif
67
68
69 #ifdef ANSIC
70 float igamif( float aa, float yy0 )
71 #else
72 float igamif( aa, yy0 )
73 double aa, yy0;
74 #endif
75 {
76 float a, y0, d, y, x0, lgm;
77 int i;
78
79 a = aa;
80 y0 = yy0;
81 /* approximation to inverse function */
82 d = 1.0/(9.0*a);
83 y = ( 1.0 - d - ndtrif(y0) * sqrtf(d) );
84 x0 = a * y * y * y;
85
86 lgm = lgamf(a);
87
88 for( i=0; i<10; i++ )
89         {
90         if( x0 <= 0.0 )
91                 {
92                 mtherr( "igamif", UNDERFLOW );
93                 return(0.0);
94                 }
95         y = igamcf(a,x0);
96 /* compute the derivative of the function at this point */
97         d = (a - 1.0) * logf(x0) - x0 - lgm;
98         if( d < -MAXLOGF )
99                 {
100                 mtherr( "igamif", UNDERFLOW );
101                 goto done;
102                 }
103         d = -expf(d);
104 /* compute the step to the next approximation of x */
105         if( d == 0.0 )
106                 goto done;
107         d = (y - y0)/d;
108         x0 = x0 - d;
109         if( i < 3 )
110                 continue;
111         if( fabsf(d/x0) < (2.0 * MACHEPF) )
112                 goto done;
113         }
114
115 done:
116 return( x0 );
117 }