8000 ENH: Add object loops to isnan, isinf, and isfinite by eric-wieser · Pull Request #14802 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

ENH: Add object loops to isnan, isinf, and isfinite #14802

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

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
ENH: Add object loops to isnan, isinf, and isfinite
These just fall back on the corresponding function from the `math` module, which in practice coerces to float
  • Loading branch information
eric-wieser committed Oct 29, 2019
commit dcc65fd22fb79011e967ceedb5054ff735d335fc
3 changes: 3 additions & 0 deletions doc/release/upcoming_changes/14802.improvement.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
``isfinite``, ``isinf``, and ``isnan`` support object arrays
------------------------------------------------------------
These fall back on the functions from the `math` module with the same names.
3 changes: 3 additions & 0 deletions numpy/core/code_generators/generate_umath.py
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,7 @@ def english_upper(s):
docstrings.get('numpy.core.umath.isnan'),
None,
TD(nodatetime_or_obj, out='?'),
TD(O, f='npy_ObjectIsNaN'),
),
'isnat':
Ufunc(1, 1, None,
Expand All @@ -863,12 +864,14 @@ def english_upper(s):
docstrings.get('numpy.core.umath.isinf'),
None,
TD(nodatetime_or_obj, out='?'),
TD(O, f='npy_ObjectIsInf'),
),
'isfinite':
Ufunc(1, 1, None,
docstrings.get('numpy.core.umath.isfinite'),
'PyUFunc_IsFiniteTypeResolver',
TD(noobj, out='?'),
TD(O, f='npy_ObjectIsFinite'),
),
'signbit':
Ufunc(1, 1, None,
Expand Down
33 changes: 33 additions & 0 deletions numpy/core/src/umath/funcs.inc.src
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,39 @@ npy_ObjectGCD(PyObject *i1, PyObject *i2)
}
}

static PyObject *
npy_ObjectIsFinite(PyObject *obj) {
static PyObject *math_isfinite_func = NULL;

npy_cache_import("math", "isfinite", &math_isfinite_func);
if (math_isfinite_func == NULL) {
return NULL;
}
return PyObject_CallFunction(math_isfinite_func, "O", obj);
}

static PyObject *
npy_ObjectIsInf(PyObject *obj) {
static PyObject *math_isinf_func = NULL;

npy_cache_import("math", "isinf", &math_isinf_func);
if (math_isinf_func == NULL) {
return NULL;
}
return PyObject_CallFunction(math_isinf_func, "O", obj);
}

static PyObject *
npy_ObjectIsNaN(PyObject *obj) {
static PyObject *math_isnan_func = NULL;

npy_cache_import("math", "isnan", &math_isnan_func);
if (math_isnan_func == NULL) {
return NULL;
}
return PyObject_CallFunction(math_isnan_func, "O", obj);
}

static PyObject *
npy_ObjectLCM(PyObject *i1, PyObject *i2)
{
Expand Down
25 changes: 25 additions & 0 deletions numpy/core/tests/test_umath.py
Original file line number Diff line number Diff line change
Expand Up @@ -2661,6 +2661,31 @@ def test_fraction(self):
assert_equal(np.trunc(f), -1)


class TestWrappedMathModuleFunctions(object):
""" Tests of ufuncs which just wrap the math module on object arrays """
def test_float_coercible(self):
class C:
def __init__(self, val):
self.val = val
def __float__(self):
return float(self.val)

# this test is trying to test object arrays
assert np.array(C(1)).dtype == object

assert_equal(np.isfinite(C(0)), True)
assert_equal(np.isfinite(C(np.nan)), False)
assert_equal(np.isfinite(C(np.inf)), False)

assert_equal(np.isinf(C(0)), False)
assert_equal(np.isinf(C(np.nan)), False)
assert_equal(np.isinf(C(np.inf)), True)

assert_equal(np.isnan(C(0)), False)
assert_equal(np.isnan(C(np.nan)), True)
assert_equal(np.isnan(C(np.inf)), False)


class TestComplexFunctions(object):
funcs = [np.arcsin, np.arccos, np.arctan, np.arcsinh, np.arccosh,
np.arctanh, np.sin, np.cos, np.tan, np.exp,
Expand Down
0