3 * Gauss hypergeometric function F
9 * float a, b, c, x, y, hyp2f1f();
11 * y = hyp2f1f( a, b, c, x );
17 * hyp2f1( a, b, c, x ) = F ( a, b; c; x )
21 * - a(a+1)...(a+k) b(b+1)...(b+k) k+1
22 * = 1 + > ----------------------------- x .
23 * - c(c+1)...(c+k) (k+1)!
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
35 * |x| > 1 is rejected.
37 * The parameters a, b, c are considered to be integer
38 * valued if they are within 1.0e-6 of the nearest integer.
42 * Relative error (-1 < x < 1):
43 * arithmetic domain # trials peak rms
44 * IEEE 0,3 30000 5.8e-4 4.3e-6
51 Cephes Math Library Release 2.2: November, 1992
52 Copyright 1984, 1987, 1992 by Stephen L. Moshier
53 Direct inquiries to 30 Frost Street, Cambridge, MA 02140
61 #define ETHRESH 1.0e-5
63 extern float MAXNUMF, MACHEPF;
65 #define fabsf(x) ( (x) < 0 ? -(x) : (x) )
68 float powf(float, float);
69 static float hys2f1f(float, float, float, float, float *);
70 static float hyt2f1f(float, float, float, float, float *);
71 float gammaf(float), logf(float), expf(float), psif(float);
74 float powf(), gammaf(), logf(), expf(), psif();
76 static float hyt2f1f(), hys2f1f();
79 #define roundf(x) (floorf((x)+(float )0.5))
85 float hyp2f1f( float aa, float bb, float cc, float xx )
87 float hyp2f1f( aa, bb, cc, xx )
88 double aa, bb, cc, xx;
93 float p, q, r, s, y, ax;
94 float ia, ib, ic, id, err;
105 ia = roundf(a); /* nearest integer to a */
110 if( fabsf(a-ia) < EPS ) /* a is a negative integer */
116 if( fabsf(b-ib) < EPS ) /* b is a negative integer */
122 if( fabsf(b-c) < EPS ) /* b = c */
124 y = powf( s, -a ); /* s to the -a power */
127 if( fabsf(a-c) < EPS ) /* a = c */
129 y = powf( s, -b ); /* s to the -b power */
138 ic = roundf(c); /* nearest integer to c */
139 if( fabsf(c-ic) < EPS ) /* c is a negative integer */
141 /* check if termination before explosion */
142 if( (flag & 1) && (ia > ic) )
144 if( (flag & 2) && (ib > ic) )
150 if( flag ) /* function is a polynomial */
153 if( ax > 1.0 ) /* series diverges */
158 if( (ia <= 0.0) && (fabsf(p-ia) < EPS) ) /* negative int c - a */
162 ib = roundf(r); /* nearest integer to r */
163 if( (ib <= 0.0) && (fabsf(r-ib) < EPS) ) /* negative int c - b */
167 id = roundf(d); /* nearest integer to d */
170 if( fabsf(ax-1.0) < EPS ) /* |x| == 1.0 */
174 if( flag & 12 ) /* negative int c-a or c-b */
183 y = gammaf(c)*gammaf(d)/(gammaf(p)*gammaf(r));
191 /* Conditionally make d > 0 by recurrence on c
196 /* Try the power series first */
197 y = hyt2f1f( a, b, c, x, &err );
200 /* Apply the recurrence if power series fails */
204 d2 = hyp2f1f(a,b,e,x);
205 d1 = hyp2f1f(a,b,e+1.0,x);
207 for( i=0; i<aid; i++ )
210 y = (e*(r-(2.0*e-q)*x)*d2 + (e-a)*(e-b)*x*d1)/(e*r*s);
220 goto hypf; /* negative integer c-a or c-b */
223 y = hyt2f1f( a, b, c, x, &err );
228 mtherr( "hyp2f1", PLOSS );
229 /* printf( "Estimated err = %.2e\n", err );*/
233 /* The transformation for c-a or c-b negative integer
237 y = powf( s, d ) * hys2f1f( c-a, c-b, c, x, &err );
242 mtherr( "hyp2f1f", OVERFLOW );
249 /* Apply transformations for |x| near 1
250 * then call the power series
253 static float hyt2f1f( float aa, float bb, float cc, float xx, float *loss )
255 static float hyt2f1f( aa, bb, cc, xx, loss )
256 double aa, bb, cc, xx;
261 float p, q, r, s, t, y, d, err, err1;
262 float ax, id, d1, d2, e, y1;
274 y = powf( s, -a ) * hys2f1f( a, c-b, c, -x/s, &err );
277 y = powf( s, -b ) * hys2f1f( c-a, b, c, -x/s, &err );
285 id = roundf(d); /* nearest integer to d */
290 if( fabsf(d-id) > EPS2 ) /* test for integer c-a-b */
292 /* Try the power series first */
293 y = hys2f1f( a, b, c, x, &err );
296 /* If power series fails, then apply AMS55 #15.3.6 */
297 q = hys2f1f( a, b, 1.0-d, s, &err );
298 q *= gammaf(d) /(gammaf(c-a) * gammaf(c-b));
299 r = powf(s,d) * hys2f1f( c-a, c-b, d+1.0, s, &err1 );
300 r *= gammaf(-d)/(gammaf(a) * gammaf(b));
303 q = fabsf(q); /* estimate cancellation error */
307 err += err1 + (MACHEPF*r)/y;
314 /* Psi function expansion, AMS55 #15.3.10, #15.3.11, #15.3.12 */
333 y = psif(1.0) + psif(1.0+e) - psif(a+d1) - psif(b+d1) - ax;
336 p = (a+d1) * (b+d1) * s / gammaf(e+2.0); /* Poch for t=1 */
340 r = psif(1.0+t) + psif(1.0+t+e) - psif(a+t+d1)
344 p *= s * (a+t+d1) / (t+1.0);
345 p *= (b+t+d1) / (t+1.0+e);
348 while( fabsf(q/y) > EPS );
353 y *= gammaf(c)/(gammaf(a)*gammaf(b));
364 for( i=1; i<aid; i++ )
367 p *= s * (a+t+d2) * (b+t+d2) / r;
376 y1 *= gammaf(e) * p / (gammaf(a+d1) * gammaf(b+d1));
377 y *= p / (gammaf(a+d2) * gammaf(b+d2));
381 q = powf( s, id ); /* s to the id power */
394 /* Use defining power series if no special cases */
395 y = hys2f1f( a, b, c, x, &err );
406 /* Defining power series expansion of Gauss hypergeometric function */
410 static float hys2f1f( float aa, float bb, float cc, float xx, float *loss )
412 static float hys2f1f( aa, bb, cc, xx, loss )
413 double aa, bb, cc, xx;
419 float f, g, h, k, m, s, u, umax;
440 u = u * ((f+k) * (g+k) * x / ((h+k) * m));
442 k = fabsf(u); /* remember largest term summed */
446 if( ++i > 10000 ) /* should never happen */
452 while( fabsf(u/s) > MACHEPF );
454 /* return estimated relative error */
455 *loss = (MACHEPF*umax)/fabsf(s) + (MACHEPF*i);
463 extern double MACHEP;
466 static float hys2f1f( float aa, float bb, float cc, float xx, float *loss )
468 static float hys2f1f( aa, bb, cc, xx, loss )
469 double aa, bb, cc, xx;
475 double f, g, h, k, m, s, u, umax;
499 u = u * ((f+k) * (g+k) * x / ((h+k) * m));
501 k = fabsf(u); /* remember largest term summed */
505 if( ++i > 10000 ) /* should never happen */
511 while( fabsf(u/s) > MACHEP );
513 /* return estimated relative error */
514 *loss = (MACHEPF*umax)/fabsf(s) + (MACHEPF*i);