j0.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  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 <math.h>
  92. #ifdef UNK
  93. static double PP[7] = {
  94. 7.96936729297347051624E-4,
  95. 8.28352392107440799803E-2,
  96. 1.23953371646414299388E0,
  97. 5.44725003058768775090E0,
  98. 8.74716500199817011941E0,
  99. 5.30324038235394892183E0,
  100. 9.99999999999999997821E-1,
  101. };
  102. static double PQ[7] = {
  103. 9.24408810558863637013E-4,
  104. 8.56288474354474431428E-2,
  105. 1.25352743901058953537E0,
  106. 5.47097740330417105182E0,
  107. 8.76190883237069594232E0,
  108. 5.30605288235394617618E0,
  109. 1.00000000000000000218E0,
  110. };
  111. #endif
  112. #ifdef DEC
  113. static unsigned short PP[28] = {
  114. 0035520,0164604,0140733,0054470,
  115. 0037251,0122605,0115356,0107170,
  116. 0040236,0124412,0071500,0056303,
  117. 0040656,0047737,0045720,0045263,
  118. 0041013,0172143,0045004,0142103,
  119. 0040651,0132045,0026241,0026406,
  120. 0040200,0000000,0000000,0000000,
  121. };
  122. static unsigned short PQ[28] = {
  123. 0035562,0052006,0070034,0134666,
  124. 0037257,0057055,0055242,0123424,
  125. 0040240,0071626,0046630,0032371,
  126. 0040657,0011077,0032013,0012731,
  127. 0041014,0030307,0050331,0006414,
  128. 0040651,0145457,0065021,0150304,
  129. 0040200,0000000,0000000,0000000,
  130. };
  131. #endif
  132. #ifdef IBMPC
  133. static unsigned short PP[28] = {
  134. 0x6b27,0x983b,0x1d30,0x3f4a,
  135. 0xd1cf,0xb35d,0x34b0,0x3fb5,
  136. 0x0b98,0x4e68,0xd521,0x3ff3,
  137. 0x0956,0xe97a,0xc9fb,0x4015,
  138. 0x9888,0x6940,0x7e8c,0x4021,
  139. 0x25a1,0xa594,0x3684,0x4015,
  140. 0x0000,0x0000,0x0000,0x3ff0,
  141. };
  142. static unsigned short PQ[28] = {
  143. 0x9737,0xce03,0x4a80,0x3f4e,
  144. 0x54e3,0xab54,0xebc5,0x3fb5,
  145. 0x069f,0xc9b3,0x0e72,0x3ff4,
  146. 0x62bb,0xe681,0xe247,0x4015,
  147. 0x21a1,0xea1b,0x8618,0x4021,
  148. 0x3a19,0xed42,0x3965,0x4015,
  149. 0x0000,0x0000,0x0000,0x3ff0,
  150. };
  151. #endif
  152. #ifdef MIEEE
  153. static unsigned short PP[28] = {
  154. 0x3f4a,0x1d30,0x983b,0x6b27,
  155. 0x3fb5,0x34b0,0xb35d,0xd1cf,
  156. 0x3ff3,0xd521,0x4e68,0x0b98,
  157. 0x4015,0xc9fb,0xe97a,0x0956,
  158. 0x4021,0x7e8c,0x6940,0x9888,
  159. 0x4015,0x3684,0xa594,0x25a1,
  160. 0x3ff0,0x0000,0x0000,0x0000,
  161. };
  162. static unsigned short PQ[28] = {
  163. 0x3f4e,0x4a80,0xce03,0x9737,
  164. 0x3fb5,0xebc5,0xab54,0x54e3,
  165. 0x3ff4,0x0e72,0xc9b3,0x069f,
  166. 0x4015,0xe247,0xe681,0x62bb,
  167. 0x4021,0x8618,0xea1b,0x21a1,
  168. 0x4015,0x3965,0xed42,0x3a19,
  169. 0x3ff0,0x0000,0x0000,0x0000,
  170. };
  171. #endif
  172. #ifdef UNK
  173. static double QP[8] = {
  174. -1.13663838898469149931E-2,
  175. -1.28252718670509318512E0,
  176. -1.95539544257735972385E1,
  177. -9.32060152123768231369E1,
  178. -1.77681167980488050595E2,
  179. -1.47077505154951170175E2,
  180. -5.14105326766599330220E1,
  181. -6.05014350600728481186E0,
  182. };
  183. static double QQ[7] = {
  184. /* 1.00000000000000000000E0,*/
  185. 6.43178256118178023184E1,
  186. 8.56430025976980587198E2,
  187. 3.88240183605401609683E3,
  188. 7.24046774195652478189E3,
  189. 5.93072701187316984827E3,
  190. 2.06209331660327847417E3,
  191. 2.42005740240291393179E2,
  192. };
  193. #endif
  194. #ifdef DEC
  195. static unsigned short QP[32] = {
  196. 0136472,0035021,0142451,0141115,
  197. 0140244,0024731,0150620,0105642,
  198. 0141234,0067177,0124161,0060141,
  199. 0141672,0064572,0151557,0043036,
  200. 0142061,0127141,0003127,0043517,
  201. 0142023,0011727,0060271,0144544,
  202. 0141515,0122142,0126620,0143150,
  203. 0140701,0115306,0106715,0007344,
  204. };
  205. static unsigned short QQ[28] = {
  206. /*0040200,0000000,0000000,0000000,*/
  207. 0041600,0121272,0004741,0026544,
  208. 0042526,0015605,0105654,0161771,
  209. 0043162,0123155,0165644,0062645,
  210. 0043342,0041675,0167576,0130756,
  211. 0043271,0052720,0165631,0154214,
  212. 0043000,0160576,0034614,0172024,
  213. 0042162,0000570,0030500,0051235,
  214. };
  215. #endif
  216. #ifdef IBMPC
  217. static unsigned short QP[32] = {
  218. 0x384a,0x38a5,0x4742,0xbf87,
  219. 0x1174,0x3a32,0x853b,0xbff4,
  220. 0x2c0c,0xf50e,0x8dcf,0xc033,
  221. 0xe8c4,0x5a6d,0x4d2f,0xc057,
  222. 0xe8ea,0x20ca,0x35cc,0xc066,
  223. 0x392d,0xec17,0x627a,0xc062,
  224. 0x18cd,0x55b2,0xb48c,0xc049,
  225. 0xa1dd,0xd1b9,0x3358,0xc018,
  226. };
  227. static unsigned short QQ[28] = {
  228. /*0x0000,0x0000,0x0000,0x3ff0,*/
  229. 0x25ac,0x413c,0x1457,0x4050,
  230. 0x9c7f,0xb175,0xc370,0x408a,
  231. 0x8cb5,0xbd74,0x54cd,0x40ae,
  232. 0xd63e,0xbdef,0x4877,0x40bc,
  233. 0x3b11,0x1d73,0x2aba,0x40b7,
  234. 0x9e82,0xc731,0x1c2f,0x40a0,
  235. 0x0a54,0x0628,0x402f,0x406e,
  236. };
  237. #endif
  238. #ifdef MIEEE
  239. static unsigned short QP[32] = {
  240. 0xbf87,0x4742,0x38a5,0x384a,
  241. 0xbff4,0x853b,0x3a32,0x1174,
  242. 0xc033,0x8dcf,0xf50e,0x2c0c,
  243. 0xc057,0x4d2f,0x5a6d,0xe8c4,
  244. 0xc066,0x35cc,0x20ca,0xe8ea,
  245. 0xc062,0x627a,0xec17,0x392d,
  246. 0xc049,0xb48c,0x55b2,0x18cd,
  247. 0xc018,0x3358,0xd1b9,0xa1dd,
  248. };
  249. static unsigned short QQ[28] = {
  250. /*0x3ff0,0x0000,0x0000,0x0000,*/
  251. 0x4050,0x1457,0x413c,0x25ac,
  252. 0x408a,0xc370,0xb175,0x9c7f,
  253. 0x40ae,0x54cd,0xbd74,0x8cb5,
  254. 0x40bc,0x4877,0xbdef,0xd63e,
  255. 0x40b7,0x2aba,0x1d73,0x3b11,
  256. 0x40a0,0x1c2f,0xc731,0x9e82,
  257. 0x406e,0x402f,0x0628,0x0a54,
  258. };
  259. #endif
  260. #ifdef UNK
  261. static double YP[8] = {
  262. 1.55924367855235737965E4,
  263. -1.46639295903971606143E7,
  264. 5.43526477051876500413E9,
  265. -9.82136065717911466409E11,
  266. 8.75906394395366999549E13,
  267. -3.46628303384729719441E15,
  268. 4.42733268572569800351E16,
  269. -1.84950800436986690637E16,
  270. };
  271. static double YQ[7] = {
  272. /* 1.00000000000000000000E0,*/
  273. 1.04128353664259848412E3,
  274. 6.26107330137134956842E5,
  275. 2.68919633393814121987E8,
  276. 8.64002487103935000337E10,
  277. 2.02979612750105546709E13,
  278. 3.17157752842975028269E15,
  279. 2.50596256172653059228E17,
  280. };
  281. #endif
  282. #ifdef DEC
  283. static unsigned short YP[32] = {
  284. 0043563,0120677,0042264,0046166,
  285. 0146137,0140371,0113444,0042260,
  286. 0050241,0175707,0100502,0063344,
  287. 0152144,0125737,0007265,0164526,
  288. 0053637,0051621,0163035,0060546,
  289. 0155105,0004416,0107306,0060023,
  290. 0056035,0045133,0030132,0000024,
  291. 0155603,0065132,0144061,0131732,
  292. };
  293. static unsigned short YQ[28] = {
  294. /*0040200,0000000,0000000,0000000,*/
  295. 0042602,0024422,0135557,0162663,
  296. 0045030,0155665,0044075,0160135,
  297. 0047200,0035432,0105446,0104005,
  298. 0051240,0167331,0056063,0022743,
  299. 0053223,0127746,0025764,0012160,
  300. 0055064,0044206,0177532,0145545,
  301. 0056536,0111375,0163715,0127201,
  302. };
  303. #endif
  304. #ifdef IBMPC
  305. static unsigned short YP[32] = {
  306. 0x898f,0xe896,0x7437,0x40ce,
  307. 0x8896,0x32e4,0xf81f,0xc16b,
  308. 0x4cdd,0xf028,0x3f78,0x41f4,
  309. 0xbd2b,0xe1d6,0x957b,0xc26c,
  310. 0xac2d,0x3cc3,0xea72,0x42d3,
  311. 0xcc02,0xd1d8,0xa121,0xc328,
  312. 0x4003,0x660b,0xa94b,0x4363,
  313. 0x367b,0x5906,0x6d4b,0xc350,
  314. };
  315. static unsigned short YQ[28] = {
  316. /*0x0000,0x0000,0x0000,0x3ff0,*/
  317. 0xfcb6,0x576d,0x4522,0x4090,
  318. 0xbc0c,0xa907,0x1b76,0x4123,
  319. 0xd101,0x5164,0x0763,0x41b0,
  320. 0x64bc,0x2b86,0x1ddb,0x4234,
  321. 0x828e,0xc57e,0x75fc,0x42b2,
  322. 0x596d,0xdfeb,0x8910,0x4326,
  323. 0xb5d0,0xbcf9,0xd25f,0x438b,
  324. };
  325. #endif
  326. #ifdef MIEEE
  327. static unsigned short YP[32] = {
  328. 0x40ce,0x7437,0xe896,0x898f,
  329. 0xc16b,0xf81f,0x32e4,0x8896,
  330. 0x41f4,0x3f78,0xf028,0x4cdd,
  331. 0xc26c,0x957b,0xe1d6,0xbd2b,
  332. 0x42d3,0xea72,0x3cc3,0xac2d,
  333. 0xc328,0xa121,0xd1d8,0xcc02,
  334. 0x4363,0xa94b,0x660b,0x4003,
  335. 0xc350,0x6d4b,0x5906,0x367b,
  336. };
  337. static unsigned short YQ[28] = {
  338. /*0x3ff0,0x0000,0x0000,0x0000,*/
  339. 0x4090,0x4522,0x576d,0xfcb6,
  340. 0x4123,0x1b76,0xa907,0xbc0c,
  341. 0x41b0,0x0763,0x5164,0xd101,
  342. 0x4234,0x1ddb,0x2b86,0x64bc,
  343. 0x42b2,0x75fc,0xc57e,0x828e,
  344. 0x4326,0x8910,0xdfeb,0x596d,
  345. 0x438b,0xd25f,0xbcf9,0xb5d0,
  346. };
  347. #endif
  348. #ifdef UNK
  349. /* 5.783185962946784521175995758455807035071 */
  350. static double DR1 = 5.78318596294678452118E0;
  351. /* 30.47126234366208639907816317502275584842 */
  352. static double DR2 = 3.04712623436620863991E1;
  353. #endif
  354. #ifdef DEC
  355. static unsigned short R1[] = {0040671,0007734,0001061,0056734};
  356. #define DR1 *(double *)R1
  357. static unsigned short R2[] = {0041363,0142445,0030416,0165567};
  358. #define DR2 *(double *)R2
  359. #endif
  360. #ifdef IBMPC
  361. static unsigned short R1[] = {0x2bbb,0x8046,0x21fb,0x4017};
  362. #define DR1 *(double *)R1
  363. static unsigned short R2[] = {0xdd6f,0xa621,0x78a4,0x403e};
  364. #define DR2 *(double *)R2
  365. #endif
  366. #ifdef MIEEE
  367. static unsigned short R1[] = {0x4017,0x21fb,0x8046,0x2bbb};
  368. #define DR1 *(double *)R1
  369. static unsigned short R2[] = {0x403e,0x78a4,0xa621,0xdd6f};
  370. #define DR2 *(double *)R2
  371. #endif
  372. #ifdef UNK
  373. static double RP[4] = {
  374. -4.79443220978201773821E9,
  375. 1.95617491946556577543E12,
  376. -2.49248344360967716204E14,
  377. 9.70862251047306323952E15,
  378. };
  379. static double RQ[8] = {
  380. /* 1.00000000000000000000E0,*/
  381. 4.99563147152651017219E2,
  382. 1.73785401676374683123E5,
  383. 4.84409658339962045305E7,
  384. 1.11855537045356834862E10,
  385. 2.11277520115489217587E12,
  386. 3.10518229857422583814E14,
  387. 3.18121955943204943306E16,
  388. 1.71086294081043136091E18,
  389. };
  390. #endif
  391. #ifdef DEC
  392. static unsigned short RP[16] = {
  393. 0150216,0161235,0064344,0014450,
  394. 0052343,0135216,0035624,0144153,
  395. 0154142,0130247,0003310,0003667,
  396. 0055411,0173703,0047772,0176635,
  397. };
  398. static unsigned short RQ[32] = {
  399. /*0040200,0000000,0000000,0000000,*/
  400. 0042371,0144025,0032265,0136137,
  401. 0044451,0133131,0132420,0151466,
  402. 0046470,0144641,0072540,0030636,
  403. 0050446,0126600,0045042,0044243,
  404. 0052365,0172633,0110301,0071063,
  405. 0054215,0032424,0062272,0043513,
  406. 0055742,0005013,0171731,0072335,
  407. 0057275,0170646,0036663,0013134,
  408. };
  409. #endif
  410. #ifdef IBMPC
  411. static unsigned short RP[16] = {
  412. 0x8325,0xad1c,0xdc53,0xc1f1,
  413. 0x990d,0xc772,0x7751,0x427c,
  414. 0x00f7,0xe0d9,0x5614,0xc2ec,
  415. 0x5fb4,0x69ff,0x3ef8,0x4341,
  416. };
  417. static unsigned short RQ[32] = {
  418. /*0x0000,0x0000,0x0000,0x3ff0,*/
  419. 0xb78c,0xa696,0x3902,0x407f,
  420. 0x1a67,0x36a2,0x36cb,0x4105,
  421. 0x0634,0x2eac,0x1934,0x4187,
  422. 0x4914,0x0944,0xd5b0,0x4204,
  423. 0x2e46,0x7218,0xbeb3,0x427e,
  424. 0x48e9,0x8c97,0xa6a2,0x42f1,
  425. 0x2e9c,0x7e7b,0x4141,0x435c,
  426. 0x62cc,0xc7b6,0xbe34,0x43b7,
  427. };
  428. #endif
  429. #ifdef MIEEE
  430. static unsigned short RP[16] = {
  431. 0xc1f1,0xdc53,0xad1c,0x8325,
  432. 0x427c,0x7751,0xc772,0x990d,
  433. 0xc2ec,0x5614,0xe0d9,0x00f7,
  434. 0x4341,0x3ef8,0x69ff,0x5fb4,
  435. };
  436. static unsigned short RQ[32] = {
  437. /*0x3ff0,0x0000,0x0000,0x0000,*/
  438. 0x407f,0x3902,0xa696,0xb78c,
  439. 0x4105,0x36cb,0x36a2,0x1a67,
  440. 0x4187,0x1934,0x2eac,0x0634,
  441. 0x4204,0xd5b0,0x0944,0x4914,
  442. 0x427e,0xbeb3,0x7218,0x2e46,
  443. 0x42f1,0xa6a2,0x8c97,0x48e9,
  444. 0x435c,0x4141,0x7e7b,0x2e9c,
  445. 0x43b7,0xbe34,0xc7b6,0x62cc,
  446. };
  447. #endif
  448. #ifdef ANSIPROT
  449. extern double polevl ( double, void *, int );
  450. extern double p1evl ( double, void *, int );
  451. extern double log ( double );
  452. extern double sin ( double );
  453. extern double cos ( double );
  454. extern double sqrt ( double );
  455. double j0 ( double );
  456. #else
  457. double polevl(), p1evl(), log(), sin(), cos(), sqrt();
  458. double j0();
  459. #endif
  460. extern double TWOOPI, SQ2OPI, PIO4;
  461. double j0(x)
  462. double x;
  463. {
  464. double w, z, p, q, xn;
  465. if( x < 0 )
  466. x = -x;
  467. if( x <= 5.0 )
  468. {
  469. z = x * x;
  470. if( x < 1.0e-5 )
  471. return( 1.0 - z/4.0 );
  472. p = (z - DR1) * (z - DR2);
  473. p = p * polevl( z, RP, 3)/p1evl( z, RQ, 8 );
  474. return( p );
  475. }
  476. w = 5.0/x;
  477. q = 25.0/(x*x);
  478. p = polevl( q, PP, 6)/polevl( q, PQ, 6 );
  479. q = polevl( q, QP, 7)/p1evl( q, QQ, 7 );
  480. xn = x - PIO4;
  481. p = p * cos(xn) - w * q * sin(xn);
  482. return( p * SQ2OPI / sqrt(x) );
  483. }
  484. /* y0() 2 */
  485. /* Bessel function of second kind, order zero */
  486. /* Rational approximation coefficients YP[], YQ[] are used here.
  487. * The function computed is y0(x) - 2 * log(x) * j0(x) / PI,
  488. * whose value at x = 0 is 2 * ( log(0.5) + EUL ) / PI
  489. * = 0.073804295108687225.
  490. */
  491. /*
  492. #define PIO4 .78539816339744830962
  493. #define SQ2OPI .79788456080286535588
  494. */
  495. extern double MAXNUM;
  496. double y0(x)
  497. double x;
  498. {
  499. double w, z, p, q, xn;
  500. if( x <= 5.0 )
  501. {
  502. if( x <= 0.0 )
  503. {
  504. mtherr( "y0", DOMAIN );
  505. return( -MAXNUM );
  506. }
  507. z = x * x;
  508. w = polevl( z, YP, 7) / p1evl( z, YQ, 7 );
  509. w += TWOOPI * log(x) * j0(x);
  510. return( w );
  511. }
  512. w = 5.0/x;
  513. z = 25.0 / (x * x);
  514. p = polevl( z, PP, 6)/polevl( z, PQ, 6 );
  515. q = polevl( z, QP, 7)/p1evl( z, QQ, 7 );
  516. xn = x - PIO4;
  517. p = p * sin(xn) + w * q * cos(xn);
  518. return( p * SQ2OPI / sqrt(x) );
  519. }