gsl_specfunc__bessel_zero.c 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220
  1. /* specfunc/bessel_zero.c
  2. *
  3. * Copyright (C) 1996, 1997, 1998, 1999, 2000 Gerard Jungman
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. */
  19. /* Author: G. Jungman */
  20. #include "gsl__config.h"
  21. #include "gsl_math.h"
  22. #include "gsl_errno.h"
  23. #include "gsl_sf_airy.h"
  24. #include "gsl_sf_pow_int.h"
  25. #include "gsl_sf_bessel.h"
  26. #include "gsl_specfunc__error.h"
  27. #include "gsl_specfunc__bessel_olver.h"
  28. /* For Chebyshev expansions of the roots as functions of nu,
  29. * see [G. Nemeth, Mathematical Approximation of Special Functions].
  30. * This gives the fits for all nu and s <= 10.
  31. * I made the fits for other values of s myself [GJ].
  32. */
  33. /* Chebyshev expansion: j_{nu,1} = c_k T_k*(nu/2), nu <= 2 */
  34. static const double coef_jnu1_a[] = {
  35. 3.801775243633476,
  36. 1.360704737511120,
  37. -0.030707710261106,
  38. 0.004526823746202,
  39. -0.000808682832134,
  40. 0.000159218792489,
  41. -0.000033225189761,
  42. 0.000007205599763,
  43. -0.000001606110397,
  44. 0.000000365439424,
  45. -0.000000084498039,
  46. 0.000000019793815,
  47. -0.000000004687054,
  48. 0.000000001120052,
  49. -0.000000000269767,
  50. 0.000000000065420,
  51. -0.000000000015961,
  52. 0.000000000003914,
  53. -0.000000000000965,
  54. 0.000000000000239,
  55. -0.000000000000059,
  56. 0.000000000000015,
  57. -0.000000000000004,
  58. 0.000000000000001
  59. };
  60. /* Chebyshev expansion: j_{nu,1} = nu c_k T_k*((2/nu)^(2/3)), nu >= 2 */
  61. static const double coef_jnu1_b[] = {
  62. 1.735063412537096,
  63. 0.784478100951978,
  64. 0.048881473180370,
  65. -0.000578279783021,
  66. -0.000038984957864,
  67. 0.000005758297879,
  68. -0.000000327583229,
  69. -0.000000003853878,
  70. 0.000000002284653,
  71. -0.000000000153079,
  72. -0.000000000000895,
  73. 0.000000000000283,
  74. 0.000000000000043,
  75. 0.000000000000010,
  76. -0.000000000000003
  77. };
  78. /* Chebyshev expansion: j_{nu,2} = c_k T_k*(nu/2), nu <= 2 */
  79. static const double coef_jnu2_a[] = {
  80. 6.992370244046161,
  81. 1.446379282056534,
  82. -0.023458616207293,
  83. 0.002172149448700,
  84. -0.000246262775620,
  85. 0.000030990180959,
  86. -0.000004154183047,
  87. 0.000000580766328,
  88. -0.000000083648175,
  89. 0.000000012317355,
  90. -0.000000001844887,
  91. 0.000000000280076,
  92. -0.000000000042986,
  93. 0.000000000006658,
  94. -0.000000000001039,
  95. 0.000000000000163,
  96. -0.000000000000026,
  97. 0.000000000000004,
  98. -0.000000000000001
  99. };
  100. /* Chebyshev expansion: j_{nu,2} = nu c_k T_k*((2/nu)^(2/3)), nu >= 2 */
  101. static const double coef_jnu2_b[] = {
  102. 2.465611864263400,
  103. 1.607952988471069,
  104. 0.138758034431497,
  105. -0.003687791182054,
  106. -0.000051276007868,
  107. 0.000045113570749,
  108. -0.000007579172152,
  109. 0.000000736469208,
  110. -0.000000011118527,
  111. -0.000000011919884,
  112. 0.000000002696788,
  113. -0.000000000314488,
  114. 0.000000000008124,
  115. 0.000000000005211,
  116. -0.000000000001292,
  117. 0.000000000000158,
  118. -0.000000000000004,
  119. -0.000000000000003,
  120. 0.000000000000001
  121. };
  122. /* Chebyshev expansion: j_{nu,3} = c_k T_k*(nu/3), nu <= 3 */
  123. static const double coef_jnu3_a[] = {
  124. 10.869647065239236,
  125. 2.177524286141710,
  126. -0.034822817125293,
  127. 0.003167249102413,
  128. -0.000353960349344,
  129. 0.000044039086085,
  130. -0.000005851380981,
  131. 0.000000812575483,
  132. -0.000000116463617,
  133. 0.000000017091246,
  134. -0.000000002554376,
  135. 0.000000000387335,
  136. -0.000000000059428,
  137. 0.000000000009207,
  138. -0.000000000001438,
  139. 0.000000000000226,
  140. -0.000000000000036,
  141. 0.000000000000006,
  142. -0.000000000000001
  143. };
  144. /* Chebyshev expansion: j_{nu,3} = nu c_k T_k*((3/nu)^(2/3)), nu >= 3 */
  145. static const double coef_jnu3_b[] = {
  146. 2.522816775173244,
  147. 1.673199424973720,
  148. 0.146431617506314,
  149. -0.004049001763912,
  150. -0.000039517767244,
  151. 0.000048781729288,
  152. -0.000008729705695,
  153. 0.000000928737310,
  154. -0.000000028388244,
  155. -0.000000012927432,
  156. 0.000000003441008,
  157. -0.000000000471695,
  158. 0.000000000025590,
  159. 0.000000000005502,
  160. -0.000000000001881,
  161. 0.000000000000295,
  162. -0.000000000000020,
  163. -0.000000000000003,
  164. 0.000000000000001
  165. };
  166. /* Chebyshev expansion: j_{nu,4} = c_k T_k*(nu/4), nu <= 4 */
  167. static const double coef_jnu4_a[] = {
  168. 14.750310252773009,
  169. 2.908010932941708,
  170. -0.046093293420315,
  171. 0.004147172321412,
  172. -0.000459092310473,
  173. 0.000056646951906,
  174. -0.000007472351546,
  175. 0.000001031210065,
  176. -0.000000147008137,
  177. 0.000000021475218,
  178. -0.000000003197208,
  179. 0.000000000483249,
  180. -0.000000000073946,
  181. 0.000000000011431,
  182. -0.000000000001782,
  183. 0.000000000000280,
  184. -0.000000000000044,
  185. 0.000000000000007,
  186. -0.000000000000001
  187. };
  188. /* Chebyshev expansion: j_{nu,4} = nu c_k T_k*((4/nu)^(2/3)), nu >= 4 */
  189. static const double coef_jnu4_b[] = {
  190. 2.551681323117914,
  191. 1.706177978336572,
  192. 0.150357658406131,
  193. -0.004234001378590,
  194. -0.000033854229898,
  195. 0.000050763551485,
  196. -0.000009337464057,
  197. 0.000001029717834,
  198. -0.000000037474196,
  199. -0.000000013450153,
  200. 0.000000003836180,
  201. -0.000000000557404,
  202. 0.000000000035748,
  203. 0.000000000005487,
  204. -0.000000000002187,
  205. 0.000000000000374,
  206. -0.000000000000031,
  207. -0.000000000000003,
  208. 0.000000000000001
  209. };
  210. /* Chebyshev expansion: j_{nu,5} = c_k T_k*(nu/5), nu <= 5 */
  211. static const double coef_jnu5_a[] = {
  212. 18.632261081028211,
  213. 3.638249012596966,
  214. -0.057329705998828,
  215. 0.005121709126820,
  216. -0.000563325259487,
  217. 0.000069100826174,
  218. -0.000009066603030,
  219. 0.000001245181383,
  220. -0.000000176737282,
  221. 0.000000025716695,
  222. -0.000000003815184,
  223. 0.000000000574839,
  224. -0.000000000087715,
  225. 0.000000000013526,
  226. -0.000000000002104,
  227. 0.000000000000330,
  228. -0.000000000000052,
  229. 0.000000000000008,
  230. -0.000000000000001
  231. };
  232. /* Chebyshev expansion: j_{nu,5} = nu c_k T_k*((5/nu)^(2/3)), nu >= 5 */
  233. /* FIXME: There is something wrong with this fit, in about the
  234. * 9th or 10th decimal place.
  235. */
  236. static const double coef_jnu5_b[] = {
  237. 2.569079487591442,
  238. 1.726073360882134,
  239. 0.152740776809531,
  240. -0.004346449660148,
  241. -0.000030512461856,
  242. 0.000052000821080,
  243. -0.000009713343981,
  244. 0.000001091997863,
  245. -0.000000043061707,
  246. -0.000000013779413,
  247. 0.000000004082870,
  248. -0.000000000611259,
  249. 0.000000000042242,
  250. 0.000000000005448,
  251. -0.000000000002377,
  252. 0.000000000000424,
  253. -0.000000000000038,
  254. -0.000000000000002,
  255. 0.000000000000002
  256. };
  257. /* Chebyshev expansion: j_{nu,6} = c_k T_k*(nu/6), nu <= 6 */
  258. static const double coef_jnu6_a[] = {
  259. 22.514836143374042,
  260. 4.368367257557198,
  261. -0.068550155285562,
  262. 0.006093776505822,
  263. -0.000667152784957,
  264. 0.000081486022398,
  265. -0.000010649011647,
  266. 0.000001457089679,
  267. -0.000000206105082,
  268. 0.000000029894724,
  269. -0.000000004422012,
  270. 0.000000000664471,
  271. -0.000000000101140,
  272. 0.000000000015561,
  273. -0.000000000002416,
  274. 0.000000000000378,
  275. -0.000000000000060,
  276. 0.000000000000009,
  277. -0.000000000000002
  278. };
  279. /* Chebyshev expansion: j_{nu,6} = nu c_k T_k*((6/nu)^(2/3)), nu >= 6 */
  280. static const double coef_jnu6_b[] = {
  281. 2.580710285494837,
  282. 1.739380728566154,
  283. 0.154340696401691,
  284. -0.004422028860168,
  285. -0.000028305272624,
  286. 0.000052845975269,
  287. -0.000009968794373,
  288. 0.000001134252926,
  289. -0.000000046841241,
  290. -0.000000014007555,
  291. 0.000000004251816,
  292. -0.000000000648213,
  293. 0.000000000046728,
  294. 0.000000000005414,
  295. -0.000000000002508,
  296. 0.000000000000459,
  297. -0.000000000000043,
  298. -0.000000000000002,
  299. 0.000000000000002
  300. };
  301. /* Chebyshev expansion: j_{nu,7} = c_k T_k*(nu/7), nu <= 7 */
  302. static const double coef_jnu7_a[] = {
  303. 26.397760539730869,
  304. 5.098418721711790,
  305. -0.079761896398948,
  306. 0.007064521280487,
  307. -0.000770766522482,
  308. 0.000093835449636,
  309. -0.000012225308542,
  310. 0.000001667939800,
  311. -0.000000235288157,
  312. 0.000000034040347,
  313. -0.000000005023142,
  314. 0.000000000753101,
  315. -0.000000000114389,
  316. 0.000000000017564,
  317. -0.000000000002722,
  318. 0.000000000000425,
  319. -0.000000000000067,
  320. 0.000000000000011,
  321. -0.000000000000002
  322. };
  323. /* Chebyshev expansion: j_{nu,7} = nu c_k T_k*((7/nu)^(2/3)), nu >= 7 */
  324. static const double coef_jnu7_b[] = {
  325. 2.589033335856773,
  326. 1.748907007612678,
  327. 0.155488900387653,
  328. -0.004476317805688,
  329. -0.000026737952924,
  330. 0.000053459680946,
  331. -0.000010153699240,
  332. 0.000001164804272,
  333. -0.000000049566917,
  334. -0.000000014175403,
  335. 0.000000004374840,
  336. -0.000000000675135,
  337. 0.000000000050004,
  338. 0.000000000005387,
  339. -0.000000000002603,
  340. 0.000000000000485,
  341. -0.000000000000047,
  342. -0.000000000000002,
  343. 0.000000000000002
  344. };
  345. /* Chebyshev expansion: j_{nu,8} = c_k T_k*(nu/8), nu <= 8 */
  346. static const double coef_jnu8_a[] = {
  347. 30.280900001606662,
  348. 5.828429205461221,
  349. -0.090968381181069,
  350. 0.008034479731033,
  351. -0.000874254899080,
  352. 0.000106164151611,
  353. -0.000013798098749,
  354. 0.000001878187386,
  355. -0.000000264366627,
  356. 0.000000038167685,
  357. -0.000000005621060,
  358. 0.000000000841165,
  359. -0.000000000127538,
  360. 0.000000000019550,
  361. -0.000000000003025,
  362. 0.000000000000472,
  363. -0.000000000000074,
  364. 0.000000000000012,
  365. -0.000000000000002
  366. };
  367. /* Chebyshev expansion: j_{nu,8} = nu c_k T_k*((8/nu)^(2/3)), nu >= 8 */
  368. static const double coef_jnu8_b[] = {
  369. 2.595283877150078,
  370. 1.756063044986928,
  371. 0.156352972371030,
  372. -0.004517201896761,
  373. -0.000025567187878,
  374. 0.000053925472558,
  375. -0.000010293734486,
  376. 0.000001187923085,
  377. -0.000000051625122,
  378. -0.000000014304212,
  379. 0.000000004468450,
  380. -0.000000000695620,
  381. 0.000000000052500,
  382. 0.000000000005367,
  383. -0.000000000002676,
  384. 0.000000000000505,
  385. -0.000000000000050,
  386. -0.000000000000002,
  387. 0.000000000000002
  388. };
  389. /* Chebyshev expansion: j_{nu,9} = c_k T_k*(nu/9), nu <= 9 */
  390. static const double coef_jnu9_a[] = {
  391. 34.164181213238386,
  392. 6.558412747925228,
  393. -0.102171455365016,
  394. 0.009003934361201,
  395. -0.000977663914535,
  396. 0.000118479876579,
  397. -0.000015368714220,
  398. 0.000002088064285,
  399. -0.000000293381154,
  400. 0.000000042283900,
  401. -0.000000006217033,
  402. 0.000000000928887,
  403. -0.000000000140627,
  404. 0.000000000021526,
  405. -0.000000000003326,
  406. 0.000000000000518,
  407. -0.000000000000081,
  408. 0.000000000000013,
  409. -0.000000000000002
  410. };
  411. /* Chebyshev expansion: j_{nu,9} = nu c_k T_k*((9/nu)^(2/3)), nu >= 9 */
  412. static const double coef_jnu9_b[] = {
  413. 2.600150240905079,
  414. 1.761635491694032,
  415. 0.157026743724010,
  416. -0.004549100368716,
  417. -0.000024659248617,
  418. 0.000054291035068,
  419. -0.000010403464334,
  420. 0.000001206027524,
  421. -0.000000053234089,
  422. -0.000000014406241,
  423. 0.000000004542078,
  424. -0.000000000711728,
  425. 0.000000000054464,
  426. 0.000000000005350,
  427. -0.000000000002733,
  428. 0.000000000000521,
  429. -0.000000000000052,
  430. -0.000000000000002,
  431. 0.000000000000002
  432. };
  433. /* Chebyshev expansion: j_{nu,10} = c_k T_k*(nu/10), nu <= 10 */
  434. static const double coef_jnu10_a[] = {
  435. 38.047560766184647,
  436. 7.288377637926008,
  437. -0.113372193277897,
  438. 0.009973047509098,
  439. -0.001081019701335,
  440. 0.000130786983847,
  441. -0.000016937898538,
  442. 0.000002297699179,
  443. -0.000000322354218,
  444. 0.000000046392941,
  445. -0.000000006811759,
  446. 0.000000001016395,
  447. -0.000000000153677,
  448. 0.000000000023486,
  449. -0.000000000003616,
  450. 0.000000000000561,
  451. -0.000000000000095,
  452. 0.000000000000027,
  453. -0.000000000000013,
  454. 0.000000000000005
  455. };
  456. /* Chebyshev expansion: j_{nu,10} = nu c_k T_k*((10/nu)^(2/3)), nu >= 10 */
  457. static const double coef_jnu10_b[] = {
  458. 2.604046346867949,
  459. 1.766097596481182,
  460. 0.157566834446511,
  461. -0.004574682244089,
  462. -0.000023934500688,
  463. 0.000054585558231,
  464. -0.000010491765415,
  465. 0.000001220589364,
  466. -0.000000054526331,
  467. -0.000000014489078,
  468. 0.000000004601510,
  469. -0.000000000724727,
  470. 0.000000000056049,
  471. 0.000000000005337,
  472. -0.000000000002779,
  473. 0.000000000000533,
  474. -0.000000000000054,
  475. -0.000000000000002,
  476. 0.000000000000002
  477. };
  478. /* Chebyshev expansion: j_{nu,11} = c_k T_k*(nu/22), nu <= 22 */
  479. static const double coef_jnu11_a[] = {
  480. 49.5054081076848637,
  481. 15.33692279367165101,
  482. -0.33677234163517130,
  483. 0.04623235772920729,
  484. -0.00781084960665093,
  485. 0.00147217395434708,
  486. -0.00029695043846867,
  487. 0.00006273356860235,
  488. -0.00001370575125628,
  489. 3.07171282012e-6,
  490. -7.0235041249e-7,
  491. 1.6320559339e-7,
  492. -3.843117306e-8,
  493. 9.15083800e-9,
  494. -2.19957642e-9,
  495. 5.3301703e-10,
  496. -1.3007541e-10,
  497. 3.193827e-11,
  498. -7.88605e-12,
  499. 1.95918e-12,
  500. -4.9020e-13,
  501. 1.2207e-13,
  502. -2.820e-14,
  503. 5.25e-15,
  504. -1.88e-15,
  505. 2.80e-15,
  506. -2.45e-15
  507. };
  508. /* Chebyshev expansion: j_{nu,12} = c_k T_k*(nu/24), nu <= 24 */
  509. static const double coef_jnu12_a[] = {
  510. 54.0787833216641519,
  511. 16.7336367772863598,
  512. -0.36718411124537953,
  513. 0.05035523375053820,
  514. -0.00849884978867533,
  515. 0.00160027692813434,
  516. -0.00032248114889921,
  517. 0.00006806354127199,
  518. -0.00001485665901339,
  519. 3.32668783672e-6,
  520. -7.5998952729e-7,
  521. 1.7644939709e-7,
  522. -4.151538210e-8,
  523. 9.87722772e-9,
  524. -2.37230133e-9,
  525. 5.7442875e-10,
  526. -1.4007767e-10,
  527. 3.437166e-11,
  528. -8.48215e-12,
  529. 2.10554e-12,
  530. -5.2623e-13,
  531. 1.3189e-13,
  532. -3.175e-14,
  533. 5.73e-15,
  534. 5.6e-16,
  535. -8.7e-16,
  536. -6.5e-16
  537. };
  538. /* Chebyshev expansion: j_{nu,13} = c_k T_k*(nu/26), nu <= 26 */
  539. static const double coef_jnu13_a[] = {
  540. 58.6521941921708890,
  541. 18.1303398137970284,
  542. -0.39759381380126650,
  543. 0.05447765240465494,
  544. -0.00918674227679980,
  545. 0.00172835361420579,
  546. -0.00034800528297612,
  547. 0.00007339183835188,
  548. -0.00001600713368099,
  549. 3.58154960392e-6,
  550. -8.1759873497e-7,
  551. 1.8968523220e-7,
  552. -4.459745253e-8,
  553. 1.060304419e-8,
  554. -2.54487624e-9,
  555. 6.1580214e-10,
  556. -1.5006751e-10,
  557. 3.679707e-11,
  558. -9.07159e-12,
  559. 2.24713e-12,
  560. -5.5943e-13,
  561. 1.4069e-13,
  562. -3.679e-14,
  563. 1.119e-14,
  564. -4.99e-15,
  565. 3.43e-15,
  566. -2.85e-15,
  567. 2.3e-15,
  568. -1.7e-15,
  569. 8.7e-16
  570. };
  571. /* Chebyshev expansion: j_{nu,14} = c_k T_k*(nu/28), nu <= 28 */
  572. static const double coef_jnu14_a[] = {
  573. 63.2256329577315566,
  574. 19.5270342832914901,
  575. -0.42800190567884337,
  576. 0.05859971627729398,
  577. -0.00987455163523582,
  578. 0.00185641011402081,
  579. -0.00037352439419968,
  580. 0.00007871886257265,
  581. -0.00001715728110045,
  582. 3.83632624437e-6,
  583. -8.7518558668e-7,
  584. 2.0291515353e-7,
  585. -4.767795233e-8,
  586. 1.132844415e-8,
  587. -2.71734219e-9,
  588. 6.5714886e-10,
  589. -1.6005342e-10,
  590. 3.922557e-11,
  591. -9.66637e-12,
  592. 2.39379e-12,
  593. -5.9541e-13,
  594. 1.4868e-13,
  595. -3.726e-14,
  596. 9.37e-15,
  597. -2.36e-15,
  598. 6.0e-16
  599. };
  600. /* Chebyshev expansion: j_{nu,15} = c_k T_k*(nu/30), nu <= 30 */
  601. static const double coef_jnu15_a[] = {
  602. 67.7990939565631635,
  603. 20.9237219226859859,
  604. -0.45840871823085836,
  605. 0.06272149946755639,
  606. -0.01056229551143042,
  607. 0.00198445078693100,
  608. -0.00039903958650729,
  609. 0.00008404489865469,
  610. -0.00001830717574922,
  611. 4.09103745566e-6,
  612. -9.3275533309e-7,
  613. 2.1614056403e-7,
  614. -5.075725222e-8,
  615. 1.205352081e-8,
  616. -2.88971837e-9,
  617. 6.9846848e-10,
  618. -1.7002946e-10,
  619. 4.164941e-11,
  620. -1.025859e-11,
  621. 2.53921e-12,
  622. -6.3128e-13,
  623. 1.5757e-13,
  624. -3.947e-14,
  625. 9.92e-15,
  626. -2.50e-15,
  627. 6.3e-16
  628. };
  629. /* Chebyshev expansion: j_{nu,16} = c_k T_k*(nu/32), nu <= 32 */
  630. static const double coef_jnu16_a[] = {
  631. 72.3725729616724770,
  632. 22.32040402918608585,
  633. -0.48881449782358690,
  634. 0.06684305681828766,
  635. -0.01124998690363398,
  636. 0.00211247882775445,
  637. -0.00042455166484632,
  638. 0.00008937015316346,
  639. -0.00001945687139551,
  640. 4.34569739281e-6,
  641. -9.9031173548e-7,
  642. 2.2936247195e-7,
  643. -5.383562595e-8,
  644. 1.277835103e-8,
  645. -3.06202860e-9,
  646. 7.3977037e-10,
  647. -1.8000071e-10,
  648. 4.407196e-11,
  649. -1.085046e-11,
  650. 2.68453e-12,
  651. -6.6712e-13,
  652. 1.6644e-13,
  653. -4.168e-14,
  654. 1.047e-14,
  655. -2.64e-15,
  656. 6.7e-16
  657. };
  658. /* Chebyshev expansion: j_{nu,17} = c_k T_k*(nu/34), nu <= 34 */
  659. static const double coef_jnu17_a[] = {
  660. 76.9460667535209549,
  661. 23.71708159112252670,
  662. -0.51921943142405352,
  663. 0.07096442978067622,
  664. -0.01193763559341369,
  665. 0.00224049662974902,
  666. -0.00045006122941781,
  667. 0.00009469477941684,
  668. -0.00002060640777107,
  669. 4.60031647195e-6,
  670. -1.04785755046e-6,
  671. 2.4258161247e-7,
  672. -5.691327087e-8,
  673. 1.350298805e-8,
  674. -3.23428733e-9,
  675. 7.8105847e-10,
  676. -1.8996825e-10,
  677. 4.649350e-11,
  678. -1.144205e-11,
  679. 2.82979e-12,
  680. -7.0294e-13,
  681. 1.7531e-13,
  682. -4.388e-14,
  683. 1.102e-14,
  684. -2.78e-15,
  685. 7.0e-16
  686. };
  687. /* Chebyshev expansion: j_{nu,18} = c_k T_k*(nu/36), nu <= 36 */
  688. static const double coef_jnu18_a[] = {
  689. 81.5195728368096659,
  690. 25.11375537470259305,
  691. -0.54962366347317668,
  692. 0.07508565026117689,
  693. -0.01262524908033818,
  694. 0.00236850602019778,
  695. -0.00047556873651929,
  696. 0.00010001889347161,
  697. -0.00002175581482429,
  698. 4.85490251239e-6,
  699. -1.10539483940e-6,
  700. 2.5579853343e-7,
  701. -5.999033352e-8,
  702. 1.422747129e-8,
  703. -3.40650521e-9,
  704. 8.2233565e-10,
  705. -1.9993286e-10,
  706. 4.891426e-11,
  707. -1.203343e-11,
  708. 2.97498e-12,
  709. -7.3875e-13,
  710. 1.8418e-13,
  711. -4.608e-14,
  712. 1.157e-14,
  713. -2.91e-15,
  714. 7.4e-16
  715. };
  716. /* Chebyshev expansion: j_{nu,19} = c_k T_k*(nu/38), nu <= 38 */
  717. static const double coef_jnu19_a[] = {
  718. 86.0930892477047512,
  719. 26.51042598308271729,
  720. -0.58002730731948358,
  721. 0.07920674321589394,
  722. -0.01331283320930301,
  723. 0.00249650841778073,
  724. -0.00050107453900793,
  725. 0.00010534258471335,
  726. -0.00002290511552874,
  727. 5.10946148897e-6,
  728. -1.16292517157e-6,
  729. 2.6901365037e-7,
  730. -6.306692473e-8,
  731. 1.495183048e-8,
  732. -3.57869025e-9,
  733. 8.6360410e-10,
  734. -2.0989514e-10,
  735. 5.133439e-11,
  736. -1.262465e-11,
  737. 3.12013e-12,
  738. -7.7455e-13,
  739. 1.9304e-13,
  740. -4.829e-14,
  741. 1.212e-14,
  742. -3.05e-15,
  743. 7.7e-16
  744. };
  745. /* Chebyshev expansion: j_{nu,20} = c_k T_k*(nu/40), nu <= 40 */
  746. static const double coef_jnu20_a[] = {
  747. 90.6666144195163770,
  748. 27.9070938975436823,
  749. -0.61043045315390591,
  750. 0.08332772844325554,
  751. -0.01400039260208282,
  752. 0.00262450494035660,
  753. -0.00052657891389470,
  754. 0.00011066592304919,
  755. -0.00002405432778364,
  756. 5.36399803946e-6,
  757. -1.22044976064e-6,
  758. 2.8222728362e-7,
  759. -6.614312964e-8,
  760. 1.567608839e-8,
  761. -3.75084856e-9,
  762. 9.0486546e-10,
  763. -2.1985553e-10,
  764. 5.375401e-11,
  765. -1.321572e-11,
  766. 3.26524e-12,
  767. -8.1033e-13,
  768. 2.0190e-13,
  769. -5.049e-14,
  770. 1.267e-14,
  771. -3.19e-15,
  772. 8.0e-16,
  773. -2.0e-16
  774. };
  775. static const double * coef_jnu_a[] = {
  776. 0,
  777. coef_jnu1_a,
  778. coef_jnu2_a,
  779. coef_jnu3_a,
  780. coef_jnu4_a,
  781. coef_jnu5_a,
  782. coef_jnu6_a,
  783. coef_jnu7_a,
  784. coef_jnu8_a,
  785. coef_jnu9_a,
  786. coef_jnu10_a,
  787. coef_jnu11_a,
  788. coef_jnu12_a,
  789. coef_jnu13_a,
  790. coef_jnu14_a,
  791. coef_jnu15_a,
  792. coef_jnu16_a,
  793. coef_jnu17_a,
  794. coef_jnu18_a,
  795. coef_jnu19_a,
  796. coef_jnu20_a
  797. };
  798. static const size_t size_jnu_a[] = {
  799. 0,
  800. sizeof(coef_jnu1_a)/sizeof(double),
  801. sizeof(coef_jnu2_a)/sizeof(double),
  802. sizeof(coef_jnu3_a)/sizeof(double),
  803. sizeof(coef_jnu4_a)/sizeof(double),
  804. sizeof(coef_jnu5_a)/sizeof(double),
  805. sizeof(coef_jnu6_a)/sizeof(double),
  806. sizeof(coef_jnu7_a)/sizeof(double),
  807. sizeof(coef_jnu8_a)/sizeof(double),
  808. sizeof(coef_jnu9_a)/sizeof(double),
  809. sizeof(coef_jnu10_a)/sizeof(double),
  810. sizeof(coef_jnu11_a)/sizeof(double),
  811. sizeof(coef_jnu12_a)/sizeof(double),
  812. sizeof(coef_jnu13_a)/sizeof(double),
  813. sizeof(coef_jnu14_a)/sizeof(double),
  814. sizeof(coef_jnu15_a)/sizeof(double),
  815. sizeof(coef_jnu16_a)/sizeof(double),
  816. sizeof(coef_jnu17_a)/sizeof(double),
  817. sizeof(coef_jnu18_a)/sizeof(double),
  818. sizeof(coef_jnu19_a)/sizeof(double),
  819. sizeof(coef_jnu20_a)/sizeof(double)
  820. };
  821. static const double * coef_jnu_b[] = {
  822. 0,
  823. coef_jnu1_b,
  824. coef_jnu2_b,
  825. coef_jnu3_b,
  826. coef_jnu4_b,
  827. coef_jnu5_b,
  828. coef_jnu6_b,
  829. coef_jnu7_b,
  830. coef_jnu8_b,
  831. coef_jnu9_b,
  832. coef_jnu10_b
  833. };
  834. static const size_t size_jnu_b[] = {
  835. 0,
  836. sizeof(coef_jnu1_b)/sizeof(double),
  837. sizeof(coef_jnu2_b)/sizeof(double),
  838. sizeof(coef_jnu3_b)/sizeof(double),
  839. sizeof(coef_jnu4_b)/sizeof(double),
  840. sizeof(coef_jnu5_b)/sizeof(double),
  841. sizeof(coef_jnu6_b)/sizeof(double),
  842. sizeof(coef_jnu7_b)/sizeof(double),
  843. sizeof(coef_jnu8_b)/sizeof(double),
  844. sizeof(coef_jnu9_b)/sizeof(double),
  845. sizeof(coef_jnu10_b)/sizeof(double)
  846. };
  847. /* Evaluate Clenshaw recurrence for
  848. * a T* Chebyshev series.
  849. * sizeof(c) = N+1
  850. */
  851. static double
  852. clenshaw(const double * c, int N, double u)
  853. {
  854. double B_np1 = 0.0;
  855. double B_n = c[N];
  856. double B_nm1;
  857. int n;
  858. for(n=N; n>0; n--) {
  859. B_nm1 = 2.0*(2.0*u-1.0) * B_n - B_np1 + c[n-1];
  860. B_np1 = B_n;
  861. B_n = B_nm1;
  862. }
  863. return B_n - (2.0*u-1.0)*B_np1;
  864. }
  865. /* correction terms to leading McMahon expansion
  866. * [Abramowitz+Stegun 9.5.12]
  867. * [Olver, Royal Society Math. Tables, v. 7]
  868. * We factor out a beta, so that this is a multiplicative
  869. * correction:
  870. * j_{nu,s} = beta(s,nu) * mcmahon_correction(nu, beta(s,nu))
  871. * macmahon_correction --> 1 as s --> Inf
  872. */
  873. static double
  874. mcmahon_correction(const double mu, const double beta)
  875. {
  876. const double eb = 8.0*beta;
  877. const double ebsq = eb*eb;
  878. if(mu < GSL_DBL_EPSILON) {
  879. /* Prevent division by zero below. */
  880. const double term1 = 1.0/ebsq;
  881. const double term2 = -4.0*31.0/(3*ebsq*ebsq);
  882. const double term3 = 32.0*3779.0/(15.0*ebsq*ebsq*ebsq);
  883. const double term4 = -64.0*6277237.0/(105.0*ebsq*ebsq*ebsq*ebsq);
  884. const double term5 = 512.0*2092163573.0/(315.0*ebsq*ebsq*ebsq*ebsq*ebsq);
  885. return 1.0 + 8.0*(term1 + term2 + term3 + term4 + term5);
  886. }
  887. else {
  888. /* Here we do things in terms of 1/mu, which
  889. * is purely to prevent overflow in the very
  890. * unlikely case that mu is really big.
  891. */
  892. const double mi = 1.0/mu;
  893. const double r = mu/ebsq;
  894. const double n2 = 4.0/3.0 * (7.0 - 31.0*mi);
  895. const double n3 = 32.0/15.0 * (83.0 + (-982.0 + 3779.0*mi)*mi);
  896. const double n4 = 64.0/105.0 * (6949.0 + (-153855.0 + (1585743.0 - 6277237.0*mi)*mi)*mi);
  897. const double n5 = 512.0/315.0 * (70197.0 + (-2479316.0 + (48010494.0 + (-512062548.0 + 2092163573.0*mi)*mi)*mi)*mi);
  898. const double n6 = 2048.0/3465.0 * (5592657.0 + (-287149133.0 + (8903961290.0 + (-179289628602.0 + (1982611456181.0 - 8249725736393.0*mi)*mi)*mi)*mi)*mi);
  899. const double term1 = (1.0 - mi) * r;
  900. const double term2 = term1 * n2 * r;
  901. const double term3 = term1 * n3 * r*r;
  902. const double term4 = term1 * n4 * r*r*r;
  903. const double term5 = term1 * n5 * r*r*r*r;
  904. const double term6 = term1 * n6 * r*r*r*r*r;
  905. return 1.0 - 8.0*(term1 + term2 + term3 + term4 + term5 + term6);
  906. }
  907. }
  908. /* Assumes z >= 1.0 */
  909. static double
  910. olver_b0(double z, double minus_zeta)
  911. {
  912. if(z < 1.02) {
  913. const double a = 1.0-z;
  914. const double c0 = 0.0179988721413553309252458658183;
  915. const double c1 = 0.0111992982212877614645974276203;
  916. const double c2 = 0.0059404069786014304317781160605;
  917. const double c3 = 0.0028676724516390040844556450173;
  918. const double c4 = 0.0012339189052567271708525111185;
  919. const double c5 = 0.0004169250674535178764734660248;
  920. const double c6 = 0.0000330173385085949806952777365;
  921. const double c7 = -0.0001318076238578203009990106425;
  922. const double c8 = -0.0001906870370050847239813945647;
  923. return c0 + a*(c1 + a*(c2 + a*(c3 + a*(c4 + a*(c5 + a*(c6 + a*(c7 + a*c8)))))));
  924. }
  925. else {
  926. const double abs_zeta = minus_zeta;
  927. const double t = 1.0/(z*sqrt(1.0 - 1.0/(z*z)));
  928. return -5.0/(48.0*abs_zeta*abs_zeta) + t*(3.0 + 5.0*t*t)/(24.0*sqrt(abs_zeta));
  929. }
  930. }
  931. inline
  932. static double
  933. olver_f1(double z, double minus_zeta)
  934. {
  935. const double b0 = olver_b0(z, minus_zeta);
  936. const double h2 = sqrt(4.0*minus_zeta/(z*z-1.0)); /* FIXME */
  937. return 0.5 * z * h2 * b0;
  938. }
  939. int
  940. gsl_sf_bessel_zero_J0_e(unsigned int s, gsl_sf_result * result)
  941. {
  942. /* CHECK_POINTER(result) */
  943. if(s == 0){
  944. result->val = 0.0;
  945. result->err = 0.0;
  946. GSL_ERROR ("error", GSL_EINVAL);
  947. }
  948. else {
  949. /* See [F. Lether, J. Comp. Appl .Math. 67, 167 (1996)]. */
  950. static const double P[] = { 1567450796.0/12539606369.0,
  951. 8903660.0/2365861.0,
  952. 10747040.0/536751.0,
  953. 17590991.0/1696654.0
  954. };
  955. static const double Q[] = { 1.0,
  956. 29354255.0/954518.0,
  957. 76900001.0/431847.0,
  958. 67237052.0/442411.0
  959. };
  960. const double beta = (s - 0.25) * M_PI;
  961. const double bi2 = 1.0/(beta*beta);
  962. const double R33num = P[0] + bi2 * (P[1] + bi2 * (P[2] + P[3] * bi2));
  963. const double R33den = Q[0] + bi2 * (Q[1] + bi2 * (Q[2] + Q[3] * bi2));
  964. const double R33 = R33num/R33den;
  965. result->val = beta + R33/beta;
  966. result->err = fabs(3.0e-15 * result->val);
  967. return GSL_SUCCESS;
  968. }
  969. }
  970. int
  971. gsl_sf_bessel_zero_J1_e(unsigned int s, gsl_sf_result * result)
  972. {
  973. /* CHECK_POINTER(result) */
  974. if(s == 0) {
  975. result->val = 0.0;
  976. result->err = 0.0;
  977. return GSL_SUCCESS;
  978. }
  979. else {
  980. /* See [M. Branders et al., J. Comp. Phys. 42, 403 (1981)]. */
  981. static const double a[] = { -0.362804405737084,
  982. 0.120341279038597,
  983. 0.439454547101171e-01,
  984. 0.159340088474713e-02
  985. };
  986. static const double b[] = { 1.0,
  987. -0.325641790801361,
  988. -0.117453445968927,
  989. -0.424906902601794e-02
  990. };
  991. const double beta = (s + 0.25) * M_PI;
  992. const double bi2 = 1.0/(beta*beta);
  993. const double Rnum = a[3] + bi2 * (a[2] + bi2 * (a[1] + bi2 * a[0]));
  994. const double Rden = b[3] + bi2 * (b[2] + bi2 * (b[1] + bi2 * b[0]));
  995. const double R = Rnum/Rden;
  996. result->val = beta * (1.0 + R*bi2);
  997. result->err = fabs(2.0e-14 * result->val);
  998. return GSL_SUCCESS;
  999. }
  1000. }
  1001. int
  1002. gsl_sf_bessel_zero_Jnu_e(double nu, unsigned int s, gsl_sf_result * result)
  1003. {
  1004. /* CHECK_POINTER(result) */
  1005. if(nu <= -1.0) {
  1006. DOMAIN_ERROR(result);
  1007. }
  1008. else if(s == 0) {
  1009. result->val = 0.0;
  1010. result->err = 0.0;
  1011. if (nu == 0.0) {
  1012. GSL_ERROR ("no zero-th root for nu = 0.0", GSL_EINVAL);
  1013. }
  1014. return GSL_SUCCESS;
  1015. }
  1016. else if(nu < 0.0) {
  1017. /* This can be done, I'm just lazy now. */
  1018. result->val = 0.0;
  1019. result->err = 0.0;
  1020. GSL_ERROR("unimplemented", GSL_EUNIMPL);
  1021. }
  1022. else if(s == 1) {
  1023. /* Chebyshev fits for the first positive zero.
  1024. * For some reason Nemeth made this different from the others.
  1025. */
  1026. if(nu < 2.0) {
  1027. const double * c = coef_jnu_a[s];
  1028. const size_t L = size_jnu_a[s];
  1029. const double arg = nu/2.0;
  1030. const double chb = clenshaw(c, L-1, arg);
  1031. result->val = chb;
  1032. result->err = 2.0e-15 * result->val;
  1033. }
  1034. else {
  1035. const double * c = coef_jnu_b[s];
  1036. const size_t L = size_jnu_b[s];
  1037. const double arg = pow(2.0/nu, 2.0/3.0);
  1038. const double chb = clenshaw(c, L-1, arg);
  1039. result->val = nu * chb;
  1040. result->err = 2.0e-15 * result->val;
  1041. }
  1042. return GSL_SUCCESS;
  1043. }
  1044. else if(s <= 10) {
  1045. /* Chebyshev fits for the first 10 positive zeros. */
  1046. if(nu < s) {
  1047. const double * c = coef_jnu_a[s];
  1048. const size_t L = size_jnu_a[s];
  1049. const double arg = nu/s;
  1050. const double chb = clenshaw(c, L-1, arg);
  1051. result->val = chb;
  1052. result->err = 2.0e-15 * result->val;
  1053. }
  1054. else {
  1055. const double * c = coef_jnu_b[s];
  1056. const size_t L = size_jnu_b[s];
  1057. const double arg = pow(s/nu, 2.0/3.0);
  1058. const double chb = clenshaw(c, L-1, arg);
  1059. result->val = nu * chb;
  1060. result->err = 2.0e-15 * result->val;
  1061. /* FIXME: truth in advertising for the screwed up
  1062. * s = 5 fit. Need to fix that.
  1063. */
  1064. if(s == 5) {
  1065. result->err *= 5.0e+06;
  1066. }
  1067. }
  1068. return GSL_SUCCESS;
  1069. }
  1070. else if(s > 0.5*nu && s <= 20) {
  1071. /* Chebyshev fits for 10 < s <= 20. */
  1072. const double * c = coef_jnu_a[s];
  1073. const size_t L = size_jnu_a[s];
  1074. const double arg = nu/(2.0*s);
  1075. const double chb = clenshaw(c, L-1, arg);
  1076. result->val = chb;
  1077. result->err = 4.0e-15 * chb;
  1078. return GSL_SUCCESS;
  1079. }
  1080. else if(s > 2.0 * nu) {
  1081. /* McMahon expansion if s is large compared to nu. */
  1082. const double beta = (s + 0.5*nu - 0.25) * M_PI;
  1083. const double mc = mcmahon_correction(4.0*nu*nu, beta);
  1084. gsl_sf_result rat12;
  1085. gsl_sf_pow_int_e(nu/beta, 14, &rat12);
  1086. result->val = beta * mc;
  1087. result->err = 4.0 * fabs(beta) * rat12.val;
  1088. result->err += 4.0 * fabs(GSL_DBL_EPSILON * result->val);
  1089. return GSL_SUCCESS;
  1090. }
  1091. else {
  1092. /* Olver uniform asymptotic. */
  1093. gsl_sf_result as;
  1094. const int stat_as = gsl_sf_airy_zero_Ai_e(s, &as);
  1095. const double minus_zeta = -pow(nu,-2.0/3.0) * as.val;
  1096. const double z = gsl_sf_bessel_Olver_zofmzeta(minus_zeta);
  1097. const double f1 = olver_f1(z, minus_zeta);
  1098. result->val = nu * (z + f1/(nu*nu));
  1099. result->err = 0.001/(nu*nu*nu);
  1100. result->err += 2.0 * GSL_DBL_EPSILON * fabs(result->val);
  1101. return stat_as;
  1102. }
  1103. }
  1104. /*-*-*-*-*-*-*-*-*-* Functions w/ Natural Prototypes *-*-*-*-*-*-*-*-*-*-*/
  1105. #include "gsl_specfunc__eval.h"
  1106. double gsl_sf_bessel_zero_J0(unsigned int s)
  1107. {
  1108. EVAL_RESULT(gsl_sf_bessel_zero_J0_e(s, &result));
  1109. }
  1110. double gsl_sf_bessel_zero_J1(unsigned int s)
  1111. {
  1112. EVAL_RESULT(gsl_sf_bessel_zero_J1_e(s, &result));
  1113. }
  1114. double gsl_sf_bessel_zero_Jnu(double nu, unsigned int s)
  1115. {
  1116. EVAL_RESULT(gsl_sf_bessel_zero_Jnu_e(nu, s, &result));
  1117. }