|  | #include <u.h> | 
|  | #include <libc.h> | 
|  | #include "map.h" | 
|  |  | 
|  | /* elliptic integral routine, R.Bulirsch, | 
|  | *	Numerische Mathematik 7(1965) 78-90 | 
|  | *	calculate integral from 0 to x+iy of | 
|  | *	(a+b*t^2)/((1+t^2)*sqrt((1+t^2)*(1+kc^2*t^2))) | 
|  | *	yields about D valid figures, where CC=10e-D | 
|  | *	for a*b>=0, except at branchpoints x=0,y=+-i,+-i/kc; | 
|  | *	there the accuracy may be reduced. | 
|  | *	fails for kc=0 or x<0 | 
|  | *	return(1) for success, return(0) for fail | 
|  | * | 
|  | *	special case a=b=1 is equivalent to | 
|  | *	standard elliptic integral of first kind | 
|  | *	from 0 to atan(x+iy) of | 
|  | *	1/sqrt(1-k^2*(sin(t))^2) where k^2=1-kc^2 | 
|  | */ | 
|  |  | 
|  | #define ROOTINF 10.e18 | 
|  | #define CC 1.e-6 | 
|  |  | 
|  | int | 
|  | elco2(double x, double y, double kc, double a, double b, double *u, double *v) | 
|  | { | 
|  | double c,d,dn1,dn2,e,e1,e2,f,f1,f2,h,k,m,m1,m2,sy; | 
|  | double d1[13],d2[13]; | 
|  | int i,l; | 
|  | if(kc==0||x<0) | 
|  | return(0); | 
|  | sy = y>0? 1: y==0? 0: -1; | 
|  | y = fabs(y); | 
|  | csq(x,y,&c,&e2); | 
|  | d = kc*kc; | 
|  | k = 1-d; | 
|  | e1 = 1+c; | 
|  | cdiv2(1+d*c,d*e2,e1,e2,&f1,&f2); | 
|  | f2 = -k*x*y*2/f2; | 
|  | csqr(f1,f2,&dn1,&dn2); | 
|  | if(f1<0) { | 
|  | f1 = dn1; | 
|  | dn1 = -dn2; | 
|  | dn2 = -f1; | 
|  | } | 
|  | if(k<0) { | 
|  | dn1 = fabs(dn1); | 
|  | dn2 = fabs(dn2); | 
|  | } | 
|  | c = 1+dn1; | 
|  | cmul(e1,e2,c,dn2,&f1,&f2); | 
|  | cdiv(x,y,f1,f2,&d1[0],&d2[0]); | 
|  | h = a-b; | 
|  | d = f = m = 1; | 
|  | kc = fabs(kc); | 
|  | e = a; | 
|  | a += b; | 
|  | l = 4; | 
|  | for(i=1;;i++) { | 
|  | m1 = (kc+m)/2; | 
|  | m2 = m1*m1; | 
|  | k *= f/(m2*4); | 
|  | b += e*kc; | 
|  | e = a; | 
|  | cdiv2(kc+m*dn1,m*dn2,c,dn2,&f1,&f2); | 
|  | csqr(f1/m1,k*dn2*2/f2,&dn1,&dn2); | 
|  | cmul(dn1,dn2,x,y,&f1,&f2); | 
|  | x = fabs(f1); | 
|  | y = fabs(f2); | 
|  | a += b/m1; | 
|  | l *= 2; | 
|  | c = 1 +dn1; | 
|  | d *= k/2; | 
|  | cmul(x,y,x,y,&e1,&e2); | 
|  | k *= k; | 
|  |  | 
|  | cmul(c,dn2,1+e1*m2,e2*m2,&f1,&f2); | 
|  | cdiv(d*x,d*y,f1,f2,&d1[i],&d2[i]); | 
|  | if(k<=CC) | 
|  | break; | 
|  | kc = sqrt(m*kc); | 
|  | f = m2; | 
|  | m = m1; | 
|  | } | 
|  | f1 = f2 = 0; | 
|  | for(;i>=0;i--) { | 
|  | f1 += d1[i]; | 
|  | f2 += d2[i]; | 
|  | } | 
|  | x *= m1; | 
|  | y *= m1; | 
|  | cdiv2(1-y,x,1+y,-x,&e1,&e2); | 
|  | e2 = x*2/e2; | 
|  | d = a/(m1*l); | 
|  | *u = atan2(e2,e1); | 
|  | if(*u<0) | 
|  | *u += PI; | 
|  | a = d*sy/2; | 
|  | *u = d*(*u) + f1*h; | 
|  | *v = (-1-log(e1*e1+e2*e2))*a + f2*h*sy + a; | 
|  | return(1); | 
|  | } | 
|  |  | 
|  | void | 
|  | cdiv2(double c1, double c2, double d1, double d2, double *e1, double *e2) | 
|  | { | 
|  | double t; | 
|  | if(fabs(d2)>fabs(d1)) { | 
|  | t = d1, d1 = d2, d2 = t; | 
|  | t = c1, c1 = c2, c2 = t; | 
|  | } | 
|  | if(fabs(d1)>ROOTINF) | 
|  | *e2 = ROOTINF*ROOTINF; | 
|  | else | 
|  | *e2 = d1*d1 + d2*d2; | 
|  | t = d2/d1; | 
|  | *e1 = (c1+t*c2)/(d1+t*d2); /* (c1*d1+c2*d2)/(d1*d1+d2*d2) */ | 
|  | } | 
|  |  | 
|  | /* complex square root of |x|+iy */ | 
|  | void | 
|  | csqr(double c1, double c2, double *e1, double *e2) | 
|  | { | 
|  | double r2; | 
|  | r2 = c1*c1 + c2*c2; | 
|  | if(r2<=0) { | 
|  | *e1 = *e2 = 0; | 
|  | return; | 
|  | } | 
|  | *e1 = sqrt((sqrt(r2) + fabs(c1))/2); | 
|  | *e2 = c2/(*e1*2); | 
|  | } |