@@ -229,6 +229,9 @@ function besselk_positive_args(nu, x::T) where T <: Union{Float32, Float64}
229
229
# check if nu is a half-integer
230
230
(isinteger (nu- 1 / 2 ) && sphericalbesselk_cutoff (nu)) && return sphericalbesselk_int (Int (nu- 1 / 2 ), x)* SQPIO2 (T)* sqrt (x)
231
231
232
+ # check if the standard asymptotic expansion can be used
233
+ besseli_large_argument_cutoff (nu, x) && return besselk_large_argument (nu, x)
234
+
232
235
# use uniform debye expansion if x or nu is large
233
236
besselik_debye_cutoff (nu, x) && return besselk_large_orders (nu, x)
234
237
@@ -427,3 +430,37 @@ function besselk_power_series(v, x::T) where T
427
430
end
428
431
besselk_power_series_cutoff (nu, x:: Float64 ) = x < 2.0 || nu > 1.6 x - 1.0
429
432
besselk_power_series_cutoff (nu, x:: Float32 ) = x < 10.0f0 || nu > 1.65f0 * x - 8.0f0
433
+
434
+ # ####
435
+ # #### Large argument expansion for K_{nu}(x)
436
+ # ####
437
+
438
+ # Computes the asymptotic expansion of K_ν w.r.t. argument.
439
+ # Accurate for large x, and faster than uniform asymptotic expansion for small to small-ish orders
440
+ # See http://dlmf.nist.gov/10.40.E2
441
+
442
+ function besselk_large_argument (v, x:: T ) where T
443
+ a = exp (- x / 2 )
444
+ coef = a * sqrt (pi / 2 x)
445
+ return T (_besselk_large_argument (v, x) * coef * a)
446
+ end
447
+
448
+ besselk_large_argument_scaled (v, x:: T ) where T = T (_besselk_large_argument (v, x) * sqrt (pi / 2 x))
449
+
450
+ function _besselk_large_argument (v, x:: T ) where T
451
+ MaxIter = 5000
452
+ S = promote_type (T, Float64)
453
+ v, x = S (v), S (x)
454
+
455
+ fv2 = 4 * v^ 2
456
+ term = one (S)
457
+ res = term
458
+ s = term
459
+ for i in 1 : MaxIter
460
+ offset = muladd (2 , i, - 1 )
461
+ term *= muladd (offset, - offset, fv2) / (8 * x * i)
462
+ res = muladd (term, s, res)
463
+ abs (term) <= eps (T) && break
464
+ end
465
+ return res
466
+ end
0 commit comments