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

BUG: Fixed behavior of assert_array_less for +/-inf #8410

Merged
merged 4 commits into from
Jan 5, 2017

Conversation

jotasi
Copy link

@jotasi jotasi commented Dec 21, 2016

At the moment assert_array_less in np.testing does not correctly treat +/-inf (see #2418). This is fixed by changing the underlying call to assert_array_compare, which now has an parameter equal_inf to compare infs rather than to ignore them analogous to the already present parameter equal_nan. The default is set to reproduce the old behavior and thus to not break existing code.

@jotasi
Copy link
Author

jotasi commented Jan 4, 2017

Is there anything for me to do first, or can I just wait now for someone to review my PR? Sorry if this is a silly question or the wrong place to ask, as it is my first time trying to contribute to numpy.

@seberg
Copy link
Member

seberg commented Jan 4, 2017

No, you can only remind us once in a while or try to convince everyone that this is vital, unless you know someone who can already start reviewing a little ;). Unfortunately review time is rather short in general....

@jotasi
Copy link
Author

jotasi commented Jan 4, 2017

Thanks for the quick reply, good to know. I was just wondering if I might have forgotten something so I thought I'd ask. Vital might be a stretch it is more of an edge case, it will just have to wait then.

Copy link
Member

@seberg seberg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. If you want to be thorough, could add a higher dimensional test and maybe a test to point out that -inf < -inf is also an error (maybe its there already and I missed it).

Since it is a change in behaviour (even if bug fix) that other tests suits could run into, a short mention in the release notes might be good (we can always edit those later again before the release).

class TestArrayAssertLess(unittest.TestCase):

def setUp(self):
self._assert_func = assert_array_less
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not much reason for this unless there is some form of inheritance somewhere, but if you like it...

Copy link
Author

@jotasi jotasi Jan 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have any strong opinion concerning this. I was just trying to follow the surrounding style as TestApproxEqual is also using it without inheriting from anywhere and not being inherited from. As it doesn't make the code less understandable I would tend to leave it in, but if you feel that it should be dropped, I can also do that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have a slight preference only, so whichever you like. Makes me a bit wonder whether TestApproxEqual probably should inherit from _GenericTest, though, hehe.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really, release notes, and maybe double check if the tests cover all important and it should be good.

__tracebackhide__ = True # Hide traceback for py.test
from numpy.core import array, isnan, isinf, any, all, inf
from numpy.core import array, isnan, isinf, any, all, inf, zeros_like
from numpy.core.numerictypes import bool_
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@charris do you know why we have the imports here always? Circular imports I guess? Could put it to the top of the file, but again, seems fine can stay for another time.

@@ -930,7 +931,7 @@ def compare(x, y):
if npany(gisinf(x)) or npany( gisinf(y)):
xinfid = gisinf(x)
yinfid = gisinf(y)
if not xinfid == yinfid:
if not (xinfid == yinfid).all():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Out of curiousity, why did this not create an error before? It seems obviously wrong?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, this code was never called for arrays containing either np.inf, -np.inf, or np.nan as these were filtered before by assert_array_compare. It is obviously wrong though and surfaces as soon as you allow the compare method to actually compare np.inf's by the new equal_inf=False option of assert_array_compare.

@seberg
Copy link
Member

seberg commented Jan 4, 2017

A few small comments, nothing much though, it was really a very good PR, good tests coverage, etc.

@jotasi jotasi force-pushed the arrayAssertLessFix branch 2 times, most recently from 93c910c to 6290d89 Compare January 4, 2017 21:34
Jonathan Tammo Siebert added 4 commits January 4, 2017 22:36
Added tests for simple arrays/elements,
tests that ensure that nans are not compared when they are in the same
position in both arrays but raise AssertionError when they are not,
and tests that ensure inf logic
(-np.inf < np.inf, 1.0 < np.inf, -np.inf < 1.0)
and that all other cases fail.
This failed to raise AssertionError in an earlier rewrite of
assert_array_compare and is thus tested explicitly now.
See issue numpy#2418

assert_array_less does now treat inf/nan
correctly, namely:
-inf < x < inf for any real number x
nans still are not compared, when they occur
at the same position

To achieve this without breaking any other
functions relying on assert_array_compare,
an additional parameter (equal_inf) was
introduced that defaults to the old behavior
(analogous to equal_nan).
The bug that +/- inf where not treated correctly in
np.testing.assert_array_less changed the behavior and is thus mentioned
in the release notes.
@jotasi
Copy link
Author

jotasi commented Jan 4, 2017

Thanks for the review and the nice comments! You were right, I forgot to check that -np.inf < -np.inf fails. This is included now as well as tests for arrays of dimensions 2 and 3. At the moment, I don't see any other important cases that are missing.
Also I added a commit extending the release notes. I hope this it's in the right place and correctly phrased.
If something else should be changed, please let me know.

@seberg
Copy link
Member

seberg commented Jan 5, 2017

Good enough for me. The release notes get a bit extra work anyway before the actual release. And the style stuff, can be done when the whole file gets some updates ;).

Thanks again!

@seberg seberg merged commit b9fb986 into numpy:master Jan 5, 2017
@seberg
Copy link
Member

seberg commented Jan 5, 2017

Also this kind of change.... better to do it early in the release cycle, so that others notice if it screws with their tests....

@jotasi jotasi deleted the arrayAssertLessFix branch January 5, 2017 19:15
@jotasi
Copy link
Author

jotasi commented Jan 5, 2017

Perfect. Thanks for your help @seberg!

@mhvk
Copy link
Contributor

mhvk commented Jan 6, 2017

This PR is causing numerous test failures on astropy; see #8452 for a fix.

mhvk added a commit to mhvk/numpy that referenced this pull request Jan 9, 2017
numpygh-8410 breaks a large number of astropy tests, because it sets up
a boolean array for values that should actually be compared (i.e.,
are not `nan` or `inf`) using `zeros_like`. The latter means that
for subclasses, the boolean test array is not a plain `ndarray` but
the subclass. But for astropy's `Quantity`, the `all` method is
undefined.

This commit ensures the test arrays from `isinf` and `isnan` are
used directly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants