Skip to content

Commit d9fc0e6

Browse files
committed
Move implementation to modified spherical file, change branching a bit.
1 parent 5bd6e59 commit d9fc0e6

File tree

3 files changed

+39
-23
lines changed

3 files changed

+39
-23
lines changed

src/Bessels.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ include("bessely.jl")
4141
include("hankel.jl")
4242
include("airy.jl")
4343
include("sphericalbessel.jl")
44+
include("modifiedsphericalbessel.jl")
4445

4546
include("Float128/besseli.jl")
4647
include("Float128/besselj.jl")

src/besselk.jl

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -225,12 +225,15 @@ function besselk_positive_args(nu, x::T) where T <: Union{Float32, Float64}
225225

226226
# dispatch to avoid uniform expansion when nu = 0
227227
iszero(nu) && return besselk0(x)
228+
229+
# pre-compute the uniform asymptotic expansion cutoff:
230+
debye_cut = besselik_debye_cutoff(nu, x)
228231

229232
# check if nu is a half-integer:
230-
besselk_vhalfint_check(nu, x) && return besselk_vhalfint(nu, x)
233+
(isinteger(nu-1/2) && !debye_cut) && return sphericalbesselk_int(nu-1/2, x)*SQRT_PID2(T)*sqrt(x)
231234

232235
# use uniform debye expansion if x or nu is large
233-
besselik_debye_cutoff(nu, x) && return besselk_large_orders(nu, x)
236+
debye_cut && return besselk_large_orders(nu, x)
234237

235238
# for integer nu use forward recurrence starting with K_0 and K_1
236239
isinteger(nu) && return besselk_up_recurrence(x, besselk1(x), besselk0(x), 1, nu)[1]
@@ -428,24 +431,3 @@ end
428431
besselk_power_series_cutoff(nu, x::Float64) = x < 2.0 || nu > 1.6x - 1.0
429432
besselk_power_series_cutoff(nu, x::Float32) = x < 10.0f0 || nu > 1.65f0*x - 8.0f0
430433

431-
432-
"""
433-
besselk_vhalfint(nu, x::T) where T <: {Float32, Float64}
434-
435-
Computes `K_{ν}(x)` when `v + 1/2` is an integer using the fact that the
436-
asymptotic expansion actually terminates and is exact for those specific `v` values.
437-
"""
438-
function besselk_vhalfint(v, x::T) where T
439-
v = abs(v)
440-
invx = inv(x)
441-
b0 = b1 = SQRT_PID2(T)*sqrt(invx)*exp(-x)
442-
twodx = 2*invx
443-
_v = T(1/2)
444-
while _v < v
445-
b0, b1 = b1, muladd(b1, twodx*_v, b0)
446-
_v += one(T)
447-
end
448-
b1
449-
end
450-
besselk_vhalfint_check(nu, x) = isinteger(nu-1/2) && (nu < 41.5) #@inline?
451-

src/modifiedsphericalbessel.jl

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
2+
function sphericalbesselk_int(v, x)
3+
b0 = inv(x)
4+
b1 = (x+one(x))/(x*x)
5+
iszero(v) && return b0*exp(-x)
6+
_v = one(v)
7+
invx = inv(x)
8+
while _v < v
9+
_v += one(_v)
10+
b0, b1 = b1, b0 + (2*_v - one(_v))*b1*invx
11+
end
12+
exp(-x)*b1
13+
end
14+
15+
function _sphericalbesselk(nu, x::T) where T
16+
if isinteger(nu) && nu < 41.5
17+
return sphericalbesselk_int(nu, x)
18+
else
19+
return inv(SQRT_PID2(T)*sqrt(x))*besselk(nu+1/2, x)
20+
end
21+
end
22+
23+
24+
"""
25+
sphericalbesselk(nu, x::T) where T <: {Float32, Float64}
26+
27+
Computes `k_{ν}(x)`, the modified second-kind spherical Bessel function, and \
28+
offers special branches for integer orders.
29+
"""
30+
sphericalbesselk(nu, x) = _sphericalbesselk(nu, float(x))
31+
32+
33+

0 commit comments

Comments
 (0)