Skip to content

Commit 91c229f

Browse files
committed
fix some cutoffs
1 parent 9961fca commit 91c229f

File tree

1 file changed

+16
-13
lines changed

1 file changed

+16
-13
lines changed

src/BesselFunctions/besselk.jl

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -243,8 +243,8 @@ function _besselk(v::T, x::T) where T <: Union{Float32, Float64}
243243
elseif besselik_debye_cutoff(v, x) return besselk_large_orders(v, x)
244244

245245
else
246-
v_floor, v_int = modf(v)
247-
if x > 1.5 # determine cutoff as function for differnet types
246+
v_floor, _ = modf(v)
247+
if x > besselkx_levin_min(T)
248248
kv, kvp1 = besselkx_levin(v_floor, x, Val(16)), besselkx_levin(v_floor + 1, x, Val(16))
249249
return besselk_up_recurrence(x, kvp1, kv, v_floor + 1, v)[1] * exp(-x)
250250
else
@@ -253,7 +253,6 @@ function _besselk(v::T, x::T) where T <: Union{Float32, Float64}
253253
# requires starting values -0.5 < v < 0.5 and computes K_v and K_{v+1}
254254
if v_floor > T(0.5)
255255
v_floor -= 1
256-
v_int += 1
257256
end
258257
kv, kvp1 = besselk_temme_series(v_floor, x)
259258
return besselk_up_recurrence(x, kvp1, kv, v_floor + 1, v)[1]
@@ -276,8 +275,8 @@ function _besselkx(v::T, x::T) where T <: Union{Float32, Float64}
276275
elseif besselik_debye_cutoff(v, x) return besselk_large_orders_scaled(v, x)
277276

278277
else
279-
v_floor, v_int = modf(v)
280-
if x >= 1.5 # determine cutoff as function for differnet types
278+
v_floor, _ = modf(v)
279+
if x > besselkx_levin_min(T)
281280
kv, kvp1 = besselkx_levin(v_floor, x, Val(16)), besselkx_levin(v_floor + 1, x, Val(16))
282281
return besselk_up_recurrence(x, kvp1, kv, v_floor + 1, v)[1]
283282
else
@@ -286,7 +285,6 @@ function _besselkx(v::T, x::T) where T <: Union{Float32, Float64}
286285
# requires starting values -0.5 < v < 0.5 and computes K_v and K_{v+1}
287286
if v_floor > T(0.5)
288287
v_floor -= 1
289-
v_int += 1
290288
end
291289
kv, kvp1 = besselk_temme_series(v_floor, x)
292290
return besselk_up_recurrence(x, kvp1, kv, v_floor + 1, v)[1] * exp(x)
@@ -467,7 +465,6 @@ end
467465

468466
besselk_large_args_cutoff(v, x::Float64) = x > v^2 / 36 + 18
469467
besselk_large_args_cutoff(v, x::Float32) = x > v^2 / 50 + 9
470-
besselk_large_args_cutoff(v, x::Float16) = x > v^2 / 50 + 5
471468

472469
#####
473470
##### Levin sequence transform for K_{nu}(x)
@@ -494,6 +491,9 @@ end
494491
besselkx_levin_cutoff(v, x::Float64) = x > v^4 / 2401 + 1.5
495492
besselkx_levin_cutoff(v, x::Float32) = x > v^4 / 3000 + 0.95
496493

494+
besselkx_levin_min(::Type{Float64}) = 1.5
495+
besselkx_levin_min(::Type{Float32}) = 0.95
496+
497497
@generated function besselkx_levin(v, x::Complex{T}, ::Val{N}) where {T <: FloatTypes, N}
498498
:(
499499
begin
@@ -521,12 +521,14 @@ end
521521
##### Power series for K_{nu}(x)
522522
#####
523523

524-
# Use power series form of K_v(x) which is accurate for small x (x<2) or when nu > x
525-
# We use the form as described by Equation 3.2 from reference [7].
524+
# Power series form of K_v(x) valid when v is a non - integer
525+
# Can only be used for small x (x < 1.5) or when nu > x
526+
# Cancellation will also occur when v is close to an integer
527+
# We use a more simplified form described by Equation 3.2 from reference [7].
526528
# This method was originally contributed by @cgeoga https://github.com/cgeoga/BesselK.jl/blob/main/src/besk_ser.jl
527-
# A modified form appears below. See more discussion at https://github.com/heltonmc/Bessels.jl/pull/29
528-
# This is only valid for noninteger orders (nu) and no checks are performed.
529+
# A modified form appears below.
529530
#
531+
530532
"""
531533
besselk_power_series(nu, x::T) where T <: Float64
532534
@@ -570,9 +572,10 @@ besselk_power_series_cutoff(nu, x::Float32) = x < 10.0f0 || nu > 1.65f0*x - 8.0f
570572
# whose standard forms can't be naively evaluated by a computer at the origin.
571573

572574
# This function assumes |v|<1e-5!
573-
function besselk_temme_series(v::V, x::X) where {V , X}
575+
besselk_temme_series(v, x::Float32) = Float32(besselk_temme_series(v, Float64(x)))
576+
577+
function besselk_temme_series(v::T, x::T) where T <: Float64
574578
Max_Iter = 500
575-
T = promote_type(V , X)
576579
z = x / 2
577580
zz = z * z
578581
fk = f0_local_expansion_v0(v, x)

0 commit comments

Comments
 (0)