|
15 | 15 | # Hankel's asymptotic expansion is used
|
16 | 16 | # where R7 and R8 are rational functions (Pn(x)/Qn(x)) of degree 7 and 8 respectively
|
17 | 17 | # See section 4 of [3] for more details and [1] for coefficients of polynomials
|
18 |
| -# |
| 18 | +# |
19 | 19 | # Branch 3: x >= 25.0
|
20 | 20 | # bessely0 = sqrt(2/(pi*x))*beta(x)*(sin(x - pi/4 - alpha(x))
|
21 | 21 | # See modified expansions given in [3]. Exact coefficients are used.
|
22 | 22 | #
|
23 | 23 | # Calculation of bessely1 is done in a similar way as bessely0.
|
24 | 24 | # See [3] for details on similarities.
|
25 |
| -# |
| 25 | +# |
26 | 26 | # [1] https://github.com/deepmind/torch-cephes
|
27 | 27 | # [2] Cephes Math Library Release 2.8: June, 2000 by Stephen L. Moshier
|
28 |
| -# [3] Harrison, John. "Fast and accurate Bessel function computation." |
| 28 | +# [3] Harrison, John. "Fast and accurate Bessel function computation." |
29 | 29 | # 2009 19th IEEE Symposium on Computer Arithmetic. IEEE, 2009.
|
30 | 30 | #
|
31 | 31 |
|
@@ -63,19 +63,22 @@ function _bessely0_compute(x::Float64)
|
63 | 63 | p = p * sc[1] + w * q * sc[2]
|
64 | 64 | return p * SQ2OPI(T) / sqrt(x)
|
65 | 65 | else
|
| 66 | + xinv = inv(x) |
| 67 | + x2 = xinv*xinv |
66 | 68 | if x < 120.0
|
67 |
| - p = (one(T), -1/16, 53/512, -4447/8192, 3066403/524288, -896631415/8388608, 796754802993/268435456, -500528959023471/4294967296) |
68 |
| - q = (-1/8, 25/384, -1073/5120, 375733/229376, -55384775/2359296, 24713030909/46137344, -7780757249041/436207616) |
| 69 | + p1 = (one(T), -1/16, 53/512, -4447/8192, 3066403/524288, -896631415/8388608, 796754802993/268435456, -500528959023471/4294967296) |
| 70 | + q1 = (-1/8, 25/384, -1073/5120, 375733/229376, -55384775/2359296, 24713030909/46137344, -7780757249041/436207616) |
| 71 | + p = evalpoly(x2, p1) |
| 72 | + q = evalpoly(x2, q1) |
69 | 73 | else
|
70 |
| - p = (one(T), -1/16, 53/512, -4447/8192) |
71 |
| - q = (-1/8, 25/384, -1073/5120, 375733/229376) |
| 74 | + p2 = (one(T), -1/16, 53/512, -4447/8192) |
| 75 | + q2 = (-1/8, 25/384, -1073/5120, 375733/229376) |
| 76 | + p = evalpoly(x2, p2) |
| 77 | + evalpoly(x2, q2) |
72 | 78 | end
|
73 |
| - xinv = inv(x) |
74 |
| - x2 = xinv*xinv |
75 | 79 |
|
76 |
| - p = evalpoly(x2, p) |
77 | 80 | a = SQ2OPI(T) * sqrt(xinv) * p
|
78 |
| - xn = muladd(xinv, evalpoly(x2, q), - PIO4(T)) |
| 81 | + xn = muladd(xinv, q, - PIO4(T)) |
79 | 82 |
|
80 | 83 | # the following computes b = sin(x + xn) more accurately
|
81 | 84 | # see src/misc.jl
|
@@ -136,19 +139,22 @@ function _bessely1_compute(x::Float64)
|
136 | 139 | p = p * sc[1] + w * q * sc[2]
|
137 | 140 | return p * SQ2OPI(T) / sqrt(x)
|
138 | 141 | else
|
| 142 | + xinv = inv(x) |
| 143 | + x2 = xinv*xinv |
139 | 144 | if x < 120.0
|
140 |
| - p = (one(T), 3/16, -99/512, 6597/8192, -4057965/524288, 1113686901/8388608, -951148335159/268435456, 581513783771781/4294967296) |
141 |
| - q = (3/8, -21/128, 1899/5120, -543483/229376, 8027901/262144, -30413055339/46137344, 9228545313147/436207616) |
| 145 | + p1 = (one(T), 3/16, -99/512, 6597/8192, -4057965/524288, 1113686901/8388608, -951148335159/268435456, 581513783771781/4294967296) |
| 146 | + q1 = (3/8, -21/128, 1899/5120, -543483/229376, 8027901/262144, -30413055339/46137344, 9228545313147/436207616) |
| 147 | + p = evalpoly(x2, p1) |
| 148 | + q = evalpoly(x2, q1) |
142 | 149 | else
|
143 |
| - p = (one(T), 3/16, -99/512, 6597/8192) |
144 |
| - q = (3/8, -21/128, 1899/5120, -543483/229376) |
| 150 | + p2 = (one(T), 3/16, -99/512, 6597/8192) |
| 151 | + q2 = (3/8, -21/128, 1899/5120, -543483/229376) |
| 152 | + p = evalpoly(x2, q2) |
| 153 | + q = evalpoly(x2, q2) |
145 | 154 | end
|
146 |
| - xinv = inv(x) |
147 |
| - x2 = xinv*xinv |
148 | 155 |
|
149 |
| - p = evalpoly(x2, p) |
150 | 156 | a = SQ2OPI(T) * sqrt(xinv) * p
|
151 |
| - xn = muladd(xinv, evalpoly(x2, q), - 3 * PIO4(T)) |
| 157 | + xn = muladd(xinv, q, - 3 * PIO4(T)) |
152 | 158 |
|
153 | 159 | # the following computes b = sin(x + xn) more accurately
|
154 | 160 | # see src/misc.jl
|
|
0 commit comments