ellpk.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. /* ellpk.c
  2. *
  3. * Complete elliptic integral of the first kind
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * double m1, y, ellpk();
  10. *
  11. * y = ellpk( m1 );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Approximates the integral
  18. *
  19. *
  20. *
  21. * pi/2
  22. * -
  23. * | |
  24. * | dt
  25. * K(m) = | ------------------
  26. * | 2
  27. * | | sqrt( 1 - m sin t )
  28. * -
  29. * 0
  30. *
  31. * where m = 1 - m1, using the approximation
  32. *
  33. * P(x) - log x Q(x).
  34. *
  35. * The argument m1 is used rather than m so that the logarithmic
  36. * singularity at m = 1 will be shifted to the origin; this
  37. * preserves maximum accuracy.
  38. *
  39. * K(0) = pi/2.
  40. *
  41. * ACCURACY:
  42. *
  43. * Relative error:
  44. * arithmetic domain # trials peak rms
  45. * DEC 0,1 16000 3.5e-17 1.1e-17
  46. * IEEE 0,1 30000 2.5e-16 6.8e-17
  47. *
  48. * ERROR MESSAGES:
  49. *
  50. * message condition value returned
  51. * ellpk domain x<0, x>1 0.0
  52. *
  53. */
  54. /* ellpk.c */
  55. /*
  56. Cephes Math Library, Release 2.8: June, 2000
  57. Copyright 1984, 1987, 2000 by Stephen L. Moshier
  58. */
  59. #include "mconf.h"
  60. #ifdef DEC
  61. static unsigned short P[] = {
  62. 0035020, 0127576, 0040430, 0051544, 0036025, 0070136, 0042703, 0153716,
  63. 0036402, 0122614, 0062555, 0077777, 0036441, 0102130, 0072334, 0025172,
  64. 0036341, 0043320, 0117242, 0172076, 0036312, 0146456, 0077242, 0154141,
  65. 0036420, 0003467, 0013727, 0035407, 0036564, 0137263, 0110651, 0020237,
  66. 0036775, 0001330, 0144056, 0020305, 0037305, 0144137, 0157521, 0141734,
  67. 0040261, 0071027, 0173721, 0147572};
  68. static unsigned short Q[] = {
  69. 0034366, 0130371, 0103453, 0077633, 0035557, 0122745, 0173515, 0113016,
  70. 0036302, 0124470, 0167304, 0074473, 0036575, 0132403, 0117226, 0117576,
  71. 0036703, 0156271, 0047124, 0147733, 0036766, 0137465, 0002053, 0157312,
  72. 0037031, 0014423, 0154274, 0176515, 0037107, 0177747, 0143216, 0016145,
  73. 0037217, 0177777, 0172621, 0074000, 0037377, 0177777, 0177776, 0156435,
  74. 0040000, 0000000, 0000000, 0000000};
  75. static unsigned short ac1[] = {0040261, 0071027, 0173721, 0147572};
  76. #define C1 (*(double *)ac1)
  77. #endif
  78. #ifdef IBMPC
  79. static unsigned short P[] = {
  80. 0x0a6d, 0xc823, 0x15ef, 0x3f22, 0x7afa, 0xc8b8, 0xae0b, 0x3f62, 0xb000,
  81. 0x8cad, 0x54b1, 0x3f80, 0x854f, 0x0e9b, 0x308b, 0x3f84, 0x5e88, 0x13d4,
  82. 0x28da, 0x3f7c, 0x5b0c, 0xcfd4, 0x59a5, 0x3f79, 0xe761, 0xe2fa, 0x00e6,
  83. 0x3f82, 0x2414, 0x7235, 0x97d6, 0x3f8e, 0xc419, 0x1905, 0xa05b, 0x3f9f,
  84. 0x387c, 0xfbea, 0xb90b, 0x3fb8, 0x39ef, 0xfefa, 0x2e42, 0x3ff6};
  85. static unsigned short Q[] = {
  86. 0x6ff3, 0x30e5, 0xd61f, 0x3efe, 0xb2c2, 0xbee9, 0xf4bc, 0x3f4d, 0x8f27,
  87. 0x1dd8, 0x5527, 0x3f78, 0xd3f0, 0x73d2, 0xb6a0, 0x3f8f, 0x99fb, 0x29ca,
  88. 0x7b97, 0x3f98, 0x7bd9, 0xa085, 0xd7e6, 0x3f9e, 0x9faa, 0x7b17, 0x2322,
  89. 0x3fa3, 0xc38d, 0xf8d1, 0xfffc, 0x3fa8, 0x2f00, 0xfeb2, 0xffff, 0x3fb1,
  90. 0xdba4, 0xffff, 0xffff, 0x3fbf, 0x0000, 0x0000, 0x0000, 0x3fe0};
  91. static unsigned short ac1[] = {0x39ef, 0xfefa, 0x2e42, 0x3ff6};
  92. #define C1 (*(double *)ac1)
  93. #endif
  94. #ifdef MIEEE
  95. static unsigned short P[] = {
  96. 0x3f22, 0x15ef, 0xc823, 0x0a6d, 0x3f62, 0xae0b, 0xc8b8, 0x7afa, 0x3f80,
  97. 0x54b1, 0x8cad, 0xb000, 0x3f84, 0x308b, 0x0e9b, 0x854f, 0x3f7c, 0x28da,
  98. 0x13d4, 0x5e88, 0x3f79, 0x59a5, 0xcfd4, 0x5b0c, 0x3f82, 0x00e6, 0xe2fa,
  99. 0xe761, 0x3f8e, 0x97d6, 0x7235, 0x2414, 0x3f9f, 0xa05b, 0x1905, 0xc419,
  100. 0x3fb8, 0xb90b, 0xfbea, 0x387c, 0x3ff6, 0x2e42, 0xfefa, 0x39ef};
  101. static unsigned short Q[] = {
  102. 0x3efe, 0xd61f, 0x30e5, 0x6ff3, 0x3f4d, 0xf4bc, 0xbee9, 0xb2c2, 0x3f78,
  103. 0x5527, 0x1dd8, 0x8f27, 0x3f8f, 0xb6a0, 0x73d2, 0xd3f0, 0x3f98, 0x7b97,
  104. 0x29ca, 0x99fb, 0x3f9e, 0xd7e6, 0xa085, 0x7bd9, 0x3fa3, 0x2322, 0x7b17,
  105. 0x9faa, 0x3fa8, 0xfffc, 0xf8d1, 0xc38d, 0x3fb1, 0xffff, 0xfeb2, 0x2f00,
  106. 0x3fbf, 0xffff, 0xffff, 0xdba4, 0x3fe0, 0x0000, 0x0000, 0x0000};
  107. static unsigned short ac1[] = {0x3ff6, 0x2e42, 0xfefa, 0x39ef};
  108. #define C1 (*(double *)ac1)
  109. #endif
  110. #ifdef UNK
  111. static double P[] = {1.37982864606273237150E-4, 2.28025724005875567385E-3,
  112. 7.97404013220415179367E-3, 9.85821379021226008714E-3,
  113. 6.87489687449949877925E-3, 6.18901033637687613229E-3,
  114. 8.79078273952743772254E-3, 1.49380448916805252718E-2,
  115. 3.08851465246711995998E-2, 9.65735902811690126535E-2,
  116. 1.38629436111989062502E0};
  117. static double Q[] = {2.94078955048598507511E-5, 9.14184723865917226571E-4,
  118. 5.94058303753167793257E-3, 1.54850516649762399335E-2,
  119. 2.39089602715924892727E-2, 3.01204715227604046988E-2,
  120. 3.73774314173823228969E-2, 4.88280347570998239232E-2,
  121. 7.03124996963957469739E-2, 1.24999999999870820058E-1,
  122. 4.99999999999999999821E-1};
  123. static double C1 = 1.3862943611198906188E0; /* log(4) */
  124. #endif
  125. #ifdef ANSIPROT
  126. extern double polevl(double, void *, int);
  127. extern double p1evl(double, void *, int);
  128. extern double log(double);
  129. #else
  130. double polevl(), p1evl(), log();
  131. #endif
  132. extern double MACHEP, MAXNUM;
  133. double ellpk(x) double x;
  134. {
  135. if ((x < 0.0) || (x > 1.0)) {
  136. mtherr("ellpk", DOMAIN);
  137. return (0.0);
  138. }
  139. if (x > MACHEP) {
  140. return (polevl(x, P, 10) - log(x) * polevl(x, Q, 10));
  141. } else {
  142. if (x == 0.0) {
  143. mtherr("ellpk", SING);
  144. return (MAXNUM);
  145. } else {
  146. return (C1 - 0.5 * log(x));
  147. }
  148. }
  149. }