Skip to content

Commit 8d394ba

Browse files
committed
cleanup and add scaled airy tests
1 parent 077d01a commit 8d394ba

File tree

2 files changed

+60
-47
lines changed

2 files changed

+60
-47
lines changed

src/AiryFunctions/cairy.jl

Lines changed: 58 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -47,26 +47,20 @@ External links: [DLMF](https://dlmf.nist.gov/9.2.2), [Wikipedia](https://en.wiki
4747
See also: [`airyaiprime`](@ref), [`airybi`](@ref)
4848
"""
4949
airyai(z::Number) = _airyai(float(z))
50+
airyaix(z::Number) = _airyaix(float(z))
5051

5152
function _airyai(z::Complex{T}) where T <: Union{Float32, Float64}
52-
if ~isfinite(z)
53-
if abs(angle(z)) < T(2π/3)
54-
return exp(-z)
55-
else
56-
return 1 / z
57-
end
58-
end
59-
6053
x, y = reim(z)
6154

6255
check_conj = false
6356
if y < zero(T)
6457
z = conj(z)
58+
y = -y
6559
check_conj = true
6660
end
6761

6862
if airy_large_argument_cutoff(x, y)
69-
r = airyaix_large_args(z)[1] * exp(-T(2/3) * z * sqrt(z))
63+
r = airyai_large_args(z)[1]
7064
elseif airyai_levin_cutoff(x, y)
7165
r = airyaix_levin(z, Val(17)) * exp(-T(2/3) * z * sqrt(z))
7266
elseif airyai_power_series_cutoff(x, y)
@@ -85,6 +79,7 @@ function _airyaix(z::Complex{T}) where T <: Union{Float32, Float64}
8579
check_conj = false
8680
if y < zero(T)
8781
z = conj(z)
82+
y = -y
8883
check_conj = true
8984
end
9085

@@ -122,26 +117,20 @@ External links: [DLMF](https://dlmf.nist.gov/9.2), [Wikipedia](https://en.wikipe
122117
See also: [`airyai`](@ref), [`airybi`](@ref)
123118
"""
124119
airyaiprime(z::Number) = _airyaiprime(float(z))
120+
airyaiprimex(z::Number) = _airyaiprimex(float(z))
125121

126122
function _airyaiprime(z::Complex{T}) where T <: Union{Float32, Float64}
127-
if ~isfinite(z)
128-
if abs(angle(z)) < T(2π/3)
129-
return -exp(-z)
130-
else
131-
return 1 / z
132-
end
133-
end
134-
135123
x, y = reim(z)
136124

137125
check_conj = false
138126
if y < zero(T)
139127
z = conj(z)
128+
y = -y
140129
check_conj = true
141130
end
142131

143132
if airy_large_argument_cutoff(x, y)
144-
r = airyaix_large_args(z)[2] * exp(-T(2/3) * z * sqrt(z))
133+
r = airyai_large_args(z)[2]
145134
elseif airyai_levin_cutoff(x, y)
146135
r = airyaiprimex_levin(z, Val(17)) * exp(-T(2/3) * z * sqrt(z))
147136
elseif airyai_power_series_cutoff(x, y)
@@ -159,6 +148,7 @@ function _airyaiprimex(z::Complex{T}) where T <: Union{Float32, Float64}
159148
check_conj = false
160149
if y < zero(T)
161150
z = conj(z)
151+
y = -y
162152
check_conj = true
163153
end
164154

@@ -198,24 +188,26 @@ See also: [`airybiprime`](@ref), [`airyai`](@ref)
198188
airybi(z::Number) = _airybi(float(z))
199189

200190
function _airybi(z::Complex{T}) where T <: Union{Float32, Float64}
201-
if ~isfinite(z)
202-
if abs(angle(z)) < T(2π/3)
203-
return exp(z)
204-
else
205-
return 1 / z
206-
end
207-
end
208191
x, y = real(z), imag(z)
209192

193+
check_conj = false
194+
if y < zero(T)
195+
z = conj(z)
196+
y = -y
197+
check_conj = true
198+
end
199+
210200
if airy_large_argument_cutoff(z)
211-
return airybi_large_args(z)[1]
201+
r = airybi_large_args(z)[1]
212202
elseif x > 1.1 && y > 4.2
213-
return airybi_levin(z, Val(16))
203+
r = airybi_levin(z, Val(16))
214204
elseif angle(z) < 7pi/8 || x > -4.5
215-
return airybi_power_series(z)[1]
205+
r = airybi_power_series(z)[1]
216206
else
217-
return cispi(-1/6) * _airyai(z * cispi(-2/3)) + cispi(1/6) * _airyai(z*cispi(2/3))
207+
r = cispi(-1/6) * _airyai(z * cispi(-2/3)) + cispi(1/6) * _airyai(z*cispi(2/3))
218208
end
209+
210+
return check_conj ? conj(r) : r
219211
end
220212
"""
221213
airybiprime(z)
@@ -240,24 +232,26 @@ See also: [`airybi`](@ref), [`airyai`](@ref)
240232
airybiprime(z::Number) = _airybiprime(float(z))
241233

242234
function _airybiprime(z::Complex{T}) where T <: Union{Float32, Float64}
243-
if ~isfinite(z)
244-
if abs(angle(z)) < T(2π/3)
245-
return exp(z)
246-
else
247-
return -1 / z
248-
end
249-
end
250235
x, y = real(z), imag(z)
251236

237+
check_conj = false
238+
if y < zero(T)
239+
z = conj(z)
240+
y = -y
241+
check_conj = true
242+
end
243+
252244
if airy_large_argument_cutoff(z)
253-
return airybi_large_args(z)[2]
245+
r = airybi_large_args(z)[2]
254246
elseif x > 1.1 && y > 4.2
255-
return airybiprime_levin(z, Val(16))
247+
r = airybiprime_levin(z, Val(16))
256248
elseif angle(z) < 7pi/8 || x > -4.5
257-
return airybi_power_series(z)[2]
249+
r = airybi_power_series(z)[2]
258250
else
259-
return cispi(-5/6) * airyaiprime(z * cispi(-2/3)) + cispi(5/6) * airyaiprime(z*cispi(2/3))
251+
r = cispi(-5/6) * airyaiprime(z * cispi(-2/3)) + cispi(5/6) * airyaiprime(z*cispi(2/3))
260252
end
253+
254+
return check_conj ? conj(r) : r
261255
end
262256

263257
#####
@@ -307,18 +301,26 @@ airy_large_argument_cutoff(z::ComplexOrReal{Float32}) = abs(z) > 4
307301

308302
# valid in 0 <= angle(z) <= pi
309303
# use conjugation for bottom half plane
310-
airyai_large_args(z::Complex{T}) where T = airyaix_large_args(z) .* exp(-2/3 * z * sqrt(z))
304+
function airyai_large_args(z::Complex{T}) where T
305+
out = airyaix_large_args(z)
306+
return isfinite(z) ? out .* exp(-T(2/3) * z * sqrt(z)) : out
307+
end
311308

312309
function airybi_large_args(z::Complex{T}) where T
313-
if imag(z) < zero(T)
314-
out = conj.(airybix_large_args(conj(z)))
315-
else
316-
out = airybix_large_args(z)
317-
end
318-
return out .* exp(T(2/3) * z * sqrt(z))
310+
out = airybix_large_args(z)
311+
return isfinite(z) ? out .* exp(T(2/3) * z * sqrt(z)) : out
319312
end
320313

321314
@inline function airyaix_large_args(z::Complex{T}) where T
315+
if ~isfinite(z)
316+
if abs(angle(z)) < T(2π/3)
317+
e = exp(-z)
318+
return (e, -e)
319+
else
320+
invz = 1 / z
321+
return (invz, invz)
322+
end
323+
end
322324
xsqr = sqrt(z)
323325
xsqrx = Base.FastMath.inv_fast(z * xsqr)
324326
A, B, C, D = compute_airy_asy_coef(z, xsqrx)
@@ -337,6 +339,15 @@ end
337339
end
338340

339341
@inline function airybix_large_args(z::Complex{T}) where T
342+
if ~isfinite(z)
343+
if abs(angle(z)) < T(2π/3)
344+
e = exp(z)
345+
return (e, e)
346+
else
347+
invz = 1 / z
348+
return (invz, -invz)
349+
end
350+
end
340351
xsqr = sqrt(z)
341352
xsqrx = Base.FastMath.inv_fast(z * xsqr)
342353
A, B, C, D = compute_airy_asy_coef(z, xsqrx)

test/airy_test.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ end
5151
for x in [0.0, 0.01, 0.5, 1.0, 2.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 50.0], a in 0:pi/12:2pi
5252
z = x*exp(im*a)
5353
@test isapprox(airyai(z), SpecialFunctions.airyai(z), rtol=5e-10)
54+
@test isapprox(airyaix(z), SpecialFunctions.airyaix(z), rtol=5e-10)
5455
@test isapprox(airyaiprime(z), SpecialFunctions.airyaiprime(z), rtol=5e-10)
56+
@test isapprox(airyaiprimex(z), SpecialFunctions.airyaiprimex(z), rtol=5e-10)
5557
@test isapprox(airybi(z), SpecialFunctions.airybi(z), rtol=5e-10)
5658
@test isapprox(airybiprime(z), SpecialFunctions.airybiprime(z), rtol=5e-10)
5759
end

0 commit comments

Comments
 (0)