Skip to content

Commit 30526b8

Browse files
committed
fix underflow for besselk
1 parent c9ff1c2 commit 30526b8

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

src/besselk.jl

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,32 @@ end
218218

219219
function _besselk(nu::AbstractRange, x::T) where T
220220
(nu[1] >= 0 && step(nu) == 1) || throw(ArgumentError("nu must be >= 0 with step(nu)=1"))
221-
out = Vector{T}(undef, length(nu))
222-
out[1], out[2] = _besselk(nu[1], x), _besselk(nu[2], x)
223-
return besselk_up_recurrence!(out, x, nu)
221+
len = length(nu)
222+
isone(len) && return [besselk(nu[1], x)]
223+
out = zeros(T, len)
224+
k = 1
225+
knu = zero(T)
226+
while abs(knu) < floatmin(T)
227+
if besselk_underflow_check(nu[k], x)
228+
knu = zero(T)
229+
else
230+
knu = _besselk(nu[k], x)
231+
end
232+
out[k] = knu
233+
k += 1
234+
k == len && break
235+
end
236+
if k < len
237+
out[k] = _besselk(nu[k], x)
238+
out[k-1:end] = besselk_up_recurrence!(out[k-1:end], x, nu[k-1:end])
239+
return out
240+
else
241+
return out
242+
end
224243
end
225244

245+
besselk_underflow_check(nu, x::T) where T = nu < T(1.45)*(x - 780) + 45*Base.Math._approx_cbrt(x - 780)
246+
226247
"""
227248
besselk_positive_args(x::T) where T <: Union{Float32, Float64}
228249

test/besselk_test.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ end
129129
# test nu_range
130130
@test besselk(0:50, 2.0) SpecialFunctions.besselk.(0:50, 2.0) rtol=1e-13
131131
@test besselk(0.5:1:10.5, 12.0) SpecialFunctions.besselk.(0.5:1:10.5, 12.0) rtol=1e-13
132+
@test besselk(1:700, 800.0) SpecialFunctions.besselk.(1:700, 800.0) rtol=1e-13
132133

133134
# test Float16
134135
@test besselk(Int16(10), Float16(1.0)) isa Float16

0 commit comments

Comments
 (0)