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
- =#
1
+ # Bessel functions of the second kind of order zero and one
2
+ # bessely0, bessely1
3
+ #
4
+ # Calculation of bessely0 is done in three branches using polynomial approximations
5
+ #
6
+ # Branch 1: x <= 5.0
7
+ # bessely0 = R(x^2) + 2*log(x)*besselj0(x) / pi
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
+ # For tiny arugments the power series expansion is used.
13
+ #
14
+ # Branch 2: 5.0 < x < 75.0
15
+ # bessely0 = sqrt(2/(pi*x))*(sin(x - pi/4)*R7(x) - cos(x - pi/4)*R8(x))
16
+ # Hankel's asymptotic expansion is used
17
+ # where R7 and R8 are rational functions (Pn(x)/Qn(x)) of degree 7 and 8 respectively
18
+ # See section 4 of [3] for more details and [1] for coefficients of polynomials
19
+ #
20
+ # Branch 3: x >= 75.0
21
+ # bessely0 = sqrt(2/(pi*x))*beta(x)*(sin(x - pi/4 - alpha(x))
22
+ # See modified expansions given in [3]. Exact coefficients are used.
23
+ #
24
+ # Calculation of bessely1 is done in a similar way as bessely0.
25
+ # See [3] for details on similarities.
26
+ #
27
+ # [1] https://github.com/deepmind/torch-cephes
28
+ # [2] Cephes Math Library Release 2.8: June, 2000 by Stephen L. Moshier
29
+ # [3] Harrison, John. "Fast and accurate Bessel function computation."
30
+ # 2009 19th IEEE Symposium on Computer Arithmetic. IEEE, 2009.
31
+ #
7
32
function bessely0 (x:: T ) where T <: Union{Float32, Float64}
8
33
if x <= zero (x)
9
34
if iszero (x)
@@ -43,12 +68,9 @@ function _bessely0_compute(x::Float64)
43
68
q = (- 1 / 8 , 25 / 384 , - 1073 / 5120 , 375733 / 229376 , - 55384775 / 2359296 )
44
69
xn = muladd (xinv, evalpoly (x2, q), - PIO4 (T))
45
70
46
- # the following computes b = sin(x + xn)
47
- # but uses cos(x)*sin(xn) + sin(x)*cos(xn)
48
- # to improve accuracy when x >> xn
49
- c1 = sincos (x)
50
- c2 = sincos (xn)
51
- b = c1[2 ] * c2[1 ] + c1[1 ] * c2[2 ]
71
+ # the following computes b = sin(x + xn) more accurately
72
+ # see src/misc.jl
73
+ b = mysin (x, xn)
52
74
return a * b
53
75
end
54
76
end
@@ -110,12 +132,9 @@ function _bessely1_compute(x::Float64)
110
132
q = (3 / 8 , - 21 / 128 , 1899 / 5120 , - 543483 / 229376 , 8027901 / 262144 )
111
133
xn = muladd (xinv, evalpoly (x2, q), - 3 * PIO4 (T))
112
134
113
- # the following computes b = sin(x + xn)
114
- # but uses cos(x)*sin(xn) + sin(x)*cos(xn)
115
- # to improve accuracy when x >> xn
116
- c1 = sincos (x)
117
- c2 = sincos (xn)
118
- b = c1[2 ] * c2[1 ] + c1[1 ] * c2[2 ]
135
+ # the following computes b = sin(x + xn) more accurately
136
+ # see src/misc.jl
137
+ b = mysin (x, xn)
119
138
return a * b
120
139
end
121
140
end
@@ -124,7 +143,7 @@ function _bessely1_compute(x::Float32)
124
143
T = Float32
125
144
if x <= 2.0f0
126
145
z = x * x
127
- YO1 = 4.66539330185668857532f0
146
+ YO1 = 4.66539330185668857532f0
128
147
w = (z - YO1) * x * evalpoly (z, YP32)
129
148
w += TWOOPI (Float32) * (besselj1 (x) * log (x) - inv (x))
130
149
return w
0 commit comments