@@ -136,17 +136,16 @@ end
136
136
Modified Bessel function of the first kind of order nu, ``I_{nu}(x)``.
137
137
Nu must be real.
138
138
"""
139
- function besseli (nu, x:: T ) where T <: Union{Float32, Float64, BigFloat }
139
+ function besseli (nu, x:: T ) where T <: Union{Float32, Float64}
140
140
nu == 0 && return besseli0 (x)
141
141
nu == 1 && return besseli1 (x)
142
-
143
- branch = 60
144
- if nu < branch
145
- inp1 = besseli_large_orders (branch + 1 , x)
146
- in = besseli_large_orders (branch, x)
147
- return down_recurrence (x, in, inp1, nu, branch)
142
+
143
+ if x > maximum ((T (50 ), nu^ 2 / 2 ))
144
+ return T (besseli_large_argument (nu, x))
145
+ elseif nu < 100
146
+ return T (_besseli_continued_fractions (nu, x))
148
147
else
149
- return besseli_large_orders (nu, x)
148
+ return T ( besseli_large_orders (nu, x) )
150
149
end
151
150
end
152
151
156
155
Scaled modified Bessel function of the first kind of order nu, ``I_{nu}(x)*e^{-x}``.
157
156
Nu must be real.
158
157
"""
159
- function besselix (nu, x:: T ) where T <: Union{Float32, Float64, BigFloat }
158
+ function besselix (nu, x:: T ) where T <: Union{Float32, Float64}
160
159
nu == 0 && return besseli0x (x)
161
160
nu == 1 && return besseli1x (x)
162
161
@@ -169,7 +168,7 @@ function besselix(nu, x::T) where T <: Union{Float32, Float64, BigFloat}
169
168
return besseli_large_orders_scaled (nu, x)
170
169
end
171
170
end
172
- function besseli_large_orders (v, x:: T ) where T <: Union{Float32, Float64, BigFloat }
171
+ function besseli_large_orders (v, x:: T ) where T <: Union{Float32, Float64}
173
172
S = promote_type (T, Float64)
174
173
x = S (x)
175
174
z = x / v
@@ -179,9 +178,9 @@ function besseli_large_orders(v, x::T) where T <: Union{Float32, Float64, BigFlo
179
178
p = inv (zs)
180
179
p2 = v^ 2 / fma (max (v,x), max (v,x), min (v,x)^ 2 )
181
180
182
- return T (coef* Uk_poly_In (p, v, p2, T ))
181
+ return T (coef* Uk_poly_In (p, v, p2, Float64 ))
183
182
end
184
- function besseli_large_orders_scaled (v, x:: T ) where T <: Union{Float32, Float64, BigFloat }
183
+ function besseli_large_orders_scaled (v, x:: T ) where T <: Union{Float32, Float64}
185
184
S = promote_type (T, Float64)
186
185
x = S (x)
187
186
z = x / v
@@ -194,19 +193,22 @@ function besseli_large_orders_scaled(v, x::T) where T <: Union{Float32, Float64,
194
193
return T (coef* Uk_poly_In (p, v, p2, T))
195
194
end
196
195
197
- function _besseli_continued_fractions (nu, x)
198
- knu, knum1 = up_recurrence (x, besselk0 (x), besselk1 (x), nu)
196
+ function _besseli_continued_fractions (nu, x:: T ) where T
197
+ S = promote_type (T, Float64)
198
+ xx = S (x)
199
+ knu, knum1 = up_recurrence (xx, besselk0 (xx), besselk1 (xx), nu)
199
200
return 1 / (x * (knum1 + knu / steed (nu, x)))
200
201
end
201
202
202
203
function steed (n, x:: T ) where T
204
+ MaxIter = 1000
203
205
xinv = inv (x)
204
206
xinv2 = 2 * xinv
205
207
d = x / (n + n)
206
208
a = d
207
209
h = a
208
210
b = muladd (2 , n, 2 ) * xinv
209
- for _ in 1 : 100000
211
+ for _ in 1 : MaxIter
210
212
d = inv (b + d)
211
213
a = muladd (b, d, - 1 ) * a
212
214
h = h + a
@@ -215,3 +217,23 @@ function steed(n, x::T) where T
215
217
end
216
218
return h
217
219
end
220
+
221
+ function besseli_large_argument (v, z:: T ) where T
222
+ MaxIter = 1000
223
+ S = promote_type (T, Float64)
224
+ z = S (z)
225
+ coef = exp (z) / sqrt (2 * S (pi )* z)
226
+ fv2 = 4 v^ 2
227
+ term = one (S)
228
+ res = term
229
+ s = - term
230
+ for i in 1 : MaxIter
231
+ offset = muladd (2 , i, - 1 )
232
+ term *= S (0.125 )* (muladd (offset, - offset, fv2)) / (z* i)
233
+ res = muladd (term, s, res)
234
+ s = - s
235
+ abs (term) <= eps (T) && break
236
+ end
237
+ return res* coef
238
+ end
239
+
0 commit comments