Skip to content

Commit e317d3a

Browse files
author
Chris Geoga
committed
Rolling back to the old power series.
1 parent 232f566 commit e317d3a

File tree

1 file changed

+31
-17
lines changed

1 file changed

+31
-17
lines changed

src/BesselFunctions/besselk.jl

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -500,24 +500,38 @@ besselk_power_series(v, x::ComplexF32) = ComplexF32(besselk_power_series(v, Comp
500500

501501
function besselk_power_series(v, x::ComplexOrReal{T}) where T
502502
Math.isnearint(v) && return besselk_power_series_int(v, x)
503-
MaxIter = 5000
504-
gam = gamma(v)
505-
ngam = π / (sinpi(-abs(v)) * gam * v)
506-
507-
s1, s2 = zero(T), zero(T)
508-
t1, t2 = one(T), one(T)
509-
510-
for k in 1:MaxIter
511-
s1 += t1
512-
s2 += t2
513-
t1 *= x^2 / (4k * (k - v))
514-
t2 *= x^2 / (4k * (k + v))
515-
abs(t1) < eps(T) && break
503+
MaxIter = 1000
504+
S = eltype(x)
505+
v, x = S(v), S(x)
506+
507+
z = x / 2
508+
zz = z * z
509+
logz = log(z)
510+
xd2_v = exp(v*logz)
511+
xd2_nv = inv(xd2_v)
512+
513+
# use the reflection identify to calculate gamma(-v)
514+
# use relation gamma(v)*v = gamma(v+1) to avoid two gamma calls
515+
gam_v = gamma(v)
516+
gam_nv = π / (sinpi(-abs(v)) * gam_v * v)
517+
gam_1mv = -gam_nv * v
518+
gam_1mnv = gam_v * v
519+
520+
_t1 = gam_v * xd2_nv * gam_1mv
521+
_t2 = gam_nv * xd2_v * gam_1mnv
522+
(xd2_pow, fact_k, out) = (one(S), one(S), zero(S))
523+
for k in 0:MaxIter
524+
t1 = xd2_pow * T(0.5)
525+
tmp = muladd(_t1, gam_1mnv, _t2 * gam_1mv)
526+
tmp *= inv(gam_1mv * gam_1mnv * fact_k)
527+
term = t1 * tmp
528+
out += term
529+
abs(term / out) < eps(T) && break
530+
(gam_1mnv, gam_1mv) = (gam_1mnv*(one(S) + v + k), gam_1mv*(one(S) - v + k))
531+
xd2_pow *= zz
532+
fact_k *= k + one(S)
516533
end
517-
518-
xpv = (x/2)^v
519-
s = gam * s1 + xpv^2 * ngam * s2
520-
return s / (2*xpv)
534+
return out
521535
end
522536
besselk_power_series_cutoff(nu, x::Float64) = x < 2.0 || nu > 1.6x - 1.0
523537
besselk_power_series_cutoff(nu, x::Float32) = x < 10.0f0 || nu > 1.65f0*x - 8.0f0

0 commit comments

Comments
 (0)