summaryrefslogtreecommitdiff
path: root/libm/float/incbetf.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-11-22 14:04:29 +0000
committerEric Andersen <andersen@codepoet.org>2001-11-22 14:04:29 +0000
commit7ce331c01ce6eb7b3f5c715a38a24359da9c6ee2 (patch)
tree3a7e8476e868ae15f4da1b7ce26b2db6f434468c /libm/float/incbetf.c
parentc117dd5fb183afb1a4790a6f6110d88704be6bf8 (diff)
Totally rework the math library, this time based on the MacOs X
math library (which is itself based on the math lib from FreeBSD). -Erik
Diffstat (limited to 'libm/float/incbetf.c')
-rw-r--r--libm/float/incbetf.c424
1 files changed, 0 insertions, 424 deletions
diff --git a/libm/float/incbetf.c b/libm/float/incbetf.c
deleted file mode 100644
index fed9aae4b..000000000
--- a/libm/float/incbetf.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/* incbetf.c
- *
- * Incomplete beta integral
- *
- *
- * SYNOPSIS:
- *
- * float a, b, x, y, incbetf();
- *
- * y = incbetf( a, b, x );
- *
- *
- * DESCRIPTION:
- *
- * Returns incomplete beta integral of the arguments, evaluated
- * from zero to x. The function is defined as
- *
- * x
- * - -
- * | (a+b) | | a-1 b-1
- * ----------- | t (1-t) dt.
- * - - | |
- * | (a) | (b) -
- * 0
- *
- * The domain of definition is 0 <= x <= 1. In this
- * implementation a and b are restricted to positive values.
- * The integral from x to 1 may be obtained by the symmetry
- * relation
- *
- * 1 - incbet( a, b, x ) = incbet( b, a, 1-x ).
- *
- * The integral is evaluated by a continued fraction expansion.
- * If a < 1, the function calls itself recursively after a
- * transformation to increase a to a+1.
- *
- * ACCURACY:
- *
- * Tested at random points (a,b,x) with a and b in the indicated
- * interval and x between 0 and 1.
- *
- * arithmetic domain # trials peak rms
- * Relative error:
- * IEEE 0,30 10000 3.7e-5 5.1e-6
- * IEEE 0,100 10000 1.7e-4 2.5e-5
- * The useful domain for relative error is limited by underflow
- * of the single precision exponential function.
- * Absolute error:
- * IEEE 0,30 100000 2.2e-5 9.6e-7
- * IEEE 0,100 10000 6.5e-5 3.7e-6
- *
- * Larger errors may occur for extreme ratios of a and b.
- *
- * ERROR MESSAGES:
- * message condition value returned
- * incbetf domain x<0, x>1 0.0
- */
-
-
-/*
-Cephes Math Library, Release 2.2: July, 1992
-Copyright 1984, 1987, 1992 by Stephen L. Moshier
-Direct inquiries to 30 Frost Street, Cambridge, MA 02140
-*/
-
-#include <math.h>
-
-#ifdef ANSIC
-float lgamf(float), expf(float), logf(float);
-static float incbdf(float, float, float);
-static float incbcff(float, float, float);
-float incbpsf(float, float, float);
-#else
-float lgamf(), expf(), logf();
-float incbpsf();
-static float incbcff(), incbdf();
-#endif
-
-#define fabsf(x) ( (x) < 0 ? -(x) : (x) )
-
-/* BIG = 1/MACHEPF */
-#define BIG 16777216.
-extern float MACHEPF, MAXLOGF;
-#define MINLOGF (-MAXLOGF)
-
-float incbetf( float aaa, float bbb, float xxx )
-{
-float aa, bb, xx, ans, a, b, t, x, onemx;
-int flag;
-
-aa = aaa;
-bb = bbb;
-xx = xxx;
-if( (xx <= 0.0) || ( xx >= 1.0) )
- {
- if( xx == 0.0 )
- return(0.0);
- if( xx == 1.0 )
- return( 1.0 );
- mtherr( "incbetf", DOMAIN );
- return( 0.0 );
- }
-
-onemx = 1.0 - xx;
-
-
-/* transformation for small aa */
-
-if( aa <= 1.0 )
- {
- ans = incbetf( aa+1.0, bb, xx );
- t = aa*logf(xx) + bb*logf( 1.0-xx )
- + lgamf(aa+bb) - lgamf(aa+1.0) - lgamf(bb);
- if( t > MINLOGF )
- ans += expf(t);
- return( ans );
- }
-
-
-/* see if x is greater than the mean */
-
-if( xx > (aa/(aa+bb)) )
- {
- flag = 1;
- a = bb;
- b = aa;
- t = xx;
- x = onemx;
- }
-else
- {
- flag = 0;
- a = aa;
- b = bb;
- t = onemx;
- x = xx;
- }
-
-/* transformation for small aa */
-/*
-if( a <= 1.0 )
- {
- ans = a*logf(x) + b*logf( onemx )
- + lgamf(a+b) - lgamf(a+1.0) - lgamf(b);
- t = incbetf( a+1.0, b, x );
- if( ans > MINLOGF )
- t += expf(ans);
- goto bdone;
- }
-*/
-/* Choose expansion for optimal convergence */
-
-
-if( b > 10.0 )
- {
-if( fabsf(b*x/a) < 0.3 )
- {
- t = incbpsf( a, b, x );
- goto bdone;
- }
- }
-
-ans = x * (a+b-2.0)/(a-1.0);
-if( ans < 1.0 )
- {
- ans = incbcff( a, b, x );
- t = b * logf( t );
- }
-else
- {
- ans = incbdf( a, b, x );
- t = (b-1.0) * logf(t);
- }
-
-t += a*logf(x) + lgamf(a+b) - lgamf(a) - lgamf(b);
-t += logf( ans/a );
-
-if( t < MINLOGF )
- {
- t = 0.0;
- if( flag == 0 )
- {
- mtherr( "incbetf", UNDERFLOW );
- }
- }
-else
- {
- t = expf(t);
- }
-bdone:
-
-if( flag )
- t = 1.0 - t;
-
-return( t );
-}
-
-/* Continued fraction expansion #1
- * for incomplete beta integral
- */
-
-static float incbcff( float aa, float bb, float xx )
-{
-float a, b, x, xk, pk, pkm1, pkm2, qk, qkm1, qkm2;
-float k1, k2, k3, k4, k5, k6, k7, k8;
-float r, t, ans;
-static float big = BIG;
-int n;
-
-a = aa;
-b = bb;
-x = xx;
-k1 = a;
-k2 = a + b;
-k3 = a;
-k4 = a + 1.0;
-k5 = 1.0;
-k6 = b - 1.0;
-k7 = k4;
-k8 = a + 2.0;
-
-pkm2 = 0.0;
-qkm2 = 1.0;
-pkm1 = 1.0;
-qkm1 = 1.0;
-ans = 1.0;
-r = 0.0;
-n = 0;
-do
- {
-
- xk = -( x * k1 * k2 )/( k3 * k4 );
- pk = pkm1 + pkm2 * xk;
- qk = qkm1 + qkm2 * xk;
- pkm2 = pkm1;
- pkm1 = pk;
- qkm2 = qkm1;
- qkm1 = qk;
-
- xk = ( x * k5 * k6 )/( k7 * k8 );
- pk = pkm1 + pkm2 * xk;
- qk = qkm1 + qkm2 * xk;
- pkm2 = pkm1;
- pkm1 = pk;
- qkm2 = qkm1;
- qkm1 = qk;
-
- if( qk != 0 )
- r = pk/qk;
- if( r != 0 )
- {
- t = fabsf( (ans - r)/r );
- ans = r;
- }
- else
- t = 1.0;
-
- if( t < MACHEPF )
- goto cdone;
-
- k1 += 1.0;
- k2 += 1.0;
- k3 += 2.0;
- k4 += 2.0;
- k5 += 1.0;
- k6 -= 1.0;
- k7 += 2.0;
- k8 += 2.0;
-
- if( (fabsf(qk) + fabsf(pk)) > big )
- {
- pkm2 *= MACHEPF;
- pkm1 *= MACHEPF;
- qkm2 *= MACHEPF;
- qkm1 *= MACHEPF;
- }
- if( (fabsf(qk) < MACHEPF) || (fabsf(pk) < MACHEPF) )
- {
- pkm2 *= big;
- pkm1 *= big;
- qkm2 *= big;
- qkm1 *= big;
- }
- }
-while( ++n < 100 );
-
-cdone:
-return(ans);
-}
-
-
-/* Continued fraction expansion #2
- * for incomplete beta integral
- */
-
-static float incbdf( float aa, float bb, float xx )
-{
-float a, b, x, xk, pk, pkm1, pkm2, qk, qkm1, qkm2;
-float k1, k2, k3, k4, k5, k6, k7, k8;
-float r, t, ans, z;
-static float big = BIG;
-int n;
-
-a = aa;
-b = bb;
-x = xx;
-k1 = a;
-k2 = b - 1.0;
-k3 = a;
-k4 = a + 1.0;
-k5 = 1.0;
-k6 = a + b;
-k7 = a + 1.0;;
-k8 = a + 2.0;
-
-pkm2 = 0.0;
-qkm2 = 1.0;
-pkm1 = 1.0;
-qkm1 = 1.0;
-z = x / (1.0-x);
-ans = 1.0;
-r = 0.0;
-n = 0;
-do
- {
-
- xk = -( z * k1 * k2 )/( k3 * k4 );
- pk = pkm1 + pkm2 * xk;
- qk = qkm1 + qkm2 * xk;
- pkm2 = pkm1;
- pkm1 = pk;
- qkm2 = qkm1;
- qkm1 = qk;
-
- xk = ( z * k5 * k6 )/( k7 * k8 );
- pk = pkm1 + pkm2 * xk;
- qk = qkm1 + qkm2 * xk;
- pkm2 = pkm1;
- pkm1 = pk;
- qkm2 = qkm1;
- qkm1 = qk;
-
- if( qk != 0 )
- r = pk/qk;
- if( r != 0 )
- {
- t = fabsf( (ans - r)/r );
- ans = r;
- }
- else
- t = 1.0;
-
- if( t < MACHEPF )
- goto cdone;
-
- k1 += 1.0;
- k2 -= 1.0;
- k3 += 2.0;
- k4 += 2.0;
- k5 += 1.0;
- k6 += 1.0;
- k7 += 2.0;
- k8 += 2.0;
-
- if( (fabsf(qk) + fabsf(pk)) > big )
- {
- pkm2 *= MACHEPF;
- pkm1 *= MACHEPF;
- qkm2 *= MACHEPF;
- qkm1 *= MACHEPF;
- }
- if( (fabsf(qk) < MACHEPF) || (fabsf(pk) < MACHEPF) )
- {
- pkm2 *= big;
- pkm1 *= big;
- qkm2 *= big;
- qkm1 *= big;
- }
- }
-while( ++n < 100 );
-
-cdone:
-return(ans);
-}
-
-
-/* power series */
-float incbpsf( float aa, float bb, float xx )
-{
-float a, b, x, t, u, y, s;
-
-a = aa;
-b = bb;
-x = xx;
-
-y = a * logf(x) + (b-1.0)*logf(1.0-x) - logf(a);
-y -= lgamf(a) + lgamf(b);
-y += lgamf(a+b);
-
-
-t = x / (1.0 - x);
-s = 0.0;
-u = 1.0;
-do
- {
- b -= 1.0;
- if( b == 0.0 )
- break;
- a += 1.0;
- u *= t*b/a;
- s += u;
- }
-while( fabsf(u) > MACHEPF );
-
-if( y < MINLOGF )
- {
- mtherr( "incbetf", UNDERFLOW );
- s = 0.0;
- }
-else
- s = expf(y) * (1.0 + s);
-/*printf( "incbpsf: %.4e\n", s );*/
-return(s);
-}