-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Type stability issue in complex sin? #11839
Comments
There are explicit checks for NaNs in the edge cases: function sin(z::Complex)
zr, zi = reim(z)
if !isfinite(zi) && zr == 0 return Complex(zr, zi) end
if isnan(zr) && !isfinite(zi) return Complex(zr, zi) end
if !isfinite(zr) && zi == 0 return Complex(oftype(zr, NaN), zi) end
if !isfinite(zr) && isfinite(zi) return Complex(oftype(zr, NaN), oftype(zi, NaN)) end
if !isfinite(zr) && !isfinite(zi) return Complex(zr, oftype(zi, NaN)) end
Complex(sin(zr)*cosh(zi), cos(zr)*sinh(zi))
end which is why static analysis thinks it could be type unstable, but really it isn't because those branches can only be triggered for numeric types that support infinite representations. Many of the elementary functions have similar checks. In principle we could have a separate function for |
Actually the current implementation doesn't work exactly right for julia> sin(1//0 + 2im)
ERROR: ArgumentError: invalid rational: zero(Int64)//zero(Int64)
in call at rational.jl:8
in rationalize at rational.jl:95
in convert at rational.jl:76
in sin at complex.jl:525 |
But can |
julia> 1//0
1//0
julia> isinf(1//0)
true |
Ahh, right... (I thought it was not allowed but what's actually not allowed is |
So on the other hand, for the "separate issue" we can make |
In principle it is possible, but NaN is very tricky to get correct. For example, NaN != NaN in floating point but 0//0 == 0//0 if all you do is compare numerators and denominators. You'd have to ask if NaN semantics are worth the trouble. |
The main argument for the existence of NaNs is that they allow for exception-less code when invalid arguments are used: since |
For what it's worth, I originally had |
Shouldn't we determine the return type at the beginning of the function, and then ensure that all return statements return this type? This would probably implicitly convert the arguments to Alternatively, we could reject calls with integer or rational types, and require that these be explicitly converted to a floating-point type. |
Is this type instability really a problem? I wouldn't expect the input to If it is considered a problem, I think the method should be restricted to |
fixed by #13539 |
The text was updated successfully, but these errors were encountered: