Your expressions are the result of evaluating limits. However, even your limits are not well defined, since both a and b could be approximated from the other side (negative), being both real numbers.
In computing, to deal with these situations in an uniform way, the IEEE 754 standard defines the inverse of 0.0 as NaN (not-a-number).
If you let b go to zero first, then a, the limit is \infty. But if you let a go to zero first, then the expression is always zero (0/b). So the limit isn’t well defined, but for a different reason.
As for whether one approaches the limit from positive or negative, you have this:
There are more than two sides here in the complex plane. In the figure below, x is the real component, y is the imaginary component, and z is the angle of the complex number.
julia> using Makie, CairoMakie
julia> begin
fig = Figure();
ax3d = Axis3(fig[1, 1]; aspect = (1, 1, 1),
perspectiveness = 0.5, azimuth = 2.19, elevation = 0.9)
x = -1:0.1:1
y = -1:0.1:1
z = angle.(1 ./ (x .+ y'*im))
p = surface!(x, y, z)
ax3d.xlabel = "Real"
ax3d.ylabel = "Imag"
ax3d.zlabel = "Angle of Multiplicative Inverse"
save("multiplicative_inverse.png", fig)
end
If you let b go to zero first, then a, the limit is ∞ . But if you let a go to zero first, then the expression is always zero ( 0/b ).
Ahh, sorry I was stupid.
What I was trying to say is, it is better to define inv function that is commutative with abs function.
julia> c1 = Complex(3,4)
3 + 4im
julia> inv(abs(c1))
0.2
julia> abs(inv(c1))
0.2
julia> c2 = Complex(0,0)
0 + 0im
julia> inv(abs(c2))
Inf
julia> abs(inv(c2)) # This should be Inf
NaN
In the theory of complex functions, we sometimes equate all infinite points as \infty = 1/0 (See Riemannian sphere), so returning NaN is not useful here.
The choice for the return value of inv(Complex(0.0, 0.0)) will be the following:
Complex(NaN, NaN)
The current output.
As @mkitti mentioned, the limit of arguments does not exist. So returning NaN makes a little sense (similar to 0.0 / 0.0).
Complex(Inf, 0.0) or Complex(0.0, Inf)
If we need inv∘abs == abs∘inv (or ≈ ), these will be acceptable.
But choosing the position of 0.0 is not straightforward, so this is not a good way.
Complex(Inf, Inf)
This is okay.
Complex(Inf, -Inf)
This is better because this is consistent with inv(Complex(Inf,Inf)).
My sense is that we are somewhat limited by our Cartesian description of complex values. If we moved to polar description, I think we might have a few more options. That is if we described the complex values in terms of abs and angle such that
θ = angle(C)
R = abs(C)
C = exp(θ*1im)
Then we could have R == ∞ for some θ dependent on the original angle.
TLDR: Julia’s behavior seems to be consistent with the ISO standard, and with the viewpoint that 0.0 + 0.0im represents a limit of x + iy as x,y \to 0^+ but in which the order of the limits is undefined (hence giving NaN from division in which the resultt cannot be determined). It’s also consistent with gfortran, but other languages make different choices.
Now that we’ve established that this already has been investigated and that we should not change this, perhaps we could discuss how to make a custom Complex type with the desired behavior?
Probably a lot easier just to define your own division operator /′, or check for zero denominators on a case-by-case basis since the desired behavior is probably application-dependent. Depends on what your practical use-case (if any) is.