-
-
Notifications
You must be signed in to change notification settings - Fork 10.9k
isclose behavior on non-finite complex values seems incorrect #15959
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
Comments
Thanks @mruberry, that's a clear bug.
That sounds right. |
as far as I know, Complex Numbers cannot be compared. which means that it's unreasonable to judging whether 1+2i is close to 2+1i. |
While the complex numbers aren't part of any ordered field, which means there's not a great mathematical concept of saying that a < b, there is a well-defined and widely accepted notion of saying "a is close to b" even when both a and b are complex. See Python's cmath.isclose, for example: https://docs.python.org/3/library/cmath.html. |
It might be a bit more complicated? Since |
The implementation we're proposing for PyTorch would never consider (NaN, 0) close to (0, NaN). That said, while isfinite(Complex) seems OK to define (true if neither part is -inf, inf, or NaN), isnan(Complex) may not be definable. |
The thing is, if we make it a ufunc, or implement with something like |
I suggest to keep this focused on behavior. We can't make it a ufunc anyway (it has non-ufunc keywords), but either way it's not really relevant to the discussion.
This may make sense, given that a complex number really is a single number, so the whole complex number should be "not a number".
I'd say that's fine. We're talking about "identical" for semantic purposes here, not numerical behavior. |
Just a reminder that matching the behavior of |
@rgommers right, you can say that I may have been thinking a bit more of testing, where this is not what you want probably. However, testing is not as important in the sense that I do not worry about generalizing it. The reason why I mention ufuncs is that a ufunc is the best way we have find a solution without putting in complex special paths everywhere which do not generalize. |
Summary: Previously torch.isclose would RuntimeError when called on complex tensors. This update updates torch.isclose to run on complex tensors and be consistent with [NumPy](https://numpy.org/doc/1.18/reference/generated/numpy.isclose.html). However, NumPy's handling of NaN, -inf, and inf values is odd, so I adopted Python's [cmath.isclose](https://docs.python.org/3/library/cmath.html) behavior when dealing with them. See numpy/numpy#15959 for more on NumPy's behavior. While implementing complex isclose I also simplified the isclose algorithm to: - A is close to B if A and B are equal, if equal_nan is true then NaN is equal to NaN - If A and B are finite, then A is close to B if `abs(a - b) <= (atol + abs(rtol * b))` This PR also documents torch.isclose, since it was undocumented, and adds multiple tests for its behavior to test_torch.py since it had no dedicated tests. The PR leaves equal_nan=True with complex inputs an error for now, pending the outcome of numpy/numpy#15959. Pull Request resolved: #36456 Differential Revision: D21159853 Pulled By: mruberry fbshipit-source-id: fb18fa7048e6104cc24f5ce308fdfb0ba5e4bb30
Follow-up from PyTorch: complex isclose was implemented in pytorch/pytorch#36456. We punted on supporting equal_nan=True, however, pending resolution of this discussion. Seems like the questions to be resolved are:
|
I'd lean towards yes, support |
@rgommers I agree with you. The implementation is simple snd the concept consistent. |
I think I am fine with defining it this way. Would be good to briefly mention it in the documentation though that this employs There are some other subtleties, which are maybe not immediately vital... If we assume that |
@vrakesh and @anirudh2290 pointed out that we should make sure to stay aligned with Python (not sure if that means updating us or them).
as |
So to summarize, we should consider the current behavior
as a bug and fix it. For inf, to be aligned with python, if there is an inf in any component then both components have to exactly match otherwise its false. It doesnt look like it honors absolute in python, so we shouldnt support it either.
For rel_tol, also it seems to not consider rel_tol For equal_nan, it seems fine to say that if isnan is true then it is nan and if equal_nan is True for isclose then isclose should return true. We can add the isnan bit to the documentation. Also, the PEP https://www.python.org/dev/peps/pep-0485/ indicates that complex tolerances can be passed in though that doesn't seem to be really true.
|
I assume you forgot to replace some number with |
To repeat what I've said a few times before: that's great if it's possible, but not a good enough reason to break backwards compatibility in case NumPy and Python both made reasonable but different choices (didn't check in detail if that's the case here). That's especially true if Python came way later with its implementation. |
Oh, I had forgotten after all this discussion that the original issue post already mentioned |
😄 sorry, my bad. yes for inf it looks like it will be a breaking change, though i find the following behavior inconsistent in numpy:
|
For example:
In the first case it seems like the same number should be close to itself, and in the latter case I think the numbers should not be close since NaN is not close to anything.
Python's cmath.isclose behavior appears to demand that complex numbers containing -inf or inf must be identical to be close. It does not support equal_nan so complex numbers containing NaN are never close to other complex numbers. If equal_nan is True I would expect NaNs to act like infinities and require the numbers be identical to be "close."
The text was updated successfully, but these errors were encountered: