Skip to content

Commit 454126d

Browse files
authored
more expint fixes (#262)
* more expint fixes * typography fix in LaTeX equations
1 parent e91a47d commit 454126d

File tree

3 files changed

+16
-11
lines changed

3 files changed

+16
-11
lines changed

docs/src/functions_overview.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ Here the *Special Functions* are listed according to the structure of [NIST Digi
2626
## [Exponential and Trigonometric Integrals](https://dlmf.nist.gov/6)
2727
| Function | Description |
2828
|:-------- |:----------- |
29-
| [`expint(ν, z)`](@ref SpecialFunctions.expint) | [exponential integral](https://en.wikipedia.org/wiki/Exponential_integral) ``E_\nu(z)`` |
29+
| [`expint(ν, z)`](@ref SpecialFunctions.expint) | [exponential integral](https://en.wikipedia.org/wiki/Exponential_integral) ``\operatorname{E}_\nu(z)`` |
3030
| [`expinti(x)`](@ref SpecialFunctions.expint) | [exponential integral](https://en.wikipedia.org/wiki/Exponential_integral) ``\operatorname{Ei}(z)`` |
31-
| [`sinint(x)`](@ref SpecialFunctions.sinint) | [sine integral](https://en.wikipedia.org/wiki/Trigonometric_integral#Sine_integral) ``Si(x)`` |
32-
| [`cosint(x)`](@ref SpecialFunctions.cosint) | [cosine integral](https://en.wikipedia.org/wiki/Trigonometric_integral#Cosine_integral) ``Ci(x)`` |
31+
| [`sinint(x)`](@ref SpecialFunctions.sinint) | [sine integral](https://en.wikipedia.org/wiki/Trigonometric_integral#Sine_integral) ``\operatorname{Si}(x)`` |
32+
| [`cosint(x)`](@ref SpecialFunctions.cosint) | [cosine integral](https://en.wikipedia.org/wiki/Trigonometric_integral#Cosine_integral) ``\operatorname{Ci}(x)`` |
3333

3434

3535
## [Error Functions, Dawson’s and Fresnel Integrals](https://dlmf.nist.gov/7)

src/expint.jl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ function En_cf_nogamma(ν::Number, z::Number, n::Int=1000)
187187
end
188188

189189
exppart = exp(-z)
190-
if abs(real(exppart)) == Inf && abs(imag(exppart)) == Inf
190+
if isinf(exppart)
191191
return exp(-z + log(A) - log(B)), iters
192192
else
193193
cfpart = A/B
@@ -235,7 +235,7 @@ function En_cf_gamma(ν::Number, z::Number, n::Int=1000)
235235

236236
gammapart = En_safe_gamma_term(ν, z)
237237
cfpart = exp(-z)
238-
if abs(real(cfpart)) == Inf || abs(imag(cfpart)) == Inf
238+
if isinf(cfpart)
239239
factor = sign(real(cfpart)) + sign(imag(cfpart))*im
240240
cfpart = exp(-z + log(B) - log(A))
241241
else
@@ -351,12 +351,11 @@ function En_imagbranchcut(ν::Number, z::Number)
351351
return imag(impart) * im # get rid of any real error
352352
end
353353

354-
const ORIGIN_EXPAND_THRESH = 3
355354
"""
356355
expint(z)
357356
expint(ν, z)
358357
359-
Computes the exponential integral ``E_\\nu(z) = \\int_0^\\infty \\frac{e^{-zt}}{t^\\nu} dt``.
358+
Computes the exponential integral ``\\operatorname{E}_\\nu(z) = \\int_0^\\infty \\frac{e^{-zt}}{t^\\nu} dt``.
360359
If ``\\nu`` is not specified, ``\\nu=1`` is used. Arbitrary complex ``\\nu`` and ``z`` are supported.
361360
362361
External links: [DLMF](https://dlmf.nist.gov/8.19), [Wikipedia](https://en.wikipedia.org/wiki/Exponential_integral)
@@ -384,13 +383,13 @@ function expint(ν::Number, z::Number, niter::Int=1000)
384383
elseif ν == 1 && real(z) > 0 && z isa Union{Float64, Complex{Float64}}
385384
return expint_opt(z)
386385
end
387-
# asymptotic test for |z| → ∞
386+
# asymptotic test for underflow when Re z → ∞
388387
# https://functions.wolfram.com/GammaBetaErf/ExpIntegralE/06/02/0003/
389-
if exp(-z) / z == 0
388+
if real(z) > -log(nextfloat(zero(real(z))))+1 # exp(-z) is zero
390389
return zero(z)
391390
end
392391

393-
if abs(z) < ORIGIN_EXPAND_THRESH
392+
if abs2(z) < 9
394393
# use Taylor series about the origin for small z
395394
return En_expand_origin(ν, z)
396395
end
@@ -413,6 +412,7 @@ function expint(ν::Number, z::Number, niter::Int=1000)
413412
imstart = (imz == 0) ? abs(z)*sqrt(eps(typeof(real(z)))) : imz
414413
z₀ = rez + imstart*im
415414
E_start, i, _ = En_cf(ν, z₀, quick_niter)
415+
isnan(E_start) && return E_start
416416
if imz > 0 && i < nmax
417417
# didn't need to take any steps
418418
return doconj ? conj(E_start) : E_start
@@ -451,7 +451,7 @@ end
451451
expinti(x::Real)
452452
453453
Computes the exponential integral function ``\\operatorname{Ei}(x) = \\int_{-\\infty}^x \\frac{e^t}{t} dt``,
454-
which is equivalent to ``-\\Re[E_1(-x)]`` where ``E_1`` is the `expint` function.
454+
which is equivalent to ``-\\Re[\\operatorname{E}_1(-x)]`` where ``\\operatorname{E}_1`` is the `expint` function.
455455
"""
456456
expinti(x::Real) = x 0 ? -expint(-x) : -real(expint(complex(-x)))
457457

test/expint.jl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ using Base.MathConstants
33
@testset "exponential integral" begin
44
@testset "E1 real" begin
55
@test expint(0) == Inf
6+
@test expint(Inf) == 0
67
@test expint(1) 0.219383934395520273677163775460121649031047293406908207577
78
@test expint(2) 0.048900510708061119567239835228049522314492184963023116327
89
@test expint(4) 0.0037793524098489064788748601324664148517165470424895803607340203
@@ -80,6 +81,10 @@ using Base.MathConstants
8081
@test isnan(expint(NaN, 1.0))
8182
@test isnan(expint(NaN, NaN))
8283
@test isnan(expint(NaN+NaN*im, NaN+NaN*im))
84+
@test expint(4, Inf) == expint(4, Inf + 3im) == expint(-4, Inf) == expint(4+1im, Inf) == expint(4+1im, Inf + Inf*im) == 0
85+
@test isnan(expint(-Inf+0im))
86+
@test isnan(expint(4, -Inf+3im))
87+
@test isnan(expint(4, -Inf+Inf*im))
8388

8489
# |ν| > 50 not currently supported
8590
@test_throws ArgumentError expint(-100, 5) 2.3661006604908971561634280511260954613666084788690790e87

0 commit comments

Comments
 (0)