1
- #=
2
- Cephes Math Library Release 2.8: June, 2000
3
- Copyright 1984, 1987, 2000 by Stephen L. Moshier
4
- https://github.com/jeremybarnes/cephes/blob/master/bessel/j0.c
5
- https://github.com/jeremybarnes/cephes/blob/master/bessel/j1.c
6
- =#
7
- function besselj0 (x:: Float64 )
8
- T = Float64
1
+ # Bessel functions of the first kind of order zero and one
2
+ # besselj0, besselj1
3
+ #
4
+ # Calculation of besselj0 is done in three branches using polynomial approximations
5
+ #
6
+ # Branch 1: x <= 5.0
7
+ # besselj0 = (x^2 - r1^2)*(x^2 - r2^2)*P3(x^2) / Q8(x^2)
8
+ # where r1 and r2 are zeros of J0
9
+ # and P3 and Q8 are a 3 and 8 degree polynomial respectively
10
+ # Polynomial coefficients are from [1] which is based on [2]
11
+ # See [1] for more details and [2] for coefficients of polynomials
12
+ #
13
+ # Branch 2: 5.0 < x < 80.0
14
+ # besselj0 = sqrt(2/(pi*x))*(cos(x - pi/4)*R7(x) - sin(x - pi/4)*R8(x))
15
+ # Hankel's asymptotic expansion is used
16
+ # where R7 and R8 are rational functions (Pn(x)/Qn(x)) of degree 7 and 8 respectively
17
+ # See section 4 of [3] for more details and [1] for coefficients of polynomials
18
+ #
19
+ # Branch 3: x >= 80.0
20
+ # besselj0 = sqrt(2/(pi*x))*beta(x)*(cos(x - pi/4 - alpha(x))
21
+ # See modified expansions given in [3]. Exact coefficients are used
22
+ #
23
+ # Calculation of besselj1 is done in a similar way as besselj0.
24
+ # See [3] for details on similarities.
25
+ #
26
+ # [1] https://github.com/deepmind/torch-cephes
27
+ # [2] Cephes Math Library Release 2.8: June, 2000 by Stephen L. Moshier
28
+ # [3] Harrison, John. "Fast and accurate Bessel function computation."
29
+ # 2009 19th IEEE Symposium on Computer Arithmetic. IEEE, 2009.
30
+
31
+ function besselj0 (x:: T ) where T
9
32
x = abs (x)
10
- iszero (x) && return one (x)
11
33
isinf (x) && return zero (x)
12
34
13
35
if x <= 5
14
36
z = x * x
15
37
if x < 1.0e-5
16
38
return 1.0 - z / 4.0
17
39
end
18
-
19
- DR1 = 5.78318596294678452118E0
20
- DR2 = 3.04712623436620863991E1
21
-
40
+ DR1 = 5.78318596294678452118e0
41
+ DR2 = 3.04712623436620863991e1
22
42
p = (z - DR1) * (z - DR2)
23
43
p = p * evalpoly (z, RP_j0 (T)) / evalpoly (z, RQ_j0 (T))
24
44
return p
25
- elseif x < 100 .0
45
+ elseif x < 80 .0
26
46
w = 5.0 / x
27
47
q = 25.0 / (x * x)
28
48
@@ -40,8 +60,9 @@ function besselj0(x::Float64)
40
60
a = SQ2OPI (T) * sqrt (xinv) * p
41
61
42
62
q = (- 1 / 8 , 25 / 384 , - 1073 / 5120 , 375733 / 229376 , - 55384775 / 2359296 )
43
- xn = muladd (xinv, evalpoly (x2, q), - PIO4 (T))
44
- b = cos (x + xn)
63
+ xn = fma (xinv, evalpoly (x2, q), - PIO4 (T))
64
+ b = cos (x)* cos (xn) - sin (x)* sin (xn)# cos(x + xn)
65
+ # b = cos(x + xn)
45
66
return a * b
46
67
end
47
68
end
@@ -187,53 +208,3 @@ function besselj(n::Int, x::Float64)
187
208
188
209
return sign * ans
189
210
end
190
-
191
-
192
- function b2 (v, x)
193
-
194
- a = (x/ 2 )^ v
195
- out = 1 / gamma (v + 1 )
196
- for k in 1 : 100
197
- out += (- x^ 2 / 4 )^ k / factorial (BigFloat (k)) / factorial (v + BigFloat (k))
198
- end
199
- return out* a
200
- end
201
-
202
- function b (nu, x:: T ) where T
203
- coef = (x/ 2 )^ nu / gamma (nu + 1 )
204
-
205
- x2 = (x/ 2 )^ 2
206
-
207
-
208
- maxiter = 10000
209
- b = one (T)
210
- for k in 1 : maxiter
211
- z = - x2 / (k * (k + nu))
212
- b += z* b
213
- end
214
- return b * coef
215
- end
216
-
217
-
218
- # ## for this function dd can be calculated accurately but there is a build up in error for val as we sum
219
- # # looks like only works for small arguments and smallish orders....
220
- function b3 (v, x:: T ) where T
221
- MaxIter = 5000
222
- if v < 20
223
- coef = (x / 2 )^ v / factorial (v)
224
- else
225
- vinv = inv (v)
226
- coef = sqrt (vinv / (2 * π)) * MathConstants. e^ (v * (log (x / (2 * v)) + 1 ))
227
- coef *= evalpoly (vinv, (1 , - 1 / 12 , 1 / 288 , 139 / 51840 , - 571 / 2488320 , - 163879 / 209018880 , 5246819 / 75246796800 , 534703531 / 902961561600 ))
228
- end
229
-
230
- x2 = (x / 2 )^ 2
231
- val = zero (T)
232
-
233
- for k in 1 : MaxIter
234
- val += coef
235
- coef = - coef * x2 / (k * (v + k))
236
- abs (coef) < eps (T) * abs (val) && break
237
- end
238
- return val
239
- end
0 commit comments