Skip to content

Commit 83592cf

Browse files
authored
faster inv for normal sized ComplexF64 (#47255)
* faster `inv` for normal sized `ComplexF64`
1 parent 86bb1fc commit 83592cf

File tree

2 files changed

+11
-6
lines changed

2 files changed

+11
-6
lines changed

base/complex.jl

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -472,9 +472,13 @@ function inv(z::Complex{T}) where T<:Union{Float16,Float32}
472472
end
473473
function inv(w::ComplexF64)
474474
c, d = reim(w)
475-
(isinf(c) | isinf(d)) && return complex(copysign(0.0, c), flipsign(-0.0, d))
476475
absc, absd = abs(c), abs(d)
477-
cd = ifelse(absc>absd, absc, absd) # cheap `max`: don't need sign- and nan-checks here
476+
cd, dc = ifelse(absc>absd, (absc, absd), (absd, absc))
477+
# no overflow from abs2
478+
if sqrt(floatmin(Float64)/2) <= cd <= sqrt(floatmax(Float64)/2)
479+
return conj(w) / muladd(cd, cd, dc*dc)
480+
end
481+
(isinf(c) | isinf(d)) && return complex(copysign(0.0, c), flipsign(-0.0, d))
478482

479483
ϵ = eps(Float64)
480484
bs = 2/*ϵ)
@@ -493,12 +497,13 @@ function inv(w::ComplexF64)
493497
else
494498
q, p = robust_cinv(-d, -c)
495499
end
496-
return ComplexF64(p*s, q*s) # undo scaling
500+
return ComplexF64(p*s, q*s)
497501
end
498502
function robust_cinv(c::Float64, d::Float64)
499503
r = d/c
500-
p = inv(muladd(d, r, c))
501-
q = -r*p
504+
z = muladd(d, r, c)
505+
p = 1.0/z
506+
q = -r/z
502507
return p, q
503508
end
504509

doc/src/manual/complex-and-rational-numbers.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ julia> 3(2 - 5im)^2
4848
-63 - 60im
4949
5050
julia> 3(2 - 5im)^-1.0
51-
0.20689655172413796 + 0.5172413793103449im
51+
0.20689655172413793 + 0.5172413793103449im
5252
```
5353

5454
The promotion mechanism ensures that combinations of operands of different types just work:

0 commit comments

Comments
 (0)