@@ -54,6 +54,9 @@ Asymptotic formula for the `n`th zero of the the Bessel J (Y) function of order
5454"""
5555function bessel_zero_asymptotic (nu_in:: Real , n:: Integer , kind= 1 )
5656 nu = abs (nu_in)
57+ if nu > 25 && n ≤ length (airy_zeros (). ai)
58+ return bessel_zero_largenu_asymptotic (nu, n, kind, false )
59+ end
5760 if kind == 1
5861 beta = MathConstants. pi * (n + nu / 2 - 1 // 4 )
5962 else # kind == 2
@@ -191,8 +194,12 @@ Asymptotic formula for the `n`th zero of the the derivative of Bessel J (Y) func
191194of order `nu`. `kind == 1 (2)` for Bessel function of the first (second) kind, J (Y).
192195"""
193196function bessel_deriv_zero_asymptotic (nu_in:: Real , n:: Integer , kind= 1 )
194- # Reference: https://dlmf.nist.gov/10.21.E20
195197 nu = abs (nu_in)
198+ if nu > 25 && n ≤ length (airy_zeros (). ai)
199+ return bessel_zero_largenu_asymptotic (nu, n, kind, true )
200+ end
201+
202+ # Reference: https://dlmf.nist.gov/10.21.E20
196203 if kind == 1
197204 beta = MathConstants. pi * (n + nu / 2 - 3 // 4 )
198205 else # kind == 2
@@ -297,4 +304,87 @@ function bessely_deriv_zero(nu::Union{Integer,Float64}, n::Integer)
297304 end
298305end
299306
307+ """
308+ airy_zeros()
309+
310+ Return the first few negative zeros of the functions `airyai`, `airybi`, `airyaiprime`, and `airybiprime`
311+
312+ ## Return Value
313+ - `(; ai, bi, aiprime, biprime)`: A named tuple containing the first few negative zeros of the functions
314+ `airyai`, `airybi`, `airyaiprime`, and `airybiprime`, respectively, as defined in the `SpecialFunctions`
315+ package. Each field in the named tuple consists of a tuple of `n` increasingly negative values. Here `n`
316+ is a small integer, say 2 or 3.
317+ """
318+ @inline function airy_zeros ()
319+ ai = (- 2.338107410459767 , - 4.087949444130973 , - 5.520559828095556 )
320+ bi = (- 1.173713222709127 , - 3.2710933028363516 , - 4.8307378416620095 )
321+ aiprime = (- 1.0187929716474717 , - 3.248197582179841 , - 4.820099211178737 )
322+ biprime = (- 2.2944396826141227 , - 4.073155089071816 , - 5.5123957296635835 )
323+ return (; ai, bi, aiprime, biprime)
324+ end
325+
326+ """
327+ bessel_zero_largenu_asymptotic(nu::Real, m::Integer, kind::Integer, deriv::Bool)
328+
329+ Compute an asymptotic approximation for a zero of the J or Y Bessel function (or their derivative) suitable for large order.
330+
331+ ## Input Arguments
332+ - `nu`: The (nonnegative) order of the Bessel function.
333+ - `m`: A small positive integer enumerating which zero is sought. Can not exceed `length(airy_zeros().ai)`.
334+ The asymptotic formulas used herein weaken as `m` increases.
335+ - `kind`: Kind of Bessel function whose zero is sought. Either 1 for the J Bessel function or 2 for the Y Bessel function.
336+ - `deriv`: If false, returns the zero of the function. If true, returns the zero of the function's derivative.
337+
338+ ## Return Value
339+ `z`: A `Float64` approximation of the desired zero.
340+
341+ ## Reference
342+ - https://dlmf.nist.gov/10.21.vii
343+ """
344+ function bessel_zero_largenu_asymptotic (nu:: Real , m:: Integer , kind:: Integer , deriv:: Bool )
345+ abfactor = inv (cbrt (2.0 ))
346+
347+ if kind == 1
348+ alpha = - abfactor * (deriv ? airy_zeros (). aiprime[m] : airy_zeros (). ai[m])
349+ elseif kind == 2
350+ alpha = - abfactor * (deriv ? airy_zeros (). biprime[m] : airy_zeros (). bi[m])
351+ else
352+ throw (ArgumentError (" kind must be 1 or 2 but is $kind " ))
353+ end
354+
355+ alphap2 = alpha * alpha
356+ alphap3 = alpha * alphap2
357+ alphap4 = alpha * alphap3
358+ alphap5 = alpha * alphap4
359+
360+ alpha0 = 1.0
361+ alpha1 = alpha
362+
363+ if deriv
364+ alpha2 = 3 * alphap2 / 10 - inv (10 * alpha)
365+ alpha3 = - (alphap3 / 350 + inv (25 ) + inv (200 * alphap3))
366+ alpha4 = - 479 * alphap4 / 630_000 + 509 * alpha / 31_500 + inv (1500 * alphap2) - inv (2_000 * alphap5)
367+ alpha5 = 0.0
368+ else
369+ alpha2 = 3 * alphap2 / 10
370+ alpha3 = - alphap3 / 350 + inv (70 )
371+ alpha4 = - (479 * alphap4 / 63_000 + alpha / 3150 )
372+ alpha5 = 20_231 * alphap5 / 8_085_000 - 551 * alphap2 / 161_700
373+ end
374+
375+ x = inv (cbrt (nu)^ 2 )
376+ xpk = 1.0
377+ zsum = lastterm = alpha0
378+ for alphak in (alpha1, alpha2, alpha3, alpha4, alpha5)
379+ xpk *= x
380+ nextterm = alphak * xpk
381+ abs (nextterm) > abs (lastterm) && break # Asymptotic series starting to diverge
382+ zsum += nextterm
383+ lastterm = nextterm
384+ end
385+
386+ zsum *= nu
387+ return zsum
388+ end
389+
300390end # module FunctionZeros
0 commit comments