elco2.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. #include <u.h>
  2. #include <libc.h>
  3. #include "map.h"
  4. /* elliptic integral routine, R.Bulirsch,
  5. * Numerische Mathematik 7(1965) 78-90
  6. * calculate integral from 0 to x+iy of
  7. * (a+b*t^2)/((1+t^2)*sqrt((1+t^2)*(1+kc^2*t^2)))
  8. * yields about D valid figures, where CC=10e-D
  9. * for a*b>=0, except at branchpoints x=0,y=+-i,+-i/kc;
  10. * there the accuracy may be reduced.
  11. * fails for kc=0 or x<0
  12. * return(1) for success, return(0) for fail
  13. *
  14. * special case a=b=1 is equivalent to
  15. * standard elliptic integral of first kind
  16. * from 0 to atan(x+iy) of
  17. * 1/sqrt(1-k^2*(sin(t))^2) where k^2=1-kc^2
  18. */
  19. #define ROOTINF 10.e18
  20. #define CC 1.e-6
  21. int
  22. elco2(double x, double y, double kc, double a, double b, double *u, double *v)
  23. {
  24. double c,d,dn1,dn2,e,e1,e2,f,f1,f2,h,k,m,m1,m2,sy;
  25. double d1[13],d2[13];
  26. int i,l;
  27. if(kc==0||x<0)
  28. return(0);
  29. sy = y>0? 1: y==0? 0: -1;
  30. y = fabs(y);
  31. csq(x,y,&c,&e2);
  32. d = kc*kc;
  33. k = 1-d;
  34. e1 = 1+c;
  35. cdiv2(1+d*c,d*e2,e1,e2,&f1,&f2);
  36. f2 = -k*x*y*2/f2;
  37. csqr(f1,f2,&dn1,&dn2);
  38. if(f1<0) {
  39. f1 = dn1;
  40. dn1 = -dn2;
  41. dn2 = -f1;
  42. }
  43. if(k<0) {
  44. dn1 = fabs(dn1);
  45. dn2 = fabs(dn2);
  46. }
  47. c = 1+dn1;
  48. cmul(e1,e2,c,dn2,&f1,&f2);
  49. cdiv(x,y,f1,f2,&d1[0],&d2[0]);
  50. h = a-b;
  51. d = f = m = 1;
  52. kc = fabs(kc);
  53. e = a;
  54. a += b;
  55. l = 4;
  56. for(i=1;;i++) {
  57. m1 = (kc+m)/2;
  58. m2 = m1*m1;
  59. k *= f/(m2*4);
  60. b += e*kc;
  61. e = a;
  62. cdiv2(kc+m*dn1,m*dn2,c,dn2,&f1,&f2);
  63. csqr(f1/m1,k*dn2*2/f2,&dn1,&dn2);
  64. cmul(dn1,dn2,x,y,&f1,&f2);
  65. x = fabs(f1);
  66. y = fabs(f2);
  67. a += b/m1;
  68. l *= 2;
  69. c = 1 +dn1;
  70. d *= k/2;
  71. cmul(x,y,x,y,&e1,&e2);
  72. k *= k;
  73. cmul(c,dn2,1+e1*m2,e2*m2,&f1,&f2);
  74. cdiv(d*x,d*y,f1,f2,&d1[i],&d2[i]);
  75. if(k<=CC)
  76. break;
  77. kc = sqrt(m*kc);
  78. f = m2;
  79. m = m1;
  80. }
  81. f1 = f2 = 0;
  82. for(;i>=0;i--) {
  83. f1 += d1[i];
  84. f2 += d2[i];
  85. }
  86. x *= m1;
  87. y *= m1;
  88. cdiv2(1-y,x,1+y,-x,&e1,&e2);
  89. e2 = x*2/e2;
  90. d = a/(m1*l);
  91. *u = atan2(e2,e1);
  92. if(*u<0)
  93. *u += PI;
  94. a = d*sy/2;
  95. *u = d*(*u) + f1*h;
  96. *v = (-1-log(e1*e1+e2*e2))*a + f2*h*sy + a;
  97. return(1);
  98. }
  99. void
  100. cdiv2(double c1, double c2, double d1, double d2, double *e1, double *e2)
  101. {
  102. double t;
  103. if(fabs(d2)>fabs(d1)) {
  104. t = d1, d1 = d2, d2 = t;
  105. t = c1, c1 = c2, c2 = t;
  106. }
  107. if(fabs(d1)>ROOTINF)
  108. *e2 = ROOTINF*ROOTINF;
  109. else
  110. *e2 = d1*d1 + d2*d2;
  111. t = d2/d1;
  112. *e1 = (c1+t*c2)/(d1+t*d2); /* (c1*d1+c2*d2)/(d1*d1+d2*d2) */
  113. }
  114. /* complex square root of |x|+iy */
  115. void
  116. csqr(double c1, double c2, double *e1, double *e2)
  117. {
  118. double r2;
  119. r2 = c1*c1 + c2*c2;
  120. if(r2<=0) {
  121. *e1 = *e2 = 0;
  122. return;
  123. }
  124. *e1 = sqrt((sqrt(r2) + fabs(c1))/2);
  125. *e2 = c2/(*e1*2);
  126. }