bessel.py 37 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108
  1. from .functions import defun, defun_wrapped
  2. @defun
  3. def j0(ctx, x):
  4. """Computes the Bessel function `J_0(x)`. See :func:`~mpmath.besselj`."""
  5. return ctx.besselj(0, x)
  6. @defun
  7. def j1(ctx, x):
  8. """Computes the Bessel function `J_1(x)`. See :func:`~mpmath.besselj`."""
  9. return ctx.besselj(1, x)
  10. @defun
  11. def besselj(ctx, n, z, derivative=0, **kwargs):
  12. if type(n) is int:
  13. n_isint = True
  14. else:
  15. n = ctx.convert(n)
  16. n_isint = ctx.isint(n)
  17. if n_isint:
  18. n = int(ctx._re(n))
  19. if n_isint and n < 0:
  20. return (-1)**n * ctx.besselj(-n, z, derivative, **kwargs)
  21. z = ctx.convert(z)
  22. M = ctx.mag(z)
  23. if derivative:
  24. d = ctx.convert(derivative)
  25. # TODO: the integer special-casing shouldn't be necessary.
  26. # However, the hypergeometric series gets inaccurate for large d
  27. # because of inaccurate pole cancellation at a pole far from
  28. # zero (needs to be fixed in hypercomb or hypsum)
  29. if ctx.isint(d) and d >= 0:
  30. d = int(d)
  31. orig = ctx.prec
  32. try:
  33. ctx.prec += 15
  34. v = ctx.fsum((-1)**k * ctx.binomial(d,k) * ctx.besselj(2*k+n-d,z)
  35. for k in range(d+1))
  36. finally:
  37. ctx.prec = orig
  38. v *= ctx.mpf(2)**(-d)
  39. else:
  40. def h(n,d):
  41. r = ctx.fmul(ctx.fmul(z, z, prec=ctx.prec+M), -0.25, exact=True)
  42. B = [0.5*(n-d+1), 0.5*(n-d+2)]
  43. T = [([2,ctx.pi,z],[d-2*n,0.5,n-d],[],B,[(n+1)*0.5,(n+2)*0.5],B+[n+1],r)]
  44. return T
  45. v = ctx.hypercomb(h, [n,d], **kwargs)
  46. else:
  47. # Fast case: J_n(x), n int, appropriate magnitude for fixed-point calculation
  48. if (not derivative) and n_isint and abs(M) < 10 and abs(n) < 20:
  49. try:
  50. return ctx._besselj(n, z)
  51. except NotImplementedError:
  52. pass
  53. if not z:
  54. if not n:
  55. v = ctx.one + n+z
  56. elif ctx.re(n) > 0:
  57. v = n*z
  58. else:
  59. v = ctx.inf + z + n
  60. else:
  61. #v = 0
  62. orig = ctx.prec
  63. try:
  64. # XXX: workaround for accuracy in low level hypergeometric series
  65. # when alternating, large arguments
  66. ctx.prec += min(3*abs(M), ctx.prec)
  67. w = ctx.fmul(z, 0.5, exact=True)
  68. def h(n):
  69. r = ctx.fneg(ctx.fmul(w, w, prec=max(0,ctx.prec+M)), exact=True)
  70. return [([w], [n], [], [n+1], [], [n+1], r)]
  71. v = ctx.hypercomb(h, [n], **kwargs)
  72. finally:
  73. ctx.prec = orig
  74. v = +v
  75. return v
  76. @defun
  77. def besseli(ctx, n, z, derivative=0, **kwargs):
  78. n = ctx.convert(n)
  79. z = ctx.convert(z)
  80. if not z:
  81. if derivative:
  82. raise ValueError
  83. if not n:
  84. # I(0,0) = 1
  85. return 1+n+z
  86. if ctx.isint(n):
  87. return 0*(n+z)
  88. r = ctx.re(n)
  89. if r == 0:
  90. return ctx.nan*(n+z)
  91. elif r > 0:
  92. return 0*(n+z)
  93. else:
  94. return ctx.inf+(n+z)
  95. M = ctx.mag(z)
  96. if derivative:
  97. d = ctx.convert(derivative)
  98. def h(n,d):
  99. r = ctx.fmul(ctx.fmul(z, z, prec=ctx.prec+M), 0.25, exact=True)
  100. B = [0.5*(n-d+1), 0.5*(n-d+2), n+1]
  101. T = [([2,ctx.pi,z],[d-2*n,0.5,n-d],[n+1],B,[(n+1)*0.5,(n+2)*0.5],B,r)]
  102. return T
  103. v = ctx.hypercomb(h, [n,d], **kwargs)
  104. else:
  105. def h(n):
  106. w = ctx.fmul(z, 0.5, exact=True)
  107. r = ctx.fmul(w, w, prec=max(0,ctx.prec+M))
  108. return [([w], [n], [], [n+1], [], [n+1], r)]
  109. v = ctx.hypercomb(h, [n], **kwargs)
  110. return v
  111. @defun_wrapped
  112. def bessely(ctx, n, z, derivative=0, **kwargs):
  113. if not z:
  114. if derivative:
  115. # Not implemented
  116. raise ValueError
  117. if not n:
  118. # ~ log(z/2)
  119. return -ctx.inf + (n+z)
  120. if ctx.im(n):
  121. return ctx.nan * (n+z)
  122. r = ctx.re(n)
  123. q = n+0.5
  124. if ctx.isint(q):
  125. if n > 0:
  126. return -ctx.inf + (n+z)
  127. else:
  128. return 0 * (n+z)
  129. if r < 0 and int(ctx.floor(q)) % 2:
  130. return ctx.inf + (n+z)
  131. else:
  132. return ctx.ninf + (n+z)
  133. # XXX: use hypercomb
  134. ctx.prec += 10
  135. m, d = ctx.nint_distance(n)
  136. if d < -ctx.prec:
  137. h = +ctx.eps
  138. ctx.prec *= 2
  139. n += h
  140. elif d < 0:
  141. ctx.prec -= d
  142. # TODO: avoid cancellation for imaginary arguments
  143. cos, sin = ctx.cospi_sinpi(n)
  144. return (ctx.besselj(n,z,derivative,**kwargs)*cos - \
  145. ctx.besselj(-n,z,derivative,**kwargs))/sin
  146. @defun_wrapped
  147. def besselk(ctx, n, z, **kwargs):
  148. if not z:
  149. return ctx.inf
  150. M = ctx.mag(z)
  151. if M < 1:
  152. # Represent as limit definition
  153. def h(n):
  154. r = (z/2)**2
  155. T1 = [z, 2], [-n, n-1], [n], [], [], [1-n], r
  156. T2 = [z, 2], [n, -n-1], [-n], [], [], [1+n], r
  157. return T1, T2
  158. # We could use the limit definition always, but it leads
  159. # to very bad cancellation (of exponentially large terms)
  160. # for large real z
  161. # Instead represent in terms of 2F0
  162. else:
  163. ctx.prec += M
  164. def h(n):
  165. return [([ctx.pi/2, z, ctx.exp(-z)], [0.5,-0.5,1], [], [], \
  166. [n+0.5, 0.5-n], [], -1/(2*z))]
  167. return ctx.hypercomb(h, [n], **kwargs)
  168. @defun_wrapped
  169. def hankel1(ctx,n,x,**kwargs):
  170. return ctx.besselj(n,x,**kwargs) + ctx.j*ctx.bessely(n,x,**kwargs)
  171. @defun_wrapped
  172. def hankel2(ctx,n,x,**kwargs):
  173. return ctx.besselj(n,x,**kwargs) - ctx.j*ctx.bessely(n,x,**kwargs)
  174. @defun_wrapped
  175. def whitm(ctx,k,m,z,**kwargs):
  176. if z == 0:
  177. # M(k,m,z) = 0^(1/2+m)
  178. if ctx.re(m) > -0.5:
  179. return z
  180. elif ctx.re(m) < -0.5:
  181. return ctx.inf + z
  182. else:
  183. return ctx.nan * z
  184. x = ctx.fmul(-0.5, z, exact=True)
  185. y = 0.5+m
  186. return ctx.exp(x) * z**y * ctx.hyp1f1(y-k, 1+2*m, z, **kwargs)
  187. @defun_wrapped
  188. def whitw(ctx,k,m,z,**kwargs):
  189. if z == 0:
  190. g = abs(ctx.re(m))
  191. if g < 0.5:
  192. return z
  193. elif g > 0.5:
  194. return ctx.inf + z
  195. else:
  196. return ctx.nan * z
  197. x = ctx.fmul(-0.5, z, exact=True)
  198. y = 0.5+m
  199. return ctx.exp(x) * z**y * ctx.hyperu(y-k, 1+2*m, z, **kwargs)
  200. @defun
  201. def hyperu(ctx, a, b, z, **kwargs):
  202. a, atype = ctx._convert_param(a)
  203. b, btype = ctx._convert_param(b)
  204. z = ctx.convert(z)
  205. if not z:
  206. if ctx.re(b) <= 1:
  207. return ctx.gammaprod([1-b],[a-b+1])
  208. else:
  209. return ctx.inf + z
  210. bb = 1+a-b
  211. bb, bbtype = ctx._convert_param(bb)
  212. try:
  213. orig = ctx.prec
  214. try:
  215. ctx.prec += 10
  216. v = ctx.hypsum(2, 0, (atype, bbtype), [a, bb], -1/z, maxterms=ctx.prec)
  217. return v / z**a
  218. finally:
  219. ctx.prec = orig
  220. except ctx.NoConvergence:
  221. pass
  222. def h(a,b):
  223. w = ctx.sinpi(b)
  224. T1 = ([ctx.pi,w],[1,-1],[],[a-b+1,b],[a],[b],z)
  225. T2 = ([-ctx.pi,w,z],[1,-1,1-b],[],[a,2-b],[a-b+1],[2-b],z)
  226. return T1, T2
  227. return ctx.hypercomb(h, [a,b], **kwargs)
  228. @defun
  229. def struveh(ctx,n,z, **kwargs):
  230. n = ctx.convert(n)
  231. z = ctx.convert(z)
  232. # http://functions.wolfram.com/Bessel-TypeFunctions/StruveH/26/01/02/
  233. def h(n):
  234. return [([z/2, 0.5*ctx.sqrt(ctx.pi)], [n+1, -1], [], [n+1.5], [1], [1.5, n+1.5], -(z/2)**2)]
  235. return ctx.hypercomb(h, [n], **kwargs)
  236. @defun
  237. def struvel(ctx,n,z, **kwargs):
  238. n = ctx.convert(n)
  239. z = ctx.convert(z)
  240. # http://functions.wolfram.com/Bessel-TypeFunctions/StruveL/26/01/02/
  241. def h(n):
  242. return [([z/2, 0.5*ctx.sqrt(ctx.pi)], [n+1, -1], [], [n+1.5], [1], [1.5, n+1.5], (z/2)**2)]
  243. return ctx.hypercomb(h, [n], **kwargs)
  244. def _anger(ctx,which,v,z,**kwargs):
  245. v = ctx._convert_param(v)[0]
  246. z = ctx.convert(z)
  247. def h(v):
  248. b = ctx.mpq_1_2
  249. u = v*b
  250. m = b*3
  251. a1,a2,b1,b2 = m-u, m+u, 1-u, 1+u
  252. c, s = ctx.cospi_sinpi(u)
  253. if which == 0:
  254. A, B = [b*z, s], [c]
  255. if which == 1:
  256. A, B = [b*z, -c], [s]
  257. w = ctx.square_exp_arg(z, mult=-0.25)
  258. T1 = A, [1, 1], [], [a1,a2], [1], [a1,a2], w
  259. T2 = B, [1], [], [b1,b2], [1], [b1,b2], w
  260. return T1, T2
  261. return ctx.hypercomb(h, [v], **kwargs)
  262. @defun
  263. def angerj(ctx, v, z, **kwargs):
  264. return _anger(ctx, 0, v, z, **kwargs)
  265. @defun
  266. def webere(ctx, v, z, **kwargs):
  267. return _anger(ctx, 1, v, z, **kwargs)
  268. @defun
  269. def lommels1(ctx, u, v, z, **kwargs):
  270. u = ctx._convert_param(u)[0]
  271. v = ctx._convert_param(v)[0]
  272. z = ctx.convert(z)
  273. def h(u,v):
  274. b = ctx.mpq_1_2
  275. w = ctx.square_exp_arg(z, mult=-0.25)
  276. return ([u-v+1, u+v+1, z], [-1, -1, u+1], [], [], [1], \
  277. [b*(u-v+3),b*(u+v+3)], w),
  278. return ctx.hypercomb(h, [u,v], **kwargs)
  279. @defun
  280. def lommels2(ctx, u, v, z, **kwargs):
  281. u = ctx._convert_param(u)[0]
  282. v = ctx._convert_param(v)[0]
  283. z = ctx.convert(z)
  284. # Asymptotic expansion (GR p. 947) -- need to be careful
  285. # not to use for small arguments
  286. # def h(u,v):
  287. # b = ctx.mpq_1_2
  288. # w = -(z/2)**(-2)
  289. # return ([z], [u-1], [], [], [b*(1-u+v)], [b*(1-u-v)], w),
  290. def h(u,v):
  291. b = ctx.mpq_1_2
  292. w = ctx.square_exp_arg(z, mult=-0.25)
  293. T1 = [u-v+1, u+v+1, z], [-1, -1, u+1], [], [], [1], [b*(u-v+3),b*(u+v+3)], w
  294. T2 = [2, z], [u+v-1, -v], [v, b*(u+v+1)], [b*(v-u+1)], [], [1-v], w
  295. T3 = [2, z], [u-v-1, v], [-v, b*(u-v+1)], [b*(1-u-v)], [], [1+v], w
  296. #c1 = ctx.cospi((u-v)*b)
  297. #c2 = ctx.cospi((u+v)*b)
  298. #s = ctx.sinpi(v)
  299. #r1 = (u-v+1)*b
  300. #r2 = (u+v+1)*b
  301. #T2 = [c1, s, z, 2], [1, -1, -v, v], [], [-v+1], [], [-v+1], w
  302. #T3 = [-c2, s, z, 2], [1, -1, v, -v], [], [v+1], [], [v+1], w
  303. #T2 = [c1, s, z, 2], [1, -1, -v, v+u-1], [r1, r2], [-v+1], [], [-v+1], w
  304. #T3 = [-c2, s, z, 2], [1, -1, v, -v+u-1], [r1, r2], [v+1], [], [v+1], w
  305. return T1, T2, T3
  306. return ctx.hypercomb(h, [u,v], **kwargs)
  307. @defun
  308. def ber(ctx, n, z, **kwargs):
  309. n = ctx.convert(n)
  310. z = ctx.convert(z)
  311. # http://functions.wolfram.com/Bessel-TypeFunctions/KelvinBer2/26/01/02/0001/
  312. def h(n):
  313. r = -(z/4)**4
  314. cos, sin = ctx.cospi_sinpi(-0.75*n)
  315. T1 = [cos, z/2], [1, n], [], [n+1], [], [0.5, 0.5*(n+1), 0.5*n+1], r
  316. T2 = [sin, z/2], [1, n+2], [], [n+2], [], [1.5, 0.5*(n+3), 0.5*n+1], r
  317. return T1, T2
  318. return ctx.hypercomb(h, [n], **kwargs)
  319. @defun
  320. def bei(ctx, n, z, **kwargs):
  321. n = ctx.convert(n)
  322. z = ctx.convert(z)
  323. # http://functions.wolfram.com/Bessel-TypeFunctions/KelvinBei2/26/01/02/0001/
  324. def h(n):
  325. r = -(z/4)**4
  326. cos, sin = ctx.cospi_sinpi(0.75*n)
  327. T1 = [cos, z/2], [1, n+2], [], [n+2], [], [1.5, 0.5*(n+3), 0.5*n+1], r
  328. T2 = [sin, z/2], [1, n], [], [n+1], [], [0.5, 0.5*(n+1), 0.5*n+1], r
  329. return T1, T2
  330. return ctx.hypercomb(h, [n], **kwargs)
  331. @defun
  332. def ker(ctx, n, z, **kwargs):
  333. n = ctx.convert(n)
  334. z = ctx.convert(z)
  335. # http://functions.wolfram.com/Bessel-TypeFunctions/KelvinKer2/26/01/02/0001/
  336. def h(n):
  337. r = -(z/4)**4
  338. cos1, sin1 = ctx.cospi_sinpi(0.25*n)
  339. cos2, sin2 = ctx.cospi_sinpi(0.75*n)
  340. T1 = [2, z, 4*cos1], [-n-3, n, 1], [-n], [], [], [0.5, 0.5*(1+n), 0.5*(n+2)], r
  341. T2 = [2, z, -sin1], [-n-3, 2+n, 1], [-n-1], [], [], [1.5, 0.5*(3+n), 0.5*(n+2)], r
  342. T3 = [2, z, 4*cos2], [n-3, -n, 1], [n], [], [], [0.5, 0.5*(1-n), 1-0.5*n], r
  343. T4 = [2, z, -sin2], [n-3, 2-n, 1], [n-1], [], [], [1.5, 0.5*(3-n), 1-0.5*n], r
  344. return T1, T2, T3, T4
  345. return ctx.hypercomb(h, [n], **kwargs)
  346. @defun
  347. def kei(ctx, n, z, **kwargs):
  348. n = ctx.convert(n)
  349. z = ctx.convert(z)
  350. # http://functions.wolfram.com/Bessel-TypeFunctions/KelvinKei2/26/01/02/0001/
  351. def h(n):
  352. r = -(z/4)**4
  353. cos1, sin1 = ctx.cospi_sinpi(0.75*n)
  354. cos2, sin2 = ctx.cospi_sinpi(0.25*n)
  355. T1 = [-cos1, 2, z], [1, n-3, 2-n], [n-1], [], [], [1.5, 0.5*(3-n), 1-0.5*n], r
  356. T2 = [-sin1, 2, z], [1, n-1, -n], [n], [], [], [0.5, 0.5*(1-n), 1-0.5*n], r
  357. T3 = [-sin2, 2, z], [1, -n-1, n], [-n], [], [], [0.5, 0.5*(n+1), 0.5*(n+2)], r
  358. T4 = [-cos2, 2, z], [1, -n-3, n+2], [-n-1], [], [], [1.5, 0.5*(n+3), 0.5*(n+2)], r
  359. return T1, T2, T3, T4
  360. return ctx.hypercomb(h, [n], **kwargs)
  361. # TODO: do this more generically?
  362. def c_memo(f):
  363. name = f.__name__
  364. def f_wrapped(ctx):
  365. cache = ctx._misc_const_cache
  366. prec = ctx.prec
  367. p,v = cache.get(name, (-1,0))
  368. if p >= prec:
  369. return +v
  370. else:
  371. cache[name] = (prec, f(ctx))
  372. return cache[name][1]
  373. return f_wrapped
  374. @c_memo
  375. def _airyai_C1(ctx):
  376. return 1 / (ctx.cbrt(9) * ctx.gamma(ctx.mpf(2)/3))
  377. @c_memo
  378. def _airyai_C2(ctx):
  379. return -1 / (ctx.cbrt(3) * ctx.gamma(ctx.mpf(1)/3))
  380. @c_memo
  381. def _airybi_C1(ctx):
  382. return 1 / (ctx.nthroot(3,6) * ctx.gamma(ctx.mpf(2)/3))
  383. @c_memo
  384. def _airybi_C2(ctx):
  385. return ctx.nthroot(3,6) / ctx.gamma(ctx.mpf(1)/3)
  386. def _airybi_n2_inf(ctx):
  387. prec = ctx.prec
  388. try:
  389. v = ctx.power(3,'2/3')*ctx.gamma('2/3')/(2*ctx.pi)
  390. finally:
  391. ctx.prec = prec
  392. return +v
  393. # Derivatives at z = 0
  394. # TODO: could be expressed more elegantly using triple factorials
  395. def _airyderiv_0(ctx, z, n, ntype, which):
  396. if ntype == 'Z':
  397. if n < 0:
  398. return z
  399. r = ctx.mpq_1_3
  400. prec = ctx.prec
  401. try:
  402. ctx.prec += 10
  403. v = ctx.gamma((n+1)*r) * ctx.power(3,n*r) / ctx.pi
  404. if which == 0:
  405. v *= ctx.sinpi(2*(n+1)*r)
  406. v /= ctx.power(3,'2/3')
  407. else:
  408. v *= abs(ctx.sinpi(2*(n+1)*r))
  409. v /= ctx.power(3,'1/6')
  410. finally:
  411. ctx.prec = prec
  412. return +v + z
  413. else:
  414. # singular (does the limit exist?)
  415. raise NotImplementedError
  416. @defun
  417. def airyai(ctx, z, derivative=0, **kwargs):
  418. z = ctx.convert(z)
  419. if derivative:
  420. n, ntype = ctx._convert_param(derivative)
  421. else:
  422. n = 0
  423. # Values at infinities
  424. if not ctx.isnormal(z) and z:
  425. if n and ntype == 'Z':
  426. if n == -1:
  427. if z == ctx.inf:
  428. return ctx.mpf(1)/3 + 1/z
  429. if z == ctx.ninf:
  430. return ctx.mpf(-2)/3 + 1/z
  431. if n < -1:
  432. if z == ctx.inf:
  433. return z
  434. if z == ctx.ninf:
  435. return (-1)**n * (-z)
  436. if (not n) and z == ctx.inf or z == ctx.ninf:
  437. return 1/z
  438. # TODO: limits
  439. raise ValueError("essential singularity of Ai(z)")
  440. # Account for exponential scaling
  441. if z:
  442. extraprec = max(0, int(1.5*ctx.mag(z)))
  443. else:
  444. extraprec = 0
  445. if n:
  446. if n == 1:
  447. def h():
  448. # http://functions.wolfram.com/03.07.06.0005.01
  449. if ctx._re(z) > 4:
  450. ctx.prec += extraprec
  451. w = z**1.5; r = -0.75/w; u = -2*w/3
  452. ctx.prec -= extraprec
  453. C = -ctx.exp(u)/(2*ctx.sqrt(ctx.pi))*ctx.nthroot(z,4)
  454. return ([C],[1],[],[],[(-1,6),(7,6)],[],r),
  455. # http://functions.wolfram.com/03.07.26.0001.01
  456. else:
  457. ctx.prec += extraprec
  458. w = z**3 / 9
  459. ctx.prec -= extraprec
  460. C1 = _airyai_C1(ctx) * 0.5
  461. C2 = _airyai_C2(ctx)
  462. T1 = [C1,z],[1,2],[],[],[],[ctx.mpq_5_3],w
  463. T2 = [C2],[1],[],[],[],[ctx.mpq_1_3],w
  464. return T1, T2
  465. return ctx.hypercomb(h, [], **kwargs)
  466. else:
  467. if z == 0:
  468. return _airyderiv_0(ctx, z, n, ntype, 0)
  469. # http://functions.wolfram.com/03.05.20.0004.01
  470. def h(n):
  471. ctx.prec += extraprec
  472. w = z**3/9
  473. ctx.prec -= extraprec
  474. q13,q23,q43 = ctx.mpq_1_3, ctx.mpq_2_3, ctx.mpq_4_3
  475. a1=q13; a2=1; b1=(1-n)*q13; b2=(2-n)*q13; b3=1-n*q13
  476. T1 = [3, z], [n-q23, -n], [a1], [b1,b2,b3], \
  477. [a1,a2], [b1,b2,b3], w
  478. a1=q23; b1=(2-n)*q13; b2=1-n*q13; b3=(4-n)*q13
  479. T2 = [3, z, -z], [n-q43, -n, 1], [a1], [b1,b2,b3], \
  480. [a1,a2], [b1,b2,b3], w
  481. return T1, T2
  482. v = ctx.hypercomb(h, [n], **kwargs)
  483. if ctx._is_real_type(z) and ctx.isint(n):
  484. v = ctx._re(v)
  485. return v
  486. else:
  487. def h():
  488. if ctx._re(z) > 4:
  489. # We could use 1F1, but it results in huge cancellation;
  490. # the following expansion is better.
  491. # TODO: asymptotic series for derivatives
  492. ctx.prec += extraprec
  493. w = z**1.5; r = -0.75/w; u = -2*w/3
  494. ctx.prec -= extraprec
  495. C = ctx.exp(u)/(2*ctx.sqrt(ctx.pi)*ctx.nthroot(z,4))
  496. return ([C],[1],[],[],[(1,6),(5,6)],[],r),
  497. else:
  498. ctx.prec += extraprec
  499. w = z**3 / 9
  500. ctx.prec -= extraprec
  501. C1 = _airyai_C1(ctx)
  502. C2 = _airyai_C2(ctx)
  503. T1 = [C1],[1],[],[],[],[ctx.mpq_2_3],w
  504. T2 = [z*C2],[1],[],[],[],[ctx.mpq_4_3],w
  505. return T1, T2
  506. return ctx.hypercomb(h, [], **kwargs)
  507. @defun
  508. def airybi(ctx, z, derivative=0, **kwargs):
  509. z = ctx.convert(z)
  510. if derivative:
  511. n, ntype = ctx._convert_param(derivative)
  512. else:
  513. n = 0
  514. # Values at infinities
  515. if not ctx.isnormal(z) and z:
  516. if n and ntype == 'Z':
  517. if z == ctx.inf:
  518. return z
  519. if z == ctx.ninf:
  520. if n == -1:
  521. return 1/z
  522. if n == -2:
  523. return _airybi_n2_inf(ctx)
  524. if n < -2:
  525. return (-1)**n * (-z)
  526. if not n:
  527. if z == ctx.inf:
  528. return z
  529. if z == ctx.ninf:
  530. return 1/z
  531. # TODO: limits
  532. raise ValueError("essential singularity of Bi(z)")
  533. if z:
  534. extraprec = max(0, int(1.5*ctx.mag(z)))
  535. else:
  536. extraprec = 0
  537. if n:
  538. if n == 1:
  539. # http://functions.wolfram.com/03.08.26.0001.01
  540. def h():
  541. ctx.prec += extraprec
  542. w = z**3 / 9
  543. ctx.prec -= extraprec
  544. C1 = _airybi_C1(ctx)*0.5
  545. C2 = _airybi_C2(ctx)
  546. T1 = [C1,z],[1,2],[],[],[],[ctx.mpq_5_3],w
  547. T2 = [C2],[1],[],[],[],[ctx.mpq_1_3],w
  548. return T1, T2
  549. return ctx.hypercomb(h, [], **kwargs)
  550. else:
  551. if z == 0:
  552. return _airyderiv_0(ctx, z, n, ntype, 1)
  553. def h(n):
  554. ctx.prec += extraprec
  555. w = z**3/9
  556. ctx.prec -= extraprec
  557. q13,q23,q43 = ctx.mpq_1_3, ctx.mpq_2_3, ctx.mpq_4_3
  558. q16 = ctx.mpq_1_6
  559. q56 = ctx.mpq_5_6
  560. a1=q13; a2=1; b1=(1-n)*q13; b2=(2-n)*q13; b3=1-n*q13
  561. T1 = [3, z], [n-q16, -n], [a1], [b1,b2,b3], \
  562. [a1,a2], [b1,b2,b3], w
  563. a1=q23; b1=(2-n)*q13; b2=1-n*q13; b3=(4-n)*q13
  564. T2 = [3, z], [n-q56, 1-n], [a1], [b1,b2,b3], \
  565. [a1,a2], [b1,b2,b3], w
  566. return T1, T2
  567. v = ctx.hypercomb(h, [n], **kwargs)
  568. if ctx._is_real_type(z) and ctx.isint(n):
  569. v = ctx._re(v)
  570. return v
  571. else:
  572. def h():
  573. ctx.prec += extraprec
  574. w = z**3 / 9
  575. ctx.prec -= extraprec
  576. C1 = _airybi_C1(ctx)
  577. C2 = _airybi_C2(ctx)
  578. T1 = [C1],[1],[],[],[],[ctx.mpq_2_3],w
  579. T2 = [z*C2],[1],[],[],[],[ctx.mpq_4_3],w
  580. return T1, T2
  581. return ctx.hypercomb(h, [], **kwargs)
  582. def _airy_zero(ctx, which, k, derivative, complex=False):
  583. # Asymptotic formulas are given in DLMF section 9.9
  584. def U(t): return t**(2/3.)*(1-7/(t**2*48))
  585. def T(t): return t**(2/3.)*(1+5/(t**2*48))
  586. k = int(k)
  587. if k < 1:
  588. raise ValueError("k cannot be less than 1")
  589. if not derivative in (0,1):
  590. raise ValueError("Derivative should lie between 0 and 1")
  591. if which == 0:
  592. if derivative:
  593. return ctx.findroot(lambda z: ctx.airyai(z,1),
  594. -U(3*ctx.pi*(4*k-3)/8))
  595. return ctx.findroot(ctx.airyai, -T(3*ctx.pi*(4*k-1)/8))
  596. if which == 1 and complex == False:
  597. if derivative:
  598. return ctx.findroot(lambda z: ctx.airybi(z,1),
  599. -U(3*ctx.pi*(4*k-1)/8))
  600. return ctx.findroot(ctx.airybi, -T(3*ctx.pi*(4*k-3)/8))
  601. if which == 1 and complex == True:
  602. if derivative:
  603. t = 3*ctx.pi*(4*k-3)/8 + 0.75j*ctx.ln2
  604. s = ctx.expjpi(ctx.mpf(1)/3) * T(t)
  605. return ctx.findroot(lambda z: ctx.airybi(z,1), s)
  606. t = 3*ctx.pi*(4*k-1)/8 + 0.75j*ctx.ln2
  607. s = ctx.expjpi(ctx.mpf(1)/3) * U(t)
  608. return ctx.findroot(ctx.airybi, s)
  609. @defun
  610. def airyaizero(ctx, k, derivative=0):
  611. return _airy_zero(ctx, 0, k, derivative, False)
  612. @defun
  613. def airybizero(ctx, k, derivative=0, complex=False):
  614. return _airy_zero(ctx, 1, k, derivative, complex)
  615. def _scorer(ctx, z, which, kwargs):
  616. z = ctx.convert(z)
  617. if ctx.isinf(z):
  618. if z == ctx.inf:
  619. if which == 0: return 1/z
  620. if which == 1: return z
  621. if z == ctx.ninf:
  622. return 1/z
  623. raise ValueError("essential singularity")
  624. if z:
  625. extraprec = max(0, int(1.5*ctx.mag(z)))
  626. else:
  627. extraprec = 0
  628. if kwargs.get('derivative'):
  629. raise NotImplementedError
  630. # Direct asymptotic expansions, to avoid
  631. # exponentially large cancellation
  632. try:
  633. if ctx.mag(z) > 3:
  634. if which == 0 and abs(ctx.arg(z)) < ctx.pi/3 * 0.999:
  635. def h():
  636. return (([ctx.pi,z],[-1,-1],[],[],[(1,3),(2,3),1],[],9/z**3),)
  637. return ctx.hypercomb(h, [], maxterms=ctx.prec, force_series=True)
  638. if which == 1 and abs(ctx.arg(-z)) < 2*ctx.pi/3 * 0.999:
  639. def h():
  640. return (([-ctx.pi,z],[-1,-1],[],[],[(1,3),(2,3),1],[],9/z**3),)
  641. return ctx.hypercomb(h, [], maxterms=ctx.prec, force_series=True)
  642. except ctx.NoConvergence:
  643. pass
  644. def h():
  645. A = ctx.airybi(z, **kwargs)/3
  646. B = -2*ctx.pi
  647. if which == 1:
  648. A *= 2
  649. B *= -1
  650. ctx.prec += extraprec
  651. w = z**3/9
  652. ctx.prec -= extraprec
  653. T1 = [A], [1], [], [], [], [], 0
  654. T2 = [B,z], [-1,2], [], [], [1], [ctx.mpq_4_3,ctx.mpq_5_3], w
  655. return T1, T2
  656. return ctx.hypercomb(h, [], **kwargs)
  657. @defun
  658. def scorergi(ctx, z, **kwargs):
  659. return _scorer(ctx, z, 0, kwargs)
  660. @defun
  661. def scorerhi(ctx, z, **kwargs):
  662. return _scorer(ctx, z, 1, kwargs)
  663. @defun_wrapped
  664. def coulombc(ctx, l, eta, _cache={}):
  665. if (l, eta) in _cache and _cache[l,eta][0] >= ctx.prec:
  666. return +_cache[l,eta][1]
  667. G3 = ctx.loggamma(2*l+2)
  668. G1 = ctx.loggamma(1+l+ctx.j*eta)
  669. G2 = ctx.loggamma(1+l-ctx.j*eta)
  670. v = 2**l * ctx.exp((-ctx.pi*eta+G1+G2)/2 - G3)
  671. if not (ctx.im(l) or ctx.im(eta)):
  672. v = ctx.re(v)
  673. _cache[l,eta] = (ctx.prec, v)
  674. return v
  675. @defun_wrapped
  676. def coulombf(ctx, l, eta, z, w=1, chop=True, **kwargs):
  677. # Regular Coulomb wave function
  678. # Note: w can be either 1 or -1; the other may be better in some cases
  679. # TODO: check that chop=True chops when and only when it should
  680. #ctx.prec += 10
  681. def h(l, eta):
  682. try:
  683. jw = ctx.j*w
  684. jwz = ctx.fmul(jw, z, exact=True)
  685. jwz2 = ctx.fmul(jwz, -2, exact=True)
  686. C = ctx.coulombc(l, eta)
  687. T1 = [C, z, ctx.exp(jwz)], [1, l+1, 1], [], [], [1+l+jw*eta], \
  688. [2*l+2], jwz2
  689. except ValueError:
  690. T1 = [0], [-1], [], [], [], [], 0
  691. return (T1,)
  692. v = ctx.hypercomb(h, [l,eta], **kwargs)
  693. if chop and (not ctx.im(l)) and (not ctx.im(eta)) and (not ctx.im(z)) and \
  694. (ctx.re(z) >= 0):
  695. v = ctx.re(v)
  696. return v
  697. @defun_wrapped
  698. def _coulomb_chi(ctx, l, eta, _cache={}):
  699. if (l, eta) in _cache and _cache[l,eta][0] >= ctx.prec:
  700. return _cache[l,eta][1]
  701. def terms():
  702. l2 = -l-1
  703. jeta = ctx.j*eta
  704. return [ctx.loggamma(1+l+jeta) * (-0.5j),
  705. ctx.loggamma(1+l-jeta) * (0.5j),
  706. ctx.loggamma(1+l2+jeta) * (0.5j),
  707. ctx.loggamma(1+l2-jeta) * (-0.5j),
  708. -(l+0.5)*ctx.pi]
  709. v = ctx.sum_accurately(terms, 1)
  710. _cache[l,eta] = (ctx.prec, v)
  711. return v
  712. @defun_wrapped
  713. def coulombg(ctx, l, eta, z, w=1, chop=True, **kwargs):
  714. # Irregular Coulomb wave function
  715. # Note: w can be either 1 or -1; the other may be better in some cases
  716. # TODO: check that chop=True chops when and only when it should
  717. if not ctx._im(l):
  718. l = ctx._re(l) # XXX: for isint
  719. def h(l, eta):
  720. # Force perturbation for integers and half-integers
  721. if ctx.isint(l*2):
  722. T1 = [0], [-1], [], [], [], [], 0
  723. return (T1,)
  724. l2 = -l-1
  725. try:
  726. chi = ctx._coulomb_chi(l, eta)
  727. jw = ctx.j*w
  728. s = ctx.sin(chi); c = ctx.cos(chi)
  729. C1 = ctx.coulombc(l,eta)
  730. C2 = ctx.coulombc(l2,eta)
  731. u = ctx.exp(jw*z)
  732. x = -2*jw*z
  733. T1 = [s, C1, z, u, c], [-1, 1, l+1, 1, 1], [], [], \
  734. [1+l+jw*eta], [2*l+2], x
  735. T2 = [-s, C2, z, u], [-1, 1, l2+1, 1], [], [], \
  736. [1+l2+jw*eta], [2*l2+2], x
  737. return T1, T2
  738. except ValueError:
  739. T1 = [0], [-1], [], [], [], [], 0
  740. return (T1,)
  741. v = ctx.hypercomb(h, [l,eta], **kwargs)
  742. if chop and (not ctx._im(l)) and (not ctx._im(eta)) and (not ctx._im(z)) and \
  743. (ctx._re(z) >= 0):
  744. v = ctx._re(v)
  745. return v
  746. def mcmahon(ctx,kind,prime,v,m):
  747. """
  748. Computes an estimate for the location of the Bessel function zero
  749. j_{v,m}, y_{v,m}, j'_{v,m} or y'_{v,m} using McMahon's asymptotic
  750. expansion (Abramowitz & Stegun 9.5.12-13, DLMF 20.21(vi)).
  751. Returns (r,err) where r is the estimated location of the root
  752. and err is a positive number estimating the error of the
  753. asymptotic expansion.
  754. """
  755. u = 4*v**2
  756. if kind == 1 and not prime: b = (4*m+2*v-1)*ctx.pi/4
  757. if kind == 2 and not prime: b = (4*m+2*v-3)*ctx.pi/4
  758. if kind == 1 and prime: b = (4*m+2*v-3)*ctx.pi/4
  759. if kind == 2 and prime: b = (4*m+2*v-1)*ctx.pi/4
  760. if not prime:
  761. s1 = b
  762. s2 = -(u-1)/(8*b)
  763. s3 = -4*(u-1)*(7*u-31)/(3*(8*b)**3)
  764. s4 = -32*(u-1)*(83*u**2-982*u+3779)/(15*(8*b)**5)
  765. s5 = -64*(u-1)*(6949*u**3-153855*u**2+1585743*u-6277237)/(105*(8*b)**7)
  766. if prime:
  767. s1 = b
  768. s2 = -(u+3)/(8*b)
  769. s3 = -4*(7*u**2+82*u-9)/(3*(8*b)**3)
  770. s4 = -32*(83*u**3+2075*u**2-3039*u+3537)/(15*(8*b)**5)
  771. s5 = -64*(6949*u**4+296492*u**3-1248002*u**2+7414380*u-5853627)/(105*(8*b)**7)
  772. terms = [s1,s2,s3,s4,s5]
  773. s = s1
  774. err = 0.0
  775. for i in range(1,len(terms)):
  776. if abs(terms[i]) < abs(terms[i-1]):
  777. s += terms[i]
  778. else:
  779. err = abs(terms[i])
  780. if i == len(terms)-1:
  781. err = abs(terms[-1])
  782. return s, err
  783. def generalized_bisection(ctx,f,a,b,n):
  784. """
  785. Given f known to have exactly n simple roots within [a,b],
  786. return a list of n intervals isolating the roots
  787. and having opposite signs at the endpoints.
  788. TODO: this can be optimized, e.g. by reusing evaluation points.
  789. """
  790. if n < 1:
  791. raise ValueError("n cannot be less than 1")
  792. N = n+1
  793. points = []
  794. signs = []
  795. while 1:
  796. points = ctx.linspace(a,b,N)
  797. signs = [ctx.sign(f(x)) for x in points]
  798. ok_intervals = [(points[i],points[i+1]) for i in range(N-1) \
  799. if signs[i]*signs[i+1] == -1]
  800. if len(ok_intervals) == n:
  801. return ok_intervals
  802. N = N*2
  803. def find_in_interval(ctx, f, ab):
  804. return ctx.findroot(f, ab, solver='illinois', verify=False)
  805. def bessel_zero(ctx, kind, prime, v, m, isoltol=0.01, _interval_cache={}):
  806. prec = ctx.prec
  807. workprec = max(prec, ctx.mag(v), ctx.mag(m))+10
  808. try:
  809. ctx.prec = workprec
  810. v = ctx.mpf(v)
  811. m = int(m)
  812. prime = int(prime)
  813. if v < 0:
  814. raise ValueError("v cannot be negative")
  815. if m < 1:
  816. raise ValueError("m cannot be less than 1")
  817. if not prime in (0,1):
  818. raise ValueError("prime should lie between 0 and 1")
  819. if kind == 1:
  820. if prime: f = lambda x: ctx.besselj(v,x,derivative=1)
  821. else: f = lambda x: ctx.besselj(v,x)
  822. if kind == 2:
  823. if prime: f = lambda x: ctx.bessely(v,x,derivative=1)
  824. else: f = lambda x: ctx.bessely(v,x)
  825. # The first root of J' is very close to 0 for small
  826. # orders, and this needs to be special-cased
  827. if kind == 1 and prime and m == 1:
  828. if v == 0:
  829. return ctx.zero
  830. if v <= 1:
  831. # TODO: use v <= j'_{v,1} < y_{v,1}?
  832. r = 2*ctx.sqrt(v*(1+v)/(v+2))
  833. return find_in_interval(ctx, f, (r/10, 2*r))
  834. if (kind,prime,v,m) in _interval_cache:
  835. return find_in_interval(ctx, f, _interval_cache[kind,prime,v,m])
  836. r, err = mcmahon(ctx, kind, prime, v, m)
  837. if err < isoltol:
  838. return find_in_interval(ctx, f, (r-isoltol, r+isoltol))
  839. # An x such that 0 < x < r_{v,1}
  840. if kind == 1 and not prime: low = 2.4
  841. if kind == 1 and prime: low = 1.8
  842. if kind == 2 and not prime: low = 0.8
  843. if kind == 2 and prime: low = 2.0
  844. n = m+1
  845. while 1:
  846. r1, err = mcmahon(ctx, kind, prime, v, n)
  847. if err < isoltol:
  848. r2, err2 = mcmahon(ctx, kind, prime, v, n+1)
  849. intervals = generalized_bisection(ctx, f, low, 0.5*(r1+r2), n)
  850. for k, ab in enumerate(intervals):
  851. _interval_cache[kind,prime,v,k+1] = ab
  852. return find_in_interval(ctx, f, intervals[m-1])
  853. else:
  854. n = n*2
  855. finally:
  856. ctx.prec = prec
  857. @defun
  858. def besseljzero(ctx, v, m, derivative=0):
  859. r"""
  860. For a real order `\nu \ge 0` and a positive integer `m`, returns
  861. `j_{\nu,m}`, the `m`-th positive zero of the Bessel function of the
  862. first kind `J_{\nu}(z)` (see :func:`~mpmath.besselj`). Alternatively,
  863. with *derivative=1*, gives the first nonnegative simple zero
  864. `j'_{\nu,m}` of `J'_{\nu}(z)`.
  865. The indexing convention is that used by Abramowitz & Stegun
  866. and the DLMF. Note the special case `j'_{0,1} = 0`, while all other
  867. zeros are positive. In effect, only simple zeros are counted
  868. (all zeros of Bessel functions are simple except possibly `z = 0`)
  869. and `j_{\nu,m}` becomes a monotonic function of both `\nu`
  870. and `m`.
  871. The zeros are interlaced according to the inequalities
  872. .. math ::
  873. j'_{\nu,k} < j_{\nu,k} < j'_{\nu,k+1}
  874. j_{\nu,1} < j_{\nu+1,2} < j_{\nu,2} < j_{\nu+1,2} < j_{\nu,3} < \cdots
  875. **Examples**
  876. Initial zeros of the Bessel functions `J_0(z), J_1(z), J_2(z)`::
  877. >>> from mpmath import *
  878. >>> mp.dps = 25; mp.pretty = True
  879. >>> besseljzero(0,1); besseljzero(0,2); besseljzero(0,3)
  880. 2.404825557695772768621632
  881. 5.520078110286310649596604
  882. 8.653727912911012216954199
  883. >>> besseljzero(1,1); besseljzero(1,2); besseljzero(1,3)
  884. 3.831705970207512315614436
  885. 7.01558666981561875353705
  886. 10.17346813506272207718571
  887. >>> besseljzero(2,1); besseljzero(2,2); besseljzero(2,3)
  888. 5.135622301840682556301402
  889. 8.417244140399864857783614
  890. 11.61984117214905942709415
  891. Initial zeros of `J'_0(z), J'_1(z), J'_2(z)`::
  892. 0.0
  893. 3.831705970207512315614436
  894. 7.01558666981561875353705
  895. >>> besseljzero(1,1,1); besseljzero(1,2,1); besseljzero(1,3,1)
  896. 1.84118378134065930264363
  897. 5.331442773525032636884016
  898. 8.536316366346285834358961
  899. >>> besseljzero(2,1,1); besseljzero(2,2,1); besseljzero(2,3,1)
  900. 3.054236928227140322755932
  901. 6.706133194158459146634394
  902. 9.969467823087595793179143
  903. Zeros with large index::
  904. >>> besseljzero(0,100); besseljzero(0,1000); besseljzero(0,10000)
  905. 313.3742660775278447196902
  906. 3140.807295225078628895545
  907. 31415.14114171350798533666
  908. >>> besseljzero(5,100); besseljzero(5,1000); besseljzero(5,10000)
  909. 321.1893195676003157339222
  910. 3148.657306813047523500494
  911. 31422.9947255486291798943
  912. >>> besseljzero(0,100,1); besseljzero(0,1000,1); besseljzero(0,10000,1)
  913. 311.8018681873704508125112
  914. 3139.236339643802482833973
  915. 31413.57032947022399485808
  916. Zeros of functions with large order::
  917. >>> besseljzero(50,1)
  918. 57.11689916011917411936228
  919. >>> besseljzero(50,2)
  920. 62.80769876483536093435393
  921. >>> besseljzero(50,100)
  922. 388.6936600656058834640981
  923. >>> besseljzero(50,1,1)
  924. 52.99764038731665010944037
  925. >>> besseljzero(50,2,1)
  926. 60.02631933279942589882363
  927. >>> besseljzero(50,100,1)
  928. 387.1083151608726181086283
  929. Zeros of functions with fractional order::
  930. >>> besseljzero(0.5,1); besseljzero(1.5,1); besseljzero(2.25,4)
  931. 3.141592653589793238462643
  932. 4.493409457909064175307881
  933. 15.15657692957458622921634
  934. Both `J_{\nu}(z)` and `J'_{\nu}(z)` can be expressed as infinite
  935. products over their zeros::
  936. >>> v,z = 2, mpf(1)
  937. >>> (z/2)**v/gamma(v+1) * \
  938. ... nprod(lambda k: 1-(z/besseljzero(v,k))**2, [1,inf])
  939. ...
  940. 0.1149034849319004804696469
  941. >>> besselj(v,z)
  942. 0.1149034849319004804696469
  943. >>> (z/2)**(v-1)/2/gamma(v) * \
  944. ... nprod(lambda k: 1-(z/besseljzero(v,k,1))**2, [1,inf])
  945. ...
  946. 0.2102436158811325550203884
  947. >>> besselj(v,z,1)
  948. 0.2102436158811325550203884
  949. """
  950. return +bessel_zero(ctx, 1, derivative, v, m)
  951. @defun
  952. def besselyzero(ctx, v, m, derivative=0):
  953. r"""
  954. For a real order `\nu \ge 0` and a positive integer `m`, returns
  955. `y_{\nu,m}`, the `m`-th positive zero of the Bessel function of the
  956. second kind `Y_{\nu}(z)` (see :func:`~mpmath.bessely`). Alternatively,
  957. with *derivative=1*, gives the first positive zero `y'_{\nu,m}` of
  958. `Y'_{\nu}(z)`.
  959. The zeros are interlaced according to the inequalities
  960. .. math ::
  961. y_{\nu,k} < y'_{\nu,k} < y_{\nu,k+1}
  962. y_{\nu,1} < y_{\nu+1,2} < y_{\nu,2} < y_{\nu+1,2} < y_{\nu,3} < \cdots
  963. **Examples**
  964. Initial zeros of the Bessel functions `Y_0(z), Y_1(z), Y_2(z)`::
  965. >>> from mpmath import *
  966. >>> mp.dps = 25; mp.pretty = True
  967. >>> besselyzero(0,1); besselyzero(0,2); besselyzero(0,3)
  968. 0.8935769662791675215848871
  969. 3.957678419314857868375677
  970. 7.086051060301772697623625
  971. >>> besselyzero(1,1); besselyzero(1,2); besselyzero(1,3)
  972. 2.197141326031017035149034
  973. 5.429681040794135132772005
  974. 8.596005868331168926429606
  975. >>> besselyzero(2,1); besselyzero(2,2); besselyzero(2,3)
  976. 3.384241767149593472701426
  977. 6.793807513268267538291167
  978. 10.02347797936003797850539
  979. Initial zeros of `Y'_0(z), Y'_1(z), Y'_2(z)`::
  980. >>> besselyzero(0,1,1); besselyzero(0,2,1); besselyzero(0,3,1)
  981. 2.197141326031017035149034
  982. 5.429681040794135132772005
  983. 8.596005868331168926429606
  984. >>> besselyzero(1,1,1); besselyzero(1,2,1); besselyzero(1,3,1)
  985. 3.683022856585177699898967
  986. 6.941499953654175655751944
  987. 10.12340465543661307978775
  988. >>> besselyzero(2,1,1); besselyzero(2,2,1); besselyzero(2,3,1)
  989. 5.002582931446063945200176
  990. 8.350724701413079526349714
  991. 11.57419546521764654624265
  992. Zeros with large index::
  993. >>> besselyzero(0,100); besselyzero(0,1000); besselyzero(0,10000)
  994. 311.8034717601871549333419
  995. 3139.236498918198006794026
  996. 31413.57034538691205229188
  997. >>> besselyzero(5,100); besselyzero(5,1000); besselyzero(5,10000)
  998. 319.6183338562782156235062
  999. 3147.086508524556404473186
  1000. 31421.42392920214673402828
  1001. >>> besselyzero(0,100,1); besselyzero(0,1000,1); besselyzero(0,10000,1)
  1002. 313.3726705426359345050449
  1003. 3140.807136030340213610065
  1004. 31415.14112579761578220175
  1005. Zeros of functions with large order::
  1006. >>> besselyzero(50,1)
  1007. 53.50285882040036394680237
  1008. >>> besselyzero(50,2)
  1009. 60.11244442774058114686022
  1010. >>> besselyzero(50,100)
  1011. 387.1096509824943957706835
  1012. >>> besselyzero(50,1,1)
  1013. 56.96290427516751320063605
  1014. >>> besselyzero(50,2,1)
  1015. 62.74888166945933944036623
  1016. >>> besselyzero(50,100,1)
  1017. 388.6923300548309258355475
  1018. Zeros of functions with fractional order::
  1019. >>> besselyzero(0.5,1); besselyzero(1.5,1); besselyzero(2.25,4)
  1020. 1.570796326794896619231322
  1021. 2.798386045783887136720249
  1022. 13.56721208770735123376018
  1023. """
  1024. return +bessel_zero(ctx, 2, derivative, v, m)