ellpk.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  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 <math.h>
  60. #ifdef DEC
  61. static unsigned short P[] =
  62. {
  63. 0035020,0127576,0040430,0051544,
  64. 0036025,0070136,0042703,0153716,
  65. 0036402,0122614,0062555,0077777,
  66. 0036441,0102130,0072334,0025172,
  67. 0036341,0043320,0117242,0172076,
  68. 0036312,0146456,0077242,0154141,
  69. 0036420,0003467,0013727,0035407,
  70. 0036564,0137263,0110651,0020237,
  71. 0036775,0001330,0144056,0020305,
  72. 0037305,0144137,0157521,0141734,
  73. 0040261,0071027,0173721,0147572
  74. };
  75. static unsigned short Q[] =
  76. {
  77. 0034366,0130371,0103453,0077633,
  78. 0035557,0122745,0173515,0113016,
  79. 0036302,0124470,0167304,0074473,
  80. 0036575,0132403,0117226,0117576,
  81. 0036703,0156271,0047124,0147733,
  82. 0036766,0137465,0002053,0157312,
  83. 0037031,0014423,0154274,0176515,
  84. 0037107,0177747,0143216,0016145,
  85. 0037217,0177777,0172621,0074000,
  86. 0037377,0177777,0177776,0156435,
  87. 0040000,0000000,0000000,0000000
  88. };
  89. static unsigned short ac1[] = {0040261,0071027,0173721,0147572};
  90. #define C1 (*(double *)ac1)
  91. #endif
  92. #ifdef IBMPC
  93. static unsigned short P[] =
  94. {
  95. 0x0a6d,0xc823,0x15ef,0x3f22,
  96. 0x7afa,0xc8b8,0xae0b,0x3f62,
  97. 0xb000,0x8cad,0x54b1,0x3f80,
  98. 0x854f,0x0e9b,0x308b,0x3f84,
  99. 0x5e88,0x13d4,0x28da,0x3f7c,
  100. 0x5b0c,0xcfd4,0x59a5,0x3f79,
  101. 0xe761,0xe2fa,0x00e6,0x3f82,
  102. 0x2414,0x7235,0x97d6,0x3f8e,
  103. 0xc419,0x1905,0xa05b,0x3f9f,
  104. 0x387c,0xfbea,0xb90b,0x3fb8,
  105. 0x39ef,0xfefa,0x2e42,0x3ff6
  106. };
  107. static unsigned short Q[] =
  108. {
  109. 0x6ff3,0x30e5,0xd61f,0x3efe,
  110. 0xb2c2,0xbee9,0xf4bc,0x3f4d,
  111. 0x8f27,0x1dd8,0x5527,0x3f78,
  112. 0xd3f0,0x73d2,0xb6a0,0x3f8f,
  113. 0x99fb,0x29ca,0x7b97,0x3f98,
  114. 0x7bd9,0xa085,0xd7e6,0x3f9e,
  115. 0x9faa,0x7b17,0x2322,0x3fa3,
  116. 0xc38d,0xf8d1,0xfffc,0x3fa8,
  117. 0x2f00,0xfeb2,0xffff,0x3fb1,
  118. 0xdba4,0xffff,0xffff,0x3fbf,
  119. 0x0000,0x0000,0x0000,0x3fe0
  120. };
  121. static unsigned short ac1[] = {0x39ef,0xfefa,0x2e42,0x3ff6};
  122. #define C1 (*(double *)ac1)
  123. #endif
  124. #ifdef MIEEE
  125. static unsigned short P[] =
  126. {
  127. 0x3f22,0x15ef,0xc823,0x0a6d,
  128. 0x3f62,0xae0b,0xc8b8,0x7afa,
  129. 0x3f80,0x54b1,0x8cad,0xb000,
  130. 0x3f84,0x308b,0x0e9b,0x854f,
  131. 0x3f7c,0x28da,0x13d4,0x5e88,
  132. 0x3f79,0x59a5,0xcfd4,0x5b0c,
  133. 0x3f82,0x00e6,0xe2fa,0xe761,
  134. 0x3f8e,0x97d6,0x7235,0x2414,
  135. 0x3f9f,0xa05b,0x1905,0xc419,
  136. 0x3fb8,0xb90b,0xfbea,0x387c,
  137. 0x3ff6,0x2e42,0xfefa,0x39ef
  138. };
  139. static unsigned short Q[] =
  140. {
  141. 0x3efe,0xd61f,0x30e5,0x6ff3,
  142. 0x3f4d,0xf4bc,0xbee9,0xb2c2,
  143. 0x3f78,0x5527,0x1dd8,0x8f27,
  144. 0x3f8f,0xb6a0,0x73d2,0xd3f0,
  145. 0x3f98,0x7b97,0x29ca,0x99fb,
  146. 0x3f9e,0xd7e6,0xa085,0x7bd9,
  147. 0x3fa3,0x2322,0x7b17,0x9faa,
  148. 0x3fa8,0xfffc,0xf8d1,0xc38d,
  149. 0x3fb1,0xffff,0xfeb2,0x2f00,
  150. 0x3fbf,0xffff,0xffff,0xdba4,
  151. 0x3fe0,0x0000,0x0000,0x0000
  152. };
  153. static unsigned short ac1[] = {
  154. 0x3ff6,0x2e42,0xfefa,0x39ef
  155. };
  156. #define C1 (*(double *)ac1)
  157. #endif
  158. #ifdef UNK
  159. static double P[] =
  160. {
  161. 1.37982864606273237150E-4,
  162. 2.28025724005875567385E-3,
  163. 7.97404013220415179367E-3,
  164. 9.85821379021226008714E-3,
  165. 6.87489687449949877925E-3,
  166. 6.18901033637687613229E-3,
  167. 8.79078273952743772254E-3,
  168. 1.49380448916805252718E-2,
  169. 3.08851465246711995998E-2,
  170. 9.65735902811690126535E-2,
  171. 1.38629436111989062502E0
  172. };
  173. static double Q[] =
  174. {
  175. 2.94078955048598507511E-5,
  176. 9.14184723865917226571E-4,
  177. 5.94058303753167793257E-3,
  178. 1.54850516649762399335E-2,
  179. 2.39089602715924892727E-2,
  180. 3.01204715227604046988E-2,
  181. 3.73774314173823228969E-2,
  182. 4.88280347570998239232E-2,
  183. 7.03124996963957469739E-2,
  184. 1.24999999999870820058E-1,
  185. 4.99999999999999999821E-1
  186. };
  187. static double C1 = 1.3862943611198906188E0; /* log(4) */
  188. #endif
  189. #ifdef ANSIPROT
  190. extern double polevl ( double, void *, int );
  191. extern double p1evl ( double, void *, int );
  192. extern double log ( double );
  193. #else
  194. double polevl(), p1evl(), log();
  195. #endif
  196. extern double MACHEP, MAXNUM;
  197. double ellpk(x)
  198. double x;
  199. {
  200. if( (x < 0.0) || (x > 1.0) )
  201. {
  202. mtherr( "ellpk", DOMAIN );
  203. return( 0.0 );
  204. }
  205. if( x > MACHEP )
  206. {
  207. return( polevl(x,P,10) - log(x) * polevl(x,Q,10) );
  208. }
  209. else
  210. {
  211. if( x == 0.0 )
  212. {
  213. mtherr( "ellpk", SING );
  214. return( MAXNUM );
  215. }
  216. else
  217. {
  218. return( C1 - 0.5 * log(x) );
  219. }
  220. }
  221. }