diff options
Diffstat (limited to 'libm/float/ellikf.c')
| -rw-r--r-- | libm/float/ellikf.c | 113 | 
1 files changed, 113 insertions, 0 deletions
| diff --git a/libm/float/ellikf.c b/libm/float/ellikf.c new file mode 100644 index 000000000..8ec890926 --- /dev/null +++ b/libm/float/ellikf.c @@ -0,0 +1,113 @@ +/*							ellikf.c + * + *	Incomplete elliptic integral of the first kind + * + * + * + * SYNOPSIS: + * + * float phi, m, y, ellikf(); + * + * y = ellikf( phi, m ); + * + * + * + * DESCRIPTION: + * + * Approximates the integral + * + * + * + *                phi + *                 - + *                | | + *                |           dt + * F(phi\m)  =    |    ------------------ + *                |                   2 + *              | |    sqrt( 1 - m sin t ) + *               - + *                0 + * + * of amplitude phi and modulus m, using the arithmetic - + * geometric mean algorithm. + * + * + * + * + * ACCURACY: + * + * Tested at random points with phi in [0, 2] and m in + * [0, 1]. + *                      Relative error: + * arithmetic   domain     # trials      peak         rms + *    IEEE      0,2         10000       2.9e-7      5.8e-8 + * + * + */ + + +/* +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 +*/ + +/*	Incomplete elliptic integral of first kind	*/ + +#include <math.h> +extern float PIF, PIO2F, MACHEPF; + +#define fabsf(x) ( (x) < 0 ? -(x) : (x) ) + +#ifdef ANSIC +float sqrtf(float), logf(float), sinf(float), tanf(float), atanf(float); +#else +float sqrtf(), logf(), sinf(), tanf(), atanf(); +#endif + + +float ellikf( float phia, float ma ) +{ +float phi, m, a, b, c, temp; +float t; +int d, mod, sign; + +phi = phia; +m = ma; +if( m == 0.0 ) +	return( phi ); +if( phi < 0.0 ) +	{ +	phi = -phi; +	sign = -1; +	} +else +	sign = 0; +a = 1.0; +b = 1.0 - m; +if( b == 0.0 ) +	return(  logf(  tanf( 0.5*(PIO2F + phi) )  )   ); +b = sqrtf(b); +c = sqrtf(m); +d = 1; +t = tanf( phi ); +mod = (phi + PIO2F)/PIF; + +while( fabsf(c/a) > MACHEPF ) +	{ +	temp = b/a; +	phi = phi + atanf(t*temp) + mod * PIF; +	mod = (phi + PIO2F)/PIF; +	t = t * ( 1.0 + temp )/( 1.0 - temp * t * t ); +	c = ( a - b )/2.0; +	temp = sqrtf( a * b ); +	a = ( a + b )/2.0; +	b = temp; +	d += d; +	} + +temp = (atanf(t) + mod * PIF)/(d * a); +if( sign < 0 ) +	temp = -temp; +return( temp ); +} | 
