Skip to content

Commit b7aa5e3

Browse files
simplify complex atanh and remove singularity perturbation (#55268)
fixes #55266, and use `inv(z)` rather than `1/z` and use `muladd` in a couple places. --------- Co-authored-by: Mosè Giordano <[email protected]>
1 parent 881be64 commit b7aa5e3

File tree

2 files changed

+13
-10
lines changed

2 files changed

+13
-10
lines changed

base/complex.jl

+7-10
Original file line numberDiff line numberDiff line change
@@ -1037,24 +1037,22 @@ end
10371037
function atanh(z::Complex{T}) where T
10381038
z = float(z)
10391039
Tf = float(T)
1040-
Ω = prevfloat(typemax(Tf))
1041-
θ = sqrt(Ω)/4
1042-
ρ = 1/θ
10431040
x, y = reim(z)
10441041
ax = abs(x)
10451042
ay = abs(y)
1043+
θ = sqrt(floatmax(Tf))/4
10461044
if ax > θ || ay > θ #Prevent overflow
10471045
if isnan(y)
10481046
if isinf(x)
10491047
return Complex(copysign(zero(x),x), y)
10501048
else
1051-
return Complex(real(1/z), y)
1049+
return Complex(real(inv(z)), y)
10521050
end
10531051
end
10541052
if isinf(y)
10551053
return Complex(copysign(zero(x),x), copysign(oftype(y,pi)/2, y))
10561054
end
1057-
return Complex(real(1/z), copysign(oftype(y,pi)/2, y))
1055+
return Complex(real(inv(z)), copysign(oftype(y,pi)/2, y))
10581056
end
10591057
β = copysign(one(Tf), x)
10601058
z *= β
@@ -1064,16 +1062,15 @@ function atanh(z::Complex{T}) where T
10641062
ξ = oftype(x, Inf)
10651063
η = y
10661064
else
1067-
ym = ay+ρ
1068-
ξ = log(sqrt(sqrt(4+y*y))/sqrt(ym))
1069-
η = copysign(oftype(y,pi)/2 + atan(ym/2), y)/2
1065+
ξ = log(sqrt(sqrt(muladd(y, y, 4)))/sqrt(ay))
1066+
η = copysign(oftype(y,pi)/2 + atan(ay/2), y)/2
10701067
end
10711068
else #Normal case
1072-
ysq = (ay+ρ)^2
1069+
ysq = ay^2
10731070
if x == 0
10741071
ξ = x
10751072
else
1076-
ξ = log1p(4x/((1-x)^2 + ysq))/4
1073+
ξ = log1p(4x/(muladd(1-x, 1-x, ysq)))/4
10771074
end
10781075
η = angle(Complex((1-x)*(1+x)-ysq, 2y))/2
10791076
end

test/complex.jl

+6
Original file line numberDiff line numberDiff line change
@@ -1215,3 +1215,9 @@ end
12151215
@test !iseven(7+0im) && isodd(7+0im)
12161216
@test !iseven(6+1im) && !isodd(7+1im)
12171217
end
1218+
1219+
@testset "issue #55266" begin
1220+
for T in (Float16, Float32, Float64)
1221+
@test isapprox(atanh(1+im*floatmin(T)), Complex{T}(atanh(1+im*big(floatmin(T)))))
1222+
end
1223+
end

0 commit comments

Comments
 (0)