1
+ # Hankel functions
2
+ #
3
+ # besseljy(nu, x)
4
+ # besselh(nu, x), hankelh1(nu, x), hankelh2(nu, x)
5
+ #
6
+ # A numerical routine to compute both Bessel functions of the first J_{ν}(x) and second kind Y_{ν}(x)
7
+ # for real orders and arguments of positive or negative value. Please see notes in src/besselj.jl and src/bessely.jl
8
+ # for notes on implementation details as most of the routine is similar. A key difference is when the methods to compute bessely
9
+ # don't also give besselj, we rely on a continued fraction approach to compute J_{ν}(x)/J_{ν-1}(x) to get J_{ν}(x) [1].
10
+ # The continued fraction approach is in general quickly converging when nu and x are small in magnitude.
11
+ # When x and nu are large and nu > x we fall back to computing J_{ν}(x) and Y_{ν}(x) separately as this was found to be more efficient.
12
+ #
13
+ # [1] Ratis, Yu L., and P. Fernández de Córdoba. "A code to calculate (high order) Bessel functions based on the continued fractions method."
14
+ # Computer physics communications 76.3 (1993): 381-388.
15
+ #
16
+
17
+ # ####
18
+ # #### Generic routine for `besseljy`
19
+ # ####
20
+
21
+ """
22
+ besseljy(nu, x::T) where T <: Float64
23
+
24
+ Return both Bessel functions of the first ``J_{nu}(x)`` and
25
+ second ``Y_{nu}(x)`` kind. This method will be faster than calling (besselj(nu, x), bessely(nu, x)) separately,
26
+ unless nu is slightly larger than x.
27
+
28
+ Results may be slightly different than individual functions in some domains due to using different algorithms.
29
+ """
1
30
function besseljy (nu:: Real , x:: T ) where T
2
31
isinteger (nu) && return besseljy (Int (nu), x)
3
32
abs_nu = abs (nu)
@@ -29,8 +58,8 @@ function besseljy(nu::Integer, x::T) where T
29
58
abs_x = abs (x)
30
59
sg = iseven (abs_nu) ? 1 : - 1
31
60
32
- Jnu = besselj_positive_args (abs_nu, abs_x)
33
- Ynu = bessely_positive_args (abs_nu, abs_x)
61
+ Jnu, Ynu = besseljy_positive_args (abs_nu, abs_x)
62
+
34
63
if nu >= zero (T)
35
64
if x >= zero (T)
36
65
return Jnu, Ynu
@@ -42,13 +71,17 @@ function besseljy(nu::Integer, x::T) where T
42
71
if x >= zero (T)
43
72
return Jnu * sg, Ynu * sg
44
73
else
45
- spi, cpi = sincospi (abs_nu)
46
74
return throw (DomainError (x, " Complex result returned for real arguments. Complex arguments are currently not supported" ))
75
+ # spi, cpi = sincospi(abs_nu)
47
76
# return (cpi*Jnu - spi*Ynu) * sg, Ynu + 2im * besselj_positive_args(abs_nu, abs_x)
48
77
end
49
78
end
50
79
end
51
80
81
+ # ####
82
+ # #### `besseljy` for positive arguments and orders
83
+ # ####
84
+
52
85
function besseljy_positive_args (nu:: Real , x:: T ) where T
53
86
nu == 0 && return (besselj0 (x), bessely0 (x))
54
87
nu == 1 && return (besselj1 (x), bessely1 (x))
@@ -69,7 +102,7 @@ function besseljy_positive_args(nu::Real, x::T) where T
69
102
if isinteger (nu) && nu < 150
70
103
Y0 = bessely0 (x)
71
104
Y1 = bessely1 (x)
72
- Ynm1, Yn = besselj_up_recurrence (x, bessely1 (x), bessely0 (x) , 1 , nu- 1 )
105
+ Ynm1, Yn = besselj_up_recurrence (x, Y1, Y0 , 1 , nu- 1 )
73
106
74
107
ratio_Jv_Jvm1 = besselj_ratio_jnu_jnum1 (nu, x)
75
108
Jn = 2 / (π* x * (Ynm1 - Yn / ratio_Jv_Jvm1))
@@ -115,6 +148,13 @@ function besseljy_positive_args(nu::Real, x::T) where T
115
148
end
116
149
end
117
150
151
+ # ####
152
+ # #### Continued fraction for J_{ν}(x)/J_{ν-1}(x)
153
+ # ####
154
+
155
+ # implements continued fraction to compute ratio of J_{ν}(x)/J_{ν-1}(x)
156
+ # using equation 22 and 24 of [1]
157
+ # in general faster converging for small magnitudes of x and nu and nu >> x
118
158
function besselj_ratio_jnu_jnum1 (n, x:: T ) where T
119
159
MaxIter = 5000
120
160
xinv = inv (x)
@@ -133,6 +173,16 @@ function besselj_ratio_jnu_jnum1(n, x::T) where T
133
173
return h
134
174
end
135
175
176
+ # ####
177
+ # #### Hankel functions
178
+ # ####
179
+
180
+ """
181
+ besselh(nu, [k=1,] x)
182
+
183
+ Bessel function of the third kind of order `nu` (the Hankel function). `k` is either 1 or 2,
184
+ selecting [`hankelh1`](@ref) or [`hankelh2`](@ref), respectively.
185
+ """
136
186
function besselh (nu:: Real , k:: Integer , x)
137
187
Jn, Yn = besseljy (nu, x)
138
188
if k == 1
@@ -144,5 +194,14 @@ function besselh(nu::Real, k::Integer, x)
144
194
end
145
195
end
146
196
197
+ """
198
+ hankelh1(nu, x)
199
+ Bessel function of the third kind of order `nu`, ``H^{(1)}_\\ nu(x)``.
200
+ """
147
201
hankelh1 (nu, x) = besselh (nu, 1 , x)
202
+
203
+ """
204
+ hankelh2(nu, x)
205
+ Bessel function of the third kind of order `nu`, ``H^{(2)}_\\ nu(x)``.
206
+ """
148
207
hankelh2 (nu, x) = besselh (nu, 2 , x)
0 commit comments