| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 | /*							ellpjf.c * *	Jacobian Elliptic Functions * * * * SYNOPSIS: * * float u, m, sn, cn, dn, phi; * int ellpj(); * * ellpj( u, m, _&sn, _&cn, _&dn, _&phi ); * * * * DESCRIPTION: * * * Evaluates the Jacobian elliptic functions sn(u|m), cn(u|m), * and dn(u|m) of parameter m between 0 and 1, and real * argument u. * * These functions are periodic, with quarter-period on the * real axis equal to the complete elliptic integral * ellpk(1.0-m). * * Relation to incomplete elliptic integral: * If u = ellik(phi,m), then sn(u|m) = sin(phi), * and cn(u|m) = cos(phi).  Phi is called the amplitude of u. * * Computation is by means of the arithmetic-geometric mean * algorithm, except when m is within 1e-9 of 0 or 1.  In the * latter case with m close to 1, the approximation applies * only for phi < pi/2. * * ACCURACY: * * Tested at random points with u between 0 and 10, m between * 0 and 1. * *            Absolute error (* = relative error): * arithmetic   function   # trials      peak         rms *    IEEE      sn          10000       1.7e-6      2.2e-7 *    IEEE      cn          10000       1.6e-6      2.2e-7 *    IEEE      dn          10000       1.4e-3      1.9e-5 *    IEEE      phi         10000       3.9e-7*     6.7e-8* * *  Peak error observed in consistency check using addition * theorem for sn(u+v) was 4e-16 (absolute).  Also tested by * the above relation to the incomplete elliptic integral. * Accuracy deteriorates when u is large. * *//*							ellpj.c		*//*Cephes Math Library Release 2.2:  July, 1992Copyright 1984, 1987, 1992 by Stephen L. MoshierDirect inquiries to 30 Frost Street, Cambridge, MA 02140*/#include <math.h>extern float PIO2F, MACHEPF;#define fabsf(x) ( (x) < 0 ? -(x) : (x) )#ifdef ANSICfloat sqrtf(float), sinf(float), cosf(float), asinf(float), tanhf(float);float sinhf(float), coshf(float), atanf(float), expf(float);#elsefloat sqrtf(), sinf(), cosf(), asinf(), tanhf();float sinhf(), coshf(), atanf(), expf();#endifint ellpjf( float uu, float mm,   float *sn, float *cn, float *dn, float *ph ){float u, m, ai, b, phi, t, twon;float a[10], c[10];int i;u = uu;m = mm;/* Check for special cases */if( m < 0.0 || m > 1.0 )	{	mtherr( "ellpjf", DOMAIN );	return(-1);	}if( m < 1.0e-5 )	{	t = sinf(u);	b = cosf(u);	ai = 0.25 * m * (u - t*b);	*sn = t - ai*b;	*cn = b + ai*t;	*ph = u - ai;	*dn = 1.0 - 0.5*m*t*t;	return(0);	}if( m >= 0.99999 )	{	ai = 0.25 * (1.0-m);	b = coshf(u);	t = tanhf(u);	phi = 1.0/b;	twon = b * sinhf(u);	*sn = t + ai * (twon - u)/(b*b);	*ph = 2.0*atanf(expf(u)) - PIO2F + ai*(twon - u)/b;	ai *= t * phi;	*cn = phi - ai * (twon - u);	*dn = phi + ai * (twon + u);	return(0);	}/*	A. G. M. scale		*/a[0] = 1.0;b = sqrtf(1.0 - m);c[0] = sqrtf(m);twon = 1.0;i = 0;while( fabsf( (c[i]/a[i]) ) > MACHEPF )	{	if( i > 8 )		{/*		mtherr( "ellpjf", OVERFLOW );*/		break;		}	ai = a[i];	++i;	c[i] = 0.5 * ( ai - b );	t = sqrtf( ai * b );	a[i] = 0.5 * ( ai + b );	b = t;	twon += twon;	}/* backward recurrence */phi = twon * a[i] * u;do	{	t = c[i] * sinf(phi) / a[i];	b = phi;	phi = 0.5 * (asinf(t) + phi);	}while( --i );*sn = sinf(phi);t = cosf(phi);*cn = t;*dn = t/cosf(phi-b);*ph = phi;return(0);}
 |