This is an automated email from the ASF dual-hosted git repository. haoj pushed a commit to branch numpy in repository https://gitbox.apache.org/repos/asf/incubator-mxnet.git
commit fe15eb3e51500c027ce988dcad536f2c4ce8a140 Author: Zoey Xinyi Ge <33736316+zoey...@users.noreply.github.com> AuthorDate: Wed Jul 3 02:13:04 2019 +0800 [numpy][doc-fix] sum, copy, tile, argmax, sign, log, degrees (#15382) * seven numpy docs finished * Style partly fixed * Style fixed; example output updated according to new output style * Style fixed; added scalar input support for np.tile * End of file spare line fixed * Fixed according to comments * Fixed according to comments * Removed dead code according to comment * `out` param comment modified * trailing newline fixed * Function signature override fixed * Mistype typo fixed * Removed duplicate functions due to rebase * Fixed signature of tile; minor refinement in style * Fixed tile typo for sanity check --- python/mxnet/_numpy_op_doc.py | 145 +++++++++- python/mxnet/ndarray/numpy/_op.py | 281 ++++++++++++++++++- python/mxnet/numpy/multiarray.py | 334 ++++++++++++++++++++--- python/mxnet/symbol/numpy/_symbol.py | 161 +++++++++-- src/operator/numpy/np_elemwise_unary_op_basic.cc | 6 +- src/operator/numpy/np_elemwise_unary_op_basic.cu | 6 +- 6 files changed, 856 insertions(+), 77 deletions(-) diff --git a/python/mxnet/_numpy_op_doc.py b/python/mxnet/_numpy_op_doc.py index f32e832..b285346 100644 --- a/python/mxnet/_numpy_op_doc.py +++ b/python/mxnet/_numpy_op_doc.py @@ -17,8 +17,8 @@ # pylint: skip-file -"""Doc placeholder for numpy ops with prefix _np.""" +"""Doc placeholder for numpy ops with prefix _np.""" def _np_reshape(a, newshape, order='C'): """ @@ -223,3 +223,146 @@ def _np_dot(a, b, out=None): array(29884.) """ pass + + +def _np_sum(a, axis=0, dtype=None, keepdims=None, initial=None, out=None): + r""" + sum(a, axis=None, dtype=None, keepdims=_Null, initial=_Null, out=None) + + Sum of array elements over a given axis. + + Parameters + ---------- + a : ndarray + Input data. + axis : None or int, optional + Axis or axes along which a sum is performed. The default, + axis=None, will sum all of the elements of the input array. If + axis is negative it counts from the last to the first axis. + dtype : dtype, optional + The type of the returned array and of the accumulator in which the + elements are summed. The default type is float32. + keepdims : bool, optional + If this is set to True, the axes which are reduced are left + in the result as dimensions with size one. With this option, + the result will broadcast correctly against the input array. + + If the default value is passed, then `keepdims` will not be + passed through to the `sum` method of sub-classes of + `ndarray`, however any non-default value will be. If the + sub-classes `sum` method does not implement `keepdims` any + exceptions will be raised. + initial: Currently only supports None as input, optional + Starting value for the sum. + Currently not implemented. Please use ``None`` as input or skip this argument. + out : ndarray or None, optional + Alternative output array in which to place the result. It must have + the same shape and dtype as the expected output. + + Returns + ------- + sum_along_axis : ndarray + An ndarray with the same shape as `a`, with the specified + axis removed. If an output array is specified, a reference to + `out` is returned. + + Notes + ----- + - Input type does not support Python native iterables. + - "out" param: cannot perform auto type change. out ndarray's dtype must be the same as the expected output. + - "initial" param is not supported yet. Please use None as input. + - Arithmetic is modular when using integer types, and no error is raised on overflow. + - The sum of an empty array is the neutral element 0: + + >>> a = np.empty(1) + >>> np.sum(a) + array(0.) + + This function differs from the original `numpy.sum + <https://docs.scipy.org/doc/numpy/reference/generated/numpy.sum.html>`_ in + the following aspects: + + - Input type does not support Python native iterables(list, tuple, ...). + - "out" param: cannot perform auto type cast. out ndarray's dtype must be the same as the expected output. + - "initial" param is not supported yet. Please use ``None`` as input or skip it. + + Examples + -------- + >>> a = np.array([0.5, 1.5]) + >>> np.sum(a) + array(2.) + >>> a = np.array([0.5, 0.7, 0.2, 1.5]) + >>> np.sum(a, dtype=np.int32) + array(2, dtype=int32) + >>> a = np.array([[0, 1], [0, 5]]) + >>> np.sum(a) + array(6.) + >>> np.sum(a, axis=0) + array([0., 6.]) + >>> np.sum(a, axis=1) + array([1., 5.]) + + With output ndarray: + + >>> a = np.array([[0, 1], [0, 5]]) + >>> b = np.ones((2,), dtype=np.float32) + >>> np.sum(a, axis = 0, out=b) + array([0., 6.]) + >>> b + array([0., 6.]) + + If the accumulator is too small, overflow occurs: + + >>> np.ones(128, dtype=np.int8).sum(dtype=np.int8) + array(-128, dtype=int8) + """ + pass + + +def _np_copy(a, out=None): + """ + copy(a, out=None) + + Return an array copy of the given object. + + Parameters + ---------- + a : ndarray + Input data. + out : ndarray or None, optional + Alternative output array in which to place the result. It must have + the same shape and dtype as the expected output. + + Returns + ------- + arr : ndarray + Array interpretation of `a`. + + Notes + ------- + This function differs from the original `numpy.copy + <https://docs.scipy.org/doc/numpy/reference/generated/numpy.copy.html>`_ in + the following aspects: + + - Input type does not support Python native iterables(list, tuple, ...). + - ``out`` param: cannot perform auto broadcasting. ``out`` ndarray's shape must be the same as the expected output. + - ``out`` param: cannot perform auto type cast. ``out`` ndarray's dtype must be the same as the expected output. + - Does not support "order" parameter. + + Examples + -------- + Create an array x, with a reference y and a copy z: + + >>> x = np.array([1, 2, 3]) + >>> y = x + >>> z = np.copy(x) + + Note that, when ``x`` is modified, ``y`` is also modified, but not ``z``: + + >>> x[0] = 10 + >>> x[0] == y[0] + array([1.]) + >>> x[0] == z[0] + array([0.]) + """ + pass diff --git a/python/mxnet/ndarray/numpy/_op.py b/python/mxnet/ndarray/numpy/_op.py index 132b179..054d9b8 100644 --- a/python/mxnet/ndarray/numpy/_op.py +++ b/python/mxnet/ndarray/numpy/_op.py @@ -29,7 +29,8 @@ from ..ndarray import NDArray __all__ = ['zeros', 'ones', 'maximum', 'minimum', 'stack', 'arange', 'argmax', 'add', 'subtract', 'multiply', 'divide', 'mod', 'power', 'concatenate', 'clip', 'split', 'swapaxes', 'expand_dims', 'tile', 'linspace', - 'sin', 'cos', 'sinh', 'cosh', 'log10', 'sqrt', 'abs', 'exp', 'arctan'] + 'sin', 'cos', 'sinh', 'cosh', 'log10', 'sqrt', 'abs', 'exp', 'arctan', 'sign', 'log', + 'degrees'] @set_module('mxnet.ndarray.numpy') @@ -262,7 +263,10 @@ def arange(start, stop=None, step=1, dtype=None, ctx=None): @set_module('mxnet.ndarray.numpy') def argmax(a, axis=None, out=None): - """Returns the indices of the maximum values along an axis. + r""" + argmax(a, axis=None, out=None) + + Returns the indices of the maximum values along an axis. Parameters ---------- @@ -271,15 +275,60 @@ def argmax(a, axis=None, out=None): axis : int, optional By default, the index is into the flattened array, otherwise along the specified axis. - out : array, optional - If provided, the result will be inserted into this array. It should - be of the appropriate shape and dtype. + out : ndarray or None, optional + A location into which the result is stored. + If provided, it must have the same shape and dtype as input ndarray. + If not provided or `None`, a freshly-allocated array is returned. Returns ------- index_array : ndarray of indices whose dtype is same as the input ndarray. Array of indices into the array. It has the same shape as `a.shape` with the dimension along `axis` removed. + + Notes + ----- + In case of multiple occurrences of the maximum values, the indices + corresponding to the first occurrence are returned. + + This function differs from the original `numpy.argmax + <https://docs.scipy.org/doc/numpy/reference/generated/numpy.argmax.html>`_ in + the following aspects: + + - Input type does not support Python native iterables(list, tuple, ...). + - Output has dtype that is same as the input ndarray. + - ``out`` param: cannot perform auto broadcasting. ``out`` ndarray's shape must be the same as the expected output. + - ``out`` param: cannot perform auto type cast. ``out`` ndarray's dtype must be the same as the expected output. + - ``out`` param does not support scalar input case. + + Examples + -------- + >>> a = np.arange(6).reshape(2,3) + 10 + >>> a + array([[10., 11., 12.], + [13., 14., 15.]]) + >>> np.argmax(a) + array(5.) + >>> np.argmax(a, axis=0) + array([1., 1., 1.]) + >>> np.argmax(a, axis=1) + array([2., 2.]) + + >>> b = np.arange(6) + >>> b[1] = 5 + >>> b + array([0., 5., 2., 3., 4., 5.]) + >>> np.argmax(b) # Only the first occurrence is returned. + array(1.) + + Specify ``out`` ndarray: + + >>> a = np.arange(6).reshape(2,3) + 10 + >>> b = np.zeros((2,)) + >>> np.argmax(a, axis=1, out=b) + array([2., 2.]) + >>> b + array([2., 2.]) """ return _npi.argmax(a, axis=axis, keepdims=False, out=out) @@ -615,7 +664,7 @@ def split(ary, indices_or_sections, axis=0): @set_module('mxnet.ndarray.numpy') def tile(A, reps): - """ + r""" Construct an array by repeating A the number of times given by reps. If `reps` has length ``d``, the result will have dimension of @@ -631,22 +680,54 @@ def tile(A, reps): Thus for an `A` of shape (2, 3, 4, 5), a `reps` of (2, 2) is treated as (1, 1, 2, 2). - Note : Although tile may be used for broadcasting, it is strongly - recommended to use numpy's broadcasting operations and functions. - Parameters ---------- - A : ndarray - The input array. - reps : tuple of integers + A : ndarray or scalar + An input array or a scalar to repeat. + reps : a single integer or tuple of integers The number of repetitions of `A` along each axis. Returns ------- c : ndarray The tiled output array. + + Examples + -------- + >>> a = np.array([0, 1, 2]) + >>> np.tile(a, 2) + array([0., 1., 2., 0., 1., 2.]) + >>> np.tile(a, (2, 2)) + array([[0., 1., 2., 0., 1., 2.], + [0., 1., 2., 0., 1., 2.]]) + >>> np.tile(a, (2, 1, 2)) + array([[[0., 1., 2., 0., 1., 2.]], + [[0., 1., 2., 0., 1., 2.]]]) + + >>> b = np.array([[1, 2], [3, 4]]) + >>> np.tile(b, 2) + array([[1., 2., 1., 2.], + [3., 4., 3., 4.]]) + >>> np.(b, (2, 1)) + array([[1., 2.], + [3., 4.], + [1., 2.], + [3., 4.]]) + + >>> c = np.array([1,2,3,4]) + >>> np.tile(c,(4,1)) + array([[1., 2., 3., 4.], + [1., 2., 3., 4.], + [1., 2., 3., 4.], + [1., 2., 3., 4.]]) + + Scalar as input: + + >>> np.tile(2, 3) + array([2, 2, 2]) # repeating integer `2` + """ - return _npi.tile(A, reps) + return _unary_func_helper(A, _npi.tile, _np.tile, reps=reps) @set_module('mxnet.ndarray.numpy') @@ -694,6 +775,7 @@ def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis ----- This function currently does not support ``start`` and ``stop`` as ndarrays and axis could only be 0 now. + """ if isinstance(start, (list, _np.ndarray, NDArray)) or \ isinstance(stop, (list, _np.ndarray, NDArray)): @@ -930,6 +1012,62 @@ def abs(x, out=None, **kwargs): return _unary_func_helper(x, _npi.abs, _np.abs, out=out, **kwargs) +def sign(x, out=None, **kwargs): + r""" + sign(x, out=None) + + Returns an element-wise indication of the sign of a number. + + The `sign` function returns ``-1 if x < 0, 0 if x==0, 1 if x > 0``. Only supports real number. + + Parameters + ---------- + x : ndarray or a scalar + Input values. + out : ndarray or None, optional + A location into which the result is stored. + If provided, it must have the same shape and dtype as input ndarray. + If not provided or `None`, a freshly-allocated array is returned. + + Returns + ------- + y : ndarray + The sign of `x`. + This is a scalar if `x` is a scalar. + + Note + ------- + - Only supports real number as input elements. + - Input type does not support Python native iterables(list, tuple, ...). + - ``out`` param: cannot perform auto broadcasting. ``out`` ndarray's shape must be the same as the expected output. + - ``out`` param: cannot perform auto type cast. ``out`` ndarray's dtype must be the same as the expected output. + - ``out`` param does not support scalar input case. + + Examples + -------- + >>> a = np.array([-5., 4.5]) + >>> np.sign(a) + array([-1., 1.]) + + Scalars as input: + + >>> np.sign(4.0) + 1.0 + >>> np.sign(0) + 0 + + Use ``out`` parameter: + + >>> b = np.zeros((2, )) + >>> np.sign(a, out=b) + array([-1., 1.]) + >>> b + array([-1., 1.]) + + """ + return _unary_func_helper(x, _npi.sign, _np.sign, out=out, **kwargs) + + @set_module('mxnet.ndarray.numpy') def exp(x, out=None, **kwargs): r"""exp(x, out=None, **kwargs) @@ -1012,3 +1150,120 @@ def arctan(x, out=None, **kwargs): 0.7853981633974483 """ return _unary_func_helper(x, _npi.arctan, _np.arctan, out=out, **kwargs) + + +@set_module('mxnet.ndarray.numpy') +def log(x, out=None, **kwargs): + """ + log(x, out=None) + + Natural logarithm, element-wise. + + The natural logarithm `log` is the inverse of the exponential function, + so that `log(exp(x)) = x`. The natural logarithm is logarithm in base + `e`. + + Parameters + ---------- + x : ndarray + Input value. Elements must be of real value. + out : ndarray or None, optional + A location into which the result is stored. + If provided, it must have the same shape and dtype as input ndarray. + If not provided or `None`, a freshly-allocated array is returned. + + Returns + ------- + y : ndarray + The natural logarithm of `x`, element-wise. + This is a scalar if `x` is a scalar. + + Notes + ----- + Currently only supports data of real values and ``inf`` as input. Returns data of real value, ``inf``, ``-inf`` and + ``nan`` according to the input. + + This function differs from the original `numpy.log + <https://docs.scipy.org/doc/numpy/reference/generated/numpy.log.html>`_ in + the following aspects: + + - Does not support complex number for now + - Input type does not support Python native iterables(list, tuple, ...). + - ``out`` param: cannot perform auto broadcasting. ``out`` ndarray's shape must be the same as the expected output. + - ``out`` param: cannot perform auto type cast. ``out`` ndarray's dtype must be the same as the expected output. + - ``out`` param does not support scalar input case. + + Examples + -------- + >>> a = np.array([1, np.exp(1), np.exp(2), 0], dtype=np.float64) + >>> np.log(a) + array([ 0., 1., 2., -inf], dtype=float64) + + + Due to internal calculation mechanism, using default float32 dtype may cause some special behavior: + + >>> a = np.array([1, np.exp(1), np.exp(2), 0], dtype=np.float32) + >>> np.log(a) + array([ 0., 0.99999994, 2., -inf]) + + Scalar calculation: + + >>> np.log(1) + 0.0 + + """ + return _unary_func_helper(x, _npi.log, _np.log, out=out, **kwargs) + + +@set_module('mxnet.ndarray.numpy') +def degrees(x, out=None, **kwargs): + """ + degrees(x, out=None) + + Convert angles from radians to degrees. + + Parameters + ---------- + x : ndarray + Input value. Elements must be of real value. + out : ndarray or None, optional + A location into which the result is stored. + If provided, it must have the same shape and dtype as input ndarray. + If not provided or `None`, a freshly-allocated array is returned. + + Returns + ------- + y : ndarray + The corresponding degree values; if `out` was supplied this is a + reference to it. + This is a scalar if `x` is a scalar. + + Notes + ------- + This function differs from the original `numpy.degrees + <https://docs.scipy.org/doc/numpy/reference/generated/numpy.degrees.html>`_ in + the following aspects: + + - Input type does not support Python native iterables(list, tuple, ...). Only ndarray is supported. + - ``out`` param: cannot perform auto broadcasting. ``out`` ndarray's shape must be the same as the expected output. + - ``out`` param: cannot perform auto type cast. ``out`` ndarray's dtype must be the same as the expected output. + - ``out`` param does not support scalar input case. + + Examples + -------- + Convert a radian array to degrees + + >>> rad = np.arange(12.) * np.pi / 6 + >>> np.degrees(rad) + array([ 0., 30., 60., 90., 120., 150., 180., 210., 240., 270., 300., 330.]) + + Use specified ``out`` ndarray: + + >>> out = np.zeros((rad.shape)) + >>> np.degrees(rad, out) + array([ 0., 30., 60., 90., 120., 150., 180., 210., 240., 270., 300., 330.]) + >>> out + array([ 0., 30., 60., 90., 120., 150., 180., 210., 240., 270., 300., 330.]) + + """ + return _unary_func_helper(x, _npi.degrees, _np.degrees, out=out, **kwargs) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index 10cfe7d..db7b084 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -46,7 +46,8 @@ from ..ndarray.numpy import _internal as _npi __all__ = ['ndarray', 'empty', 'array', 'zeros', 'ones', 'maximum', 'minimum', 'stack', 'arange', 'argmax', 'add', 'subtract', 'multiply', 'divide', 'mod', 'power', 'concatenate', 'clip', 'split', 'swapaxes', 'expand_dims', 'tile', 'linspace', 'sin', 'cos', - 'sinh', 'cosh', 'log10', 'sqrt', 'abs', 'exp', 'arctan'] + 'sin', 'cos', 'sinh', 'cosh', 'log10', 'sqrt', 'abs', 'exp', 'arctan', 'sign', 'log', + 'degrees'] # This function is copied from ndarray.py since pylint @@ -822,7 +823,7 @@ class ndarray(NDArray): The arguments are the same as for :py:func:`sign`, with this array as data. """ - raise AttributeError('mxnet.numpy.ndarray object has no attribute abs') + raise AttributeError('mxnet.numpy.ndarray object has no attribute sign') def flatten(self, order='C'): # pylint: disable=arguments-differ """Return a copy of the array collapsed into one dimension.""" @@ -1268,6 +1269,7 @@ class ndarray(NDArray): def broadcast_like(self, other): raise AttributeError('mxnet.numpy.ndarray object has no attribute broadcast_like') + @property def shape(self): return super(ndarray, self).shape @@ -1509,7 +1511,10 @@ def arange(start, stop=None, step=1, dtype=None, ctx=None): @set_module('mxnet.numpy') def argmax(a, axis=None, out=None): - """Returns the indices of the maximum values along an axis. + r""" + argmax(a, axis=None, out=None) + + Returns the indices of the maximum values along an axis. Parameters ---------- @@ -1518,7 +1523,7 @@ def argmax(a, axis=None, out=None): axis : int, optional By default, the index is into the flattened array, otherwise along the specified axis. - out : array, optional + out : ndarray or None, optional If provided, the result will be inserted into this array. It should be of the appropriate shape and dtype. @@ -1527,6 +1532,50 @@ def argmax(a, axis=None, out=None): index_array : ndarray of indices whose dtype is same as the input ndarray. Array of indices into the array. It has the same shape as `a.shape` with the dimension along `axis` removed. + + Notes + ----- + In case of multiple occurrences of the maximum values, the indices + corresponding to the first occurrence are returned. + + This function differs from the original `numpy.argmax + <https://docs.scipy.org/doc/numpy/reference/generated/numpy.argmax.html>`_ in + the following aspects: + + - Input type does not support Python native iterables(list, tuple, ...). + - Output has dtype that is same as the input ndarray. + - ``out`` param: cannot perform auto broadcasting. ``out`` ndarray's shape must be the same as the expected output. + - ``out`` param: cannot perform auto type cast. ``out`` ndarray's dtype must be the same as the expected output. + - ``out`` param does not support scalar input case. + + Examples + -------- + >>> a = np.arange(6).reshape(2,3) + 10 + >>> a + array([[10., 11., 12.], + [13., 14., 15.]]) + >>> np.argmax(a) + array(5.) + >>> np.argmax(a, axis=0) + array([1., 1., 1.]) + >>> np.argmax(a, axis=1) + array([2., 2.]) + + >>> b = np.arange(6) + >>> b[1] = 5 + >>> b + array([0., 5., 2., 3., 4., 5.]) + >>> np.argmax(b) # Only the first occurrence is returned. + array(1.) + + Specify ``out`` ndarray: + + >>> a = np.arange(6).reshape(2,3) + 10 + >>> b = np.zeros((2,)) + >>> np.argmax(a, axis=1, out=b) + array([2., 2.]) + >>> b + array([2., 2.]) """ return _mx_nd_np.argmax(a, axis, out) @@ -1836,42 +1885,6 @@ def split(ary, indices_or_sections, axis=0): @set_module('mxnet.numpy') -def tile(A, reps): - """ - Construct an array by repeating A the number of times given by reps. - - If `reps` has length ``d``, the result will have dimension of - ``max(d, A.ndim)``. - - If ``A.ndim < d``, `A` is promoted to be d-dimensional by prepending new - axes. So a shape (3,) array is promoted to (1, 3) for 2-D replication, - or shape (1, 1, 3) for 3-D replication. If this is not the desired - behavior, promote `A` to d-dimensions manually before calling this - function. - - If ``A.ndim > d``, `reps` is promoted to `A`.ndim by pre-pending 1's to it. - Thus for an `A` of shape (2, 3, 4, 5), a `reps` of (2, 2) is treated as - (1, 1, 2, 2). - - Note : Although tile may be used for broadcasting, it is strongly - recommended to use numpy's broadcasting operations and functions. - - Parameters - ---------- - A : ndarray - The input array. - reps : tuple of integers - The number of repetitions of `A` along each axis. - - Returns - ------- - c : ndarray - The tiled output array. - """ - return _npi.tile(A, reps) - - -@set_module('mxnet.numpy') def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0, **kwargs): """Return evenly spaced numbers over a specified interval. @@ -2076,6 +2089,75 @@ def sqrt(x, out=None, **kwargs): return _mx_nd_np.sqrt(x, out=out, **kwargs) + +@set_module('mxnet.numpy') +def tile(A, reps): + r""" + Construct an array by repeating A the number of times given by reps. + + If `reps` has length ``d``, the result will have dimension of + ``max(d, A.ndim)``. + + If ``A.ndim < d``, `A` is promoted to be d-dimensional by prepending new + axes. So a shape (3,) array is promoted to (1, 3) for 2-D replication, + or shape (1, 1, 3) for 3-D replication. If this is not the desired + behavior, promote `A` to d-dimensions manually before calling this + function. + + If ``A.ndim > d``, `reps` is promoted to `A`.ndim by pre-pending 1's to it. + Thus for an `A` of shape (2, 3, 4, 5), a `reps` of (2, 2) is treated as + (1, 1, 2, 2). + + Parameters + ---------- + A : ndarray or scalar + An input array or a scalar to repeat. + reps : a single integer or tuple of integers + The number of repetitions of `A` along each axis. + + Returns + ------- + c : ndarray + The tiled output array. + + Examples + -------- + >>> a = np.array([0, 1, 2]) + >>> np.tile(a, 2) + array([0., 1., 2., 0., 1., 2.]) + >>> np.tile(a, (2, 2)) + array([[0., 1., 2., 0., 1., 2.], + [0., 1., 2., 0., 1., 2.]]) + >>> np.tile(a, (2, 1, 2)) + array([[[0., 1., 2., 0., 1., 2.]], + [[0., 1., 2., 0., 1., 2.]]]) + + >>> b = np.array([[1, 2], [3, 4]]) + >>> np.tile(b, 2) + array([[1., 2., 1., 2.], + [3., 4., 3., 4.]]) + >>> np.(b, (2, 1)) + array([[1., 2.], + [3., 4.], + [1., 2.], + [3., 4.]]) + + >>> c = np.array([1,2,3,4]) + >>> np.tile(c,(4,1)) + array([[1., 2., 3., 4.], + [1., 2., 3., 4.], + [1., 2., 3., 4.], + [1., 2., 3., 4.]]) + + Scalar as input: + + >>> np.tile(2, 3) + array([2, 2, 2]) # repeating integer `2` + + """ + return _mx_nd_np.tile(A, reps) + + @set_module('mxnet.numpy') def abs(x, out=None, **kwargs): r"""abs(x, out=None, **kwargs) @@ -2188,3 +2270,175 @@ def arctan(x, out=None, **kwargs): 0.7853981633974483 """ return _mx_nd_np.arctan(x, out=out, **kwargs) + +@set_module('mxnet.numpy') +def sign(x, out=None): + """ + sign(x, out=None) + + Returns an element-wise indication of the sign of a number. + + The `sign` function returns ``-1 if x < 0, 0 if x==0, 1 if x > 0``. Only supports real number. + + Parameters + ---------- + x : ndarray or a scalar + Input values. + out : ndarray or None, optional + A location into which the result is stored. + If provided, it must have the same shape and dtype as input ndarray. + If not provided or `None`, a freshly-allocated array is returned. + + Returns + ------- + y : ndarray + The sign of `x`. + This is a scalar if `x` is a scalar. + + Note + ------- + - Only supports real number as input elements. + - Input type does not support Python native iterables(list, tuple, ...). + - ``out`` param: cannot perform auto broadcasting. ``out`` ndarray's shape must be the same as the expected output. + - ``out`` param: cannot perform auto type cast. ``out`` ndarray's dtype must be the same as the expected output. + - ``out`` param does not support scalar input case. + + Examples + -------- + >>> a = np.array([-5., 4.5]) + >>> np.sign(a) + array([-1., 1.]) + + Scalars as input: + + >>> np.sign(4.0) + 1.0 + >>> np.sign(0) + 0 + + Use ``out`` parameter: + + >>> b = np.zeros((2, )) + >>> np.sign(a, out=b) + array([-1., 1.]) + >>> b + array([-1., 1.]) + + """ + return _mx_nd_np.sign(x, out=out) + + +@set_module('mxnet.symbol.numpy') +def log(x, out=None, **kwargs): + """ + log(x, out=None) + + Natural logarithm, element-wise. + + The natural logarithm `log` is the inverse of the exponential function, + so that `log(exp(x)) = x`. The natural logarithm is logarithm in base + `e`. + + Parameters + ---------- + x : ndarray + Input value. Elements must be of real value. + out : ndarray or None, optional + A location into which the result is stored. + If provided, it must have the same shape and dtype as input ndarray. + If not provided or `None`, a freshly-allocated array is returned. + + Returns + ------- + y : ndarray + The natural logarithm of `x`, element-wise. + This is a scalar if `x` is a scalar. + + Notes + ----- + Currently only supports data of real values and ``inf`` as input. Returns data of real value, ``inf``, ``-inf`` and + ``nan`` according to the input. + + This function differs from the original `numpy.log + <https://docs.scipy.org/doc/numpy/reference/generated/numpy.log.html>`_ in + the following aspects: + + - Does not support complex number for now + - Input type does not support Python native iterables(list, tuple, ...). + - ``out`` param: cannot perform auto broadcasting. ``out`` ndarray's shape must be the same as the expected output. + - ``out`` param: cannot perform auto type cast. ``out`` ndarray's dtype must be the same as the expected output. + - ``out`` param does not support scalar input case. + + Examples + -------- + >>> a = np.array([1, np.exp(1), np.exp(2), 0], dtype=np.float64) + >>> np.log(a) + array([ 0., 1., 2., -inf], dtype=float64) + + Due to internal calculation mechanism, using default float32 dtype may cause some special behavior: + + >>> a = np.array([1, np.exp(1), np.exp(2), 0]) + >>> np.log(a) + array([ 0., 0.99999994, 2., -inf]) + + Scalar calculation: + + >>> np.log(1) + 0.0 + + """ + return _mx_nd_np.log(x, out=out, **kwargs) + + +@set_module('mxnet.symbol.numpy') +def degrees(x, out=None, **kwargs): + """ + degrees(x, out=None) + + Convert angles from radians to degrees. + + Parameters + ---------- + x : ndarray + Input value. Elements must be of real value. + out : ndarray or None, optional + A location into which the result is stored. + If provided, it must have the same shape and dtype as input ndarray. + If not provided or `None`, a freshly-allocated array is returned. + + Returns + ------- + y : ndarray + The corresponding degree values; if `out` was supplied this is a + reference to it. + This is a scalar if `x` is a scalar. + + Notes + ------- + This function differs from the original `numpy.degrees + <https://docs.scipy.org/doc/numpy/reference/generated/numpy.degrees.html>`_ in + the following aspects: + + - Input type does not support Python native iterables(list, tuple, ...). Only ndarray is supported. + - ``out`` param: cannot perform auto broadcasting. ``out`` ndarray's shape must be the same as the expected output. + - ``out`` param: cannot perform auto type cast. ``out`` ndarray's dtype must be the same as the expected output. + - ``out`` param does not support scalar input case. + + Examples + -------- + Convert a radian array to degrees + + >>> rad = np.arange(12.) * np.pi / 6 + >>> np.degrees(rad) + array([ 0., 30., 60., 90., 120., 150., 180., 210., 240., 270., 300., 330.]) + + Use specified ``out`` ndarray: + + >>> out = np.zeros((rad.shape)) + >>> np.degrees(rad, out) + array([ 0., 30., 60., 90., 120., 150., 180., 210., 240., 270., 300., 330.]) + >>> out + array([ 0., 30., 60., 90., 120., 150., 180., 210., 240., 270., 300., 330.]) + + """ + return _mx_nd_np.degrees(x, out=out, **kwargs) diff --git a/python/mxnet/symbol/numpy/_symbol.py b/python/mxnet/symbol/numpy/_symbol.py index 8970bea..efdbf51 100644 --- a/python/mxnet/symbol/numpy/_symbol.py +++ b/python/mxnet/symbol/numpy/_symbol.py @@ -32,7 +32,7 @@ from . import _internal as _npi __all__ = ['zeros', 'ones', 'maximum', 'minimum', 'stack', 'concatenate', 'arange', 'argmax', 'clip', 'add', 'subtract', 'multiply', 'divide', 'mod', 'power', 'split', 'swapaxes', 'expand_dims', 'tile', 'linspace', 'sin', 'cos', 'sinh', 'cosh', 'log10', 'sqrt', - 'abs', 'exp', 'arctan'] + 'abs', 'exp', 'arctan', 'sign', 'log', 'degrees'] def _num_outputs(sym): @@ -1131,24 +1131,42 @@ def arange(start, stop=None, step=1, dtype=None, ctx=None): @set_module('mxnet.symbol.numpy') def argmax(a, axis=None, out=None): - """Returns the indices of the maximum values along an axis. + r""" + argmax(a, axis=None, out=None) + + Returns the indices of the maximum values along an axis. Parameters ---------- - a : ndarray - Input array. Only support ndarrays of dtype `float16`, `float32`, and `float64`. + a : _Symbol + Input array. Only support dtype `float16`, `float32`, and `float64`. axis : int, optional By default, the index is into the flattened array, otherwise along the specified axis. - out : array, optional - If provided, the result will be inserted into this array. It should - be of the appropriate shape and dtype. + out : _Symbol or None, optional + Dummy parameter to keep the consistency with the ndarray counterpart. Returns ------- - index_array : ndarray of indices whose dtype is same as the input ndarray. + index_array : _Symbol of indices whose dtype is same as the input ndarray. Array of indices into the array. It has the same shape as `a.shape` with the dimension along `axis` removed. + + Notes + ----- + In case of multiple occurrences of the maximum values, the indices + corresponding to the first occurrence are returned. + + This function differs from the original `numpy.argmax + <https://docs.scipy.org/doc/numpy/reference/generated/numpy.argmax.html>`_ in + the following aspects: + + - Input type does not support Python native iterables(list, tuple, ...). + - Output has dtype that is same as the input ndarray. + - ``out`` param: cannot perform auto broadcasting. ``out`` symbol's shape must be the same as the expected output. + - ``out`` param: cannot perform auto type cast. ``out`` symnbol's dtype must be the same as the expected output. + - ``out`` param does not support scalar input case. + """ return _npi.argmax(a, axis=axis, keepdims=False, out=out) @@ -1293,7 +1311,7 @@ def split(ary, indices_or_sections, axis=0): @set_module('mxnet.symbol.numpy') def tile(A, reps): - """ + r""" Construct an array by repeating A the number of times given by reps. If `reps` has length ``d``, the result will have dimension of @@ -1309,22 +1327,19 @@ def tile(A, reps): Thus for an `A` of shape (2, 3, 4, 5), a `reps` of (2, 2) is treated as (1, 1, 2, 2). - Note : Although tile may be used for broadcasting, it is strongly - recommended to use numpy's broadcasting operations and functions. - Parameters ---------- - A : _Symbol - The input array. - reps : tuple of integers - The number of repetitions of `A` along each axis. + A : _Symbol or scalar + An input array or a scalar to repeat. + reps : a single integer or tuple of integers + The number of repetitions of `x` along each axis. Returns ------- c : _Symbol The tiled output array. """ - return _npi.tile(A, reps) + return _unary_func_helper(A, _npi.tile, _np.tile, reps=reps) @set_module('mxnet.symbol.numpy') @@ -1582,6 +1597,39 @@ def abs(x, out=None, **kwargs): """ return _unary_func_helper(x, _npi.abs, _np.abs, out=out, **kwargs) +@set_module('mxnet.symbol.numpy') +def sign(x, out=None, **kwargs): + r""" + sign(x, out=None) + + Returns an element-wise indication of the sign of a number. + + The `sign` function returns ``-1 if x < 0, 0 if x==0, 1 if x > 0``. Only supports real number. + + Parameters + ---------- + x : _Symbol or a scalar + Input values. + out : _Symbol or None, optional + Dummy parameter to keep the consistency with the ndarray counterpart. + + Returns + ------- + y : _Symbol + The sign of `x`. + This is a scalar if `x` is a scalar. + + Note + ------- + - Only supports real number as input elements. + - Input type does not support Python native iterables(list, tuple, ...) + - ``out`` param: cannot perform auto broadcasting. ``out`` symbol's shape must be the same as the expected output. + - ``out`` param: cannot perform auto type cast. ``out`` symbol's dtype must be the same as the expected output. + - ``out`` param does not support scalar input case. + + """ + return _unary_func_helper(x, _npi.sign, _np.sign, out=out, **kwargs) + @set_module('mxnet.symbol.numpy') def exp(x, out=None, **kwargs): @@ -1644,4 +1692,83 @@ def arctan(x, out=None, **kwargs): return _unary_func_helper(x, _npi.arctan, _np.arctan, out=out, **kwargs) +@set_module('mxnet.symbol.numpy') +def log(x, out=None, **kwargs): + """ + log(x, out=None) + + Natural logarithm, element-wise. + + The natural logarithm `log` is the inverse of the exponential function, + so that `log(exp(x)) = x`. The natural logarithm is logarithm in base + `e`. + + Parameters + ---------- + x : _Symbol + Input value. Elements must be of real value. + out : _Symbol or None, optional + Dummy parameter to keep the consistency with the ndarray counterpart. + + Returns + ------- + y : _Symbol + The natural logarithm of `x`, element-wise. + This is a scalar if `x` is a scalar. + + Notes + ----- + Currently only supports data of real values and ``inf`` as input. Returns data of real value, ``inf``, ``-inf`` and + ``nan`` according to the input. + + This function differs from the original `numpy.log + <https://docs.scipy.org/doc/numpy/reference/generated/numpy.log.html>`_ in + the following aspects: + + - Does not support complex number for now + - Input type does not support Python native iterables(list, tuple, ...). Only ndarray is supported. + - ``out`` param: cannot perform auto braodcasting. ``out`` symbol's shape must be the same as the expected output. + - ``out`` param: cannot perform auto type cast. ``out`` symbol's dtype must be the same as the expected output. + - ``out`` param does not support scalar input case. + + """ + return _unary_func_helper(x, _npi.log, _np.log, out=out, **kwargs) + + +@set_module('mxnet.symbol.numpy') +def degrees(x, out=None, **kwargs): + """ + degrees(x, out=None) + + Convert angles from radians to degrees. + + Parameters + ---------- + x : _Symbol + Input value. Elements must be of real value. + out : _Symbol or None, optional + Dummy parameter to keep the consistency with the ndarray counterpart. + + Returns + ------- + y : _Symbol of floats + The corresponding degree values; if `out` was supplied this is a + reference to it. + This is a scalar if `x` is a scalar. + + Notes + ------- + This function differs from the original `numpy.degrees + <https://docs.scipy.org/doc/numpy/reference/generated/numpy.degrees.html>`_ in + the following aspects: + + - Input type does not support Python native iterables(list, tuple, ...). Only ndarray is supported. + - ``out`` param: cannot perform auto broadcasting. ``out`` symbol's shape must be the same as the expected output. + - ``out`` param: cannot perform auto type cast. ``out`` symbol's dtype must be the same as the expected output. + - ``out`` param does not support scalar input case. + + """ + return _unary_func_helper(x, _npi.degrees, _np.degrees, out=out, **kwargs) + + _set_np_symbol_class(_Symbol) diff --git a/src/operator/numpy/np_elemwise_unary_op_basic.cc b/src/operator/numpy/np_elemwise_unary_op_basic.cc index 768f1bb..3ff4400 100644 --- a/src/operator/numpy/np_elemwise_unary_op_basic.cc +++ b/src/operator/numpy/np_elemwise_unary_op_basic.cc @@ -112,7 +112,7 @@ Example:: .set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{"_backward_abs"}); // sign -MXNET_OPERATOR_REGISTER_NUMPY_UNARY(_np_sign, "x", mshadow_op::sign) +MXNET_OPERATOR_REGISTER_NUMPY_UNARY(_npi_sign, "x", mshadow_op::sign) .describe(R"code(Returns an element-wise indication of the sign of a number. The sign function returns -1 if x < 0, 0 if x==0, 1 if x > 0. Example:: @@ -199,7 +199,7 @@ Example:: .set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseOut{"_mul"}); // log -NNVM_REGISTER_OP(_np_log) +NNVM_REGISTER_OP(_npi_log) .describe(R"code(Returns element-wise Natural logarithmic value of the input. The natural logarithm is logarithm in base *e*, so that ``log(exp(x)) = x`` )code" ADD_FILELINE) @@ -306,7 +306,7 @@ MXNET_OPERATOR_REGISTER_NUMPY_UNARY(_npi_arctan, "x", mshadow_op::arctan) .set_attr<nnvm::FGradient>("FGradient", ElemwiseGradUseIn{ "_backward_arctan" }); // degrees -MXNET_OPERATOR_REGISTER_NUMPY_UNARY(_np_degrees, "x", mshadow_op::degrees) +MXNET_OPERATOR_REGISTER_NUMPY_UNARY(_npi_degrees, "x", mshadow_op::degrees) .describe(R"code(Converts each element of the input array from radians to degrees. .. math:: degrees([0, \pi/2, \pi, 3\pi/2, 2\pi]) = [0, 90, 180, 270, 360] diff --git a/src/operator/numpy/np_elemwise_unary_op_basic.cu b/src/operator/numpy/np_elemwise_unary_op_basic.cu index 8364ace..de9416e 100644 --- a/src/operator/numpy/np_elemwise_unary_op_basic.cu +++ b/src/operator/numpy/np_elemwise_unary_op_basic.cu @@ -45,7 +45,7 @@ MXNET_OPERATOR_REGISTER_NUMPY_UNARY_GPU(_np_reciprocal, mshadow_op::reciprocal); MXNET_OPERATOR_REGISTER_NUMPY_UNARY_GPU(_np_absolute, mshadow_op::abs); -MXNET_OPERATOR_REGISTER_NUMPY_UNARY_GPU(_np_sign, mshadow_op::sign); +MXNET_OPERATOR_REGISTER_NUMPY_UNARY_GPU(_npi_sign, mshadow_op::sign); MXNET_OPERATOR_REGISTER_NUMPY_UNARY_GPU(_np_rint, mshadow_op::rint); @@ -65,7 +65,7 @@ MXNET_OPERATOR_REGISTER_NUMPY_UNARY_GPU(_np_cbrt, mshadow_op::cube_root); MXNET_OPERATOR_REGISTER_NUMPY_UNARY_GPU(_npi_exp, mshadow_op::exp); -NNVM_REGISTER_OP(_np_log) +NNVM_REGISTER_OP(_npi_log) .set_attr<FCompute>("FCompute<gpu>", UnaryOp::Compute<gpu, mshadow_op::log>); MXNET_OPERATOR_REGISTER_NUMPY_UNARY_GPU(_npi_log10, mshadow_op::log10); @@ -90,7 +90,7 @@ MXNET_OPERATOR_REGISTER_NUMPY_UNARY_GPU(_np_arccos, mshadow_op::arccos); MXNET_OPERATOR_REGISTER_NUMPY_UNARY_GPU(_npi_arctan, mshadow_op::arctan); -MXNET_OPERATOR_REGISTER_NUMPY_UNARY_GPU(_np_degrees, mshadow_op::degrees); +MXNET_OPERATOR_REGISTER_NUMPY_UNARY_GPU(_npi_degrees, mshadow_op::degrees); MXNET_OPERATOR_REGISTER_NUMPY_UNARY_GPU(_np_radians, mshadow_op::radians);