You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mxnet.apache.org by ha...@apache.org on 2018/10/29 18:26:11 UTC

[incubator-mxnet] branch master updated: [MXNET-1173] Debug operators - isfinite, isinf and isnan (#12967)

This is an automated email from the ASF dual-hosted git repository.

haibin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git


The following commit(s) were added to refs/heads/master by this push:
     new a362df1  [MXNET-1173] Debug operators - isfinite, isinf and isnan (#12967)
a362df1 is described below

commit a362df1eb1b7a2f48423b21adc53c099f9b9383e
Author: Chaitanya Prakash Bapat <ch...@gmail.com>
AuthorDate: Mon Oct 29 11:25:47 2018 -0700

    [MXNET-1173] Debug operators - isfinite, isinf and isnan (#12967)
    
    * is_finite and is_inf implementation for front-end python api debug operator
    
    * updated unit-tests
    
    * updated test cases and incorporated is_nan function
    
    * solved index out of bounds issue and added comments
    
    * simplified abs function call and added isnan to contrib.py and all debug ops to doc
    
    * changed dimensions, added regular number, assert_equal instead of almost, removed ctx and added data.abs
---
 docs/api/python/ndarray/contrib.md    |  3 ++
 python/mxnet/ndarray/contrib.py       | 84 ++++++++++++++++++++++++++++++++++-
 tests/python/unittest/test_ndarray.py | 42 ++++++++++++++++++
 3 files changed, 128 insertions(+), 1 deletion(-)

diff --git a/docs/api/python/ndarray/contrib.md b/docs/api/python/ndarray/contrib.md
index 63f5f13..b2bfa17 100644
--- a/docs/api/python/ndarray/contrib.md
+++ b/docs/api/python/ndarray/contrib.md
@@ -55,6 +55,9 @@ In the rest of this document, we list routines provided by the `ndarray.contrib`
     foreach
     while_loop
     cond
+    isinf
+    isfinite
+    isnan
     index_copy
     getnnz
 ```
diff --git a/python/mxnet/ndarray/contrib.py b/python/mxnet/ndarray/contrib.py
index 67ee7e4..5dcc54a 100644
--- a/python/mxnet/ndarray/contrib.py
+++ b/python/mxnet/ndarray/contrib.py
@@ -19,6 +19,7 @@
 # pylint: disable=wildcard-import, unused-wildcard-import,redefined-outer-name
 """Contrib NDArray API of MXNet."""
 import math
+import numpy as np
 from ..context import current_context
 from ..random import uniform
 from ..base import _as_list
@@ -28,7 +29,7 @@ try:
 except ImportError:
     pass
 
-__all__ = ["rand_zipfian", "foreach", "while_loop", "cond"]
+__all__ = ["rand_zipfian", "foreach", "while_loop", "cond", "isinf", "isfinite", "isnan"]
 
 # pylint: disable=line-too-long
 def rand_zipfian(true_classes, num_sampled, range_max, ctx=None):
@@ -460,3 +461,84 @@ def cond(pred, then_func, else_func):
         return then_func()
     else:
         return else_func()
+
+def isinf(data):
+    """Performs an element-wise check to determine if the NDArray contains an infinite element
+    or not.
+
+
+    Parameters
+    ----------
+    input : NDArray
+        An N-D NDArray.
+
+    Returns
+    -------
+    output: NDArray
+        The output NDarray, with same shape as input, where 1 indicates the array element is
+        equal to positive or negative infinity and 0 otherwise.
+
+    Examples
+    --------
+    >>> data = mx.nd.array([np.inf, -np.inf, np.NINF, -1])
+    >>> output = mx.nd.contrib.isinf(data)
+    >>> output
+    [1. 1. 1. 0.]
+    <NDArray 4 @cpu(0)>
+    """
+    return data.abs() == np.inf
+
+def isfinite(data):
+    """Performs an element-wise check to determine if the NDArray contains an infinite element
+    or not.
+
+
+    Parameters
+    ----------
+    input : NDArray
+        An N-D NDArray.
+
+    Returns
+    -------
+    output: NDArray
+        The output NDarray, with same shape as input, where 1 indicates the array element is
+        finite i.e. not equal to positive or negative infinity and 0 in places where it is
+        positive or negative infinity.
+
+    Examples
+    --------
+    >>> data = mx.nd.array([np.inf, -np.inf, np.NINF, -1])
+    >>> output = mx.nd.contrib.isfinite(data)
+    >>> output
+    [0. 0. 0. 1.]
+    <NDArray 4 @cpu(0)>
+    """
+    is_data_not_nan = data == data
+    is_data_not_infinite = data.abs() != np.inf
+    return ndarray.logical_and(is_data_not_infinite, is_data_not_nan)
+
+def isnan(data):
+    """Performs an element-wise check to determine if the NDArray contains a NaN element
+    or not.
+
+
+    Parameters
+    ----------
+    input : NDArray
+        An N-D NDArray.
+
+    Returns
+    -------
+    output: NDArray
+        The output NDarray, with same shape as input, where 1 indicates the array element is
+        NaN i.e. Not a Number and 0 otherwise.
+
+    Examples
+    --------
+    >>> data = mx.nd.array([np.nan, -1])
+    >>> output = mx.nd.contrib.isnan(data)
+    >>> output
+    [1. 0.]
+    <NDArray 2 @cpu(0)>
+    """
+    return data != data
diff --git a/tests/python/unittest/test_ndarray.py b/tests/python/unittest/test_ndarray.py
index 128dfa6..0aa4855 100644
--- a/tests/python/unittest/test_ndarray.py
+++ b/tests/python/unittest/test_ndarray.py
@@ -1506,6 +1506,48 @@ def test_dlpack():
             mx.test_utils.assert_almost_equal(a_np, d_np)
             mx.test_utils.assert_almost_equal(a_np, e_np)
 
+@with_seed()
+def test_ndarray_is_inf():
+    random_dimensions = np.random.randint(2, 5)
+    random_shape = [np.random.randint(2, 5) for i in range(random_dimensions)]
+    data = mxnet.test_utils.rand_ndarray(random_shape,'default')
+    data[0][0] = np.inf
+    data[0][1] = -np.inf
+    data[1][0] = np.nan
+    data[1][1] = 5
+    output = mx.nd.contrib.isinf(data)
+    expected_output = np.isinf(data.asnumpy())
+    np.testing.assert_equal(output.asnumpy(), expected_output.astype(int))
+    # astype since numpy functions default return type is boolean array instead of int
+
+@with_seed()
+def test_ndarray_is_finite():
+    random_dimensions = np.random.randint(2, 5)
+    random_shape = [np.random.randint(2, 5) for i in range(random_dimensions)]
+    data = mxnet.test_utils.rand_ndarray(random_shape,'default')
+    data[0][0] = np.inf
+    data[0][1] = -np.inf
+    data[1][0] = np.nan
+    data[1][1] = 5
+    output = mx.nd.contrib.isfinite(data)
+    expected_output = np.isfinite(data.asnumpy())
+    np.testing.assert_equal(output.asnumpy(), expected_output.astype(int))
+    # astype since numpy functions default return type is boolean array instead of int
+
+@with_seed()
+def test_ndarray_is_nan():
+    random_dimensions = np.random.randint(2, 5)
+    random_shape = [np.random.randint(2, 5) for i in range(random_dimensions)]
+    data = mxnet.test_utils.rand_ndarray(random_shape,'default')
+    data[0][0] = np.inf
+    data[0][1] = -np.inf
+    data[1][0] = np.nan
+    data[1][1] = 5
+    output = mx.nd.contrib.isnan(data)
+    expected_output = np.isnan(data.asnumpy())
+    np.testing.assert_equal(output.asnumpy(), expected_output.astype(int))
+    # astype since numpy functions default return type is boolean array instead of int
+
 if __name__ == '__main__':
     import nose
     nose.runmodule()