Skip to content

Commit f82635a

Browse files
Support complex numbers in eps (#21858)
This came up in JuliaLinearAlgebra/IterativeSolvers.jl#113 (comment) . JuliaDiffEq and IterativeSolvers.jl have to make sure that the real-type is pulled out in order for `eps` to work: ```julia eps(real(typeof(b))) ``` This detail can make many algorithms with tolerances that are written generically that would otherwise work with complex numbers error. This PR proposes to do just that trick, so that way `eps(1.0 + 1.0im)` returns machine epsilon for a Float64 (and generally works for `AbstractFloat` of course). --------- Co-authored-by: Steven G. Johnson <[email protected]>
1 parent 0d9e0ef commit f82635a

File tree

3 files changed

+24
-0
lines changed

3 files changed

+24
-0
lines changed

base/complex.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1141,3 +1141,13 @@ function complex(A::AbstractArray{T}) where T
11411141
end
11421142
convert(AbstractArray{typeof(complex(zero(T)))}, A)
11431143
end
1144+
1145+
## Promotion to complex ##
1146+
1147+
_default_type(T::Type{Complex}) = Complex{Int}
1148+
1149+
## Machine epsilon for complex ##
1150+
1151+
eps(z::Complex{<:AbstractFloat}) = hypot(eps(real(z)), eps(imag(z)))
1152+
1153+
eps(::Type{Complex{T}}) where {T<:AbstractFloat} = sqrt(2*one(T))*eps(T)

base/float.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,6 +1064,13 @@ julia> 1.0 + eps()
10641064
julia> 1.0 + eps()/2
10651065
1.0
10661066
```
1067+
1068+
More generally, for any floating-point numeric type, `eps` corresponds to an
1069+
upper bound on the distance to the nearest floating-point complex value: if ``\text{fl}(x)`` is the closest
1070+
floating-point value to a number ``x`` (e.g. an arbitrary real number), then ``\text{fl}(x)``
1071+
satisfies ``|x - \text{fl}(x)| ≤ \text{eps}(x)/2``, not including overflow cases.
1072+
This allows the definition of `eps` to be extended to complex numbers,
1073+
for which ``\text{fl}(a + ib) = \text{fl}(a) + i \text{fl}(b)``.
10671074
"""
10681075
eps(::Type{<:AbstractFloat})
10691076

test/complex.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,13 @@ end
932932
end
933933
end
934934

935+
@testset "eps" begin
936+
@test eps(1.0+1.0im) === 3.1401849173675503e-16
937+
@test eps(Complex128) === eps(1.0+1.0im)
938+
@test eps(Complex64) === 1.6858739f-7
939+
@test eps(Float32(1.0)+Float32(1.0)im) === eps(Complex{Float32})
940+
end
941+
935942
@testset "cis" begin
936943
@test cis(0.0+1.0im) 0.367879441171442321595523770161460867445811131031767834507836+0.0im
937944
@test cis(1.0+0.0im) 0.54030230586813971740093660744297660373231042061+0.84147098480789650665250232163029899962256306079im

0 commit comments

Comments
 (0)