// ell_ag.cpp -- Complete and incomplete elliptic integrals of // the 1st and 2nd kinds. Algorithms and coefficient values // from "Computation of Special Functions", Zhang and Jin, // John Wiley and Sons, 1996. // // (C) 2005, C. Bond. All rights reserved. // // #include #include // // int ellit(double phi,double k,double *fe,double *ee); // // Input: // phi -- argument in radians (pi/2 for complete elliptic integral) // k -- (k) modulus, (0.0 - 1.0) // // Returns: (error code) // 0 -- no error // 1 -- bad modulus // 2 -- bad argument // // Output: // fe -- F(k,phi) (in)complete Elliptic function of 1st kind // ee -- E(k,phi) (in)complete Elliptic function fo 2nd kind // // // This routine has been modified to accept an argument (phi) in radians, // rather than degrees. It has also been modified to take the argument // as the first parameter and the modulus as the second. // // Some treatments use the modulus 'm', rather than 'k' where m = k^2. // // int ellit(double phi,double k,double *fe,double *ee) { double g,fac,a,b,c,d,a0,b0,d0,r,ck,ce; if ((k < 0.0) || (k > 1.0)) return 1; if ((phi < 0.0) || (phi > 0.5*M_PI)) return 2; g = 0.0; a0 = 1.0; r = k*k; b0 = sqrt(1.0-r); d0 = phi; if ((k == 1.0) && (phi == 0.5*M_PI)) { *fe = 1.0e300; *ee = 1.0; } else if (k == 1.0) { *fe = log((1.0+sin(d0))/cos(d0)); *ee = sin(d0); } else { fac = 1.0; for (int n=1;n<41;n++) { a = 0.5*(a0+b0); b = sqrt(a0*b0); c = 0.5*(a0-b0); fac *= 2.0; r += (fac*c*c); if (phi != 0.5*M_PI) { d = d0+atan((b0/a0)*tan(d0)); g += (c*sin(d)); d0 = d+M_PI*int(d/M_PI+0.5); } a0 = a; b0 = b; if (c < 1.0e-7) break; } ck = M_PI/(2.0*a); ce = M_PI*(2.0-r)/(4.0*a); if (phi == 90.0) { *fe = ck; *ee = ce; } else { *fe = d/(fac*a); *ee = *fe*ce/ck+g; } } return 0; }