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

np.nan is np.nan behaves differently when jitted #5086

Open
2 tasks done
timothymillar opened this issue Jan 16, 2020 · 6 comments
Open
2 tasks done

np.nan is np.nan behaves differently when jitted #5086

timothymillar opened this issue Jan 16, 2020 · 6 comments
Labels
bug - incorrect behavior Bugs: incorrect behavior

Comments

@timothymillar
Copy link

Reporting a bug

  • I am using versions 0.47.0 and 0.45.1 installed with conda

  • I have included below a minimal working reproducer

Comparison of np.nan to itself using is behaves differently when jitted:

import numpy as np
import numba

def foo():
    return np.nan is np.nan

@numba.njit
def jitfoo():
    return np.nan is np.nan

foo() returns True
jitfoo() returns False

Obviously it's best to use np.isnan where possible

@stuartarchibald
Copy link
Contributor

Thanks for the report. I don't recall the implementation but would imagine that this is because the np.nan singleton (and other similar) is not handled explicitly in the Numba re-implementation.

@recycletechno
Copy link

The same issue. Is there any way to check if some value is nan? Maybe some workaround?

atr[i] = nan

type(atr[i]) -> float64
np.isnan(atr[i]) -> False
math.isnan(atr[i]) -> False
atr[i] -> nan
atr[i] == np.nan -> False
atr[i] == nb.float64(math.nan)) -> False

Thank you!

@timothymillar
Copy link
Author

@recycletechno np.isnan(atr[i]) should work correctly

@stuartarchibald stuartarchibald added bug - incorrect behavior Bugs: incorrect behavior and removed bug labels Dec 15, 2021
@AlessandroFazio
Copy link

Hello, I'm having the same problem with the following in nopython mode:

np.isnan(data[i:, j]).all()

Of course there are several workarounds, but it would be nice if this behaves correctly.

@joooeey
Copy link

joooeey commented Apr 24, 2023

Thanks for the report. I don't recall the implementation but would imagine that this is because the np.nan singleton (and other similar) is not handled explicitly in the Numba re-implementation.

NaN isn't a singleton, so checking with is doesn't make sense. It's about as reliable as checking integer equality with is. Integers in CPython 3.11 are the same object if they are either in the range -5 to 256 or if they are both on the same line (try it). But at least, mathematically speaking, there's only one 1000, so you can compare with ==. This is not the case for NaNs, neither in a mathematical sense (how many objects are there that are not numbers?) nor in the way floats are specified in IEEE 754 (float64 allows 9'007'199'254'740'990 different NaN values). In addition, IEEE 754 sets the arbitrary rule that NaNs don't compare equal (==) to anything.

Proof in numpy:

import numpy as np

np.log(-1)
C:\CENSOREDPATH\153577755.py:1: RuntimeWarning: invalid value encountered in log
  np.log(-1)
Out[15]: nan

np.log(-1) is np.nan
C:\CENSOREDPATH\3480224941.py:1: RuntimeWarning: invalid value encountered in log
  np.log(-1) is np.nan
Out[16]: False

So don't check NaNs with is! And no, that's not a bug. np.isnan should work though.

@stuartarchibald
Copy link
Contributor

Thanks for your input @joooeey. Checking for nan with is does not make numerical sense for the reasons you (and others) note, however, from a compiler perspective, it's legal code.

I think the issue here is that the np.nan comparison via is does not behave the same way when compiled as it does when run in the interpreter. The np.nan object is probably singleton-like, there's only one instance of that specific object returned by the nan attribute on the np module in the process at a time. Given np.nan is an object, doing np.nan is np.nan should by default return True, because they are the same object. Arguably this might be considered an implementation detail of NumPy cf. interning integer values within a low range in the CPython interpreter, however, it is what is present and Numba is not replicating the behaviour.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug - incorrect behavior Bugs: incorrect behavior
Projects
None yet
Development

No branches or pull requests

5 participants