Skip to content

Commit 90731ea

Browse files
committed
fix general fall back method
1 parent 6c18d2b commit 90731ea

File tree

1 file changed

+15
-10
lines changed

1 file changed

+15
-10
lines changed

src/hankel.jl

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ function besseljy(nu::Real, x::T) where T
33
abs_nu = abs(nu)
44
abs_x = abs(x)
55

6-
Ynu = bessely_positive_args(abs_nu, abs_x)
7-
Jnu = bessely_positive_args(abs_nu, abs_x)
8-
6+
Jnu, Ynu = besseljy_positive_args(abs_nu, abs_x)
7+
98
if nu >= zero(T)
109
if x >= zero(T)
1110
return Jnu, Ynu
@@ -66,7 +65,6 @@ function besseljy_positive_args(nu::Real, x::T) where T
6665
H = hankel_debye(nu, x)
6766
return real(H), imag(H)
6867
end
69-
7068
# use forward recurrence if nu is an integer up until the continued fraction becomes inefficient
7169
if isinteger(nu) && nu < 150
7270
Y0 = bessely0(x)
@@ -99,15 +97,21 @@ function besseljy_positive_args(nu::Real, x::T) where T
9997

10098
Hnu = hankel_debye(v2, x)
10199
Hnum1 = hankel_debye(v2 - 1, x)
100+
102101
# forward recurrence is stable for Hankel when x >= nu
103102
if x >= nu
104103
H = besselj_up_recurrence(x, Hnu, Hnum1, v2, nu)[1]
105104
return real(H), imag(H)
106105
else
107-
Yn, Ynp1 = besselj_up_recurrence(x, imag(Hnu), imag(Hnum1), v2, nu)
108-
ratio_Jvp1_Jv = besselj_ratio_jnu_jnum1(nu+1, x)
109-
Jnp1 = 2 /*x * (Yn - Ynp1 / ratio_Jvp1_Jv))
110-
return Jnp1 / ratio_Jvp1_Jv, Yn
106+
# At this point besselj can not be calculated with forward recurrence
107+
# We could calculate it from bessely using the continued fraction approach like the following
108+
# Yn, Ynp1 = besselj_up_recurrence(x, imag(Hnu), imag(Hnum1), v2, nu)
109+
# ratio_Jvp1_Jv = besselj_ratio_jnu_jnum1(nu+1, x)
110+
# Jnp1 = 2 / (π*x * (Yn - Ynp1 / ratio_Jvp1_Jv))
111+
# return Jnp1 / ratio_Jvp1_Jv, Yn
112+
# However, the continued fraction approach is slowly converging for large arguments
113+
# We will fall back to computing besselj separately instead
114+
return besselj_positive_args(nu, x), besselj_up_recurrence(x, imag(Hnu), imag(Hnum1), v2, nu)[1]
111115
end
112116
end
113117

@@ -130,10 +134,11 @@ function besselj_ratio_jnu_jnum1(n, x::T) where T
130134
end
131135

132136
function besselh(nu::Float64, k::Integer, x::AbstractFloat)
137+
Jn, Yn = besseljy(nu, x)
133138
if k == 1
134-
return complex(besselj(nu, x), bessely(nu, x))
139+
return complex(Jn, Yn)
135140
elseif k == 2
136-
return complex(besselj(nu, x), -bessely(nu, x))
141+
return complex(Jn, -Yn)
137142
else
138143
throw(ArgumentError("k must be 1 or 2"))
139144
end

0 commit comments

Comments
 (0)