@@ -472,9 +472,13 @@ function inv(z::Complex{T}) where T<:Union{Float16,Float32}
472
472
end
473
473
function inv (w:: ComplexF64 )
474
474
c, d = reim (w)
475
- (isinf (c) | isinf (d)) && return complex (copysign (0.0 , c), flipsign (- 0.0 , d))
476
475
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))
478
482
479
483
ϵ = eps (Float64)
480
484
bs = 2 / (ϵ* ϵ)
@@ -493,12 +497,13 @@ function inv(w::ComplexF64)
493
497
else
494
498
q, p = robust_cinv (- d, - c)
495
499
end
496
- return ComplexF64 (p* s, q* s) # undo scaling
500
+ return ComplexF64 (p* s, q* s)
497
501
end
498
502
function robust_cinv (c:: Float64 , d:: Float64 )
499
503
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
502
507
return p, q
503
508
end
504
509
0 commit comments