@@ -163,9 +163,9 @@ function besselix(nu, x::T) where T <: Union{Float32, Float64}
163
163
164
164
branch = 60
165
165
if nu < branch
166
- inp1 = besseli_large_orders_scaled (branch + 1 , x)
166
+ inup1 = besseli_large_orders_scaled (branch + 1 , x)
167
167
inu = besseli_large_orders_scaled (branch, x)
168
- return down_recurrence (x, inu, inp1 , nu, branch)
168
+ return down_recurrence (x, inu, inup1 , nu, branch)
169
169
else
170
170
return besseli_large_orders_scaled (nu, x)
171
171
end
@@ -199,10 +199,10 @@ function _besseli_continued_fractions(nu, x::T) where T
199
199
S = promote_type (T, Float64)
200
200
xx = S (x)
201
201
knu, knum1 = up_recurrence (xx, besselk0 (xx), besselk1 (xx), nu)
202
+ # if knu or knum1 is zero then besseli will likely overflow
202
203
(iszero (knu) || iszero (knum1)) && return throw (DomainError (x, " Overflow error" ))
203
204
return 1 / (x * (knum1 + knu / steed (nu, x)))
204
205
end
205
-
206
206
function steed (n, x:: T ) where T
207
207
MaxIter = 1000
208
208
xinv = inv (x)
@@ -213,7 +213,7 @@ function steed(n, x::T) where T
213
213
b = muladd (2 , n, 2 ) * xinv
214
214
for _ in 1 : MaxIter
215
215
d = inv (b + d)
216
- a = muladd (b, d, - 1 ) * a
216
+ a * = muladd (b, d, - 1 )
217
217
h = h + a
218
218
b = b + xinv2
219
219
abs (a / h) <= eps (T) && break
@@ -240,37 +240,25 @@ function besseli_large_argument(v, z::T) where T
240
240
return res * coef * a
241
241
end
242
242
243
- # power series definition of besseli
244
- # fast convergence for small arguments
245
- # for large orders and small arguments there is increased roundoff error ~ 1e-14
246
- # need to investigate further if this can be mitigated
247
243
function besseli_small_arguments (v, z:: T ) where T
244
+ S = promote_type (T, Float64)
245
+ x = S (z)
248
246
if v < 20
249
- coef = (z / 2 )^ v / factorial (v)
247
+ coef = (x / 2 )^ v / factorial (v)
250
248
else
251
- coef = v * log (z / 2 )
252
- coef -= _loggam (v + 1 )
253
- coef = exp (coef )
249
+ vinv = inv (v )
250
+ coef = sqrt (vinv / ( 2 * π)) * MathConstants . e ^ (v * ( log (x / ( 2 * v)) + 1 ))
251
+ coef *= evalpoly (vinv, ( 1 , - 1 / 12 , 1 / 288 , 139 / 51840 , - 571 / 2488320 , - 163879 / 209018880 , 5246819 / 75246796800 , 534703531 / 902961561600 ) )
254
252
end
255
253
256
254
MaxIter = 1000
257
- out = one (T )
258
- zz = z ^ 2 / 4
259
- a = one (T )
260
- for k in 0 : MaxIter
261
- a *= zz / (k + 1 ) / (k + v + 1 )
255
+ out = one (S )
256
+ zz = x ^ 2 / 4
257
+ a = one (S )
258
+ for k in 1 : MaxIter
259
+ a *= zz / (k * (k + v) )
262
260
out += a
263
261
a <= eps (T) && break
264
262
end
265
263
return coef * out
266
264
end
267
- @inline function _loggam (x)
268
- xinv = inv (x)
269
- xinv2 = xinv * xinv
270
- out = (x - 0.5 ) * log (x) - x + 9.1893853320467274178032927e-01
271
- out += xinv * evalpoly (
272
- xinv2, (8.3333333333333333333333368e-02 , - 2.7777777777777777777777776e-03 ,
273
- 7.9365079365079365079365075e-04 , - 5.9523809523809523809523806e-04 )
274
- )
275
- return out
276
- end
0 commit comments