Skip to content

Commit d37b06b

Browse files
committed
add domain errors bessely
1 parent 3d2f133 commit d37b06b

File tree

4 files changed

+103
-45
lines changed

4 files changed

+103
-45
lines changed

src/j0.jl

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@
2020
#
2121
#
2222
function besselj0(x::Float64)
23+
x = abs(x)
24+
if iszero(x)
25+
return one(x)
26+
elseif isinf(x)
27+
return zero(x)
28+
end
29+
2330
if x <= 5.0
2431
z = x * x
2532
if x < 1.0e-5
@@ -78,8 +85,11 @@ end
7885

7986

8087
function besselj0(x::Float32)
81-
if x < 0.0f0
82-
x *= -1
88+
x = abs(x)
89+
if iszero(x)
90+
return one(x)
91+
elseif isinf(x)
92+
return zero(x)
8393
end
8494

8595
if x <= 2.0f0
@@ -97,7 +107,7 @@ function besselj0(x::Float32)
97107
p = (z - DR1) * evalpoly(z, JP)
98108
return p
99109
else
100-
q = 1.0f0 / x
110+
q = inv(x)
101111
w = sqrt(q)
102112

103113
MO = (
@@ -142,17 +152,22 @@ end
142152
# Q0(x) = 1/x (-.125 + 1/x^2 R(1/x^2))
143153
#
144154
function besselj0(x::BigFloat)
145-
xx = abs(x)
146-
if iszero(xx)
147-
return one(BigFloat)
148-
elseif xx <= 2.0
149-
z = xx * xx
155+
x = abs(x)
156+
T = eltype(x)
157+
if iszero(x)
158+
return one(x)
159+
elseif isinf(x)
160+
return zero(x)
161+
end
162+
163+
if x <= 2.0
164+
z = x * x
150165
p = z * z * evalpoly(z, J0_2N) / evalpoly(z, J0_2D)
151166
p -= 0.25 * z
152-
p += 1.0
167+
p += one(T)
153168
return p
154169
else
155-
xinv = 1.0 / xx
170+
xinv = inv(x)
156171
z = xinv * xinv
157172
if xinv <= 0.25
158173
if xinv <= 0.125
@@ -191,17 +206,17 @@ function besselj0(x::BigFloat)
191206
p = 1.0 + z * p
192207
q = z * xinv * q
193208
q = q - 0.125 * xinv
194-
c = cos(xx)
195-
s = sin(xx)
209+
c = cos(x)
210+
s = sin(x)
196211
ss = s - c
197212
cc = s + c
198-
z = -cos(xx + xx)
213+
z = -cos(x + x)
199214
if (s * c) < 0
200215
cc = z / ss;
201216
else
202217
ss = z / cc;
203218
end
204-
z = ONEOSQPI(BigFloat) * (p * cc - q * ss) / sqrt(xx)
219+
z = ONEOSQPI(T) * (p * cc - q * ss) / sqrt(x)
205220
return z
206221
end
207222
end

src/j1.jl

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
function besselj1(x::Float32)
2-
if x < zero(x)
3-
x = -x
2+
x = abs(x)
3+
if iszero(x)
4+
return one(x)
5+
elseif isinf(x)
6+
return zero(x)
47
end
8+
59
if x <= 2.0f0
610
z = x * x
711
Z1 = 1.46819706421238932572f1
@@ -19,15 +23,17 @@ function besselj1(x::Float32)
1923
end
2024

2125
function besselj1(x::Float64)
22-
w = x
23-
if x < 0
24-
w = -x
26+
x = abs(x)
27+
if iszero(x)
28+
return one(x)
29+
elseif isinf(x)
30+
return zero(x)
2531
end
2632

27-
if w <= 5.0
33+
if x <= 5.0
2834
z = x * x
2935
w = evalpoly(z, RP) / evalpoly(z, RQ)
30-
w = w * x * (z - 1.46819706421238932572E1) * (z - 4.92184563216946036703E1)
36+
w = w * x * (z - 1.46819706421238932572e1) * (z - 4.92184563216946036703e1)
3137
return w
3238
else
3339
w = 5.0 / x
@@ -41,10 +47,17 @@ function besselj1(x::Float64)
4147
end
4248

4349
function bessely1(x::Float32)
44-
if x <= 2.0f0
45-
if x <= zero(x)
46-
return error("Domain error: x <= 0")
50+
if x <= zero(x)
51+
if iszero(x)
52+
return -Inf32
53+
else
54+
return throw(DomainError(x, "NaN result for non-NaN input."))
4755
end
56+
elseif isinf(x)
57+
return zero(x)
58+
end
59+
60+
if x <= 2.0f0
4861
z = x * x
4962
YO1 = 4.66539330185668857532f0
5063
w = (z - YO1) * x * evalpoly(z, YP32)
@@ -62,10 +75,17 @@ function bessely1(x::Float32)
6275
end
6376

6477
function bessely1(x::Float64)
65-
if x <= 5.0
66-
if x< 0.0
67-
return NaN
78+
if x <= zero(x)
79+
if iszero(x)
80+
return -Inf64
81+
else
82+
return throw(DomainError(x, "NaN result for non-NaN input."))
6883
end
84+
elseif isinf(x)
85+
return zero(x)
86+
end
87+
88+
if x <= 5.0
6989
z = x * x
7090
w = x * (evalpoly(z, YP) / evalpoly(z, YQ))
7191
w += TWOOPI(Float64) * (besselj1(x) * log(x) - inv(x))

src/y0.jl

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,16 @@
2121
# Ported to Julia in December 2021 by Michael Helton
2222
#
2323
function bessely0(x::Float64)
24-
if x <= 5.0
25-
if x <= 0.0
26-
return NaN64
24+
if x <= zero(x)
25+
if iszero(x)
26+
return -Inf64
27+
else
28+
return throw(DomainError(x, "NaN result for non-NaN input."))
2729
end
30+
elseif isinf(x)
31+
return zero(x)
32+
end
33+
if x <= 5.0
2834
z = x * x
2935

3036
YP = (
@@ -78,14 +84,16 @@ end
7884

7985

8086
function bessely0(x::Float32)
81-
if x <= 2.0f0
82-
if x <= 0.0f0
83-
if x == 0.0f0
84-
return -Inf32
85-
end
86-
return NaN32
87+
if x <= zero(x)
88+
if iszero(x)
89+
return -Inf32
90+
else
91+
return throw(DomainError(x, "NaN result for non-NaN input."))
8792
end
88-
93+
elseif isinf(x)
94+
return zero(x)
95+
end
96+
if x <= 2.0f0
8997
z = x * x
9098
YZ1 = 0.43221455686510834878f0
9199
YP = (
@@ -122,16 +130,16 @@ end
122130

123131

124132
function bessely0(x::BigFloat)
125-
if isnan(x)
126-
return NaN
127-
elseif x < zero(x)
128-
return NaN
129-
elseif iszero(x)
130-
return -Inf
133+
if x <= zero(x)
134+
if iszero(x)
135+
return -Inf
136+
else
137+
return throw(DomainError(x, "NaN result for non-NaN input."))
138+
end
131139
elseif isinf(x)
132140
return zero(x)
133141
end
134-
142+
135143
xx = abs(x)
136144

137145
if xx <= 2.0
@@ -141,7 +149,7 @@ function bessely0(x::BigFloat)
141149
return p
142150
end
143151

144-
xinv = 1.0 / xx
152+
xinv = inv(xx)
145153
z = xinv * xinv
146154
if xinv <= 0.25
147155
if xinv <= 0.125

test/bessely_test.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ y0_big = bessely0.(big.(x))
1616

1717
@test isapprox(y0_big, y0_SpecialFunctions, atol=1.5e-34)
1818

19+
@test_throws DomainError bessely0(-1.0)
20+
21+
@test bessely0(zero(Float32)) == -Inf32
22+
@test bessely0(zero(Float64)) == -Inf64
23+
@test bessely0(zero(BigFloat)) == -Inf
24+
25+
@test bessely0(Inf32) == zero(Float32)
26+
@test bessely0(Inf64) == zero(Float64)
1927

2028
y1_SpecialFunctions = SpecialFunctions.bessely1.(big.(x))
2129
@assert y1_SpecialFunctions[1] isa BigFloat
@@ -31,4 +39,11 @@ y1_32 = bessely1.(Float32.(x))
3139
@test y1_64 y1_SpecialFunctions
3240
@test y1_32 y1_SpecialFunctions
3341

42+
@test_throws DomainError bessely1(-1.0)
43+
44+
@test bessely1(zero(Float32)) == -Inf32
45+
@test bessely1(zero(Float64)) == -Inf64
46+
47+
@test bessely1(Inf32) == zero(Float32)
48+
@test bessely1(Inf64) == zero(Float64)
3449

0 commit comments

Comments
 (0)