Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

incorrect (Inf + Inf*im)^2.0 and other complex^float #24515

Closed
stevengj opened this issue Nov 7, 2017 · 5 comments
Closed

incorrect (Inf + Inf*im)^2.0 and other complex^float #24515

stevengj opened this issue Nov 7, 2017 · 5 comments
Labels
domain:complex Complex numbers domain:maths Mathematical functions

Comments

@stevengj
Copy link
Member

stevengj commented Nov 7, 2017

In Julia 0.4–0.7, I get:

julia> (Inf + Inf*im)^2.0
0.0 + Inf*im

which seems wrong (it assumes that the two Inf components are the "same"). The correct answer is given for ^2:

julia> (Inf + Inf*im)^2
NaN + Inf*im

The error seems to be due to this line, which dates back to #2891 by @jiahao.

My first inclination is to remove the entire p==2 special case from this ^ method. As I commented in #24497, that seems to be a performance optimization that is probably largely superseded, since most cases that need a fast z^2 probably use (a) an integer exponent (that calls a different method) and/or (b) a literal integer exponent (for which z^2 is inlined as z*z for Complex64 and Complex128).

@stevengj stevengj added the domain:maths Mathematical functions label Nov 7, 2017
@stevengj
Copy link
Member Author

stevengj commented Nov 7, 2017

On the other hand, we have:

julia> m = realmax(Float64)
1.7976931348623157e308

julia> (m + m*im)^2      # incorrect
NaN + Inf*im

julia> (m + m*im)^2.0    # correct
0.0 + Inf*im

I don't think that it is worth the extra checks to deal with this overflow case correctly, however. You'd have to slow down all complex multiplications to make (m + m*im) * (m + m*im) give 0.0 + Inf*im.

@JeffBezanson JeffBezanson added the domain:complex Complex numbers label Nov 9, 2017
@stevengj stevengj changed the title incorrect (Inf + Inf*im)^2.0 incorrect (Inf + Inf*im)^2.0 and other complex^float Nov 9, 2017
@stevengj
Copy link
Member Author

stevengj commented Nov 9, 2017

Wow, I found some even worse bugs:

julia> (0+0im)^-3.0
0.0 + 0.0im

(!!!) and

julia> (1.0+0.0im)^1e300
ERROR: InexactError: convert(Int64, 1.0e300)
Stacktrace:
 [1] convert at ./float.jl:703 [inlined]
 [2] convert at ./int.jl:530 [inlined]
 [3] convert at ./int.jl:534 [inlined]
 [4] ^(::Complex{Float64}, ::Complex{Float64}) at ./complex.jl:657
 [5] ^(::Complex{Float64}, ::Float64) at ./promotion.jl:310

stevengj added a commit to stevengj/julia that referenced this issue Nov 10, 2017
stevengj added a commit to stevengj/julia that referenced this issue Nov 11, 2017
@stevengj
Copy link
Member Author

I'm working at a patch that fixes this, and also makes the code 60% faster for complex^complex and 120% faster for real^complex.

@stevengj
Copy link
Member Author

stevengj commented Nov 11, 2017

Another bad case?

julia> Inf^(-Inf + 0.0im)
-0.0 - 0.0im

Actually, maybe that's correct: Inf^(-Inf + 0.0im) = exp((-Inf + 0.0im) * log(Inf)) = exp((-Inf + 0.0im) * Inf) = exp(-Inf + NaN*im), and it makes sense that the latter would be zero (though the sign of zero is unclear).

Python seems to get this one wrong:

In [1]: inf = float('inf')
In [2]: inf ** (-inf + 0j)
Out[2]: (nan+nanj)

@stevengj
Copy link
Member Author

Closed by #24570.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain:complex Complex numbers domain:maths Mathematical functions
Projects
None yet
Development

No branches or pull requests

2 participants