@@ -344,11 +344,10 @@ end
344
344
# https://functions.wolfram.com/GammaBetaErf/ExpIntegralE/04/05/01/0003/
345
345
function En_imagbranchcut (ν:: Number , z:: Number )
346
346
a = real (z)
347
- e1 = exp (π * imag (ν))
347
+ e1 = exp (oftype (a, π) * imag (ν))
348
348
e2 = Complex (cospi (real (ν)), - sinpi (real (ν)))
349
- impart = π * im * e1 * e2 * exp ((ν- 1 )* log (complex (a)) - loggamma (ν))
350
- impart *= signbit (imag (z)) ? - 1 : 1
351
- return imag (impart) * im # get rid of any real error
349
+ lgamma, lgammasign = ν isa Real ? logabsgamma (ν) : (loggamma (ν), 1 )
350
+ return - 2 * lgammasign * e1 * π * e2 * exp ((ν- 1 )* log (complex (a)) - lgamma) * im
352
351
end
353
352
354
353
"""
@@ -375,7 +374,8 @@ function expint(ν::Number, z::Number, niter::Int=1000)
375
374
end
376
375
377
376
if z == 0
378
- return oftype (z, real (ν) > 0 ? 1 / (ν- 1 ) : Inf )
377
+ typ = typeof (real (z))
378
+ return oftype (z, real (ν) > 0 ? one (typ)/ (ν- 1 ) : convert (typ, Inf ))
379
379
end
380
380
381
381
if ν == 0
@@ -394,8 +394,8 @@ function expint(ν::Number, z::Number, niter::Int=1000)
394
394
return En_expand_origin (ν, z)
395
395
end
396
396
397
- if z isa Real
398
- return first (z > 0 ? En_cf (ν, z, niter) : En_cf_nogamma (ν, z, niter))
397
+ if z isa Real || real (z) > 0
398
+ return first (real (z) > 0 ? En_cf (ν, z, niter) : En_cf_nogamma (ν, z, niter))
399
399
else
400
400
# Procedure for z near the negative real axis based on
401
401
# (without looking at the accompanying source code):
@@ -434,12 +434,22 @@ function expint(ν::Number, z::Number, niter::Int=1000)
434
434
z₀ += Δ
435
435
end
436
436
437
- # more exact imaginary part available for non-integer ν
437
+ En = doconj ? conj (E_start) : E_start
438
+
439
+ # handle branch cut
438
440
if imz == 0
439
- E_start = real (E_start) + En_imagbranchcut (ν, z)
441
+ bc = En_imagbranchcut (ν, z)
442
+ bit = ! signbit (imag (z))
443
+ sign = bit ? 1 : - 1
444
+ if isreal (ν)
445
+ # can separate real/im in case of real ν
446
+ return real (En) - sign * imag (bc)/ 2 * im
447
+ else
448
+ return bit ? En : En + bc
449
+ end
450
+ else
451
+ return En
440
452
end
441
-
442
- return doconj ? conj (E_start) : E_start
443
453
end
444
454
throw (" unreachable" )
445
455
end
0 commit comments