Skip to content

MAINT: improve error message for isposinf and isneginf on complex values #11503

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

Merged
merged 9 commits into from
Aug 1, 2018

Conversation

jor-
Copy link
Contributor

@jor- jor- commented Jul 5, 2018

Fixes a bug in isposinf and isneginf for complex values (#11438) and adds additional tests for these functions with complex values.

@jor- jor- force-pushed the master branch 6 times, most recently from ab2bf66 to fedb233 Compare July 5, 2018 13:56
@pv
Copy link
Member

pv commented Jul 5, 2018 via email

@mattip
Copy link
Member

mattip commented Jul 5, 2018

Interesting. We should at least raise an error that makes it clear this is by design.

@jor- how did you come across this code path, was it part of NumPy, an external library, or just exploring the limits of NumPy's complex handling?

@jor-
Copy link
Contributor Author

jor- commented Jul 6, 2018

Positive and negative infinity can be values in complex NumPy arrays so I think it makes sense that isposinf and isneginf work also for complex arrays.

@mattip: You mean how I found the bug? I use NumPy in one of my libraries to handle complex valued arrays. These arrays might also contain positive and negative infinity which need to be handled separately in my library.

@eric-wieser
Copy link
Member

Positive and negative infinity don't really exist in the C99 complex number model

I think this model only makes sense if you provide the proj function to normalize the invalid complex infinities, which both C99 and C++11 have:

https://www.ideone.com/IpsC42

Perhaps that has a place in numpy?

@pv
Copy link
Member

pv commented Jul 6, 2018 via email

@jor-
Copy link
Contributor Author

jor- commented Jul 6, 2018

In my opinion, inf is infinity and inf+nanj is not infinity, so isposinf is correct on this. It returns only True if the value is np.inf.

That isposinf(a) and isposinf(b) would not imply isposinf(a*b) is due to the specification of the arithmetic and in my option no reason not to implement isposinf for complex values.

@charris
Copy link
Member

charris commented Jul 6, 2018

I don't think +/- infinity makes sense for complex values.

@eric-wieser
Copy link
Member

eric-wieser commented Jul 6, 2018

In my opinion, inf is infinity and inf+nanj is not infinity

Unfortunately, your opinion carries less weight than the C99 standard, which seems to disagree with you

In order to support the one-infinity model, C99 regards any complex value with at least one infinite part as a complex infinity (even if the other part is a NaN)

Or at least, it dictates that inf + nanj is an infinity.

@jor-
Copy link
Contributor Author

jor- commented Jul 9, 2018

Okay, I did not know about that. Thank you for pointing this out. You have convinced me. With the one infinity model for complex values, the functions isposinf and isneginf are superfluous or are already covered by isinf.

What originally brought me to this problem was, that +inf and -inf can be stored in complex arrays and thus it looks like the complex plane with +inf and -inf and not the Riemann sphere with +inf only is used.

@mattip
Copy link
Member

mattip commented Jul 25, 2018

So the conclusion is that calling np.isposinf npisneginf should raise a Warning/Exception ?

@jor-
Copy link
Contributor Author

jor- commented Jul 26, 2018

I changed the code so that an exception is raised now if np.isposinf or np.isneginf is called with complex values.

The failures in the tests are due to connection errors. Can I restart the failing tests somehow?

scalar input, or if first and second arguments have different shapes.
Errors result if the second argument is also supplied when x is a scalar
input, if first and second arguments have different shapes, or if the
first argument as complex values
Copy link
Member

Choose a reason for hiding this comment

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

as -> has, here and in the second docstring

Copy link
Contributor Author

Choose a reason for hiding this comment

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

changed

@mattip
Copy link
Member

mattip commented Jul 26, 2018

Tests that reach the exceptions are missing, you can use assert_raises(...

@codecov-io
Copy link

codecov-io commented Jul 27, 2018

Codecov Report

Merging #11503 into master will increase coverage by <.01%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master   #11503      +/-   ##
==========================================
+ Coverage    85.7%    85.7%   +<.01%     
==========================================
  Files         327      327              
  Lines       82002    82018      +16     
==========================================
+ Hits        70281    70297      +16     
  Misses      11721    11721
Impacted Files Coverage Δ
numpy/lib/ufunclike.py 97.36% <100%> (+0.93%) ⬆️
numpy/lib/tests/test_ufunclike.py 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0df3563...b11b764. Read the comment docs.

@jor-
Copy link
Contributor Author

jor- commented Jul 27, 2018

I added a test. The tests passed. Only one failed due to a failure at Travis.

@mattip
Copy link
Member

mattip commented Jul 27, 2018

restarted the failing test, now all tests are green.

Copy link
Member

@eric-wieser eric-wieser left a comment

Choose a reason for hiding this comment

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

Can you justify choosing valueerror instead of typeerror?

@eric-wieser
Copy link
Member

The asanyarray breaks this function on duck-types...

Copy link
Contributor

@mhvk mhvk left a comment

Choose a reason for hiding this comment

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

To avoid the duck-type issue with np.asanyarray and also ensure the functions do not become slower for the normal case where the inputs are not complex, I'd suggest using a try/except, catching the exception raised by signbit and then raising a more informative error message.

@@ -138,6 +139,10 @@ def isposinf(x, out=None):
array([0, 0, 1])

"""
x = nx.asanyarray(x)
Copy link
Contributor

Choose a reason for hiding this comment

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

As @eric-wieser notes, this leads to a change of behaviour for objects that implement __array_ufunc__ but cannot be converted to arrays.

@mhvk mhvk changed the title BUG: isposinf and isneginf for complex values MAINT: improve error message for isposinf and isneginf on complex values Jul 27, 2018
@mhvk
Copy link
Contributor

mhvk commented Jul 27, 2018

p.s. I changed the title of this PR to reflect the consensus that arose that these functions should not work on complex values.

p.p.s. I think this is a very nice example of how review makes things better! Thanks for starting it, @jor-!

@jor-
Copy link
Contributor Author

jor- commented Jul 30, 2018

@mhvk: I now use try/except instead of asanyarray.

@eric-wieser: I changed the error raised to TypeError instead of ValueError.

@mattip mattip merged commit b72d52a into numpy:master Aug 1, 2018
@mattip
Copy link
Member

mattip commented Aug 1, 2018

Thanks @jor-

@jor-
Copy link
Contributor Author

jor- commented Aug 2, 2018

Thanks for the reviewing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants