#include "mconf.h"
#ifdef ANSIPROT
extern
double
sqrt
(
double
);
extern
double
md_fabs (
double
);
extern
double
md_log (
double
);
extern
double
md_tan (
double
);
extern
double
md_atan (
double
);
extern
double
md_floor (
double
);
extern
double
ellpk (
double
);
double
ellik (
double
,
double
);
#else
double
sqrt
(), md_fabs(), md_log(), md_tan(), md_atan(), md_floor(), ellpk();
double
ellik();
#endif
extern
double
PI, PIO2, MACHEP, MAXNUM;
double
ellik( phi, m )
double
phi, m;
{
double
a, b, c, e, temp, t, K;
int
d, mod, sign, npio2;
if
( m == 0.0 )
return
( phi );
a = 1.0 - m;
if
( a == 0.0 )
{
if
( md_fabs(phi) >= PIO2 )
{
mtherr(
"ellik"
, SING );
return
( MAXNUM );
}
return
( md_log( md_tan( (PIO2 + phi)/2.0 ) ) );
}
npio2 = md_floor( phi/PIO2 );
if
( npio2 & 1 )
npio2 += 1;
if
( npio2 )
{
K = ellpk( a );
phi = phi - npio2 * PIO2;
}
else
K = 0.0;
if
( phi < 0.0 )
{
phi = -phi;
sign = -1;
}
else
sign = 0;
b =
sqrt
(a);
t = md_tan( phi );
if
( md_fabs(t) > 10.0 )
{
e = 1.0/(b*t);
if
( md_fabs(e) < 10.0 )
{
e = md_atan(e);
if
( npio2 == 0 )
K = ellpk( a );
temp = K - ellik( e, m );
goto
done;
}
}
a = 1.0;
c =
sqrt
(m);
d = 1;
mod = 0;
while
( md_fabs(c/a) > MACHEP )
{
temp = b/a;
phi = phi + md_atan(t*temp) + mod * PI;
mod = (phi + PIO2)/PI;
t = t * ( 1.0 + temp )/( 1.0 - temp * t * t );
c = ( a - b )/2.0;
temp =
sqrt
( a * b );
a = ( a + b )/2.0;
b = temp;
d += d;
}
temp = (md_atan(t) + mod * PI)/(d * a);
done:
if
( sign < 0 )
temp = -temp;
temp += npio2 * K;
return
( temp );
}