bessel.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561
  1. /* This file is part of the GNU plotutils package. */
  2. /* Bessel function approximations, as given in the book "Computer
  3. * Approximations" by Hart, Cheney et al., Wiley, 1968. Taken in part from
  4. * the file standard.c in the gnuplot 3.5 distribution. */
  5. #include "sys-defines.h"
  6. #include "ode.h"
  7. #include "extern.h"
  8. /*
  9. * Copyright (C) 1986 - 1993 Thomas Williams, Colin Kelley
  10. *
  11. * Permission to use, copy, and distribute this software and its
  12. * documentation for any purpose with or without fee is hereby granted,
  13. * provided that the above copyright notice appear in all copies and
  14. * that both that copyright notice and this permission notice appear
  15. * in supporting documentation.
  16. */
  17. /*
  18. * AUTHORS
  19. *
  20. * Original Software:
  21. * Thomas Williams, Colin Kelley.
  22. *
  23. * Gnuplot 2.0 additions:
  24. * Russell Lang, Dave Kotz, John Campbell.
  25. *
  26. * Gnuplot 3.0 additions:
  27. * Gershon Elber and many others.
  28. *
  29. */
  30. /*
  31. * There appears to be a mistake in Hart, Cheney et al. on page 149.
  32. * Where it lists Qn(x)/x ~ P(z*z)/Q(z*z), z = 8/x, it should read
  33. * Qn(x)/z ~ P(z*z)/Q(z*z), z = 8/x
  34. * In the functions below, Qn(x) is implemented using the later
  35. * equation.
  36. * These Bessel functions are accurate to about 1e-13.
  37. */
  38. #ifndef HAVE_J0
  39. #define PI_ON_FOUR 0.78539816339744830961566084581987572
  40. #define PI_ON_TWO 1.57079632679489661923131269163975144
  41. #define THREE_PI_ON_FOUR 2.35619449019234492884698253745962716
  42. #define TWO_ON_PI 0.63661977236758134307553505349005744
  43. static const double dzero = 0.0;
  44. /* jzero for x in [0,8]
  45. * Index 5849, 19.22 digits precision
  46. */
  47. static const double pjzero[9] =
  48. {
  49. 0.4933787251794133561816813446e+21,
  50. -0.11791576291076105360384408e+21,
  51. 0.6382059341072356562289432465e+19,
  52. -0.1367620353088171386865416609e+18,
  53. 0.1434354939140346111664316553e+16,
  54. -0.8085222034853793871199468171e+13,
  55. 0.2507158285536881945555156435e+11,
  56. -0.4050412371833132706360663322e+8,
  57. 0.2685786856980014981415848441e+5
  58. };
  59. static const double qjzero[9] =
  60. {
  61. 0.4933787251794133562113278438e+21,
  62. 0.5428918384092285160200195092e+19,
  63. 0.3024635616709462698627330784e+17,
  64. 0.1127756739679798507056031594e+15,
  65. 0.3123043114941213172572469442e+12,
  66. 0.669998767298223967181402866e+9,
  67. 0.1114636098462985378182402543e+7,
  68. 0.1363063652328970604442810507e+4,
  69. 0.1e+1
  70. };
  71. /* pzero for x in [8,inf]
  72. * Index 6548, 18.16 digits precision
  73. */
  74. static const double ppzero[6] =
  75. {
  76. 0.2277909019730468430227002627e+5,
  77. 0.4134538663958076579678016384e+5,
  78. 0.2117052338086494432193395727e+5,
  79. 0.348064864432492703474453111e+4,
  80. 0.15376201909008354295771715e+3,
  81. 0.889615484242104552360748e+0
  82. };
  83. static const double qpzero[6] =
  84. {
  85. 0.2277909019730468431768423768e+5,
  86. 0.4137041249551041663989198384e+5,
  87. 0.2121535056188011573042256764e+5,
  88. 0.350287351382356082073561423e+4,
  89. 0.15711159858080893649068482e+3,
  90. 0.1e+1
  91. };
  92. /* qzero for x in [8,inf]
  93. * Index 6948, 18.33 digits precision
  94. */
  95. static const double pqzero[6] =
  96. {
  97. -0.8922660020080009409846916e+2,
  98. -0.18591953644342993800252169e+3,
  99. -0.11183429920482737611262123e+3,
  100. -0.2230026166621419847169915e+2,
  101. -0.124410267458356384591379e+1,
  102. -0.8803330304868075181663e-2,
  103. };
  104. static const double qqzero[6] =
  105. {
  106. 0.571050241285120619052476459e+4,
  107. 0.1195113154343461364695265329e+5,
  108. 0.726427801692110188369134506e+4,
  109. 0.148872312322837565816134698e+4,
  110. 0.9059376959499312585881878e+2,
  111. 0.1e+1
  112. };
  113. /* yzero for x in [0,8]
  114. * Index 6245, 18.78 digits precision
  115. */
  116. static const double pyzero[9] =
  117. {
  118. -0.2750286678629109583701933175e+20,
  119. 0.6587473275719554925999402049e+20,
  120. -0.5247065581112764941297350814e+19,
  121. 0.1375624316399344078571335453e+18,
  122. -0.1648605817185729473122082537e+16,
  123. 0.1025520859686394284509167421e+14,
  124. -0.3436371222979040378171030138e+11,
  125. 0.5915213465686889654273830069e+8,
  126. -0.4137035497933148554125235152e+5
  127. };
  128. static const double qyzero[9] =
  129. {
  130. 0.3726458838986165881989980739e+21,
  131. 0.4192417043410839973904769661e+19,
  132. 0.2392883043499781857439356652e+17,
  133. 0.9162038034075185262489147968e+14,
  134. 0.2613065755041081249568482092e+12,
  135. 0.5795122640700729537380087915e+9,
  136. 0.1001702641288906265666651753e+7,
  137. 0.1282452772478993804176329391e+4,
  138. 0.1e+1
  139. };
  140. /* jone for x in [0,8]
  141. * Index 6050, 20.98 digits precision
  142. */
  143. static const double pjone[9] =
  144. {
  145. 0.581199354001606143928050809e+21,
  146. -0.6672106568924916298020941484e+20,
  147. 0.2316433580634002297931815435e+19,
  148. -0.3588817569910106050743641413e+17,
  149. 0.2908795263834775409737601689e+15,
  150. -0.1322983480332126453125473247e+13,
  151. 0.3413234182301700539091292655e+10,
  152. -0.4695753530642995859767162166e+7,
  153. 0.270112271089232341485679099e+4
  154. };
  155. static const double qjone[9] =
  156. {
  157. 0.11623987080032122878585294e+22,
  158. 0.1185770712190320999837113348e+20,
  159. 0.6092061398917521746105196863e+17,
  160. 0.2081661221307607351240184229e+15,
  161. 0.5243710262167649715406728642e+12,
  162. 0.1013863514358673989967045588e+10,
  163. 0.1501793594998585505921097578e+7,
  164. 0.1606931573481487801970916749e+4,
  165. 0.1e+1
  166. };
  167. /* pone for x in [8,inf]
  168. * Index 6749, 18.11 digits precision
  169. */
  170. static const double ppone[6] =
  171. {
  172. 0.352246649133679798341724373e+5,
  173. 0.62758845247161281269005675e+5,
  174. 0.313539631109159574238669888e+5,
  175. 0.49854832060594338434500455e+4,
  176. 0.2111529182853962382105718e+3,
  177. 0.12571716929145341558495e+1
  178. };
  179. static const double qpone[6] =
  180. {
  181. 0.352246649133679798068390431e+5,
  182. 0.626943469593560511888833731e+5,
  183. 0.312404063819041039923015703e+5,
  184. 0.4930396490181088979386097e+4,
  185. 0.2030775189134759322293574e+3,
  186. 0.1e+1
  187. };
  188. /* qone for x in [8,inf]
  189. * Index 7149, 18.28 digits precision
  190. */
  191. static const double pqone[6] =
  192. {
  193. 0.3511751914303552822533318e+3,
  194. 0.7210391804904475039280863e+3,
  195. 0.4259873011654442389886993e+3,
  196. 0.831898957673850827325226e+2,
  197. 0.45681716295512267064405e+1,
  198. 0.3532840052740123642735e-1
  199. };
  200. static const double qqone[6] =
  201. {
  202. 0.74917374171809127714519505e+4,
  203. 0.154141773392650970499848051e+5,
  204. 0.91522317015169922705904727e+4,
  205. 0.18111867005523513506724158e+4,
  206. 0.1038187585462133728776636e+3,
  207. 0.1e+1
  208. };
  209. /* yone for x in [0,8]
  210. * Index 6444, 18.24 digits precision
  211. */
  212. static const double pyone[8] =
  213. {
  214. -0.2923821961532962543101048748e+20,
  215. 0.7748520682186839645088094202e+19,
  216. -0.3441048063084114446185461344e+18,
  217. 0.5915160760490070618496315281e+16,
  218. -0.4863316942567175074828129117e+14,
  219. 0.2049696673745662182619800495e+12,
  220. -0.4289471968855248801821819588e+9,
  221. 0.3556924009830526056691325215e+6
  222. };
  223. static const double qyone[9] =
  224. {
  225. 0.1491311511302920350174081355e+21,
  226. 0.1818662841706134986885065935e+19,
  227. 0.113163938269888452690508283e+17,
  228. 0.4755173588888137713092774006e+14,
  229. 0.1500221699156708987166369115e+12,
  230. 0.3716660798621930285596927703e+9,
  231. 0.726914730719888456980191315e+6,
  232. 0.10726961437789255233221267e+4,
  233. 0.1e+1
  234. };
  235. /* Bessel function approximations */
  236. double
  237. jzero (double x)
  238. {
  239. double p, q, x2;
  240. int n;
  241. x2 = x * x;
  242. p = pjzero[8];
  243. q = qjzero[8];
  244. for (n=7; n>=0; n--)
  245. {
  246. p = p*x2 + pjzero[n];
  247. q = q*x2 + qjzero[n];
  248. }
  249. return (p/q);
  250. }
  251. static double
  252. pzero (double x)
  253. {
  254. double p, q, z, z2;
  255. int n;
  256. z = 8.0 / x;
  257. z2 = z * z;
  258. p = ppzero[5];
  259. q = qpzero[5];
  260. for (n=4; n>=0; n--)
  261. {
  262. p = p*z2 + ppzero[n];
  263. q = q*z2 + qpzero[n];
  264. }
  265. return (p/q);
  266. }
  267. static double
  268. qzero (double x)
  269. {
  270. double p, q, z, z2;
  271. int n;
  272. z = 8.0 / x;
  273. z2 = z * z;
  274. p = pqzero[5];
  275. q = qqzero[5];
  276. for (n=4; n>=0; n--)
  277. {
  278. p = p*z2 + pqzero[n];
  279. q = q*z2 + qqzero[n];
  280. }
  281. return (p/q);
  282. }
  283. static double
  284. yzero (double x)
  285. {
  286. double p, q, x2;
  287. int n;
  288. x2 = x * x;
  289. p = pyzero[8];
  290. q = qyzero[8];
  291. for (n=7; n>=0; n--)
  292. {
  293. p = p*x2 + pyzero[n];
  294. q = q*x2 + qyzero[n];
  295. }
  296. return p/q;
  297. }
  298. double
  299. j0 (double x)
  300. {
  301. if (x <= 0.0)
  302. x = -x;
  303. if (x < 8.0)
  304. return jzero(x);
  305. else
  306. return (sqrt(TWO_ON_PI/x)
  307. * (pzero(x) * cos (x - PI_ON_FOUR)
  308. - 8.0/x * qzero(x) * sin (x - PI_ON_FOUR)));
  309. }
  310. double
  311. y0 (double x)
  312. {
  313. if (x < 0.0)
  314. return (dzero/dzero); /* IEEE machines: invalid operation */
  315. if (x < 8.0)
  316. return yzero(x) + TWO_ON_PI * j0(x) * log(x);
  317. else
  318. return (sqrt (TWO_ON_PI/x)
  319. * (pzero(x) * sin (x - PI_ON_FOUR)
  320. + (8.0/x) * qzero(x) * cos(x - PI_ON_FOUR)));
  321. }
  322. static double
  323. jone (double x)
  324. {
  325. double p, q, x2;
  326. int n;
  327. x2 = x * x;
  328. p = pjone[8];
  329. q = qjone[8];
  330. for (n=7; n>=0; n--)
  331. {
  332. p = p*x2 + pjone[n];
  333. q = q*x2 + qjone[n];
  334. }
  335. return (p/q);
  336. }
  337. static double
  338. pone (double x)
  339. {
  340. double p, q, z, z2;
  341. int n;
  342. z = 8.0 / x;
  343. z2 = z * z;
  344. p = ppone[5];
  345. q = qpone[5];
  346. for (n=4; n>=0; n--)
  347. {
  348. p = p*z2 + ppone[n];
  349. q = q*z2 + qpone[n];
  350. }
  351. return (p/q);
  352. }
  353. static double
  354. qone (double x)
  355. {
  356. double p, q, z, z2;
  357. int n;
  358. z = 8.0 / x;
  359. z2 = z * z;
  360. p = pqone[5];
  361. q = qqone[5];
  362. for (n=4; n>=0; n--)
  363. {
  364. p = p*z2 + pqone[n];
  365. q = q*z2 + qqone[n];
  366. }
  367. return p/q;
  368. }
  369. static double
  370. yone (double x)
  371. {
  372. double p, q, x2;
  373. int n;
  374. x2 = x * x;
  375. p = 0.0;
  376. q = qyone[8];
  377. for (n=7; n>=0; n--)
  378. {
  379. p = p*x2 + pyone[n];
  380. q = q*x2 + qyone[n];
  381. }
  382. return p/q;
  383. }
  384. double
  385. j1 (double x)
  386. {
  387. double v,w;
  388. v = x;
  389. if (x < 0.0)
  390. x = -x;
  391. if (x < 8.0)
  392. return v * jone(x);
  393. else
  394. {
  395. w = (sqrt(TWO_ON_PI/x)
  396. * (pone(x) * cos(x - THREE_PI_ON_FOUR)
  397. - 8.0 / x * qone(x) * sin (x - THREE_PI_ON_FOUR)));
  398. if (v < 0.0)
  399. w = -w;
  400. return w;
  401. }
  402. }
  403. double
  404. y1 (double x)
  405. {
  406. if (x <= 0.0)
  407. return (dzero/dzero); /* IEEE machines: invalid operation */
  408. if (x < 8.0)
  409. return x * yone(x) + TWO_ON_PI * (j1(x) * log(x) - 1.0/x);
  410. else
  411. return (sqrt(TWO_ON_PI/x)
  412. * (pone(x) * sin (x - THREE_PI_ON_FOUR)
  413. + (8.0/x) * qone(x) * cos(x - THREE_PI_ON_FOUR)));
  414. }
  415. /* Computation of jn(n,x), i.e., a Bessel function of arbitrary
  416. non-negative index, is as follows.
  417. For n=0, j0() is called.
  418. For n=1, j1() is called.
  419. For n<x, forward recursion is used, starting from values of j0(x)
  420. and j1(x).
  421. For n>x, a continued fraction approximation to jn(n,x)/jn(n-1,x) is
  422. evaluated, and then backward recursion is used starting from a
  423. supposed value for jn(n,x). The resulting value of jn(0,x) is
  424. compared with the actual value, to correct the supposed value of
  425. jn(n,x).
  426. Computation of yn(n,x) is similar in all respects, except that forward
  427. recursion is used for all positive values of n.
  428. */
  429. double
  430. jn (int n, double x)
  431. {
  432. int i;
  433. if (n < 0)
  434. {
  435. n = -n;
  436. x = -x;
  437. }
  438. if (n == 0)
  439. return j0(x);
  440. if (n == 1)
  441. return j1(x);
  442. if (x == 0.0)
  443. return 0.0;
  444. if (n <= x)
  445. {
  446. double a = j0(x), b = j1(x), tmp;
  447. for (i = 1; i < n; i++)
  448. {
  449. tmp = b;
  450. b = (2.0*i / x) * b - a;
  451. a = tmp;
  452. }
  453. return b;
  454. }
  455. else /* n > x */
  456. {
  457. double a, b, xsq, t, tmp;
  458. xsq = x*x;
  459. for (t=0, i=n+16; i > n; i--)
  460. t = xsq / (2.0*i - t);
  461. t = x / (2.0*n - t);
  462. a = t;
  463. b = 1.0;
  464. for (i = n - 1; i > 0; i--)
  465. {
  466. tmp = b;
  467. b = (2.0*i / x ) * b - a;
  468. a = tmp;
  469. }
  470. return t*j0(x)/b;
  471. }
  472. }
  473. double
  474. yn (int n, double x)
  475. {
  476. int i, sign;
  477. double a, b, tmp;
  478. if (x <= 0)
  479. return (dzero/dzero); /* IEEE machines: invalid operation */
  480. sign = 1;
  481. if (n < 0)
  482. {
  483. n = -n;
  484. if (n%2 == 1)
  485. sign = -1;
  486. }
  487. if (n == 0)
  488. return y0(x);
  489. if (n == 1)
  490. return sign*y1(x);
  491. a = y0(x);
  492. b = y1(x);
  493. for (i = 1; i<n; i++)
  494. {
  495. tmp = b;
  496. b = (2.0*i / x) * b - a;
  497. a = tmp;
  498. }
  499. return sign*b;
  500. }
  501. #endif /* HAVE_J0 */