Skip to content

Commit b6a2996

Browse files
committed
add tests
1 parent 919c449 commit b6a2996

File tree

2 files changed

+27
-17
lines changed

2 files changed

+27
-17
lines changed

src/besselj.jl

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ Nu must be real.
159159
function _besselj(nu, x)
160160
nu == 0 && return besselj0(x)
161161
nu == 1 && return besselj1(x)
162-
if x < 30.0
162+
if x < 20.0
163163
if nu > 60.0
164164
return log_besselj_small_arguments_orders(nu, x)
165165
else
@@ -215,9 +215,10 @@ end
215215

216216
# this needs a better way to sum these as it produces large errors
217217
# only valid in non-oscillatory regime (v>1/2, 0<t<sqrt(v^2 - 0.25))
218-
# power series has premature underflow for large orders
218+
# power series has premature underflow for large orders
219+
# gives wrong answers for x > 20.0 (might want to fix this)
219220
function besselj_small_arguments_orders(v, x::T) where T
220-
MaxIter = 1_000
221+
MaxIter = 1000
221222
out = zero(T)
222223
a = (x/2)^v / gamma(v + one(T))
223224
t2 = (x/2)^2
@@ -230,10 +231,10 @@ function besselj_small_arguments_orders(v, x::T) where T
230231
end
231232

232233
# this needs a better way to sum these as it produces large errors
233-
# perhaps use when v is small i believe v also has to be positive for this to work
234+
# use when v is large and x is small
234235
# need for bessely
235236
function log_besselj_small_arguments_orders(v, x::T) where T
236-
MaxIter = 500
237+
MaxIter = 1000
237238
out = zero(T)
238239
a = one(T)
239240
x2 = (x/2)^2
@@ -242,7 +243,6 @@ function log_besselj_small_arguments_orders(v, x::T) where T
242243
a = -a * x2 * inv((i + one(T)) * (v + i + one(T)))
243244
(abs(a) < eps(T) * abs(out)) && break
244245
end
245-
@show out
246246
logout = -loggamma(v + 1) + fma(v, log(x/2), log(out))
247247
return exp(logout)
248248
end
@@ -284,6 +284,7 @@ function gamma(x)
284284
end
285285
end
286286
function large_gamma(x)
287+
isinf(x) && return x
287288
T = Float64
288289
w = inv(x)
289290
s = (
@@ -294,15 +295,10 @@ function large_gamma(x)
294295
w = w * evalpoly(w, s) + one(T)
295296
# lose precision on following block
296297
y = exp((x))
297-
if x > 143.01608
298-
isinf(x) && return x
299-
# avoid overflow
300-
v = x^(0.5 * x - 0.25)
301-
y = v * (v / y)
302-
else
303-
y = x^(x - 0.5) / y
304-
# (x - 0.5) * log(x) - x
305-
end
298+
# avoid overflow
299+
v = x^(0.5 * x - 0.25)
300+
y = v * (v / y)
301+
306302
return SQ2PI(T) * y * w
307303
end
308304
function small_gamma(x)

test/besselj_test.jl

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,25 @@ j1_32 = besselj1.(Float32.(x))
7878
#@test besselj(-5, 6.1) ≈ SpecialFunctions.besselj(-5, 6.1)
7979

8080
## test the small value approximation using power series
81-
8281
nu = [0.5, 1.5, 3.0, 10.0, 22.2, 35.0, 52.1, 100.0, 250.2, 500.0, 1000.0]
83-
x = [0.001, 1.0, 5.0, 15.0, 29.9]
82+
x = [0.001, 1.0, 5.0, 15.0, 19.9]
8483

8584
for v in nu, x in x
85+
@test Bessels._besselj(v, x) SpecialFunctions.besselj(v, x)
86+
end
87+
88+
## test the large argument asymptotic expansion
89+
vnu = ((0.5, 21.0), (0.5, 45.0), (3.5, 21.0), (10.0, 21.0), (21.2, 45.0), (43.2, 90.0), (100.1, 205.2))
90+
91+
for (v, x) in vnu
92+
@test Bessels._besselj(v, x) SpecialFunctions.besselj(v, x)
93+
end
94+
95+
## test the debye uniform asymptotic expansion for x < nu
96+
vnu = ((60.5, 21.0), (100.5, 45.0), (150.5, 61.0))
97+
98+
for (v, x) in vnu
8699
@show v, x
87100
@test Bessels._besselj(v, x) SpecialFunctions.besselj(v, x)
88101
end
102+

0 commit comments

Comments
 (0)