1
1
# Airy functions
2
2
#
3
- # airyai(x ), airybi(nu, x )
4
- # airyaiprime(x ), airybiprime(nu, x )
3
+ # airyai(z ), airybi(nu, z )
4
+ # airyaiprime(z ), airybiprime(nu, z )
5
5
#
6
- # A numerical routine to compute the airy functions and their derivatives.
7
- # These routines use their relations to other special functions using https://dlmf.nist.gov/9.6.
8
- # Specifically see (NIST 9.6.E1 - 9.6.E9) for computation from the defined bessel functions.
9
- # For negative arguments these definitions are prone to some cancellation leading to higher errors.
10
- # In the future, these could be replaced with more custom routines as they depend on a single variable.
6
+ # A numerical routine to compute the airy functions and their derivatives in the entire complex plane.
7
+ # These routines are based on the methods reported in [1] which use a combination of the power series
8
+ # for small arguments and a large argument expansion for (x > ~10). The primary difference between [1]
9
+ # and what is used here is that the regions where the power series and large argument expansions
10
+ # do not provide good results they are filled by relation to other special functions (besselk and besseli)
11
+ # using https://dlmf.nist.gov/9.6 (NIST 9.6.E1 - 9.6.E9). In this case the power series of besseli is used and then besselk
12
+ # is calculated using the continued fraction approach. This method is described in more detail in src/besselk.jl.
13
+ # However, care must be taken when computing besseli because when the imaginary component is much larger than the real part
14
+ # cancellation will occur. This can be overcome by shifting the order of besseli to be much larger and then using the power series
15
+ # and downward recurrence to get besseli(1/3, x). Another difficult region is when -10<x<-5 and the imaginary part is close to zero.
16
+ # In this region we use rotation (see connection formulas http://dlmf.nist.gov/9.2.v) to shift to different region of complex plane
17
+ # where algorithms show good convergence. If imag(z) == zero then we use the reflection identities to compute in terms of bessel functions.
18
+ # In general, the cutoff regions compared to [1] are different to provide full double precision accuracy and to prioritize using the power series
19
+ # and asymptotic expansion compared to other approaches.
11
20
#
21
+ # [1] Jentschura, Ulrich David, and E. Lötstedt. "Numerical calculation of Bessel, Hankel and Airy functions."
22
+ # Computer Physics Communications 183.3 (2012): 506-519.
12
23
13
24
"""
14
25
airyai(x)
@@ -318,6 +329,7 @@ function airyai_large_argument(x::Real)
318
329
x < zero (x) && return real (airyai_large_argument (complex (x)))
319
330
return airy_large_arg_a (abs (x))
320
331
end
332
+
321
333
function airyai_large_argument (z:: Complex{T} ) where T
322
334
x, y = real (z), imag (z)
323
335
a = airy_large_arg_a (z)
@@ -332,6 +344,7 @@ function airyaiprime_large_argument(x::Real)
332
344
x < zero (x) && return real (airyaiprime_large_argument (complex (x)))
333
345
return airy_large_arg_c (abs (x))
334
346
end
347
+
335
348
function airyaiprime_large_argument (z:: Complex{T} ) where T
336
349
x, y = real (z), imag (z)
337
350
c = airy_large_arg_c (z)
@@ -374,13 +387,15 @@ function airybi_large_argument(z::Complex{T}) where T
374
387
return out
375
388
end
376
389
end
390
+
377
391
function airybiprime_large_argument (x:: Real )
378
392
if x < zero (x)
379
393
return 2 * real (airy_large_arg_d (complex (x)))
380
394
else
381
395
return 2 * (airy_large_arg_d (x))
382
396
end
383
397
end
398
+
384
399
function airybiprime_large_argument (z:: Complex{T} ) where T
385
400
x, y = real (z), imag (z)
386
401
d = airy_large_arg_d (z)
@@ -406,6 +421,7 @@ function airybiprime_large_argument(z::Complex{T}) where T
406
421
end
407
422
end
408
423
424
+ # see equations 24 and relations using eq 25 and 26 in [1]
409
425
function airy_large_arg_a (x:: ComplexOrReal{T} ) where T
410
426
S = eltype (x)
411
427
MaxIter = 3000
0 commit comments