@@ -3,9 +3,8 @@ function besseljy(nu::Real, x::T) where T
3
3
abs_nu = abs (nu)
4
4
abs_x = abs (x)
5
5
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
+
9
8
if nu >= zero (T)
10
9
if x >= zero (T)
11
10
return Jnu, Ynu
@@ -66,7 +65,6 @@ function besseljy_positive_args(nu::Real, x::T) where T
66
65
H = hankel_debye (nu, x)
67
66
return real (H), imag (H)
68
67
end
69
-
70
68
# use forward recurrence if nu is an integer up until the continued fraction becomes inefficient
71
69
if isinteger (nu) && nu < 150
72
70
Y0 = bessely0 (x)
@@ -99,15 +97,21 @@ function besseljy_positive_args(nu::Real, x::T) where T
99
97
100
98
Hnu = hankel_debye (v2, x)
101
99
Hnum1 = hankel_debye (v2 - 1 , x)
100
+
102
101
# forward recurrence is stable for Hankel when x >= nu
103
102
if x >= nu
104
103
H = besselj_up_recurrence (x, Hnu, Hnum1, v2, nu)[1 ]
105
104
return real (H), imag (H)
106
105
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 ]
111
115
end
112
116
end
113
117
@@ -130,10 +134,11 @@ function besselj_ratio_jnu_jnum1(n, x::T) where T
130
134
end
131
135
132
136
function besselh (nu:: Float64 , k:: Integer , x:: AbstractFloat )
137
+ Jn, Yn = besseljy (nu, x)
133
138
if k == 1
134
- return complex (besselj (nu, x), bessely (nu, x) )
139
+ return complex (Jn, Yn )
135
140
elseif k == 2
136
- return complex (besselj (nu, x), - bessely (nu, x) )
141
+ return complex (Jn, - Yn )
137
142
else
138
143
throw (ArgumentError (" k must be 1 or 2" ))
139
144
end
0 commit comments