j0.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435
  1. /* j0.c
  2. *
  3. * Bessel function of order zero
  4. *
  5. *
  6. *
  7. * SYNOPSIS:
  8. *
  9. * double x, y, j0();
  10. *
  11. * y = j0( x );
  12. *
  13. *
  14. *
  15. * DESCRIPTION:
  16. *
  17. * Returns Bessel function of order zero of the argument.
  18. *
  19. * The domain is divided into the intervals [0, 5] and
  20. * (5, infinity). In the first interval the following rational
  21. * approximation is used:
  22. *
  23. *
  24. * 2 2
  25. * (w - r ) (w - r ) P (w) / Q (w)
  26. * 1 2 3 8
  27. *
  28. * 2
  29. * where w = x and the two r's are zeros of the function.
  30. *
  31. * In the second interval, the Hankel asymptotic expansion
  32. * is employed with two rational functions of degree 6/6
  33. * and 7/7.
  34. *
  35. *
  36. *
  37. * ACCURACY:
  38. *
  39. * Absolute error:
  40. * arithmetic domain # trials peak rms
  41. * DEC 0, 30 10000 4.4e-17 6.3e-18
  42. * IEEE 0, 30 60000 4.2e-16 1.1e-16
  43. *
  44. */
  45. /* y0.c
  46. *
  47. * Bessel function of the second kind, order zero
  48. *
  49. *
  50. *
  51. * SYNOPSIS:
  52. *
  53. * double x, y, y0();
  54. *
  55. * y = y0( x );
  56. *
  57. *
  58. *
  59. * DESCRIPTION:
  60. *
  61. * Returns Bessel function of the second kind, of order
  62. * zero, of the argument.
  63. *
  64. * The domain is divided into the intervals [0, 5] and
  65. * (5, infinity). In the first interval a rational approximation
  66. * R(x) is employed to compute
  67. * y0(x) = R(x) + 2 * log(x) * j0(x) / PI.
  68. * Thus a call to j0() is required.
  69. *
  70. * In the second interval, the Hankel asymptotic expansion
  71. * is employed with two rational functions of degree 6/6
  72. * and 7/7.
  73. *
  74. *
  75. *
  76. * ACCURACY:
  77. *
  78. * Absolute error, when y0(x) < 1; else relative error:
  79. *
  80. * arithmetic domain # trials peak rms
  81. * DEC 0, 30 9400 7.0e-17 7.9e-18
  82. * IEEE 0, 30 30000 1.3e-15 1.6e-16
  83. *
  84. */
  85. /*
  86. Cephes Math Library Release 2.8: June, 2000
  87. Copyright 1984, 1987, 1989, 2000 by Stephen L. Moshier
  88. */
  89. /* Note: all coefficients satisfy the relative error criterion
  90. * except YP, YQ which are designed for absolute error. */
  91. #include "mconf.h"
  92. #ifdef UNK
  93. static double PP[7] = {
  94. 7.96936729297347051624E-4, 8.28352392107440799803E-2,
  95. 1.23953371646414299388E0, 5.44725003058768775090E0,
  96. 8.74716500199817011941E0, 5.30324038235394892183E0,
  97. 9.99999999999999997821E-1,
  98. };
  99. static double PQ[7] = {
  100. 9.24408810558863637013E-4, 8.56288474354474431428E-2,
  101. 1.25352743901058953537E0, 5.47097740330417105182E0,
  102. 8.76190883237069594232E0, 5.30605288235394617618E0,
  103. 1.00000000000000000218E0,
  104. };
  105. #endif
  106. #ifdef DEC
  107. static unsigned short PP[28] = {
  108. 0035520, 0164604, 0140733, 0054470, 0037251, 0122605, 0115356,
  109. 0107170, 0040236, 0124412, 0071500, 0056303, 0040656, 0047737,
  110. 0045720, 0045263, 0041013, 0172143, 0045004, 0142103, 0040651,
  111. 0132045, 0026241, 0026406, 0040200, 0000000, 0000000, 0000000,
  112. };
  113. static unsigned short PQ[28] = {
  114. 0035562, 0052006, 0070034, 0134666, 0037257, 0057055, 0055242,
  115. 0123424, 0040240, 0071626, 0046630, 0032371, 0040657, 0011077,
  116. 0032013, 0012731, 0041014, 0030307, 0050331, 0006414, 0040651,
  117. 0145457, 0065021, 0150304, 0040200, 0000000, 0000000, 0000000,
  118. };
  119. #endif
  120. #ifdef IBMPC
  121. static unsigned short PP[28] = {
  122. 0x6b27, 0x983b, 0x1d30, 0x3f4a, 0xd1cf, 0xb35d, 0x34b0,
  123. 0x3fb5, 0x0b98, 0x4e68, 0xd521, 0x3ff3, 0x0956, 0xe97a,
  124. 0xc9fb, 0x4015, 0x9888, 0x6940, 0x7e8c, 0x4021, 0x25a1,
  125. 0xa594, 0x3684, 0x4015, 0x0000, 0x0000, 0x0000, 0x3ff0,
  126. };
  127. static unsigned short PQ[28] = {
  128. 0x9737, 0xce03, 0x4a80, 0x3f4e, 0x54e3, 0xab54, 0xebc5,
  129. 0x3fb5, 0x069f, 0xc9b3, 0x0e72, 0x3ff4, 0x62bb, 0xe681,
  130. 0xe247, 0x4015, 0x21a1, 0xea1b, 0x8618, 0x4021, 0x3a19,
  131. 0xed42, 0x3965, 0x4015, 0x0000, 0x0000, 0x0000, 0x3ff0,
  132. };
  133. #endif
  134. #ifdef MIEEE
  135. static unsigned short PP[28] = {
  136. 0x3f4a, 0x1d30, 0x983b, 0x6b27, 0x3fb5, 0x34b0, 0xb35d,
  137. 0xd1cf, 0x3ff3, 0xd521, 0x4e68, 0x0b98, 0x4015, 0xc9fb,
  138. 0xe97a, 0x0956, 0x4021, 0x7e8c, 0x6940, 0x9888, 0x4015,
  139. 0x3684, 0xa594, 0x25a1, 0x3ff0, 0x0000, 0x0000, 0x0000,
  140. };
  141. static unsigned short PQ[28] = {
  142. 0x3f4e, 0x4a80, 0xce03, 0x9737, 0x3fb5, 0xebc5, 0xab54,
  143. 0x54e3, 0x3ff4, 0x0e72, 0xc9b3, 0x069f, 0x4015, 0xe247,
  144. 0xe681, 0x62bb, 0x4021, 0x8618, 0xea1b, 0x21a1, 0x4015,
  145. 0x3965, 0xed42, 0x3a19, 0x3ff0, 0x0000, 0x0000, 0x0000,
  146. };
  147. #endif
  148. #ifdef UNK
  149. static double QP[8] = {
  150. -1.13663838898469149931E-2, -1.28252718670509318512E0,
  151. -1.95539544257735972385E1, -9.32060152123768231369E1,
  152. -1.77681167980488050595E2, -1.47077505154951170175E2,
  153. -5.14105326766599330220E1, -6.05014350600728481186E0,
  154. };
  155. static double QQ[7] = {
  156. /* 1.00000000000000000000E0,*/
  157. 6.43178256118178023184E1, 8.56430025976980587198E2,
  158. 3.88240183605401609683E3, 7.24046774195652478189E3,
  159. 5.93072701187316984827E3, 2.06209331660327847417E3,
  160. 2.42005740240291393179E2,
  161. };
  162. #endif
  163. #ifdef DEC
  164. static unsigned short QP[32] = {
  165. 0136472, 0035021, 0142451, 0141115, 0140244, 0024731, 0150620, 0105642,
  166. 0141234, 0067177, 0124161, 0060141, 0141672, 0064572, 0151557, 0043036,
  167. 0142061, 0127141, 0003127, 0043517, 0142023, 0011727, 0060271, 0144544,
  168. 0141515, 0122142, 0126620, 0143150, 0140701, 0115306, 0106715, 0007344,
  169. };
  170. static unsigned short QQ[28] = {
  171. /*0040200,0000000,0000000,0000000,*/
  172. 0041600, 0121272, 0004741, 0026544, 0042526, 0015605, 0105654,
  173. 0161771, 0043162, 0123155, 0165644, 0062645, 0043342, 0041675,
  174. 0167576, 0130756, 0043271, 0052720, 0165631, 0154214, 0043000,
  175. 0160576, 0034614, 0172024, 0042162, 0000570, 0030500, 0051235,
  176. };
  177. #endif
  178. #ifdef IBMPC
  179. static unsigned short QP[32] = {
  180. 0x384a, 0x38a5, 0x4742, 0xbf87, 0x1174, 0x3a32, 0x853b, 0xbff4,
  181. 0x2c0c, 0xf50e, 0x8dcf, 0xc033, 0xe8c4, 0x5a6d, 0x4d2f, 0xc057,
  182. 0xe8ea, 0x20ca, 0x35cc, 0xc066, 0x392d, 0xec17, 0x627a, 0xc062,
  183. 0x18cd, 0x55b2, 0xb48c, 0xc049, 0xa1dd, 0xd1b9, 0x3358, 0xc018,
  184. };
  185. static unsigned short QQ[28] = {
  186. /*0x0000,0x0000,0x0000,0x3ff0,*/
  187. 0x25ac, 0x413c, 0x1457, 0x4050, 0x9c7f, 0xb175, 0xc370,
  188. 0x408a, 0x8cb5, 0xbd74, 0x54cd, 0x40ae, 0xd63e, 0xbdef,
  189. 0x4877, 0x40bc, 0x3b11, 0x1d73, 0x2aba, 0x40b7, 0x9e82,
  190. 0xc731, 0x1c2f, 0x40a0, 0x0a54, 0x0628, 0x402f, 0x406e,
  191. };
  192. #endif
  193. #ifdef MIEEE
  194. static unsigned short QP[32] = {
  195. 0xbf87, 0x4742, 0x38a5, 0x384a, 0xbff4, 0x853b, 0x3a32, 0x1174,
  196. 0xc033, 0x8dcf, 0xf50e, 0x2c0c, 0xc057, 0x4d2f, 0x5a6d, 0xe8c4,
  197. 0xc066, 0x35cc, 0x20ca, 0xe8ea, 0xc062, 0x627a, 0xec17, 0x392d,
  198. 0xc049, 0xb48c, 0x55b2, 0x18cd, 0xc018, 0x3358, 0xd1b9, 0xa1dd,
  199. };
  200. static unsigned short QQ[28] = {
  201. /*0x3ff0,0x0000,0x0000,0x0000,*/
  202. 0x4050, 0x1457, 0x413c, 0x25ac, 0x408a, 0xc370, 0xb175,
  203. 0x9c7f, 0x40ae, 0x54cd, 0xbd74, 0x8cb5, 0x40bc, 0x4877,
  204. 0xbdef, 0xd63e, 0x40b7, 0x2aba, 0x1d73, 0x3b11, 0x40a0,
  205. 0x1c2f, 0xc731, 0x9e82, 0x406e, 0x402f, 0x0628, 0x0a54,
  206. };
  207. #endif
  208. #ifdef UNK
  209. static double YP[8] = {
  210. 1.55924367855235737965E4, -1.46639295903971606143E7,
  211. 5.43526477051876500413E9, -9.82136065717911466409E11,
  212. 8.75906394395366999549E13, -3.46628303384729719441E15,
  213. 4.42733268572569800351E16, -1.84950800436986690637E16,
  214. };
  215. static double YQ[7] = {
  216. /* 1.00000000000000000000E0,*/
  217. 1.04128353664259848412E3, 6.26107330137134956842E5,
  218. 2.68919633393814121987E8, 8.64002487103935000337E10,
  219. 2.02979612750105546709E13, 3.17157752842975028269E15,
  220. 2.50596256172653059228E17,
  221. };
  222. #endif
  223. #ifdef DEC
  224. static unsigned short YP[32] = {
  225. 0043563, 0120677, 0042264, 0046166, 0146137, 0140371, 0113444, 0042260,
  226. 0050241, 0175707, 0100502, 0063344, 0152144, 0125737, 0007265, 0164526,
  227. 0053637, 0051621, 0163035, 0060546, 0155105, 0004416, 0107306, 0060023,
  228. 0056035, 0045133, 0030132, 0000024, 0155603, 0065132, 0144061, 0131732,
  229. };
  230. static unsigned short YQ[28] = {
  231. /*0040200,0000000,0000000,0000000,*/
  232. 0042602, 0024422, 0135557, 0162663, 0045030, 0155665, 0044075,
  233. 0160135, 0047200, 0035432, 0105446, 0104005, 0051240, 0167331,
  234. 0056063, 0022743, 0053223, 0127746, 0025764, 0012160, 0055064,
  235. 0044206, 0177532, 0145545, 0056536, 0111375, 0163715, 0127201,
  236. };
  237. #endif
  238. #ifdef IBMPC
  239. static unsigned short YP[32] = {
  240. 0x898f, 0xe896, 0x7437, 0x40ce, 0x8896, 0x32e4, 0xf81f, 0xc16b,
  241. 0x4cdd, 0xf028, 0x3f78, 0x41f4, 0xbd2b, 0xe1d6, 0x957b, 0xc26c,
  242. 0xac2d, 0x3cc3, 0xea72, 0x42d3, 0xcc02, 0xd1d8, 0xa121, 0xc328,
  243. 0x4003, 0x660b, 0xa94b, 0x4363, 0x367b, 0x5906, 0x6d4b, 0xc350,
  244. };
  245. static unsigned short YQ[28] = {
  246. /*0x0000,0x0000,0x0000,0x3ff0,*/
  247. 0xfcb6, 0x576d, 0x4522, 0x4090, 0xbc0c, 0xa907, 0x1b76,
  248. 0x4123, 0xd101, 0x5164, 0x0763, 0x41b0, 0x64bc, 0x2b86,
  249. 0x1ddb, 0x4234, 0x828e, 0xc57e, 0x75fc, 0x42b2, 0x596d,
  250. 0xdfeb, 0x8910, 0x4326, 0xb5d0, 0xbcf9, 0xd25f, 0x438b,
  251. };
  252. #endif
  253. #ifdef MIEEE
  254. static unsigned short YP[32] = {
  255. 0x40ce, 0x7437, 0xe896, 0x898f, 0xc16b, 0xf81f, 0x32e4, 0x8896,
  256. 0x41f4, 0x3f78, 0xf028, 0x4cdd, 0xc26c, 0x957b, 0xe1d6, 0xbd2b,
  257. 0x42d3, 0xea72, 0x3cc3, 0xac2d, 0xc328, 0xa121, 0xd1d8, 0xcc02,
  258. 0x4363, 0xa94b, 0x660b, 0x4003, 0xc350, 0x6d4b, 0x5906, 0x367b,
  259. };
  260. static unsigned short YQ[28] = {
  261. /*0x3ff0,0x0000,0x0000,0x0000,*/
  262. 0x4090, 0x4522, 0x576d, 0xfcb6, 0x4123, 0x1b76, 0xa907,
  263. 0xbc0c, 0x41b0, 0x0763, 0x5164, 0xd101, 0x4234, 0x1ddb,
  264. 0x2b86, 0x64bc, 0x42b2, 0x75fc, 0xc57e, 0x828e, 0x4326,
  265. 0x8910, 0xdfeb, 0x596d, 0x438b, 0xd25f, 0xbcf9, 0xb5d0,
  266. };
  267. #endif
  268. #ifdef UNK
  269. /* 5.783185962946784521175995758455807035071 */
  270. static double DR1 = 5.78318596294678452118E0;
  271. /* 30.47126234366208639907816317502275584842 */
  272. static double DR2 = 3.04712623436620863991E1;
  273. #endif
  274. #ifdef DEC
  275. static unsigned short R1[] = {0040671, 0007734, 0001061, 0056734};
  276. #define DR1 *(double *)R1
  277. static unsigned short R2[] = {0041363, 0142445, 0030416, 0165567};
  278. #define DR2 *(double *)R2
  279. #endif
  280. #ifdef IBMPC
  281. static unsigned short R1[] = {0x2bbb, 0x8046, 0x21fb, 0x4017};
  282. #define DR1 *(double *)R1
  283. static unsigned short R2[] = {0xdd6f, 0xa621, 0x78a4, 0x403e};
  284. #define DR2 *(double *)R2
  285. #endif
  286. #ifdef MIEEE
  287. static unsigned short R1[] = {0x4017, 0x21fb, 0x8046, 0x2bbb};
  288. #define DR1 *(double *)R1
  289. static unsigned short R2[] = {0x403e, 0x78a4, 0xa621, 0xdd6f};
  290. #define DR2 *(double *)R2
  291. #endif
  292. #ifdef UNK
  293. static double RP[4] = {
  294. -4.79443220978201773821E9,
  295. 1.95617491946556577543E12,
  296. -2.49248344360967716204E14,
  297. 9.70862251047306323952E15,
  298. };
  299. static double RQ[8] = {
  300. /* 1.00000000000000000000E0,*/
  301. 4.99563147152651017219E2, 1.73785401676374683123E5,
  302. 4.84409658339962045305E7, 1.11855537045356834862E10,
  303. 2.11277520115489217587E12, 3.10518229857422583814E14,
  304. 3.18121955943204943306E16, 1.71086294081043136091E18,
  305. };
  306. #endif
  307. #ifdef DEC
  308. static unsigned short RP[16] = {
  309. 0150216, 0161235, 0064344, 0014450, 0052343, 0135216, 0035624, 0144153,
  310. 0154142, 0130247, 0003310, 0003667, 0055411, 0173703, 0047772, 0176635,
  311. };
  312. static unsigned short RQ[32] = {
  313. /*0040200,0000000,0000000,0000000,*/
  314. 0042371, 0144025, 0032265, 0136137, 0044451, 0133131, 0132420, 0151466,
  315. 0046470, 0144641, 0072540, 0030636, 0050446, 0126600, 0045042, 0044243,
  316. 0052365, 0172633, 0110301, 0071063, 0054215, 0032424, 0062272, 0043513,
  317. 0055742, 0005013, 0171731, 0072335, 0057275, 0170646, 0036663, 0013134,
  318. };
  319. #endif
  320. #ifdef IBMPC
  321. static unsigned short RP[16] = {
  322. 0x8325, 0xad1c, 0xdc53, 0xc1f1, 0x990d, 0xc772, 0x7751, 0x427c,
  323. 0x00f7, 0xe0d9, 0x5614, 0xc2ec, 0x5fb4, 0x69ff, 0x3ef8, 0x4341,
  324. };
  325. static unsigned short RQ[32] = {
  326. /*0x0000,0x0000,0x0000,0x3ff0,*/
  327. 0xb78c, 0xa696, 0x3902, 0x407f, 0x1a67, 0x36a2, 0x36cb, 0x4105,
  328. 0x0634, 0x2eac, 0x1934, 0x4187, 0x4914, 0x0944, 0xd5b0, 0x4204,
  329. 0x2e46, 0x7218, 0xbeb3, 0x427e, 0x48e9, 0x8c97, 0xa6a2, 0x42f1,
  330. 0x2e9c, 0x7e7b, 0x4141, 0x435c, 0x62cc, 0xc7b6, 0xbe34, 0x43b7,
  331. };
  332. #endif
  333. #ifdef MIEEE
  334. static unsigned short RP[16] = {
  335. 0xc1f1, 0xdc53, 0xad1c, 0x8325, 0x427c, 0x7751, 0xc772, 0x990d,
  336. 0xc2ec, 0x5614, 0xe0d9, 0x00f7, 0x4341, 0x3ef8, 0x69ff, 0x5fb4,
  337. };
  338. static unsigned short RQ[32] = {
  339. /*0x3ff0,0x0000,0x0000,0x0000,*/
  340. 0x407f, 0x3902, 0xa696, 0xb78c, 0x4105, 0x36cb, 0x36a2, 0x1a67,
  341. 0x4187, 0x1934, 0x2eac, 0x0634, 0x4204, 0xd5b0, 0x0944, 0x4914,
  342. 0x427e, 0xbeb3, 0x7218, 0x2e46, 0x42f1, 0xa6a2, 0x8c97, 0x48e9,
  343. 0x435c, 0x4141, 0x7e7b, 0x2e9c, 0x43b7, 0xbe34, 0xc7b6, 0x62cc,
  344. };
  345. #endif
  346. #ifdef ANSIPROT
  347. extern double polevl(double, void *, int);
  348. extern double p1evl(double, void *, int);
  349. extern double log(double);
  350. extern double sin(double);
  351. extern double cos(double);
  352. extern double sqrt(double);
  353. double j0(double);
  354. #else
  355. double polevl(), p1evl(), log(), sin(), cos(), sqrt();
  356. double j0();
  357. #endif
  358. extern double TWOOPI, SQ2OPI, PIO4;
  359. double j0(x) double x;
  360. {
  361. double w, z, p, q, xn;
  362. if (x < 0)
  363. x = -x;
  364. if (x <= 5.0) {
  365. z = x * x;
  366. if (x < 1.0e-5)
  367. return (1.0 - z / 4.0);
  368. p = (z - DR1) * (z - DR2);
  369. p = p * polevl(z, RP, 3) / p1evl(z, RQ, 8);
  370. return (p);
  371. }
  372. w = 5.0 / x;
  373. q = 25.0 / (x * x);
  374. p = polevl(q, PP, 6) / polevl(q, PQ, 6);
  375. q = polevl(q, QP, 7) / p1evl(q, QQ, 7);
  376. xn = x - PIO4;
  377. p = p * cos(xn) - w * q * sin(xn);
  378. return (p * SQ2OPI / sqrt(x));
  379. }
  380. /* y0() 2 */
  381. /* Bessel function of second kind, order zero */
  382. /* Rational approximation coefficients YP[], YQ[] are used here.
  383. * The function computed is y0(x) - 2 * log(x) * j0(x) / PI,
  384. * whose value at x = 0 is 2 * ( log(0.5) + EUL ) / PI
  385. * = 0.073804295108687225.
  386. */
  387. /*
  388. #define PIO4 .78539816339744830962
  389. #define SQ2OPI .79788456080286535588
  390. */
  391. extern double MAXNUM;
  392. double y0(x) double x;
  393. {
  394. double w, z, p, q, xn;
  395. if (x <= 5.0) {
  396. if (x <= 0.0) {
  397. mtherr("y0", DOMAIN);
  398. return (-MAXNUM);
  399. }
  400. z = x * x;
  401. w = polevl(z, YP, 7) / p1evl(z, YQ, 7);
  402. w += TWOOPI * log(x) * j0(x);
  403. return (w);
  404. }
  405. w = 5.0 / x;
  406. z = 25.0 / (x * x);
  407. p = polevl(z, PP, 6) / polevl(z, PQ, 6);
  408. q = polevl(z, QP, 7) / p1evl(z, QQ, 7);
  409. xn = x - PIO4;
  410. p = p * sin(xn) + w * q * cos(xn);
  411. return (p * SQ2OPI / sqrt(x));
  412. }