-
-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Open
Labels
Description
Describe the issue:
Writing the spec for complex number support in the Array API we found that NumPy currently fails in 2 special cases. The behavior is inconsistent with the 2014 version C99.
The full list of special cases and specification is detailed in data-apis/array-api#458
cc @kgryte
Reproduce the code example:
import numpy as np
import math
def is_equal_float(x, y):
"""Test whether two floating-point numbers are equal with special consideration for zeros and NaNs.
Parameters
----------
x : float
First input number.
y : float
Second input number.
Returns
-------
bool
Boolean indicating whether two floating-point numbers are equal.
Examples
--------
>>> is_equal_float(0.0, -0.0)
False
>>> is_equal_float(-0.0, -0.0)
True
"""
# Handle +-0:
if x == 0.0 and y == 0.0:
return math.copysign(1.0, x) == math.copysign(1.0, y)
# Handle NaNs:
if x != x:
return y != y
# Everything else, including infinities:
return x == y
def is_equal(x, y):
"""Test whether two complex numbers are equal with special consideration for zeros and NaNs.
Parameters
----------
x : complex
First input number.
y : complex
Second input number.
Returns
-------
bool
Boolean indicating whether two complex numbers are equal.
Examples
--------
>>> import numpy as np
>>> is_equal(complex(np.nan, np.nan), complex(np.nan, np.nan))
True
"""
return is_equal_float(x.real, y.real) and is_equal_float(x.imag, y.imag)
def compare(v, e):
actual = np.tanh(v)
print('Value: {value}'.format(value=str(v)))
print('Actual: {actual}'.format(actual=str(actual)))
print('Expected: {expected}'.format(expected=str(e)))
print('Equal: {is_equal}'.format(is_equal=str(is_equal(actual, e))))
print('\n')
# Case 1
v = complex(0.0, np.inf)
e = complex(0.0, np.nan)
compare(v, e) # returns `NaN + NaN j`; however, this does match old C99 behavior (see https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1892.htm#dr_471)
# Case 2
v = complex(0.0, np.nan)
e = complex(0.0, np.nan)
compare(v, e) # returns `NaN + NaN j`; however, this does match old C99 behavior (see https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1892.htm#dr_471)
Error message:
Value: infj
Actual: (nan+nanj)
Expected: nanj
Equal: False
Value: nanj
Actual: (nan+nanj)
Expected: nanj
Equal: False
NumPy/Python version information:
v1.22.4