Skip to content

Commit b4bf95d

Browse files
authored
Merge pull request #57 from JuliaMath/large_arg
Fix very large argument expansion in besselj0 and friends
2 parents 3bd0109 + 863a20c commit b4bf95d

File tree

4 files changed

+39
-1
lines changed

4 files changed

+39
-1
lines changed

src/besselj.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ function _besselj0(x::Float64)
5757
q2 = (-1/8, 25/384, -1073/5120, 375733/229376)
5858
p = evalpoly(x2, p2)
5959
q = evalpoly(x2, q2)
60+
if x > 1e15
61+
a = SQ2OPI(T) * sqrt(xinv) * p
62+
xn = muladd(xinv, q, -PIO4(T))
63+
s_x, c_x = sincos(x)
64+
s_xn, c_xn = sincos(xn)
65+
return a * (c_x * c_xn - s_x * s_xn)
66+
end
6067
end
6168

6269
a = SQ2OPI(T) * sqrt(xinv) * p
@@ -126,6 +133,13 @@ function _besselj1(x::Float64)
126133
q2 = (3/8, -21/128, 1899/5120, -543483/229376)
127134
p = evalpoly(x2, p2)
128135
q = evalpoly(x2, q2)
136+
if x > 1e15
137+
a = SQ2OPI(T) * sqrt(xinv) * p
138+
xn = muladd(xinv, q, -3 * PIO4(T))
139+
s_x, c_x = sincos(x)
140+
s_xn, c_xn = sincos(xn)
141+
return s * a * (c_x * c_xn - s_x * s_xn)
142+
end
129143
end
130144

131145
a = SQ2OPI(T) * sqrt(xinv) * p

src/bessely.jl

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,17 @@ function _bessely0_compute(x::Float64)
7979
q2 = (-1/8, 25/384, -1073/5120, 375733/229376)
8080
p = evalpoly(x2, p2)
8181
q = evalpoly(x2, q2)
82+
if x > 1e15
83+
a = SQ2OPI(T) * sqrt(xinv) * p
84+
xn = muladd(xinv, q, -PIO4(T))
85+
s_x, c_x = sincos(x)
86+
s_xn, c_xn = sincos(xn)
87+
return a * (s_x * c_xn + c_x * s_xn)
88+
end
8289
end
8390

8491
a = SQ2OPI(T) * sqrt(xinv) * p
85-
xn = muladd(xinv, q, - PIO4(T))
92+
xn = muladd(xinv, q, -PIO4(T))
8693

8794
# the following computes b = sin(x + xn) more accurately
8895
# see src/misc.jl
@@ -159,6 +166,13 @@ function _bessely1_compute(x::Float64)
159166
q2 = (3/8, -21/128, 1899/5120, -543483/229376)
160167
p = evalpoly(x2, p2)
161168
q = evalpoly(x2, q2)
169+
if x > 1e15
170+
a = SQ2OPI(T) * sqrt(xinv) * p
171+
xn = muladd(xinv, q, - 3 * PIO4(T))
172+
s_x, c_x = sincos(x)
173+
s_xn, c_xn = sincos(xn)
174+
return a * (s_x * c_xn + c_x * s_xn)
175+
end
162176
end
163177

164178
a = SQ2OPI(T) * sqrt(xinv) * p

test/besselj_test.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ j1_32 = besselj1.(Float32.(x))
7272
@test besselj1(-80.0f0) SpecialFunctions.besselj1(-80.0f0)
7373
@test besselj1(-80.0) SpecialFunctions.besselj1(-80.0)
7474

75+
# tests for very large inputs
76+
x = [1e12, 5e12, 1e13, 5e13, 1e14, 5e14, 1e15, 5e15, 1e16, 5e16, 1e17, 5e17, 1e18, 5e18, 1e19, 5e19, 1e20, 1e22, 1e25, 1e30, 1e40]
77+
@test besselj0.(x) SpecialFunctions.besselj0.(x)
78+
@test besselj1.(x) SpecialFunctions.besselj1.(x)
79+
7580
## Tests for besselj
7681

7782
#=

test/bessely_test.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ y1_32 = bessely1.(Float32.(x))
6868
@test bessely1(Inf32) == zero(Float32)
6969
@test bessely1(Inf64) == zero(Float64)
7070

71+
# tests for very large inputs
72+
x = [1e12, 5e12, 1e13, 5e13, 1e14, 5e14, 1e15, 5e15, 1e16, 5e16, 1e17, 5e17, 1e18, 5e18, 1e19, 5e19, 1e20, 1e22, 1e25, 1e30, 1e40]
73+
@test bessely0.(x) SpecialFunctions.bessely0.(x)
74+
@test bessely1.(x) SpecialFunctions.bessely1.(x)
75+
7176
## Tests for bessely
7277

7378
## test all numbers and orders for 0<nu<100

0 commit comments

Comments
 (0)