@@ -161,11 +161,12 @@ function besselix(nu, x::T) where T <: Union{Float32, Float64}
161
161
nu == 0 && return besseli0x (x)
162
162
nu == 1 && return besseli1x (x)
163
163
164
- branch = 60
165
- if nu < branch
166
- inup1 = besseli_large_orders_scaled (branch + 1 , x)
167
- inu = besseli_large_orders_scaled (branch, x)
168
- return down_recurrence (x, inu, inup1, nu, branch)
164
+ if x > maximum ((T (30 ), nu^ 2 / 4 ))
165
+ return T (besseli_large_argument_scaled (nu, x))
166
+ elseif x <= 2 * sqrt (nu + 1 )
167
+ return T (besseli_small_arguments (nu, x)) * exp (- x)
168
+ elseif nu < 100
169
+ return T (_besseli_continued_fractions_scaled (nu, x))
169
170
else
170
171
return besseli_large_orders_scaled (nu, x)
171
172
end
@@ -194,7 +195,6 @@ function besseli_large_orders_scaled(v, x::T) where T <: Union{Float32, Float64}
194
195
195
196
return T (coef* Uk_poly_In (p, v, p2, T))
196
197
end
197
-
198
198
function _besseli_continued_fractions (nu, x:: T ) where T
199
199
S = promote_type (T, Float64)
200
200
xx = S (x)
@@ -203,6 +203,14 @@ function _besseli_continued_fractions(nu, x::T) where T
203
203
(iszero (knu) || iszero (knum1)) && return throw (DomainError (x, " Overflow error" ))
204
204
return 1 / (x * (knum1 + knu / steed (nu, x)))
205
205
end
206
+ function _besseli_continued_fractions_scaled (nu, x:: T ) where T
207
+ S = promote_type (T, Float64)
208
+ xx = S (x)
209
+ knu, knum1 = up_recurrence (xx, besselk0x (xx), besselk1x (xx), nu)
210
+ # if knu or knum1 is zero then besseli will likely overflow
211
+ (iszero (knu) || iszero (knum1)) && return throw (DomainError (x, " Overflow error" ))
212
+ return 1 / (x * (knum1 + knu / steed (nu, x)))
213
+ end
206
214
function steed (n, x:: T ) where T
207
215
MaxIter = 1000
208
216
xinv = inv (x)
@@ -220,7 +228,6 @@ function steed(n, x::T) where T
220
228
end
221
229
return h
222
230
end
223
-
224
231
function besseli_large_argument (v, z:: T ) where T
225
232
MaxIter = 1000
226
233
a = exp (z / 2 )
@@ -239,6 +246,23 @@ function besseli_large_argument(v, z::T) where T
239
246
end
240
247
return res * coef * a
241
248
end
249
+ function besseli_large_argument_scaled (v, z:: T ) where T
250
+ MaxIter = 1000
251
+ coef = inv (sqrt (2 * T (pi ) * z))
252
+ fv2 = 4 * v^ 2
253
+ term = one (T)
254
+ res = term
255
+ s = - term
256
+ for i in 1 : MaxIter
257
+ i = T (i)
258
+ offset = muladd (2 , i, - 1 )
259
+ term *= T (0.125 ) * muladd (offset, - offset, fv2) / (z * i)
260
+ res = muladd (term, s, res)
261
+ s = - s
262
+ abs (term) <= eps (T) && break
263
+ end
264
+ return res * coef
265
+ end
242
266
243
267
function besseli_small_arguments (v, z:: T ) where T
244
268
S = promote_type (T, Float64)
0 commit comments