@@ -243,8 +243,8 @@ function _besselk(v::T, x::T) where T <: Union{Float32, Float64}
243
243
elseif besselik_debye_cutoff (v, x) return besselk_large_orders (v, x)
244
244
245
245
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)
248
248
kv, kvp1 = besselkx_levin (v_floor, x, Val (16 )), besselkx_levin (v_floor + 1 , x, Val (16 ))
249
249
return besselk_up_recurrence (x, kvp1, kv, v_floor + 1 , v)[1 ] * exp (- x)
250
250
else
@@ -253,7 +253,6 @@ function _besselk(v::T, x::T) where T <: Union{Float32, Float64}
253
253
# requires starting values -0.5 < v < 0.5 and computes K_v and K_{v+1}
254
254
if v_floor > T (0.5 )
255
255
v_floor -= 1
256
- v_int += 1
257
256
end
258
257
kv, kvp1 = besselk_temme_series (v_floor, x)
259
258
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}
276
275
elseif besselik_debye_cutoff (v, x) return besselk_large_orders_scaled (v, x)
277
276
278
277
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)
281
280
kv, kvp1 = besselkx_levin (v_floor, x, Val (16 )), besselkx_levin (v_floor + 1 , x, Val (16 ))
282
281
return besselk_up_recurrence (x, kvp1, kv, v_floor + 1 , v)[1 ]
283
282
else
@@ -286,7 +285,6 @@ function _besselkx(v::T, x::T) where T <: Union{Float32, Float64}
286
285
# requires starting values -0.5 < v < 0.5 and computes K_v and K_{v+1}
287
286
if v_floor > T (0.5 )
288
287
v_floor -= 1
289
- v_int += 1
290
288
end
291
289
kv, kvp1 = besselk_temme_series (v_floor, x)
292
290
return besselk_up_recurrence (x, kvp1, kv, v_floor + 1 , v)[1 ] * exp (x)
467
465
468
466
besselk_large_args_cutoff (v, x:: Float64 ) = x > v^ 2 / 36 + 18
469
467
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
471
468
472
469
# ####
473
470
# #### Levin sequence transform for K_{nu}(x)
494
491
besselkx_levin_cutoff (v, x:: Float64 ) = x > v^ 4 / 2401 + 1.5
495
492
besselkx_levin_cutoff (v, x:: Float32 ) = x > v^ 4 / 3000 + 0.95
496
493
494
+ besselkx_levin_min (:: Type{Float64} ) = 1.5
495
+ besselkx_levin_min (:: Type{Float32} ) = 0.95
496
+
497
497
@generated function besselkx_levin (v, x:: Complex{T} , :: Val{N} ) where {T <: FloatTypes , N}
498
498
:(
499
499
begin
@@ -521,12 +521,14 @@ end
521
521
# #### Power series for K_{nu}(x)
522
522
# ####
523
523
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].
526
528
# 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.
529
530
#
531
+
530
532
"""
531
533
besselk_power_series(nu, x::T) where T <: Float64
532
534
@@ -570,9 +572,10 @@ besselk_power_series_cutoff(nu, x::Float32) = x < 10.0f0 || nu > 1.65f0*x - 8.0f
570
572
# whose standard forms can't be naively evaluated by a computer at the origin.
571
573
572
574
# 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
574
578
Max_Iter = 500
575
- T = promote_type (V , X)
576
579
z = x / 2
577
580
zz = z * z
578
581
fk = f0_local_expansion_v0 (v, x)
0 commit comments