diff --git a/CHANGELOG.md b/CHANGELOG.md index 8988b02d18..fa6cc50365 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ - [#660](https://github.com/helmholtz-analytics/heat/pull/660) New feature: Data loader for H5 datasets which shuffles data in the background during training (`utils.data.partial_dataset.PartialH5Dataset`) ### Logical - [#711](https://github.com/helmholtz-analytics/heat/pull/711) `isfinite()`, `isinf()`, `isnan()` +- [#743](https://github.com/helmholtz-analytics/heat/pull/743) `isneginf()`, `isposinf()` ### Types - [#738](https://github.com/helmholtz-analytics/heat/pull/738) `iscomplex()`, `isreal()` diff --git a/heat/core/logical.py b/heat/core/logical.py index cc5bd4abfb..b0388c812a 100644 --- a/heat/core/logical.py +++ b/heat/core/logical.py @@ -17,6 +17,8 @@ "isfinite", "isinf", "isnan", + "isneginf", + "isposinf", "logical_and", "logical_not", "logical_or", @@ -275,6 +277,38 @@ def isnan(x): return _operations.__local_op(torch.isnan, x, None, no_cast=True) +def isneginf(x, out=None): + """ + Test if each element of `x` is negative infinite, return result as a bool array. + + Parameters + ---------- + x : DNDarray + + Examples + -------- + >>> ht.isnan(ht.array([1, ht.inf, -ht.inf, ht.nan])) + DNDarray([False, False, True, False], dtype=ht.bool, device=cpu:0, split=None) + """ + return _operations.__local_op(torch.isneginf, x, out, no_cast=True) + + +def isposinf(x, out=None): + """ + Test if each element of `x` is positive infinite, return result as a bool array. + + Parameters + ---------- + x : DNDarray + + Examples + -------- + >>> ht.isnan(ht.array([1, ht.inf, -ht.inf, ht.nan])) + DNDarray([False, True, False, False], dtype=ht.bool, device=cpu:0, split=None) + """ + return _operations.__local_op(torch.isposinf, x, out, no_cast=True) + + def logical_and(t1, t2): """ Compute the truth value of t1 AND t2 element-wise. diff --git a/heat/core/tests/test_logical.py b/heat/core/tests/test_logical.py index 842bbaf933..aa1782138e 100644 --- a/heat/core/tests/test_logical.py +++ b/heat/core/tests/test_logical.py @@ -341,6 +341,74 @@ def test_isnan(self): self.assertEqual(r.device, s.device) self.assertTrue(ht.equal(r, s)) + def test_isneginf(self): + a = ht.array([1, ht.inf, -ht.inf, ht.nan]) + s = ht.array([False, False, True, False]) + r = ht.isneginf(a) + self.assertEqual(r.shape, s.shape) + self.assertEqual(r.dtype, s.dtype) + self.assertEqual(r.device, s.device) + self.assertTrue(ht.equal(r, s)) + + a = ht.array([1, ht.inf, -ht.inf, ht.nan], split=0) + out = ht.empty(4, dtype=ht.bool, split=0) + s = ht.array([False, False, True, False], split=0) + ht.isneginf(a, out) + self.assertEqual(out.shape, s.shape) + self.assertEqual(out.dtype, s.dtype) + self.assertEqual(out.device, s.device) + self.assertTrue(ht.equal(r, s)) + + a = ht.ones((6, 6), dtype=ht.bool, split=0) + s = ht.zeros((6, 6), dtype=ht.bool, split=0) + r = ht.isneginf(a) + self.assertEqual(r.shape, s.shape) + self.assertEqual(r.dtype, s.dtype) + self.assertEqual(r.device, s.device) + self.assertTrue(ht.equal(r, s)) + + a = ht.ones((5, 5), dtype=ht.int, split=1) + s = ht.zeros((5, 5), dtype=ht.bool, split=1) + r = ht.isneginf(a) + self.assertEqual(r.shape, s.shape) + self.assertEqual(r.dtype, s.dtype) + self.assertEqual(r.device, s.device) + self.assertTrue(ht.equal(r, s)) + + def test_isposinf(self): + a = ht.array([1, ht.inf, -ht.inf, ht.nan]) + s = ht.array([False, True, False, False]) + r = ht.isposinf(a) + self.assertEqual(r.shape, s.shape) + self.assertEqual(r.dtype, s.dtype) + self.assertEqual(r.device, s.device) + self.assertTrue(ht.equal(r, s)) + + a = ht.array([1, ht.inf, -ht.inf, ht.nan], split=0) + out = ht.empty(4, dtype=ht.bool, split=0) + s = ht.array([False, True, False, False], split=0) + ht.isposinf(a, out) + self.assertEqual(out.shape, s.shape) + self.assertEqual(out.dtype, s.dtype) + self.assertEqual(out.device, s.device) + self.assertTrue(ht.equal(r, s)) + + a = ht.ones((6, 6), dtype=ht.bool, split=0) + s = ht.zeros((6, 6), dtype=ht.bool, split=0) + r = ht.isposinf(a) + self.assertEqual(r.shape, s.shape) + self.assertEqual(r.dtype, s.dtype) + self.assertEqual(r.device, s.device) + self.assertTrue(ht.equal(r, s)) + + a = ht.ones((5, 5), dtype=ht.int, split=1) + s = ht.zeros((5, 5), dtype=ht.bool, split=1) + r = ht.isposinf(a) + self.assertEqual(r.shape, s.shape) + self.assertEqual(r.dtype, s.dtype) + self.assertEqual(r.device, s.device) + self.assertTrue(ht.equal(r, s)) + def test_logical_and(self): first_tensor = ht.array([[True, True], [False, False]]) second_tensor = ht.array([[True, False], [True, False]])