Skip to content

Commit 1a81b80

Browse files
Merge e58ca81 into a813fae
2 parents a813fae + e58ca81 commit 1a81b80

File tree

3 files changed

+172
-1
lines changed

3 files changed

+172
-1
lines changed

dpnp/dpnp_iface_logic.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@
6666
"isfinite",
6767
"isinf",
6868
"isnan",
69+
"isneginf",
70+
"isposinf",
6971
"less",
7072
"less_equal",
7173
"logical_and",
@@ -710,6 +712,134 @@ def isclose(x1, x2, rtol=1e-05, atol=1e-08, equal_nan=False):
710712
)
711713

712714

715+
def isneginf(x, out=None):
716+
"""
717+
Test element-wise for negative infinity, return result as bool array.
718+
719+
For full documentation refer to :obj:`numpy.isneginf`.
720+
721+
Parameters
722+
----------
723+
x : {dpnp.ndarray, usm_ndarray}
724+
Input array.
725+
out : {None, dpnp.ndarray, usm_ndarray}, optional
726+
A location into which the result is stored. If provided, it must have a
727+
shape that the input broadcasts to and a boolean data type.
728+
If not provided or None, a freshly-allocated boolean array is returned
729+
730+
Returns
731+
-------
732+
out : dpnp.ndarray
733+
Boolean array of same shape as ``x``.
734+
735+
See Also
736+
--------
737+
:obj:`dpnp.isinf` : Test element-wise for positive or negative infinity.
738+
:obj:`dpnp.isposinf` : Test element-wise for positive infinity,
739+
return result as bool array.
740+
:obj:`dpnp.isnan` : Test element-wise for NaN and
741+
return result as a boolean array.
742+
:obj:`dpnp.isfinite` : Test element-wise for finiteness.
743+
744+
Examples
745+
--------
746+
>>> import dpnp as np
747+
>>> x = np.array(np.inf)
748+
>>> np.isneginf(-x)
749+
array(True)
750+
>>> np.isneginf(x)
751+
array(False)
752+
753+
>>> x = np.array([-np.inf, 0., np.inf])
754+
>>> np.isneginf(x)
755+
array([ True, False, False])
756+
757+
>>> x = np.array([-np.inf, 0., np.inf])
758+
>>> y = np.zeros(x.shape, dtype='bool')
759+
>>> np.isneginf(x, y)
760+
array([ True, False, False])
761+
>>> y
762+
array([ True, False, False])
763+
764+
"""
765+
766+
is_inf = dpnp.isinf(x)
767+
try:
768+
signbit = dpnp.signbit(x)
769+
except ValueError as e:
770+
dtype = x.dtype
771+
raise TypeError(
772+
f"This operation is not supported for {dtype} values "
773+
"because it would be ambiguous."
774+
) from e
775+
776+
return dpnp.logical_and(is_inf, signbit, out)
777+
778+
779+
def isposinf(x, out=None):
780+
"""
781+
Test element-wise for positive infinity, return result as bool array.
782+
783+
For full documentation refer to :obj:`numpy.isposinf`.
784+
785+
Parameters
786+
----------
787+
x : {dpnp.ndarray, usm_ndarray}
788+
Input array.
789+
out : {None, dpnp.ndarray, usm_ndarray}, optional
790+
A location into which the result is stored. If provided, it must have a
791+
shape that the input broadcasts to and a boolean data type.
792+
If not provided or None, a freshly-allocated boolean array is returned
793+
794+
Returns
795+
-------
796+
out : dpnp.ndarray
797+
Boolean array of same shape as ``x``.
798+
799+
See Also
800+
--------
801+
:obj:`dpnp.isinf` : Test element-wise for positive or negative infinity.
802+
:obj:`dpnp.isneginf` : Test element-wise for negative infinity,
803+
return result as bool array.
804+
:obj:`dpnp.isnan` : Test element-wise for NaN and
805+
return result as a boolean array.
806+
:obj:`dpnp.isfinite` : Test element-wise for finiteness.
807+
808+
Examples
809+
--------
810+
>>> import dpnp as np
811+
>>> x = np.array(np.inf)
812+
>>> np.isposinf(x)
813+
array(True)
814+
>>> np.isposinf(-x)
815+
array(False)
816+
817+
>>> x = np.array([-np.inf, 0., np.inf])
818+
>>> np.isposinf(x)
819+
array([False, False, True])
820+
821+
>>> x = np.array([-np.inf, 0., np.inf])
822+
>>> y = np.zeros(x.shape, dtype='bool')
823+
>>> np.isposinf(x, y)
824+
array([False, False, True])
825+
>>> y
826+
array([False, False, True])
827+
828+
"""
829+
830+
is_inf = dpnp.isinf(x)
831+
try:
832+
signbit = ~dpnp.signbit(x)
833+
except ValueError as e:
834+
dtype = x.dtype
835+
raise TypeError(
836+
f"This operation is not supported for {dtype} values "
837+
"because it would be ambiguous."
838+
) from e
839+
840+
return dpnp.logical_and(is_inf, signbit, out)
841+
842+
713843
_LESS_DOCSTRING = """
714844
Computes the less-than test results for each element `x1_i` of
715845
the input array `x1` with the respective element `x2_i` of the input array `x2`.

tests/test_logic.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from .helper import (
88
get_all_dtypes,
99
get_float_complex_dtypes,
10-
has_support_aspect64,
1110
)
1211

1312

@@ -394,3 +393,32 @@ def test_finite(op, data, dtype):
394393
dpnp_res = getattr(dpnp, op)(x, out=dp_out)
395394
assert dp_out is dpnp_res
396395
assert_equal(dpnp_res, np_res)
396+
397+
398+
@pytest.mark.parametrize("func", ["isneginf", "isposinf"])
399+
@pytest.mark.parametrize(
400+
"data",
401+
[
402+
[dpnp.inf, -1, 0, 1, dpnp.nan, -dpnp.inf],
403+
[[dpnp.inf, dpnp.nan], [dpnp.nan, 0], [1, -dpnp.inf]],
404+
],
405+
ids=[
406+
"1D array",
407+
"2D array",
408+
],
409+
)
410+
@pytest.mark.parametrize("dtype", get_float_complex_dtypes())
411+
def test_infinity_sign(func, data, dtype):
412+
x = dpnp.asarray(data, dtype=dtype)
413+
if dpnp.issubdtype(dtype, dpnp.complexfloating):
414+
with pytest.raises(TypeError):
415+
dpnp_res = getattr(dpnp, func)(x)
416+
else:
417+
np_res = getattr(numpy, func)(x.asnumpy())
418+
dpnp_res = getattr(dpnp, func)(x)
419+
assert_equal(dpnp_res, np_res)
420+
421+
dp_out = dpnp.empty(np_res.shape, dtype=dpnp.bool)
422+
dpnp_res = getattr(dpnp, func)(x, out=dp_out)
423+
assert dp_out is dpnp_res
424+
assert_equal(dpnp_res, np_res)

tests/third_party/cupy/logic_tests/test_content.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,16 @@ def test_isinf(self):
2929

3030
def test_isnan(self):
3131
self.check_unary_nan("isnan")
32+
33+
34+
class TestUfuncLike(unittest.TestCase):
35+
@testing.numpy_cupy_array_equal()
36+
def check_unary(self, name, xp):
37+
a = xp.array([-3, xp.inf, -1, -xp.inf, 0, 1, 2, xp.nan])
38+
return getattr(xp, name)(a)
39+
40+
def test_isneginf(self):
41+
self.check_unary("isneginf")
42+
43+
def test_isposinf(self):
44+
self.check_unary("isposinf")

0 commit comments

Comments
 (0)