From da94ffb06610bdd59df3c77ee998deffc8c5487c Mon Sep 17 00:00:00 2001 From: Zhenghui Jin <69359374+barry-jin@users.noreply.github.com> Date: Mon, 13 Sep 2021 22:29:34 -0700 Subject: [PATCH 01/21] [Website] Fix website publish (#20573) * fix website publish * update * remove .asf.yaml from version/master * force include .asf.yaml * include .htaccess * add .asf.yaml check in CI --- ci/docker/runtime_functions.sh | 7 +- docs/static_site/src/.asf.yaml | 2 + docs/static_site/src/_config_prod.yml | 6 + python/mxnet/numpy/linalg.py | 16 +- python/mxnet/numpy/multiarray.py | 430 +++++++++++++++++++++++++- 5 files changed, 443 insertions(+), 18 deletions(-) create mode 100644 docs/static_site/src/.asf.yaml diff --git a/ci/docker/runtime_functions.sh b/ci/docker/runtime_functions.sh index a623bfdcd564..3d33da28d7bc 100755 --- a/ci/docker/runtime_functions.sh +++ b/ci/docker/runtime_functions.sh @@ -1204,7 +1204,12 @@ build_docs() { mkdir -p $python_doc_folder && tar -xzf python-artifacts.tgz --directory $python_doc_folder mkdir -p $api_folder/cpp/docs/api && tar -xzf c-artifacts.tgz --directory $api_folder/cpp/docs/api - # check if .htaccess file exists + # check if .asf.yaml file exists + if [ ! -f "html/.asf.yaml" ]; then + echo "html/.asf.yaml file does not exist. Exiting 1" + exit 1 + fi + # check if .htaccess file exists if [ ! -f "html/.htaccess" ]; then echo "html/.htaccess file does not exist. Exiting 1" exit 1 diff --git a/docs/static_site/src/.asf.yaml b/docs/static_site/src/.asf.yaml new file mode 100644 index 000000000000..07355508b450 --- /dev/null +++ b/docs/static_site/src/.asf.yaml @@ -0,0 +1,2 @@ +publish: + whoami: asf-site diff --git a/docs/static_site/src/_config_prod.yml b/docs/static_site/src/_config_prod.yml index a2a20363c355..0139f9e385d2 100644 --- a/docs/static_site/src/_config_prod.yml +++ b/docs/static_site/src/_config_prod.yml @@ -59,6 +59,12 @@ markdown: kramdown plugins: - jekyll-feed - jekyll-seo-tag + +# Force include .asf.yaml +include: + - .asf.yaml + - .htaccess + # Exclude from processing. # The following items will not be processed, by default. Create a custom list # to override the default setting. diff --git a/python/mxnet/numpy/linalg.py b/python/mxnet/numpy/linalg.py index 5713d7d14e2a..2c1e9431e8f6 100644 --- a/python/mxnet/numpy/linalg.py +++ b/python/mxnet/numpy/linalg.py @@ -839,7 +839,7 @@ def eigvals(a): return _mx_nd_np.linalg.eigvals(a) -def eigvalsh(a, UPLO='L'): +def eigvalsh(a, upper=False): r"""Compute the eigenvalues real symmetric matrix. Main difference from eigh: the eigenvectors are not computed. @@ -890,9 +890,13 @@ def eigvalsh(a, UPLO='L'): >>> a = np.array([[ 5.4119368 , 8.996273 , -5.086096 ], ... [ 0.8866155 , 1.7490431 , -4.6107802 ], ... [-0.08034172, 4.4172044 , 1.4528792 ]]) - >>> LA.eigvalsh(a, UPLO='L') + >>> LA.eigvalsh(a, upper=False) array([-2.87381886, 5.10144682, 6.38623114]) # in ascending order """ + if(upper==False): + UPLO='L' + else: + UPLO='U' return _mx_nd_np.linalg.eigvalsh(a, UPLO) @@ -963,7 +967,7 @@ def eig(a): return _mx_nd_np.linalg.eig(a) -def eigh(a, UPLO='L'): +def eigh(a, upper=False): r"""Return the eigenvalues and eigenvectors real symmetric matrix. Returns two objects, a 1-D array containing the eigenvalues of `a`, and @@ -1018,7 +1022,7 @@ def eigh(a, UPLO='L'): >>> a = np.array([[ 6.8189726 , -3.926585 , 4.3990498 ], ... [-0.59656644, -1.9166266 , 9.54532 ], ... [ 2.1093285 , 0.19688708, -1.1634291 ]]) - >>> w, v = LA.eigh(a, UPLO='L') + >>> w, v = LA.eigh(a, upper=False) >>> w array([-2.175445 , -1.4581827, 7.3725457]) >>> v @@ -1026,4 +1030,8 @@ def eigh(a, UPLO='L'): [ 0.8242942 , 0.56326365, -0.05721384], [-0.53661287, 0.80949366, 0.23825769]]) """ + if(upper == False): + UPLO = 'L' + else: + UPLO = 'U' return _mx_nd_np.linalg.eigh(a, UPLO) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index 5cca1fa9225a..84001df5d4ce 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -60,13 +60,13 @@ 'zeros', 'zeros_like', 'ones', 'ones_like', 'full', 'full_like', 'all', 'any', 'broadcast_to', 'add', 'subtract', 'multiply', 'divide', 'mod', 'remainder', 'fmod', 'power', 'bitwise_not', 'delete', 'trace', 'transpose', 'copy', 'moveaxis', 'reshape', 'dot', - 'arctan2', 'sin', 'cos', 'tan', 'sinh', 'cosh', 'tanh', 'log10', 'invert', - 'sqrt', 'cbrt', 'abs', 'absolute', 'fabs', 'exp', 'expm1', 'arcsin', 'arccos', 'arctan', 'sign', 'log', + 'arctan2', 'atan2', 'sin', 'cos', 'tan', 'sinh', 'cosh', 'tanh', 'log10', 'invert', + 'sqrt', 'cbrt', 'abs', 'absolute', 'fabs', 'exp', 'expm1', 'arcsin','asin', 'arccos','acos', 'arctan', 'atan', 'sign', 'log', 'degrees', 'log2', 'log1p', 'rint', 'radians', 'reciprocal', 'square', 'negative', 'histogram', - 'fix', 'ceil', 'floor', 'trunc', 'logical_not', 'arcsinh', 'arccosh', 'arctanh', 'append', 'argsort', + 'fix', 'ceil', 'floor', 'trunc', 'logical_not', 'arcsinh','asinh','arccosh', 'acosh', 'arctanh', 'atanh', 'append', 'argsort', 'sort', 'tensordot', 'eye', 'linspace', 'logspace', 'expand_dims', 'tile', 'arange', 'array_split', 'split', 'hsplit', 'vsplit', 'dsplit', 'flatnonzero', 'tril_indices', - 'concatenate', 'stack', 'vstack', 'row_stack', 'column_stack', 'hstack', 'dstack', + 'concatenate', 'concat','stack', 'vstack', 'row_stack', 'column_stack', 'hstack', 'dstack', 'average', 'mean', 'maximum', 'fmax', 'minimum', 'fmin', 'amax', 'amin', 'max', 'min', 'swapaxes', 'clip', 'argmax', 'argmin', 'std', 'var', 'insert', 'indices', 'copysign', 'ravel', 'unravel_index', 'diag_indices_from', 'hanning', 'hamming', 'blackman', @@ -3075,7 +3075,7 @@ def take(a, indices, axis=None, mode='raise', out=None): @set_module('mxnet.numpy') -def unique(ar, return_index=False, return_inverse=False, return_counts=False, axis=None): +def unique(ar, return_index=False, return_inverse=False, return_counts=False): """ Find the unique elements of an array. @@ -3148,13 +3148,6 @@ def unique(ar, return_index=False, return_inverse=False, return_counts=False, ax Return the unique rows of a 2D array - >>> a = np.array([[1, 0, 0], [1, 0, 0], [2, 3, 4]]) - >>> np.unique(a, axis=0) - array([[1., 0., 0.], - [2., 3., 4.]]) - - Return the indices of the original array that give the unique values: - >>> a = np.array([1, 2, 6, 4, 2, 3, 2]) >>> u, indices = np.unique(a, return_index=True) >>> u @@ -3175,7 +3168,7 @@ def unique(ar, return_index=False, return_inverse=False, return_counts=False, ax >>> u[indices] array([1., 2., 6., 4., 2., 3., 2.]) """ - return _mx_nd_np.unique(ar, return_index, return_inverse, return_counts, axis) + return _mx_nd_np.unique(ar, return_index, return_inverse, return_counts) @set_module('mxnet.numpy') @@ -4168,6 +4161,61 @@ def expm1(x, out=None, **kwargs): """ return _mx_nd_np.expm1(x, out=out, **kwargs) +@set_module('mxnet.numpy') +@wrap_np_unary_func +def asin(x, out=None): + r""" + Inverse sine, element-wise. + + Parameters + ---------- + x : ndarray or scalar + `y`-coordinate on the unit circle. + out : ndarray or None, optional + A location into which the result is stored. + If provided, it must have the same shape as the input. + If not provided or None, a freshly-allocated array is returned. + + Returns + ------- + angle : ndarray or scalar + Output array is same shape and type as x. This is a scalar if x is a scalar. + The inverse sine of each element in `x`, in radians and in the + closed interval ``[-pi/2, pi/2]``. + + Examples + -------- + >>> np.asin(1) # pi/2 + 1.5707963267948966 + >>> np.asin(-1) # -pi/2 + -1.5707963267948966 + >>> np.asin(0) + 0.0 + + .. note:: + `arcsin` is a multivalued function: for each `x` there are infinitely + many numbers `z` such that :math:`sin(z) = x`. The convention is to + return the angle `z` whose real part lies in [-pi/2, pi/2]. + For real-valued input data types, *arcsin* always returns real output. + For each value that cannot be expressed as a real number or infinity, + it yields ``nan`` and sets the `invalid` floating point error flag. + The inverse sine is also known as `asin` or sin^{-1}. + The output `ndarray` has the same `ctx` as the input `ndarray`. + This function differs from the original `numpy.arcsin + `_ in + the following aspects: + + * Only support ndarray or scalar now. + * `where` argument is not supported. + * Complex input is not supported. + + References + ---------- + Abramowitz, M. and Stegun, I. A., *Handbook of Mathematical Functions*, + 10th printing, New York: Dover, 1964, pp. 79ff. + http://www.math.sfu.ca/~cbm/aands/ + """ + return _mx_nd_np.arcsin(x, out=out) @set_module('mxnet.numpy') @wrap_np_unary_func @@ -4225,6 +4273,44 @@ def arcsin(x, out=None, **kwargs): """ return _mx_nd_np.arcsin(x, out=out, **kwargs) +@set_module('mxnet.numpy') +@wrap_np_unary_func +def acos(x, out=None): + """ + Trigonometric inverse cosine, element-wise. + The inverse of cos so that, if y = cos(x), then x = arccos(y). + + Parameters + ---------- + x : ndarray + x-coordinate on the unit circle. For real arguments, the domain is [-1, 1]. + out : ndarray, optional + A location into which the result is stored. If provided, it must have a shape that + the inputs broadcast to. If not provided or None, a freshly-allocated array is returned. + A tuple (possible only as a keyword argument) must have length equal to the number of outputs. + + Returns + ---------- + angle : ndarray + The angle of the ray intersecting the unit circle at the given x-coordinate in radians [0, pi]. + This is a scalar if x is a scalar. + + Notes + ---------- + arccos is a multivalued function: for each x there are infinitely many numbers z such that + cos(z) = x. The convention is to return the angle z whose real part lies in [0, pi]. + For real-valued input data types, arccos always returns real output. + For each value that cannot be expressed as a real number or infinity, it yields nan and sets + the invalid floating point error flag. + The inverse cos is also known as acos or cos^-1. + + Examples + ---------- + >>> np.acos([1, -1]) + array([ 0. , 3.14159265]) + """ + return _mx_nd_np.arccos(x, out=out) + @set_module('mxnet.numpy') @wrap_np_unary_func @@ -4264,6 +4350,50 @@ def arccos(x, out=None, **kwargs): """ return _mx_nd_np.arccos(x, out=out, **kwargs) +@set_module('mxnet.numpy') +@wrap_np_unary_func +def atan(x, out=None): + r""" + Trigonometric inverse tangent, element-wise. + The inverse of tan, so that if ``y = tan(x)`` then ``x = arctan(y)``. + + Parameters + ---------- + x : ndarray or scalar + Input values. + out : ndarray or None, optional + A location into which the result is stored. If provided, it must have + a shape that the inputs broadcast to. If not provided or `None`, + a freshly-allocated array is returned. + + Returns + ------- + out : ndarray or scalar + Out has the same shape as `x`. It lies is in + ``[-pi/2, pi/2]`` (``arctan(+/-inf)`` returns ``+/-pi/2``). + This is a scalar if `x` is a scalar. + + Notes + ----- + `arctan` is a multi-valued function: for each `x` there are infinitely + many numbers `z` such that tan(`z`) = `x`. The convention is to return + the angle `z` whose real part lies in [-pi/2, pi/2]. + For real-valued input data types, `arctan` always returns real output. + For each value that cannot be expressed as a real number or infinity, + it yields ``nan`` and sets the `invalid` floating point error flag. + For complex-valued input, we do not have support for them yet. + The inverse tangent is also known as `atan` or tan^{-1}. + + Examples + -------- + >>> x = np.array([0, 1]) + >>> np.atan(x) + array([0. , 0.7853982]) + >>> np.pi/4 + 0.7853981633974483 + """ + return _mx_nd_np.arctan(x, out=out) + @set_module('mxnet.numpy') @wrap_np_unary_func @@ -5136,6 +5266,51 @@ def logical_not(x, out=None, **kwargs): """ return _mx_nd_np.logical_not(x, out=out, **kwargs) +@set_module('mxnet.numpy') +@wrap_np_unary_func +def asinh(x, out=None): + r""" + Inverse hyperbolic cosine, element-wise. + + Parameters + ---------- + x : ndarray or scalar + Input array. + out : ndarray or None, optional + A location into which the result is stored. + + Returns + ------- + asinh : ndarray + Array of the same shape as `x`. + This is a scalar if `x` is a scalar. + + .. note:: + `asinh` is a multivalued function: for each `x` there are infinitely + many numbers `z` such that `sinh(z) = x`. + + For real-valued input data types, `asinh` always returns real output. + For each value that cannot be expressed as a real number or infinity, it + yields ``nan`` and sets the `invalid` floating point error flag. + + This function differs from the original numpy.asinh in the following aspects: + + * Do not support `where`, a parameter in numpy which indicates where to calculate. + * Do not support complex-valued input. + * Cannot cast type automatically. DType of `out` must be same as the expected one. + * Cannot broadcast automatically. Shape of `out` must be same as the expected one. + * If `x` is plain python numeric, the result won't be stored in out. + + Examples + -------- + >>> a = np.array([3.2, 5.0]) + >>> np.asinh(a) + array([1.8309381, 2.2924316]) + + >>> np.asinh(1) + 0.0 + """ + return _mx_nd_np.arcsinh(x, out=out) @set_module('mxnet.numpy') @wrap_np_unary_func @@ -5183,6 +5358,51 @@ def arcsinh(x, out=None, **kwargs): """ return _mx_nd_np.arcsinh(x, out=out, **kwargs) +@set_module('mxnet.numpy') +@wrap_np_unary_func +def acosh(x, out=None): + r""" + Inverse hyperbolic cosine, element-wise. + + Parameters + ---------- + x : ndarray or scalar + Input array. + out : ndarray or None, optional + A location into which the result is stored. + + Returns + ------- + arccosh : ndarray + Array of the same shape as `x`. + This is a scalar if `x` is a scalar. + + .. note:: + `arccosh` is a multivalued function: for each `x` there are infinitely + many numbers `z` such that `cosh(z) = x`. + + For real-valued input data types, `arccosh` always returns real output. + For each value that cannot be expressed as a real number or infinity, it + yields ``nan`` and sets the `invalid` floating point error flag. + + This function differs from the original numpy.arccosh in the following aspects: + + * Do not support `where`, a parameter in numpy which indicates where to calculate. + * Do not support complex-valued input. + * Cannot cast type automatically. Dtype of `out` must be same as the expected one. + * Cannot broadcast automatically. Shape of `out` must be same as the expected one. + * If `x` is plain python numeric, the result won't be stored in out. + + Examples + -------- + >>> a = np.array([3.2, 5.0]) + >>> np.acosh(a) + array([1.8309381, 2.2924316]) + + >>> np.acosh(1) + 0.0 + """ + return _mx_nd_np.arccosh(x, out=out) @set_module('mxnet.numpy') @wrap_np_unary_func @@ -5230,6 +5450,52 @@ def arccosh(x, out=None, **kwargs): """ return _mx_nd_np.arccosh(x, out=out, **kwargs) +@set_module('mxnet.numpy') +@wrap_np_unary_func +def atanh(x, out=None): + r""" + Inverse hyperbolic tangent, element-wise. + + Parameters + ---------- + x : ndarray or scalar + Input array. + out : ndarray or None, optional + A location into which the result is stored. + + Returns + ------- + atanh : ndarray + Array of the same shape as `x`. + This is a scalar if `x` is a scalar. + + .. note:: + `atanh` is a multivalued function: for each `x` there are infinitely + many numbers `z` such that `tanh(z) = x`. + + For real-valued input data types, `atanh` always returns real output. + For each value that cannot be expressed as a real number or infinity, it + yields ``nan`` and sets the `invalid` floating point error flag. + + This function differs from the original numpy.atanh in the following aspects: + + * Do not support `where`, a parameter in numpy which indicates where to calculate. + * Do not support complex-valued input. + * Cannot cast type automatically. Dtype of `out` must be same as the expected one. + * Cannot broadcast automatically. Shape of `out` must be same as the expected one. + * If `x` is plain python numeric, the result won't be stored in out. + + Examples + -------- + >>> a = np.array([0.0, -0.5]) + >>> np.atanh(a) + array([0., -0.54930615]) + + >>> np.atanh(1) + 0.0 + """ + return _mx_nd_np.arctanh(x, out=out) + @set_module('mxnet.numpy') @wrap_np_unary_func @@ -6533,6 +6799,56 @@ def dsplit(ary, indices_or_sections): """ return _mx_nd_np.dsplit(ary, indices_or_sections) +@set_module('mxnet.numpy') +def concat(seq, axis=0, out=None): + """Join a sequence of arrays along an existing axis. + + Parameters + ---------- + a1, a2, ... : sequence of array_like + The arrays must have the same shape, except in the dimension + corresponding to `axis` (the first, by default). + axis : int, optional + The axis along which the arrays will be joined. If axis is None, + arrays are flattened before use. Default is 0. + out : ndarray, optional + If provided, the destination to place the result. The shape must be + correct, matching that of what concatenate would have returned if no + out argument were specified. + + Returns + ------- + res : ndarray + The concatenated array. + + See Also + -------- + split : Split array into a list of multiple sub-arrays of equal size. + hsplit : Split array into multiple sub-arrays horizontally (column wise) + vsplit : Split array into multiple sub-arrays vertically (row wise) + dsplit : Split array into multiple sub-arrays along the 3rd axis (depth). + stack : Stack a sequence of arrays along a new axis. + hstack : Stack arrays in sequence horizontally (column wise) + vstack : Stack arrays in sequence vertically (row wise) + dstack : Stack arrays in sequence depth wise (along third dimension) + + Examples + -------- + >>> a = np.array([[1, 2], [3, 4]]) + >>> b = np.array([[5, 6]]) + >>> np.concat((a, b), axis=0) + array([[1., 2.], + [3., 4.], + [5., 6.]]) + + >>> np.concat((a, b.T), axis=1) + array([[1., 2., 5.], + [3., 4., 6.]]) + + >>> np.concat((a, b), axis=None) + array([1., 2., 3., 4., 5., 6.]) + """ + return _mx_nd_np.concatenate(seq, axis=axis, out=out) @set_module('mxnet.numpy') def concatenate(seq, axis=0, out=None): @@ -8585,6 +8901,94 @@ def round_(x, decimals=0, out=None, **kwargs): """ return _mx_nd_np.round_(x, decimals, out=out, **kwargs) +@set_module('mxnet.numpy') +@wrap_np_binary_func +def atan2(x1, x2, out=None): + r""" + Element-wise arc tangent of ``x1/x2`` choosing the quadrant correctly. + + The quadrant (i.e., branch) is chosen so that ``atan2(x1, x2)`` is + the signed angle in radians between the ray ending at the origin and + passing through the point (1,0), and the ray ending at the origin and + passing through the point (`x2`, `x1`). (Note the role reversal: the + "`y`-coordinate" is the first function parameter, the "`x`-coordinate" + is the second.) By IEEE convention, this function is defined for + `x2` = +/-0 and for either or both of `x1` and `x2` = +/-inf (see + Notes for specific values). + + This function is not defined for complex-valued arguments; for the + so-called argument of complex values, use `angle`. + + Parameters + ---------- + x1 : ndarray or scalar + `y`-coordinates. + x2 : ndarray or scalar + `x`-coordinates. `x2` must be broadcastable to match the shape of + `x1` or vice versa. + out : ndarray or None, optional + A location into which the result is stored. If provided, it must have + a shape that the inputs broadcast to. If not provided or `None`, + a freshly-allocated array is returned. + + Returns + ------- + out : ndarray or scalar + Array of angles in radians, in the range ``[-pi, pi]``. This is a scalar if + `x1` and `x2` are scalars. + + .. notes:: + *atan2* is identical to the ``atan2`` function of the underlying + C library. The following special values are defined in the C + standard: [1]_ + + +========+========+==================+ + | `x1` | `x2` | `atan2(x1,x2)` | + +========+========+==================+ + | +/- 0 | +0 | +/- 0 | + +========+========+==================+ + | +/- 0 | -0 | +/- pi | + +========+========+==================+ + | > 0 | +/-inf | +0 / +pi | + +========+========+==================+ + | < 0 | +/-inf | -0 / -pi | + +========+========+==================+ + | +/-inf | +inf | +/- (pi/4) | + +========+========+==================+ + | +/-inf | -inf | +/- (3*pi/4) | + +========+========+==================+ + + Note that +0 and -0 are distinct floating point numbers, as are +inf + and -inf. + + This function differs from the original numpy.arange in the following aspects: + + * Only support float16, float32 and float64. + + References + ---------- + .. [1] ISO/IEC standard 9899:1999, "Programming language C." + + Examples + -------- + Consider four points in different quadrants: + + >>> x = np.array([-1, +1, +1, -1]) + >>> y = np.array([-1, -1, +1, +1]) + >>> np.atan2(y, x) * 180 / np.pi + array([-135., -45., 45., 135.]) + + Note the order of the parameters. `atan2` is defined also when `x2` = 0 + and at several other special points, obtaining values in + the range ``[-pi, pi]``: + + >>> x = np.array([1, -1]) + >>> y = np.array([0, 0]) + >>> np.atan2(x, y) + array([ 1.5707964, -1.5707964]) + """ + return _mx_nd_np.arctan2(x1, x2, out=out) + @set_module('mxnet.numpy') @wrap_np_binary_func From fb5a717c883b67f407abb14586c8b7dd0cb317c0 Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Fri, 17 Sep 2021 21:44:13 +0800 Subject: [PATCH 02/21] change linalg & statical funcs --- python/mxnet/numpy/multiarray.py | 63 ++++++++++++++++++++++++++------ python/mxnet/util.py | 26 ++++++++++++- 2 files changed, 76 insertions(+), 13 deletions(-) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index dcfab2a22dda..2551a7da2edf 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -54,7 +54,7 @@ from .utils import _get_np_op from .fallback import * # pylint: disable=wildcard-import,unused-wildcard-import from . import fallback - +from ..util import wrap_data_api_statical_func __all__ = ['ndarray', 'empty', 'empty_like', 'array', 'shape', 'median', 'zeros', 'zeros_like', 'ones', 'ones_like', 'full', 'full_like', 'all', 'any', 'broadcast_to', @@ -8072,7 +8072,8 @@ def mean(a, axis=None, dtype=None, out=None, keepdims=False): # pylint: disable # pylint: disable=redefined-outer-name @set_module('mxnet.numpy') -def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False): # pylint: disable=too-many-arguments +@wrap_data_api_statical_func +def std(a, axis=None, dtype=None, out=None, correction=0, keepdims=False): # pylint: disable=too-many-arguments """ Compute the standard deviation along the specified axis. Returns the standard deviation, a measure of the spread of a distribution, @@ -8097,10 +8098,10 @@ def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False): # pylint: Alternative output array in which to place the result. It must have the same shape as the expected output but the type (of the calculated values) will be cast if necessary. - ddof : int, optional + correction : int, optional Means Delta Degrees of Freedom. The divisor used in calculations - is ``N - ddof``, where ``N`` represents the number of elements. - By default `ddof` is zero. + is ``N - correction``, where ``N`` represents the number of elements. + By default `correction` is zero. 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, @@ -8135,7 +8136,7 @@ def std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False): # pylint: >>> np.std(a, dtype=np.float64) array(0.45, dtype=float64) """ - return _mx_nd_np.std(a, axis=axis, dtype=dtype, ddof=ddof, keepdims=keepdims, out=out) + return _mx_nd_np.std(a, axis=axis, dtype=dtype, ddof=correction, keepdims=keepdims, out=out) # pylint: enable=redefined-outer-name @@ -8190,7 +8191,8 @@ def delete(arr, obj, axis=None): # pylint: disable=redefined-outer-name @set_module('mxnet.numpy') -def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False): # pylint: disable=too-many-arguments +@wrap_data_api_statical_func +def var(a, axis=None, dtype=None, out=None, correction=0, keepdims=False): # pylint: disable=too-many-arguments """ Compute the variance along the specified axis. Returns the variance of the array elements, a measure of the spread of a @@ -8218,10 +8220,10 @@ def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False): # pylint: Alternate output array in which to place the result. It must have the same shape as the expected output, but the type is cast if necessary. - ddof : int, optional + correction : int, optional "Delta Degrees of Freedom": the divisor used in the calculation is - ``N - ddof``, where ``N`` represents the number of elements. By - default `ddof` is zero. + ``N - correction``, where ``N`` represents the number of elements. By + default `correction` is zero. 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, @@ -8258,7 +8260,7 @@ def var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False): # pylint: >>> ((1-0.55)**2 + (0.1-0.55)**2)/2 0.2025 """ - return _mx_nd_np.var(a, axis=axis, dtype=dtype, ddof=ddof, keepdims=keepdims, out=out) + return _mx_nd_np.var(a, axis=axis, dtype=dtype, ddof=correction, keepdims=keepdims, out=out) # pylint: disable=redefined-outer-name @@ -9388,6 +9390,45 @@ def ldexp(x1, x2, out=None, **kwargs): """ return _mx_nd_np.ldexp(x1, x2, out) +@set_module('mxnet.numpy') +def vecdot(a, b, axis=None): + r""" + Return the dot product of two vectors. + Note that `vecdot` handles multidimensional arrays differently than `dot`: + it does *not* perform a matrix product, but flattens input arguments + to 1-D vectors first. Consequently, it should only be used for vectors. + + Parameters + ---------- + a : ndarray + First argument to the dot product. + b : ndarray + Second argument to the dot product. + + Returns + ------- + output : ndarray + Dot product of `a` and `b`. + + See Also + -------- + dot : Return the dot product without using the complex conjugate of the + first argument. + + Examples + -------- + Note that higher-dimensional arrays are flattened! + + >>> a = np.array([[1, 4], [5, 6]]) + >>> b = np.array([[4, 1], [2, 2]]) + >>> np.vecdot(a, b) + array(30.) + >>> np.vecdot(b, a) + array(30.) + >>> 1*4 + 4*1 + 5*2 + 6*2 + 30 + """ + return tensordot(a.flatten(), b.flatten(), axis) @set_module('mxnet.numpy') def vdot(a, b): diff --git a/python/mxnet/util.py b/python/mxnet/util.py index 48475b85da59..4c83d13980ed 100644 --- a/python/mxnet/util.py +++ b/python/mxnet/util.py @@ -645,12 +645,34 @@ def _wrap_np_binary_func(x1, x2, out=None, **kwargs): return func(x1, x2, out=out) return _wrap_np_binary_func +def wrap_data_api_statical_func(func): + """A convenience decorator for wrapping data apis standardized statical functions to provide + context keyward backward compatibility + Parameters + ---------- + func : a numpy-compatible array statical function to be wrapped for context keyward change. + Returns + ------- + Function + A function wrapped with context keyward changes. + """ + + @functools.wraps(func) + def _wrap_api_creation_func(*args, **kwargs): + if len(kwargs) != 0: + correction = kwargs.pop('ddof', None) + if correction is not None: + kwargs['correction'] = correction + return func(*args, **kwargs) + + return _wrap_api_creation_func + def wrap_data_api_linalg_func(func): - """A convenience decorator for wrapping data apis standardized creation functions to provide + """A convenience decorator for wrapping data apis standardized linalg functions to provide context keyward backward compatibility Parameters ---------- - func : a numpy-compatible array creation function to be wrapped for context keyward change. + func : a numpy-compatible array linalg function to be wrapped for context keyward change. Returns ------- Function From 4b5fa7335d2a4c2ce86bf54196ceefaca4dd2e4b Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Fri, 17 Sep 2021 22:04:16 +0800 Subject: [PATCH 03/21] add vecdot --- python/mxnet/numpy/multiarray.py | 9 +++++- tests/python/unittest/test_numpy_op.py | 45 ++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index 2551a7da2edf..9f1229c08440 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -74,7 +74,7 @@ 'flip', 'flipud', 'fliplr', 'around', 'round', 'round_', 'arctan2', 'hypot', 'triu_indices_from', 'triu_indices', 'tri', 'bitwise_and', 'bitwise_xor', 'bitwise_or', 'rad2deg', 'deg2rad', - 'unique', 'lcm', 'gcd', 'tril', 'triu', 'identity', 'take', 'ldexp', 'vdot', 'inner', 'outer', + 'unique', 'lcm', 'gcd', 'tril', 'triu', 'identity', 'take', 'ldexp', 'vecdot', 'vdot', 'inner', 'outer', 'cross', 'kron', 'equal', 'not_equal', 'interp', 'greater', 'less', 'greater_equal', 'less_equal', 'roll', 'rot90', 'einsum', 'true_divide', 'nonzero', 'quantile', 'percentile', 'shares_memory', 'may_share_memory', 'diff', 'ediff1d', 'resize', 'matmul', @@ -9404,6 +9404,13 @@ def vecdot(a, b, axis=None): First argument to the dot product. b : ndarray Second argument to the dot product. + axis : axis over which to compute the dot product. Must be an integer on + the interval [-N, N) , where N is the rank (number of dimensions) of + the shape determined according to Broadcasting . If specified as a + negative integer, the function must determine the axis along which + to compute the dot product by counting backward from the last dimension + (where -1 refers to the last dimension). If None , the function must + compute the dot product over the last axis. Default: None . Returns ------- diff --git a/tests/python/unittest/test_numpy_op.py b/tests/python/unittest/test_numpy_op.py index fed62584877f..ffe171f5bfe6 100644 --- a/tests/python/unittest/test_numpy_op.py +++ b/tests/python/unittest/test_numpy_op.py @@ -258,6 +258,51 @@ def test_np_dot_error(shape_a, shape_b): with pytest.raises(mx.base.MXNetError): mx_res = np.dot(a.as_np_ndarray(), b.as_np_ndarray()) +@use_np +@pytest.mark.parametrize('shape', [(), (5,), (3, 3)]) +@pytest.mark.parametrize('hybridize', [True, False]) +@pytest.mark.parametrize('dtype', [onp.float32, onp.float64]) +def test_np_vecdot(shape, dtype, hybridize): + class TestVecdot(HybridBlock): + def __init__(self): + super(TestVecdot, self).__init__() + + def forward(self, a, b): + return np.vecdot(a, b) + + def vecdot_backward(a, b): + return [b, a] + + test_vecdot = TestVecdot() + if hybridize: + test_vecdot.hybridize() + a = rand_ndarray(shape=shape, dtype=dtype).as_np_ndarray() + b = rand_ndarray(shape=shape, dtype=dtype).as_np_ndarray() + a.attach_grad() + b.attach_grad() + + np_out = onp.vdot(a.asnumpy(), b.asnumpy()) + with mx.autograd.record(): + mx_out = test_vecdot(a, b) + assert mx_out.shape == np_out.shape + assert_almost_equal(mx_out.asnumpy(), np_out, rtol = 1e-3, atol = 1e-5) + mx_out.backward() + np_backward = vecdot_backward(a.asnumpy(), b.asnumpy()) + assert_almost_equal(a.grad.asnumpy(), np_backward[0], rtol = 1e-2, atol=1e-2) + assert_almost_equal(b.grad.asnumpy(), np_backward[1], rtol = 1e-2, atol=1e-2) + + # Test imperative once again + mx_out = np.vecdot(a, b) + np_out = onp.vdot(a.asnumpy(), b.asnumpy()) + assert_almost_equal(mx_out.asnumpy(), np_out, rtol=1e-3, atol=1e-5) + + # test numeric gradient + if len(shape) > 0 and onp.prod(shape) > 0: + a_sym = mx.sym.Variable("a").as_np_ndarray() + b_sym = mx.sym.Variable("b").as_np_ndarray() + mx_sym = mx.sym.np.vecdot(a_sym, b_sym).as_nd_ndarray() + check_numeric_gradient(mx_sym, [a.as_nd_ndarray(), b.as_nd_ndarray()], + rtol=1e-1, atol=1e-1, dtype=dtype) @use_np @pytest.mark.parametrize('shape', [(), (5,), (3, 3)]) From 22e4ed5872951cdc2135dbffdd7b7e107b51f603 Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Wed, 22 Sep 2021 08:55:41 +0800 Subject: [PATCH 04/21] changes made --- python/mxnet/numpy/linalg.py | 4 +- python/mxnet/numpy/multiarray.py | 515 +++++++------------------------ 2 files changed, 107 insertions(+), 412 deletions(-) diff --git a/python/mxnet/numpy/linalg.py b/python/mxnet/numpy/linalg.py index aec9102ebba9..c5bc883030f6 100644 --- a/python/mxnet/numpy/linalg.py +++ b/python/mxnet/numpy/linalg.py @@ -894,7 +894,7 @@ def eigvalsh(a, upper=False): >>> LA.eigvalsh(a, upper=False) array([-2.87381886, 5.10144682, 6.38623114]) # in ascending order """ - if(upper==False): + if not upper: UPLO='L' else: UPLO='U' @@ -1031,7 +1031,7 @@ def eigh(a, upper=False): [ 0.8242942 , 0.56326365, -0.05721384], [-0.53661287, 0.80949366, 0.23825769]]) """ - if(upper == False): + if not upper: UPLO = 'L' else: UPLO = 'U' diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index 9f1229c08440..895cfa76b098 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -45,7 +45,7 @@ from ..runtime import Features from ..context import Context from ..util import set_module, wrap_np_unary_func, wrap_np_binary_func,\ - is_np_default_dtype + is_np_default_dtype, wrap_data_api_statical_func from ..context import current_context from ..ndarray import numpy as _mx_nd_np from ..ndarray.numpy import _internal as _npi @@ -54,7 +54,6 @@ from .utils import _get_np_op from .fallback import * # pylint: disable=wildcard-import,unused-wildcard-import from . import fallback -from ..util import wrap_data_api_statical_func __all__ = ['ndarray', 'empty', 'empty_like', 'array', 'shape', 'median', 'zeros', 'zeros_like', 'ones', 'ones_like', 'full', 'full_like', 'all', 'any', 'broadcast_to', @@ -1165,7 +1164,7 @@ def __rpow__(self, other): @wrap_mxnp_np_ufunc def __ipow__(self, other): - """x.__ipow__(y) <=> x *= y""" + """x.__ipow__(y) <=> x **= y""" return power(self, other, out=self) @wrap_mxnp_np_ufunc @@ -3080,7 +3079,7 @@ def take(a, indices, axis=None, mode='raise', out=None): @set_module('mxnet.numpy') -def unique(ar, return_index=False, return_inverse=False, return_counts=False): +def unique(ar, return_index=False, return_inverse=False, return_counts=False, axis=None): """ Find the unique elements of an array. @@ -3153,6 +3152,13 @@ def unique(ar, return_index=False, return_inverse=False, return_counts=False): Return the unique rows of a 2D array + >>> a = np.array([[1, 0, 0], [1, 0, 0], [2, 3, 4]]) + >>> np.unique(a, axis=0) + array([[1., 0., 0.], + [2., 3., 4.]]) + + Return the indices of the original array that give the unique values: + >>> a = np.array([1, 2, 6, 4, 2, 3, 2]) >>> u, indices = np.unique(a, return_index=True) >>> u @@ -3173,7 +3179,7 @@ def unique(ar, return_index=False, return_inverse=False, return_counts=False): >>> u[indices] array([1., 2., 6., 4., 2., 3., 2.]) """ - return _mx_nd_np.unique(ar, return_index, return_inverse, return_counts) + return _mx_nd_np.unique(ar, return_index, return_inverse, return_counts, axis) @set_module('mxnet.numpy') @@ -3589,55 +3595,7 @@ def remainder(x1, x2, out=None, **kwargs): """ return _mx_nd_np.remainder(x1, x2, out=out) -@set_module('mxnet.numpy') -@wrap_np_binary_func -def pow(x1, x2): - """ - First array elements raised to powers from second array, element-wise. - - Parameters - ---------- - x1 : ndarray or scalar - The bases. - - x2 : ndarray or scalar - The exponent. - - out : ndarray - A location into which the result is stored. If provided, it must have a shape - that the inputs broadcast to. If not provided or None, a freshly-allocated array - is returned. - - Returns - ------- - out : ndarray or scalar - The bases in x1 raised to the exponents in x2. - This is a scalar if both x1 and x2 are scalars. - - Examples - -------- - >>> x1 = np.arange(6) - >>> np.pow(x1, 3) - array([ 0., 1., 8., 27., 64., 125.]) - - Raise the bases to different exponents. - - >>> x2 = np.array([1.0, 2.0, 3.0, 3.0, 2.0, 1.0]) - >>> np.pow(x1, x2) - array([ 0., 1., 8., 27., 16., 5.]) - - The effect of broadcasting. - >>> x2 = np.array([[1, 2, 3, 3, 2, 1], [1, 2, 3, 3, 2, 1]]) - >>> x2 - array([[1., 2., 3., 3., 2., 1.], - [1., 2., 3., 3., 2., 1.]]) - - >>> np.pow(x1, x2) - array([[ 0., 1., 8., 27., 16., 5.], - [ 0., 1., 8., 27., 16., 5.]]) - """ - return _mx_nd_np.pow(x1, x2) @set_module('mxnet.numpy') @wrap_np_binary_func @@ -3689,6 +3647,19 @@ def power(x1, x2, out=None, **kwargs): """ return _mx_nd_np.power(x1, x2, out=out) +pow = power +pow.__doc__=""" + ... + Notes + ----- + `pow` is an alias for `power`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#pow-x1-x2 + instead of an official NumPy operator. + + >>> np.pow is np.power + True + ... + """ @set_module('mxnet.numpy') @wrap_np_binary_func @@ -4215,62 +4186,6 @@ def expm1(x, out=None, **kwargs): """ return _mx_nd_np.expm1(x, out=out, **kwargs) -@set_module('mxnet.numpy') -@wrap_np_unary_func -def asin(x, out=None): - r""" - Inverse sine, element-wise. - - Parameters - ---------- - x : ndarray or scalar - `y`-coordinate on the unit circle. - out : ndarray or None, optional - A location into which the result is stored. - If provided, it must have the same shape as the input. - If not provided or None, a freshly-allocated array is returned. - - Returns - ------- - angle : ndarray or scalar - Output array is same shape and type as x. This is a scalar if x is a scalar. - The inverse sine of each element in `x`, in radians and in the - closed interval ``[-pi/2, pi/2]``. - - Examples - -------- - >>> np.asin(1) # pi/2 - 1.5707963267948966 - >>> np.asin(-1) # -pi/2 - -1.5707963267948966 - >>> np.asin(0) - 0.0 - - .. note:: - `arcsin` is a multivalued function: for each `x` there are infinitely - many numbers `z` such that :math:`sin(z) = x`. The convention is to - return the angle `z` whose real part lies in [-pi/2, pi/2]. - For real-valued input data types, *arcsin* always returns real output. - For each value that cannot be expressed as a real number or infinity, - it yields ``nan`` and sets the `invalid` floating point error flag. - The inverse sine is also known as `asin` or sin^{-1}. - The output `ndarray` has the same `ctx` as the input `ndarray`. - This function differs from the original `numpy.arcsin - `_ in - the following aspects: - - * Only support ndarray or scalar now. - * `where` argument is not supported. - * Complex input is not supported. - - References - ---------- - Abramowitz, M. and Stegun, I. A., *Handbook of Mathematical Functions*, - 10th printing, New York: Dover, 1964, pp. 79ff. - http://www.math.sfu.ca/~cbm/aands/ - """ - return _mx_nd_np.arcsin(x, out=out) - @set_module('mxnet.numpy') @wrap_np_unary_func def arcsin(x, out=None, **kwargs): @@ -4327,43 +4242,18 @@ def arcsin(x, out=None, **kwargs): """ return _mx_nd_np.arcsin(x, out=out, **kwargs) -@set_module('mxnet.numpy') -@wrap_np_unary_func -def acos(x, out=None): - """ - Trigonometric inverse cosine, element-wise. - The inverse of cos so that, if y = cos(x), then x = arccos(y). - - Parameters - ---------- - x : ndarray - x-coordinate on the unit circle. For real arguments, the domain is [-1, 1]. - out : ndarray, optional - A location into which the result is stored. If provided, it must have a shape that - the inputs broadcast to. If not provided or None, a freshly-allocated array is returned. - A tuple (possible only as a keyword argument) must have length equal to the number of outputs. - - Returns - ---------- - angle : ndarray - The angle of the ray intersecting the unit circle at the given x-coordinate in radians [0, pi]. - This is a scalar if x is a scalar. - +asin=arcsin +asin.__doc__=""" + ... Notes - ---------- - arccos is a multivalued function: for each x there are infinitely many numbers z such that - cos(z) = x. The convention is to return the angle z whose real part lies in [0, pi]. - For real-valued input data types, arccos always returns real output. - For each value that cannot be expressed as a real number or infinity, it yields nan and sets - the invalid floating point error flag. - The inverse cos is also known as acos or cos^-1. - - Examples - ---------- - >>> np.acos([1, -1]) - array([ 0. , 3.14159265]) + `asin` is a alias for `arcsin`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#asin-x + instead of an official NumPy operator. + + >>>np.asin is np.arcsin + True + ... """ - return _mx_nd_np.arccos(x, out=out) @set_module('mxnet.numpy') @@ -4404,50 +4294,18 @@ def arccos(x, out=None, **kwargs): """ return _mx_nd_np.arccos(x, out=out, **kwargs) -@set_module('mxnet.numpy') -@wrap_np_unary_func -def atan(x, out=None): - r""" - Trigonometric inverse tangent, element-wise. - The inverse of tan, so that if ``y = tan(x)`` then ``x = arctan(y)``. - - Parameters - ---------- - x : ndarray or scalar - Input values. - out : ndarray or None, optional - A location into which the result is stored. If provided, it must have - a shape that the inputs broadcast to. If not provided or `None`, - a freshly-allocated array is returned. - - Returns - ------- - out : ndarray or scalar - Out has the same shape as `x`. It lies is in - ``[-pi/2, pi/2]`` (``arctan(+/-inf)`` returns ``+/-pi/2``). - This is a scalar if `x` is a scalar. - +acos=arccos +acos.__doc__=""" + ... Notes - ----- - `arctan` is a multi-valued function: for each `x` there are infinitely - many numbers `z` such that tan(`z`) = `x`. The convention is to return - the angle `z` whose real part lies in [-pi/2, pi/2]. - For real-valued input data types, `arctan` always returns real output. - For each value that cannot be expressed as a real number or infinity, - it yields ``nan`` and sets the `invalid` floating point error flag. - For complex-valued input, we do not have support for them yet. - The inverse tangent is also known as `atan` or tan^{-1}. - - Examples - -------- - >>> x = np.array([0, 1]) - >>> np.atan(x) - array([0. , 0.7853982]) - >>> np.pi/4 - 0.7853981633974483 + `acos` is a alias for `arccos`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#acos-x + instead of an official NumPy operator. + + >>>np.acos is np.arccos + True + ... """ - return _mx_nd_np.arctan(x, out=out) - @set_module('mxnet.numpy') @wrap_np_unary_func @@ -4493,6 +4351,19 @@ def arctan(x, out=None, **kwargs): """ return _mx_nd_np.arctan(x, out=out, **kwargs) +atan=arctan +atan.__doc__=""" + ... + Notes + `atan` is a alias for `arctan`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#atan-x + instead of an official NumPy operator. + + >>>np.atan is np.arctan + True + ... + """ + @set_module('mxnet.numpy') @wrap_np_unary_func @@ -5373,52 +5244,6 @@ def logical_not(x, out=None, **kwargs): """ return _mx_nd_np.logical_not(x, out=out, **kwargs) -@set_module('mxnet.numpy') -@wrap_np_unary_func -def asinh(x, out=None): - r""" - Inverse hyperbolic cosine, element-wise. - - Parameters - ---------- - x : ndarray or scalar - Input array. - out : ndarray or None, optional - A location into which the result is stored. - - Returns - ------- - asinh : ndarray - Array of the same shape as `x`. - This is a scalar if `x` is a scalar. - - .. note:: - `asinh` is a multivalued function: for each `x` there are infinitely - many numbers `z` such that `sinh(z) = x`. - - For real-valued input data types, `asinh` always returns real output. - For each value that cannot be expressed as a real number or infinity, it - yields ``nan`` and sets the `invalid` floating point error flag. - - This function differs from the original numpy.asinh in the following aspects: - - * Do not support `where`, a parameter in numpy which indicates where to calculate. - * Do not support complex-valued input. - * Cannot cast type automatically. DType of `out` must be same as the expected one. - * Cannot broadcast automatically. Shape of `out` must be same as the expected one. - * If `x` is plain python numeric, the result won't be stored in out. - - Examples - -------- - >>> a = np.array([3.2, 5.0]) - >>> np.asinh(a) - array([1.8309381, 2.2924316]) - - >>> np.asinh(1) - 0.0 - """ - return _mx_nd_np.arcsinh(x, out=out) - @set_module('mxnet.numpy') @wrap_np_unary_func def arcsinh(x, out=None, **kwargs): @@ -5465,51 +5290,19 @@ def arcsinh(x, out=None, **kwargs): """ return _mx_nd_np.arcsinh(x, out=out, **kwargs) -@set_module('mxnet.numpy') -@wrap_np_unary_func -def acosh(x, out=None): - r""" - Inverse hyperbolic cosine, element-wise. - - Parameters - ---------- - x : ndarray or scalar - Input array. - out : ndarray or None, optional - A location into which the result is stored. - - Returns - ------- - arccosh : ndarray - Array of the same shape as `x`. - This is a scalar if `x` is a scalar. - - .. note:: - `arccosh` is a multivalued function: for each `x` there are infinitely - many numbers `z` such that `cosh(z) = x`. - - For real-valued input data types, `arccosh` always returns real output. - For each value that cannot be expressed as a real number or infinity, it - yields ``nan`` and sets the `invalid` floating point error flag. - - This function differs from the original numpy.arccosh in the following aspects: - - * Do not support `where`, a parameter in numpy which indicates where to calculate. - * Do not support complex-valued input. - * Cannot cast type automatically. Dtype of `out` must be same as the expected one. - * Cannot broadcast automatically. Shape of `out` must be same as the expected one. - * If `x` is plain python numeric, the result won't be stored in out. - - Examples - -------- - >>> a = np.array([3.2, 5.0]) - >>> np.acosh(a) - array([1.8309381, 2.2924316]) - - >>> np.acosh(1) - 0.0 +asinh=arcsinh +asinh.__doc__=""" + ... + Notes + `asinh` is a alias for `arcsinh`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#asinh-x + instead of an official NumPy operator. + + >>>np.asinh is np.arcsinh + True + ... """ - return _mx_nd_np.arccosh(x, out=out) + @set_module('mxnet.numpy') @wrap_np_unary_func @@ -5557,52 +5350,18 @@ def arccosh(x, out=None, **kwargs): """ return _mx_nd_np.arccosh(x, out=out, **kwargs) -@set_module('mxnet.numpy') -@wrap_np_unary_func -def atanh(x, out=None): - r""" - Inverse hyperbolic tangent, element-wise. - - Parameters - ---------- - x : ndarray or scalar - Input array. - out : ndarray or None, optional - A location into which the result is stored. - - Returns - ------- - atanh : ndarray - Array of the same shape as `x`. - This is a scalar if `x` is a scalar. - - .. note:: - `atanh` is a multivalued function: for each `x` there are infinitely - many numbers `z` such that `tanh(z) = x`. - - For real-valued input data types, `atanh` always returns real output. - For each value that cannot be expressed as a real number or infinity, it - yields ``nan`` and sets the `invalid` floating point error flag. - - This function differs from the original numpy.atanh in the following aspects: - - * Do not support `where`, a parameter in numpy which indicates where to calculate. - * Do not support complex-valued input. - * Cannot cast type automatically. Dtype of `out` must be same as the expected one. - * Cannot broadcast automatically. Shape of `out` must be same as the expected one. - * If `x` is plain python numeric, the result won't be stored in out. - - Examples - -------- - >>> a = np.array([0.0, -0.5]) - >>> np.atanh(a) - array([0., -0.54930615]) - - >>> np.atanh(1) - 0.0 +acosh=arccosh +acosh.__doc__=""" + ... + Notes + `acosh` is a alias for `arccosh`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#acosh-x + instead of an official NumPy operator. + + >>>np.acosh is np.arccosh + True + ... """ - return _mx_nd_np.arctanh(x, out=out) - @set_module('mxnet.numpy') @wrap_np_unary_func @@ -5650,6 +5409,19 @@ def arctanh(x, out=None, **kwargs): """ return _mx_nd_np.arctanh(x, out=out, **kwargs) +atanh=arctanh +atanh.__doc__=""" + ... + Notes + `atanh` is a alias for `arctanh`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#atanh-x + instead of an official NumPy operator. + + >>>np.atanh is np.arctanh + True + ... + """ + @set_module('mxnet.numpy') def argsort(a, axis=-1, kind=None, order=None): @@ -9010,95 +8782,6 @@ def round_(x, decimals=0, out=None, **kwargs): """ return _mx_nd_np.round_(x, decimals, out=out, **kwargs) -@set_module('mxnet.numpy') -@wrap_np_binary_func -def atan2(x1, x2, out=None): - r""" - Element-wise arc tangent of ``x1/x2`` choosing the quadrant correctly. - - The quadrant (i.e., branch) is chosen so that ``atan2(x1, x2)`` is - the signed angle in radians between the ray ending at the origin and - passing through the point (1,0), and the ray ending at the origin and - passing through the point (`x2`, `x1`). (Note the role reversal: the - "`y`-coordinate" is the first function parameter, the "`x`-coordinate" - is the second.) By IEEE convention, this function is defined for - `x2` = +/-0 and for either or both of `x1` and `x2` = +/-inf (see - Notes for specific values). - - This function is not defined for complex-valued arguments; for the - so-called argument of complex values, use `angle`. - - Parameters - ---------- - x1 : ndarray or scalar - `y`-coordinates. - x2 : ndarray or scalar - `x`-coordinates. `x2` must be broadcastable to match the shape of - `x1` or vice versa. - out : ndarray or None, optional - A location into which the result is stored. If provided, it must have - a shape that the inputs broadcast to. If not provided or `None`, - a freshly-allocated array is returned. - - Returns - ------- - out : ndarray or scalar - Array of angles in radians, in the range ``[-pi, pi]``. This is a scalar if - `x1` and `x2` are scalars. - - .. notes:: - *atan2* is identical to the ``atan2`` function of the underlying - C library. The following special values are defined in the C - standard: [1]_ - - +========+========+==================+ - | `x1` | `x2` | `atan2(x1,x2)` | - +========+========+==================+ - | +/- 0 | +0 | +/- 0 | - +========+========+==================+ - | +/- 0 | -0 | +/- pi | - +========+========+==================+ - | > 0 | +/-inf | +0 / +pi | - +========+========+==================+ - | < 0 | +/-inf | -0 / -pi | - +========+========+==================+ - | +/-inf | +inf | +/- (pi/4) | - +========+========+==================+ - | +/-inf | -inf | +/- (3*pi/4) | - +========+========+==================+ - - Note that +0 and -0 are distinct floating point numbers, as are +inf - and -inf. - - This function differs from the original numpy.arange in the following aspects: - - * Only support float16, float32 and float64. - - References - ---------- - .. [1] ISO/IEC standard 9899:1999, "Programming language C." - - Examples - -------- - Consider four points in different quadrants: - - >>> x = np.array([-1, +1, +1, -1]) - >>> y = np.array([-1, -1, +1, +1]) - >>> np.atan2(y, x) * 180 / np.pi - array([-135., -45., 45., 135.]) - - Note the order of the parameters. `atan2` is defined also when `x2` = 0 - and at several other special points, obtaining values in - the range ``[-pi, pi]``: - - >>> x = np.array([1, -1]) - >>> y = np.array([0, 0]) - >>> np.atan2(x, y) - array([ 1.5707964, -1.5707964]) - """ - return _mx_nd_np.arctan2(x1, x2, out=out) - - @set_module('mxnet.numpy') @wrap_np_binary_func def arctan2(x1, x2, out=None, **kwargs): @@ -9187,6 +8870,18 @@ def arctan2(x1, x2, out=None, **kwargs): """ return _mx_nd_np.arctan2(x1, x2, out=out) +atan2=arctan2 +atan2.__doc__=""" + ... + Notes + `atan2` is a alias for `arctan2`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#atan2-x + instead of an official NumPy operator. + + >>>np.atan2 is np.arctan2 + True + ... + """ @set_module('mxnet.numpy') @wrap_np_binary_func From 3fdcc3c53580952746a567dbe8e7de8c80e64b29 Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Wed, 22 Sep 2021 08:57:03 +0800 Subject: [PATCH 05/21] changes made --- python/mxnet/numpy/multiarray.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index 895cfa76b098..07279c2586c7 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -3155,7 +3155,7 @@ def unique(ar, return_index=False, return_inverse=False, return_counts=False, ax >>> a = np.array([[1, 0, 0], [1, 0, 0], [2, 3, 4]]) >>> np.unique(a, axis=0) array([[1., 0., 0.], - [2., 3., 4.]]) + [2., 3., 4.]]) Return the indices of the original array that give the unique values: From 8157c0aa50e77555489d0b909f34f300b98bc72c Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Fri, 24 Sep 2021 21:11:58 +0800 Subject: [PATCH 06/21] changes made --- python/mxnet/numpy/multiarray.py | 347 +++++++++++++++++++++++++++++-- 1 file changed, 330 insertions(+), 17 deletions(-) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index 07279c2586c7..17955021d5e8 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -4189,7 +4189,7 @@ def expm1(x, out=None, **kwargs): @set_module('mxnet.numpy') @wrap_np_unary_func def arcsin(x, out=None, **kwargs): - r""" + """ Inverse sine, element-wise. Parameters @@ -4244,15 +4244,64 @@ def arcsin(x, out=None, **kwargs): asin=arcsin asin.__doc__=""" - ... + Inverse sine, element-wise. + Notes + ---------- `asin` is a alias for `arcsin`. It is a standard API in https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#asin-x instead of an official NumPy operator. - >>>np.asin is np.arcsin + >>>np.asin is np.asin True - ... + + Parameters + ---------- + x : ndarray or scalar + `y`-coordinate on the unit circle. + out : ndarray or None, optional + A location into which the result is stored. + If provided, it must have the same shape as the input. + If not provided or None, a freshly-allocated array is returned. + + Returns + ------- + angle : ndarray or scalar + Output array is same shape and type as x. This is a scalar if x is a scalar. + The inverse sine of each element in `x`, in radians and in the + closed interval ``[-pi/2, pi/2]``. + + Examples + -------- + >>> np.asin(1) # pi/2 + 1.5707963267948966 + >>> np.asin(-1) # -pi/2 + -1.5707963267948966 + >>> np.asin(0) + 0.0 + + .. note:: + `asin` is a multivalued function: for each `x` there are infinitely + many numbers `z` such that :math:`sin(z) = x`. The convention is to + return the angle `z` whose real part lies in [-pi/2, pi/2]. + For real-valued input data types, *asin* always returns real output. + For each value that cannot be expressed as a real number or infinity, + it yields ``nan`` and sets the `invalid` floating point error flag. + The inverse sine is also known as `asin` or sin^{-1}. + The output `ndarray` has the same `ctx` as the input `ndarray`. + This function differs from the original `numpy.arcsin + `_ in + the following aspects: + + * Only support ndarray or scalar now. + * `where` argument is not supported. + * Complex input is not supported. + + References + ---------- + Abramowitz, M. and Stegun, I. A., *Handbook of Mathematical Functions*, + 10th printing, New York: Dover, 1964, pp. 79ff. + http://www.math.sfu.ca/~cbm/aands/ """ @@ -4296,15 +4345,46 @@ def arccos(x, out=None, **kwargs): acos=arccos acos.__doc__=""" - ... + Trigonometric inverse cosine, element-wise. + The inverse of cos so that, if y = cos(x), then x = acos(y). + Notes + ---------- `acos` is a alias for `arccos`. It is a standard API in https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#acos-x instead of an official NumPy operator. >>>np.acos is np.arccos True - ... + + Parameters + ---------- + x : ndarray + x-coordinate on the unit circle. For real arguments, the domain is [-1, 1]. + out : ndarray, optional + A location into which the result is stored. If provided, it must have a shape that + the inputs broadcast to. If not provided or None, a freshly-allocated array is returned. + A tuple (possible only as a keyword argument) must have length equal to the number of outputs. + + Returns + ---------- + angle : ndarray + The angle of the ray intersecting the unit circle at the given x-coordinate in radians [0, pi]. + This is a scalar if x is a scalar. + + Notes + ---------- + acos is a multivalued function: for each x there are infinitely many numbers z such that + cos(z) = x. The convention is to return the angle z whose real part lies in [0, pi]. + For real-valued input data types, acos always returns real output. + For each value that cannot be expressed as a real number or infinity, it yields nan and sets + the invalid floating point error flag. + The inverse cos is also known as acos or cos^-1. + + Examples + ---------- + >>> np.acos([1, -1]) + array([ 0. , 3.14159265]) """ @set_module('mxnet.numpy') @@ -4353,15 +4433,52 @@ def arctan(x, out=None, **kwargs): atan=arctan atan.__doc__=""" - ... + Trigonometric inverse tangent, element-wise. + The inverse of tan, so that if ``y = tan(x)`` then ``x = atan(y)``. + Notes + --------- `atan` is a alias for `arctan`. It is a standard API in https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#atan-x instead of an official NumPy operator. >>>np.atan is np.arctan True - ... + + Parameters + ---------- + x : ndarray or scalar + Input values. + out : ndarray or None, optional + A location into which the result is stored. If provided, it must have + a shape that the inputs broadcast to. If not provided or `None`, + a freshly-allocated array is returned. + + Returns + ------- + out : ndarray or scalar + Out has the same shape as `x`. It lies is in + ``[-pi/2, pi/2]`` (``atan(+/-inf)`` returns ``+/-pi/2``). + This is a scalar if `x` is a scalar. + + Notes + ----- + `atan` is a multi-valued function: for each `x` there are infinitely + many numbers `z` such that tan(`z`) = `x`. The convention is to return + the angle `z` whose real part lies in [-pi/2, pi/2]. + For real-valued input data types, `atan` always returns real output. + For each value that cannot be expressed as a real number or infinity, + it yields ``nan`` and sets the `invalid` floating point error flag. + For complex-valued input, we do not have support for them yet. + The inverse tangent is also known as `atan` or tan^{-1}. + + Examples + -------- + >>> x = np.array([0, 1]) + >>> np.atan(x) + array([0. , 0.7853982]) + >>> np.pi/4 + 0.7853981633974483 """ @@ -5292,15 +5409,54 @@ def arcsinh(x, out=None, **kwargs): asinh=arcsinh asinh.__doc__=""" - ... + Inverse hyperbolic cosine, element-wise. + Notes + ---------- `asinh` is a alias for `arcsinh`. It is a standard API in https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#asinh-x instead of an official NumPy operator. >>>np.asinh is np.arcsinh True - ... + + Parameters + ---------- + x : ndarray or scalar + Input array. + out : ndarray or None, optional + A location into which the result is stored. + + Returns + ------- + asinh : ndarray + Array of the same shape as `x`. + This is a scalar if `x` is a scalar. + + .. note:: + `asinh` is a multivalued function: for each `x` there are infinitely + many numbers `z` such that `sinh(z) = x`. + + For real-valued input data types, `asinh` always returns real output. + For each value that cannot be expressed as a real number or infinity, it + yields ``nan`` and sets the `invalid` floating point error flag. + + This function differs from the original numpy.arcsinh in the following aspects: + + * Do not support `where`, a parameter in numpy which indicates where to calculate. + * Do not support complex-valued input. + * Cannot cast type automatically. DType of `out` must be same as the expected one. + * Cannot broadcast automatically. Shape of `out` must be same as the expected one. + * If `x` is plain python numeric, the result won't be stored in out. + + Examples + -------- + >>> a = np.array([3.2, 5.0]) + >>> np.asinh(a) + array([1.8309381, 2.2924316]) + + >>> np.asinh(1) + 0.0 """ @@ -5350,9 +5506,10 @@ def arccosh(x, out=None, **kwargs): """ return _mx_nd_np.arccosh(x, out=out, **kwargs) -acosh=arccosh +acosh = arccosh acosh.__doc__=""" - ... + Inverse hyperbolic cosine, element-wise. + Notes `acosh` is a alias for `arccosh`. It is a standard API in https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#acosh-x @@ -5360,7 +5517,44 @@ def arccosh(x, out=None, **kwargs): >>>np.acosh is np.arccosh True - ... + + Parameters + ---------- + x : ndarray or scalar + Input array. + out : ndarray or None, optional + A location into which the result is stored. + + Returns + ------- + acosh : ndarray + Array of the same shape as `x`. + This is a scalar if `x` is a scalar. + + .. note:: + `acosh` is a multivalued function: for each `x` there are infinitely + many numbers `z` such that `cosh(z) = x`. + + For real-valued input data types, `acosh` always returns real output. + For each value that cannot be expressed as a real number or infinity, it + yields ``nan`` and sets the `invalid` floating point error flag. + + This function differs from the original numpy.arccosh in the following aspects: + + * Do not support `where`, a parameter in numpy which indicates where to calculate. + * Do not support complex-valued input. + * Cannot cast type automatically. Dtype of `out` must be same as the expected one. + * Cannot broadcast automatically. Shape of `out` must be same as the expected one. + * If `x` is plain python numeric, the result won't be stored in out. + + Examples + -------- + >>> a = np.array([3.2, 5.0]) + >>> np.acosh(a) + array([1.8309381, 2.2924316]) + + >>> np.acosh(1) + 0.0 """ @set_module('mxnet.numpy') @@ -5411,7 +5605,8 @@ def arctanh(x, out=None, **kwargs): atanh=arctanh atanh.__doc__=""" - ... + Inverse hyperbolic tangent, element-wise. + Notes `atanh` is a alias for `arctanh`. It is a standard API in https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#atanh-x @@ -5419,7 +5614,44 @@ def arctanh(x, out=None, **kwargs): >>>np.atanh is np.arctanh True - ... + + Parameters + ---------- + x : ndarray or scalar + Input array. + out : ndarray or None, optional + A location into which the result is stored. + + Returns + ------- + atanh : ndarray + Array of the same shape as `x`. + This is a scalar if `x` is a scalar. + + .. note:: + `atanh` is a multivalued function: for each `x` there are infinitely + many numbers `z` such that `tanh(z) = x`. + + For real-valued input data types, `atanh` always returns real output. + For each value that cannot be expressed as a real number or infinity, it + yields ``nan`` and sets the `invalid` floating point error flag. + + This function differs from the original numpy.arctanh in the following aspects: + + * Do not support `where`, a parameter in numpy which indicates where to calculate. + * Do not support complex-valued input. + * Cannot cast type automatically. Dtype of `out` must be same as the expected one. + * Cannot broadcast automatically. Shape of `out` must be same as the expected one. + * If `x` is plain python numeric, the result won't be stored in out. + + Examples + -------- + >>> a = np.array([0.0, -0.5]) + >>> np.atanh(a) + array([0., -0.54930615]) + + >>> np.atanh(1) + 0.0 """ @@ -8872,15 +9104,96 @@ def arctan2(x1, x2, out=None, **kwargs): atan2=arctan2 atan2.__doc__=""" - ... + Element-wise arc tangent of ``x1/x2`` choosing the quadrant correctly. + + The quadrant (i.e., branch) is chosen so that ``atan2(x1, x2)`` is + the signed angle in radians between the ray ending at the origin and + passing through the point (1,0), and the ray ending at the origin and + passing through the point (`x2`, `x1`). (Note the role reversal: the + "`y`-coordinate" is the first function parameter, the "`x`-coordinate" + is the second.) By IEEE convention, this function is defined for + `x2` = +/-0 and for either or both of `x1` and `x2` = +/-inf (see + Notes for specific values). + + This function is not defined for complex-valued arguments; for the + so-called argument of complex values, use `angle`. + Notes + ---------- `atan2` is a alias for `arctan2`. It is a standard API in https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#atan2-x instead of an official NumPy operator. >>>np.atan2 is np.arctan2 True - ... + + Parameters + ---------- + x1 : ndarray or scalar + `y`-coordinates. + x2 : ndarray or scalar + `x`-coordinates. `x2` must be broadcastable to match the shape of + `x1` or vice versa. + out : ndarray or None, optional + A location into which the result is stored. If provided, it must have + a shape that the inputs broadcast to. If not provided or `None`, + a freshly-allocated array is returned. + + Returns + ------- + out : ndarray or scalar + Array of angles in radians, in the range ``[-pi, pi]``. This is a scalar if + `x1` and `x2` are scalars. + + .. notes:: + *atan2* is identical to the ``atan2`` function of the underlying + C library. The following special values are defined in the C + standard: [1]_ + + +========+========+==================+ + | `x1` | `x2` | `atan2(x1,x2)` | + +========+========+==================+ + | +/- 0 | +0 | +/- 0 | + +========+========+==================+ + | +/- 0 | -0 | +/- pi | + +========+========+==================+ + | > 0 | +/-inf | +0 / +pi | + +========+========+==================+ + | < 0 | +/-inf | -0 / -pi | + +========+========+==================+ + | +/-inf | +inf | +/- (pi/4) | + +========+========+==================+ + | +/-inf | -inf | +/- (3*pi/4) | + +========+========+==================+ + + Note that +0 and -0 are distinct floating point numbers, as are +inf + and -inf. + + This function differs from the original numpy.arange in the following aspects: + + * Only support float16, float32 and float64. + + References + ---------- + .. [1] ISO/IEC standard 9899:1999, "Programming language C." + + Examples + -------- + Consider four points in different quadrants: + + >>> x = np.array([-1, +1, +1, -1]) + >>> y = np.array([-1, -1, +1, +1]) + >>> np.atan2(y, x) * 180 / np.pi + array([-135., -45., 45., 135.]) + + Note the order of the parameters. `atan2` is defined also when `x2` = 0 + and at several other special points, obtaining values in + the range ``[-pi, pi]``: + + >>> x = np.array([1, -1]) + >>> y = np.array([0, 0]) + >>> np.atan2(x, y) + array([ 1.5707964, -1.5707964]) """ @set_module('mxnet.numpy') From 5a0dea1fa16e1217fe7f3d250cb57c009432b240 Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Fri, 24 Sep 2021 21:14:57 +0800 Subject: [PATCH 07/21] changes made --- python/mxnet/numpy/multiarray.py | 46 ++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index 17955021d5e8..849c67f29a24 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -3649,7 +3649,8 @@ def power(x1, x2, out=None, **kwargs): pow = power pow.__doc__=""" - ... + First array elements raised to powers from second array, element-wise. + Notes ----- `pow` is an alias for `power`. It is a standard API in @@ -3658,7 +3659,48 @@ def power(x1, x2, out=None, **kwargs): >>> np.pow is np.power True - ... + + Parameters + ---------- + x1 : ndarray or scalar + The bases. + + x2 : ndarray or scalar + The exponent. + + out : ndarray + A location into which the result is stored. If provided, it must have a shape + that the inputs broadcast to. If not provided or None, a freshly-allocated array + is returned. + + Returns + ------- + out : ndarray or scalar + The bases in x1 raised to the exponents in x2. + This is a scalar if both x1 and x2 are scalars. + + Examples + -------- + >>> x1 = np.arange(6) + >>> np.pow(x1, 3) + array([ 0., 1., 8., 27., 64., 125.]) + + Raise the bases to different exponents. + + >>> x2 = np.array([1.0, 2.0, 3.0, 3.0, 2.0, 1.0]) + >>> np.pow(x1, x2) + array([ 0., 1., 8., 27., 16., 5.]) + + The effect of broadcasting. + + >>> x2 = np.array([[1, 2, 3, 3, 2, 1], [1, 2, 3, 3, 2, 1]]) + >>> x2 + array([[1., 2., 3., 3., 2., 1.], + [1., 2., 3., 3., 2., 1.]]) + + >>> np.pow(x1, x2) + array([[ 0., 1., 8., 27., 16., 5.], + [ 0., 1., 8., 27., 16., 5.]]) """ @set_module('mxnet.numpy') From 4e5470756568ebec3c8c166f4fc71d24bbd56c26 Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Fri, 24 Sep 2021 21:26:01 +0800 Subject: [PATCH 08/21] delete test vecdot --- tests/python/unittest/test_numpy_op.py | 46 -------------------------- 1 file changed, 46 deletions(-) diff --git a/tests/python/unittest/test_numpy_op.py b/tests/python/unittest/test_numpy_op.py index ffe171f5bfe6..a8a2e06bb5ec 100644 --- a/tests/python/unittest/test_numpy_op.py +++ b/tests/python/unittest/test_numpy_op.py @@ -258,52 +258,6 @@ def test_np_dot_error(shape_a, shape_b): with pytest.raises(mx.base.MXNetError): mx_res = np.dot(a.as_np_ndarray(), b.as_np_ndarray()) -@use_np -@pytest.mark.parametrize('shape', [(), (5,), (3, 3)]) -@pytest.mark.parametrize('hybridize', [True, False]) -@pytest.mark.parametrize('dtype', [onp.float32, onp.float64]) -def test_np_vecdot(shape, dtype, hybridize): - class TestVecdot(HybridBlock): - def __init__(self): - super(TestVecdot, self).__init__() - - def forward(self, a, b): - return np.vecdot(a, b) - - def vecdot_backward(a, b): - return [b, a] - - test_vecdot = TestVecdot() - if hybridize: - test_vecdot.hybridize() - a = rand_ndarray(shape=shape, dtype=dtype).as_np_ndarray() - b = rand_ndarray(shape=shape, dtype=dtype).as_np_ndarray() - a.attach_grad() - b.attach_grad() - - np_out = onp.vdot(a.asnumpy(), b.asnumpy()) - with mx.autograd.record(): - mx_out = test_vecdot(a, b) - assert mx_out.shape == np_out.shape - assert_almost_equal(mx_out.asnumpy(), np_out, rtol = 1e-3, atol = 1e-5) - mx_out.backward() - np_backward = vecdot_backward(a.asnumpy(), b.asnumpy()) - assert_almost_equal(a.grad.asnumpy(), np_backward[0], rtol = 1e-2, atol=1e-2) - assert_almost_equal(b.grad.asnumpy(), np_backward[1], rtol = 1e-2, atol=1e-2) - - # Test imperative once again - mx_out = np.vecdot(a, b) - np_out = onp.vdot(a.asnumpy(), b.asnumpy()) - assert_almost_equal(mx_out.asnumpy(), np_out, rtol=1e-3, atol=1e-5) - - # test numeric gradient - if len(shape) > 0 and onp.prod(shape) > 0: - a_sym = mx.sym.Variable("a").as_np_ndarray() - b_sym = mx.sym.Variable("b").as_np_ndarray() - mx_sym = mx.sym.np.vecdot(a_sym, b_sym).as_nd_ndarray() - check_numeric_gradient(mx_sym, [a.as_nd_ndarray(), b.as_nd_ndarray()], - rtol=1e-1, atol=1e-1, dtype=dtype) - @use_np @pytest.mark.parametrize('shape', [(), (5,), (3, 3)]) @pytest.mark.parametrize('hybridize', [True, False]) From a798d52ba97c583ee4e64d02ed3835a346251fd8 Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Sat, 2 Oct 2021 19:02:05 +0800 Subject: [PATCH 09/21] fixed lint add radd rand ror rxor --- python/mxnet/numpy/linalg.py | 4 +-- python/mxnet/numpy/multiarray.py | 54 ++++++++++++++++++++++---------- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/python/mxnet/numpy/linalg.py b/python/mxnet/numpy/linalg.py index c5bc883030f6..4522eb370f4b 100644 --- a/python/mxnet/numpy/linalg.py +++ b/python/mxnet/numpy/linalg.py @@ -895,9 +895,9 @@ def eigvalsh(a, upper=False): array([-2.87381886, 5.10144682, 6.38623114]) # in ascending order """ if not upper: - UPLO='L' + UPLO = 'L' else: - UPLO='U' + UPLO = 'U' return _mx_nd_np.linalg.eigvalsh(a, UPLO) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index 849c67f29a24..1707037507b7 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -60,12 +60,12 @@ 'add', 'subtract', 'multiply', 'divide', 'mod', 'remainder', 'fmod', 'pow', 'power', 'bitwise_not', 'delete', 'trace', 'transpose', 'copy', 'moveaxis', 'reshape', 'dot', 'arctan2', 'atan2', 'sin', 'cos', 'tan', 'sinh', 'cosh', 'tanh', 'log10', 'bitwise_invert', 'invert', - 'sqrt', 'cbrt', 'abs', 'absolute', 'fabs', 'exp', 'expm1', 'arcsin','asin', 'arccos','acos', 'arctan', 'atan', 'sign', 'log', + 'sqrt', 'cbrt', 'abs', 'absolute', 'fabs', 'exp', 'expm1', 'arcsin', 'asin', 'arccos', 'acos', 'arctan', 'atan', 'sign', 'log', 'degrees', 'log2', 'log1p', 'rint', 'radians', 'reciprocal', 'square', 'negative', 'histogram', - 'fix', 'ceil', 'floor', 'trunc', 'logical_not', 'arcsinh','asinh','arccosh', 'acosh', 'arctanh', 'atanh', 'append', 'argsort', + 'fix', 'ceil', 'floor', 'trunc', 'logical_not', 'arcsinh', 'asinh', 'arccosh', 'acosh', 'arctanh', 'atanh', 'append', 'argsort', 'sort', 'tensordot', 'eye', 'linspace', 'logspace', 'expand_dims', 'tile', 'arange', 'array_split', 'split', 'hsplit', 'vsplit', 'dsplit', 'flatnonzero', 'tril_indices', - 'concatenate', 'concat','stack', 'vstack', 'row_stack', 'column_stack', 'hstack', 'dstack', + 'concatenate', 'concat', 'stack', 'vstack', 'row_stack', 'column_stack', 'hstack', 'dstack', 'average', 'mean', 'maximum', 'fmax', 'minimum', 'fmin', 'amax', 'amin', 'max', 'min', 'swapaxes', 'clip', 'argmax', 'argmin', 'std', 'var', 'insert', 'indices', 'copysign', 'ravel', 'unravel_index', 'diag_indices_from', 'hanning', 'hamming', 'blackman', @@ -1016,6 +1016,11 @@ def __iadd__(self, other): raise ValueError('trying to add to a readonly ndarray') return add(self, other, out=self) + @wrap_mxnp_np_ufunc + def __radd__(self, other): + """x.__radd__(y) <=> y + x""" + return add(other, self) + def __invert__(self): """x.__invert__() <=> ~x""" return invert(self) @@ -1025,16 +1030,31 @@ def __and__(self, other): """x.__and__(y) <=> x & y""" return bitwise_and(self, other) + @wrap_mxnp_np_ufunc + def __rand__(self, other): + """x.__rand__(y) <=> y & x""" + return bitwise_and(other, self) + @wrap_mxnp_np_ufunc def __or__(self, other): """x.__or__(y) <=> x | y""" return bitwise_or(self, other) + @wrap_mxnp_np_ufunc + def __ror__(self, other): + """x.__ror__(y) <=> y | x""" + return bitwise_or(other, self) + @wrap_mxnp_np_ufunc def __xor__(self, other): """x.__xor__(y) <=> x ^ y""" return bitwise_xor(self, other) + @wrap_mxnp_np_ufunc + def __rxor__(self, other): + """x.__rxor__(y) <=> y ^ x""" + return bitwise_xor(other, self) + @wrap_mxnp_np_ufunc def __iand__(self, other): """x.__iand__(y) <=> x &= y""" @@ -3648,7 +3668,7 @@ def power(x1, x2, out=None, **kwargs): return _mx_nd_np.power(x1, x2, out=out) pow = power -pow.__doc__=""" +pow.__doc_ = """ First array elements raised to powers from second array, element-wise. Notes @@ -4284,8 +4304,8 @@ def arcsin(x, out=None, **kwargs): """ return _mx_nd_np.arcsin(x, out=out, **kwargs) -asin=arcsin -asin.__doc__=""" +asin = arcsin +asin.__doc__ = """ Inverse sine, element-wise. Notes @@ -4385,8 +4405,8 @@ def arccos(x, out=None, **kwargs): """ return _mx_nd_np.arccos(x, out=out, **kwargs) -acos=arccos -acos.__doc__=""" +acos = arccos +acos.__doc__ = """ Trigonometric inverse cosine, element-wise. The inverse of cos so that, if y = cos(x), then x = acos(y). @@ -4473,8 +4493,8 @@ def arctan(x, out=None, **kwargs): """ return _mx_nd_np.arctan(x, out=out, **kwargs) -atan=arctan -atan.__doc__=""" +atan = arctan +atan.__doc__ = """ Trigonometric inverse tangent, element-wise. The inverse of tan, so that if ``y = tan(x)`` then ``x = atan(y)``. @@ -5449,8 +5469,8 @@ def arcsinh(x, out=None, **kwargs): """ return _mx_nd_np.arcsinh(x, out=out, **kwargs) -asinh=arcsinh -asinh.__doc__=""" +asinh = arcsinh +asinh.__doc__ = """ Inverse hyperbolic cosine, element-wise. Notes @@ -5549,7 +5569,7 @@ def arccosh(x, out=None, **kwargs): return _mx_nd_np.arccosh(x, out=out, **kwargs) acosh = arccosh -acosh.__doc__=""" +acosh.__doc__ = """ Inverse hyperbolic cosine, element-wise. Notes @@ -5645,8 +5665,8 @@ def arctanh(x, out=None, **kwargs): """ return _mx_nd_np.arctanh(x, out=out, **kwargs) -atanh=arctanh -atanh.__doc__=""" +atanh = arctanh +atanh.__doc__ = """ Inverse hyperbolic tangent, element-wise. Notes @@ -9144,8 +9164,8 @@ def arctan2(x1, x2, out=None, **kwargs): """ return _mx_nd_np.arctan2(x1, x2, out=out) -atan2=arctan2 -atan2.__doc__=""" +atan2 = arctan2 +atan2.__doc__ = """ Element-wise arc tangent of ``x1/x2`` choosing the quadrant correctly. The quadrant (i.e., branch) is chosen so that ``atan2(x1, x2)`` is From 9e72e62f988bb35f49d001b949bcdc2aebeefda0 Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Sat, 2 Oct 2021 19:26:22 +0800 Subject: [PATCH 10/21] fixed lint error --- python/mxnet/numpy/multiarray.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index 1707037507b7..dabd7bdc1119 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -60,14 +60,14 @@ 'add', 'subtract', 'multiply', 'divide', 'mod', 'remainder', 'fmod', 'pow', 'power', 'bitwise_not', 'delete', 'trace', 'transpose', 'copy', 'moveaxis', 'reshape', 'dot', 'arctan2', 'atan2', 'sin', 'cos', 'tan', 'sinh', 'cosh', 'tanh', 'log10', 'bitwise_invert', 'invert', - 'sqrt', 'cbrt', 'abs', 'absolute', 'fabs', 'exp', 'expm1', 'arcsin', 'asin', 'arccos', 'acos', 'arctan', 'atan', 'sign', 'log', - 'degrees', 'log2', 'log1p', 'rint', 'radians', 'reciprocal', 'square', 'negative', 'histogram', - 'fix', 'ceil', 'floor', 'trunc', 'logical_not', 'arcsinh', 'asinh', 'arccosh', 'acosh', 'arctanh', 'atanh', 'append', 'argsort', - 'sort', 'tensordot', 'eye', 'linspace', 'logspace', 'expand_dims', 'tile', 'arange', - 'array_split', 'split', 'hsplit', 'vsplit', 'dsplit', 'flatnonzero', 'tril_indices', - 'concatenate', 'concat', 'stack', 'vstack', 'row_stack', 'column_stack', 'hstack', 'dstack', - 'average', 'mean', 'maximum', 'fmax', 'minimum', 'fmin', 'amax', 'amin', 'max', 'min', - 'swapaxes', 'clip', 'argmax', 'argmin', 'std', 'var', 'insert', + 'sqrt', 'cbrt', 'abs', 'absolute', 'fabs', 'exp', 'expm1', 'arcsin', 'asin', 'arccos', 'acos', 'arctan', + 'atan', 'sign', 'log', 'degrees', 'log2', 'log1p', 'rint', 'radians', 'reciprocal', 'square', + 'negative', 'histogram', 'fix', 'ceil', 'floor', 'trunc', 'logical_not', 'arcsinh', 'asinh', + 'arccosh', 'acosh', 'arctanh', 'atanh', 'append', 'argsort', 'sort', 'tensordot', 'eye', 'linspace', + 'logspace', 'expand_dims', 'tile', 'arange', 'array_split', 'split', 'hsplit', 'vsplit', + 'dsplit', 'flatnonzero', 'tril_indices', 'concatenate', 'concat', 'stack', 'vstack', 'row_stack', + 'column_stack', 'hstack', 'dstack', 'average', 'mean', 'maximum', 'fmax', 'minimum', 'fmin', + 'amax', 'amin', 'max', 'min', 'swapaxes', 'clip', 'argmax', 'argmin', 'std', 'var', 'insert', 'indices', 'copysign', 'ravel', 'unravel_index', 'diag_indices_from', 'hanning', 'hamming', 'blackman', 'logical_and', 'logical_or', 'logical_xor', 'flip', 'flipud', 'fliplr', 'around', 'round', 'round_', 'arctan2', 'hypot', @@ -2040,13 +2040,13 @@ def mean(self, axis=None, dtype=None, out=None, keepdims=False): # pylint: disa return mean(self, axis=axis, dtype=dtype, out=out, keepdims=keepdims) # pylint: disable=too-many-arguments, arguments-differ - def std(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): + def std(self, axis=None, dtype=None, out=None, correction=0, keepdims=False): """Returns the standard deviation of the array elements along given axis.""" - return std(self, axis=axis, dtype=dtype, ddof=ddof, keepdims=keepdims, out=out) + return std(self, axis=axis, dtype=dtype, correction=correction, keepdims=keepdims, out=out) - def var(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False): + def var(self, axis=None, dtype=None, out=None, correction=0, keepdims=False): """Returns the variance of the array elements, along given axis.""" - return var(self, axis=axis, dtype=dtype, out=out, ddof=ddof, keepdims=keepdims) + return var(self, axis=axis, dtype=dtype, out=out, correction=correction, keepdims=keepdims) # pylint: enable=too-many-arguments, arguments-differ def cumsum(self, axis=None, dtype=None, out=None): @@ -6305,7 +6305,7 @@ def trace(a, offset=0, axis1=0, axis2=1, out=None): @set_module('mxnet.numpy') -def transpose(a, axes=None): +def transpose(a: array, axes=None): """ Permute the dimensions of an array. @@ -9461,7 +9461,7 @@ def ldexp(x1, x2, out=None, **kwargs): return _mx_nd_np.ldexp(x1, x2, out) @set_module('mxnet.numpy') -def vecdot(a, b, axis=None): +def vecdot(a: ndarray, b: ndarray, /, *, axis: Optional[int] = None) -> ndarray: r""" Return the dot product of two vectors. Note that `vecdot` handles multidimensional arrays differently than `dot`: From d4138d96607711ddf3405fc2fca3b64a3099fd3b Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Sat, 2 Oct 2021 19:29:47 +0800 Subject: [PATCH 11/21] fixed lint error --- python/mxnet/numpy/multiarray.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index dabd7bdc1119..780497b19a9f 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -9461,7 +9461,7 @@ def ldexp(x1, x2, out=None, **kwargs): return _mx_nd_np.ldexp(x1, x2, out) @set_module('mxnet.numpy') -def vecdot(a: ndarray, b: ndarray, /, *, axis: Optional[int] = None) -> ndarray: +def vecdot(a, b, axis=None): r""" Return the dot product of two vectors. Note that `vecdot` handles multidimensional arrays differently than `dot`: From 74fcf517c814e8889838acbe7f96613dc61e7b9d Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Mon, 4 Oct 2021 09:22:03 +0800 Subject: [PATCH 12/21] fixed problems --- python/mxnet/numpy/linalg.py | 53 ++++++++++++- python/mxnet/numpy/multiarray.py | 129 ++++++++++--------------------- python/mxnet/util.py | 42 +++++----- 3 files changed, 114 insertions(+), 110 deletions(-) diff --git a/python/mxnet/numpy/linalg.py b/python/mxnet/numpy/linalg.py index 4522eb370f4b..81466850327f 100644 --- a/python/mxnet/numpy/linalg.py +++ b/python/mxnet/numpy/linalg.py @@ -20,10 +20,10 @@ from ..ndarray import numpy as _mx_nd_np from ..util import wrap_data_api_linalg_func from .fallback_linalg import * # pylint: disable=wildcard-import,unused-wildcard-import -from . import fallback_linalg +from . import fallback_linalg, tensordot __all__ = ['norm', 'svd', 'cholesky', 'qr', 'inv', 'det', 'slogdet', 'solve', 'tensorinv', 'tensorsolve', - 'pinv', 'eigvals', 'eig', 'eigvalsh', 'eigh', 'lstsq', 'matrix_rank'] + 'pinv', 'eigvals', 'eig', 'eigvalsh', 'eigh', 'lstsq', 'matrix_rank', 'vecdot'] __all__ += fallback_linalg.__all__ @@ -68,6 +68,53 @@ def matrix_rank(M, tol=None, hermitian=False): return _mx_nd_np.linalg.matrix_rank(M, tol, hermitian) +def vecdot(a, b, axis=None): + r""" + Return the dot product of two vectors. + Note that `vecdot` handles multidimensional arrays differently than `dot`: + it does *not* perform a matrix product, but flattens input arguments + to 1-D vectors first. Consequently, it should only be used for vectors. + + Parameters + ---------- + a : ndarray + First argument to the dot product. + b : ndarray + Second argument to the dot product. + axis : axis over which to compute the dot product. Must be an integer on + the interval [-N, N) , where N is the rank (number of dimensions) of + the shape determined according to Broadcasting . If specified as a + negative integer, the function must determine the axis along which + to compute the dot product by counting backward from the last dimension + (where -1 refers to the last dimension). If None , the function must + compute the dot product over the last axis. Default: None . + + Returns + ------- + output : ndarray + Dot product of `a` and `b`. + + See Also + -------- + dot : Return the dot product without using the complex conjugate of the + first argument. + + Examples + -------- + Note that higher-dimensional arrays are flattened! + + >>> a = np.array([[1, 4], [5, 6]]) + >>> b = np.array([[4, 1], [2, 2]]) + >>> np.vecdot(a, b) + array(30.) + >>> np.vecdot(b, a) + array(30.) + >>> 1*4 + 4*1 + 5*2 + 6*2 + 30 + """ + return tensordot(a.flatten(), b.flatten(), axis) + + def lstsq(a, b, rcond='warn'): r""" Return the least-squares solution to a linear matrix equation. @@ -839,6 +886,7 @@ def eigvals(a): """ return _mx_nd_np.linalg.eigvals(a) + @wrap_data_api_linalg_func def eigvalsh(a, upper=False): r"""Compute the eigenvalues real symmetric matrix. @@ -967,6 +1015,7 @@ def eig(a): """ return _mx_nd_np.linalg.eig(a) + @wrap_data_api_linalg_func def eigh(a, upper=False): r"""Return the eigenvalues and eigenvectors real symmetric matrix. diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index 780497b19a9f..d951c8a6ed52 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -2040,10 +2040,13 @@ def mean(self, axis=None, dtype=None, out=None, keepdims=False): # pylint: disa return mean(self, axis=axis, dtype=dtype, out=out, keepdims=keepdims) # pylint: disable=too-many-arguments, arguments-differ + + @wrap_data_api_statical_func def std(self, axis=None, dtype=None, out=None, correction=0, keepdims=False): """Returns the standard deviation of the array elements along given axis.""" return std(self, axis=axis, dtype=dtype, correction=correction, keepdims=keepdims, out=out) + @wrap_data_api_statical_func def var(self, axis=None, dtype=None, out=None, correction=0, keepdims=False): """Returns the variance of the array elements, along given axis.""" return var(self, axis=axis, dtype=dtype, out=out, correction=correction, keepdims=keepdims) @@ -4251,7 +4254,7 @@ def expm1(x, out=None, **kwargs): @set_module('mxnet.numpy') @wrap_np_unary_func def arcsin(x, out=None, **kwargs): - """ + r""" Inverse sine, element-wise. Parameters @@ -4308,12 +4311,6 @@ def arcsin(x, out=None, **kwargs): asin.__doc__ = """ Inverse sine, element-wise. - Notes - ---------- - `asin` is a alias for `arcsin`. It is a standard API in - https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#asin-x - instead of an official NumPy operator. - >>>np.asin is np.asin True @@ -4343,6 +4340,10 @@ def arcsin(x, out=None, **kwargs): 0.0 .. note:: + `asin` is a alias for `arcsin`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#asin-x + instead of an official NumPy operator. + `asin` is a multivalued function: for each `x` there are infinitely many numbers `z` such that :math:`sin(z) = x`. The convention is to return the angle `z` whose real part lies in [-pi/2, pi/2]. @@ -4410,12 +4411,6 @@ def arccos(x, out=None, **kwargs): Trigonometric inverse cosine, element-wise. The inverse of cos so that, if y = cos(x), then x = acos(y). - Notes - ---------- - `acos` is a alias for `arccos`. It is a standard API in - https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#acos-x - instead of an official NumPy operator. - >>>np.acos is np.arccos True @@ -4436,6 +4431,10 @@ def arccos(x, out=None, **kwargs): Notes ---------- + `acos` is a alias for `arccos`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#acos-x + instead of an official NumPy operator. + acos is a multivalued function: for each x there are infinitely many numbers z such that cos(z) = x. The convention is to return the angle z whose real part lies in [0, pi]. For real-valued input data types, acos always returns real output. @@ -4497,12 +4496,6 @@ def arctan(x, out=None, **kwargs): atan.__doc__ = """ Trigonometric inverse tangent, element-wise. The inverse of tan, so that if ``y = tan(x)`` then ``x = atan(y)``. - - Notes - --------- - `atan` is a alias for `arctan`. It is a standard API in - https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#atan-x - instead of an official NumPy operator. >>>np.atan is np.arctan True @@ -4525,6 +4518,10 @@ def arctan(x, out=None, **kwargs): Notes ----- + `atan` is a alias for `arctan`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#atan-x + instead of an official NumPy operator. + `atan` is a multi-valued function: for each `x` there are infinitely many numbers `z` such that tan(`z`) = `x`. The convention is to return the angle `z` whose real part lies in [-pi/2, pi/2]. @@ -5473,12 +5470,6 @@ def arcsinh(x, out=None, **kwargs): asinh.__doc__ = """ Inverse hyperbolic cosine, element-wise. - Notes - ---------- - `asinh` is a alias for `arcsinh`. It is a standard API in - https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#asinh-x - instead of an official NumPy operator. - >>>np.asinh is np.arcsinh True @@ -5496,6 +5487,10 @@ def arcsinh(x, out=None, **kwargs): This is a scalar if `x` is a scalar. .. note:: + `asinh` is a alias for `arcsinh`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#asinh-x + instead of an official NumPy operator. + `asinh` is a multivalued function: for each `x` there are infinitely many numbers `z` such that `sinh(z) = x`. @@ -5572,11 +5567,6 @@ def arccosh(x, out=None, **kwargs): acosh.__doc__ = """ Inverse hyperbolic cosine, element-wise. - Notes - `acosh` is a alias for `arccosh`. It is a standard API in - https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#acosh-x - instead of an official NumPy operator. - >>>np.acosh is np.arccosh True @@ -5592,6 +5582,12 @@ def arccosh(x, out=None, **kwargs): acosh : ndarray Array of the same shape as `x`. This is a scalar if `x` is a scalar. + + Note + ------- + `acosh` is a alias for `arccosh`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#acosh-x + instead of an official NumPy operator. .. note:: `acosh` is a multivalued function: for each `x` there are infinitely @@ -5669,11 +5665,6 @@ def arctanh(x, out=None, **kwargs): atanh.__doc__ = """ Inverse hyperbolic tangent, element-wise. - Notes - `atanh` is a alias for `arctanh`. It is a standard API in - https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#atanh-x - instead of an official NumPy operator. - >>>np.atanh is np.arctanh True @@ -5691,6 +5682,10 @@ def arctanh(x, out=None, **kwargs): This is a scalar if `x` is a scalar. .. note:: + `atanh` is a alias for `arctanh`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#atanh-x + instead of an official NumPy operator. + `atanh` is a multivalued function: for each `x` there are infinitely many numbers `z` such that `tanh(z) = x`. @@ -6305,7 +6300,7 @@ def trace(a, offset=0, axis1=0, axis2=1, out=None): @set_module('mxnet.numpy') -def transpose(a: array, axes=None): +def transpose(a, axes=None): """ Permute the dimensions of an array. @@ -6994,6 +6989,12 @@ def concat(seq, axis=0, out=None): res : ndarray The concatenated array. + Note + -------- + `concate` is a alias for `concatante`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/manipulation_functions.html#concat-arrays-axis-0 + instead of an official NumPy operator. + See Also -------- split : Split array into a list of multiple sub-arrays of equal size. @@ -9180,12 +9181,6 @@ def arctan2(x1, x2, out=None, **kwargs): This function is not defined for complex-valued arguments; for the so-called argument of complex values, use `angle`. - Notes - ---------- - `atan2` is a alias for `arctan2`. It is a standard API in - https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#atan2-x - instead of an official NumPy operator. - >>>np.atan2 is np.arctan2 True @@ -9208,6 +9203,10 @@ def arctan2(x1, x2, out=None, **kwargs): `x1` and `x2` are scalars. .. notes:: + `atan2` is a alias for `arctan2`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#atan2-x + instead of an official NumPy operator. + *atan2* is identical to the ``atan2`` function of the underlying C library. The following special values are defined in the C standard: [1]_ @@ -9460,52 +9459,6 @@ def ldexp(x1, x2, out=None, **kwargs): """ return _mx_nd_np.ldexp(x1, x2, out) -@set_module('mxnet.numpy') -def vecdot(a, b, axis=None): - r""" - Return the dot product of two vectors. - Note that `vecdot` handles multidimensional arrays differently than `dot`: - it does *not* perform a matrix product, but flattens input arguments - to 1-D vectors first. Consequently, it should only be used for vectors. - - Parameters - ---------- - a : ndarray - First argument to the dot product. - b : ndarray - Second argument to the dot product. - axis : axis over which to compute the dot product. Must be an integer on - the interval [-N, N) , where N is the rank (number of dimensions) of - the shape determined according to Broadcasting . If specified as a - negative integer, the function must determine the axis along which - to compute the dot product by counting backward from the last dimension - (where -1 refers to the last dimension). If None , the function must - compute the dot product over the last axis. Default: None . - - Returns - ------- - output : ndarray - Dot product of `a` and `b`. - - See Also - -------- - dot : Return the dot product without using the complex conjugate of the - first argument. - - Examples - -------- - Note that higher-dimensional arrays are flattened! - - >>> a = np.array([[1, 4], [5, 6]]) - >>> b = np.array([[4, 1], [2, 2]]) - >>> np.vecdot(a, b) - array(30.) - >>> np.vecdot(b, a) - array(30.) - >>> 1*4 + 4*1 + 5*2 + 6*2 - 30 - """ - return tensordot(a.flatten(), b.flatten(), axis) @set_module('mxnet.numpy') def vdot(a, b): diff --git a/python/mxnet/util.py b/python/mxnet/util.py index 4c83d13980ed..733d4843a76a 100644 --- a/python/mxnet/util.py +++ b/python/mxnet/util.py @@ -646,16 +646,17 @@ def _wrap_np_binary_func(x1, x2, out=None, **kwargs): return _wrap_np_binary_func def wrap_data_api_statical_func(func): - """A convenience decorator for wrapping data apis standardized statical functions to provide - context keyward backward compatibility - Parameters - ---------- - func : a numpy-compatible array statical function to be wrapped for context keyward change. - Returns - ------- - Function - A function wrapped with context keyward changes. - """ + """ + A convenience decorator for wrapping data apis standardized statical functions to provide + context keyward backward compatibility + Parameters + ---------- + func : a numpy-compatible array statical function to be wrapped for context keyward change. + Returns + ------- + Function + A function wrapped with context keyward changes. + """ @functools.wraps(func) def _wrap_api_creation_func(*args, **kwargs): @@ -668,16 +669,17 @@ def _wrap_api_creation_func(*args, **kwargs): return _wrap_api_creation_func def wrap_data_api_linalg_func(func): - """A convenience decorator for wrapping data apis standardized linalg functions to provide - context keyward backward compatibility - Parameters - ---------- - func : a numpy-compatible array linalg function to be wrapped for context keyward change. - Returns - ------- - Function - A function wrapped with context keyward changes. - """ + """ + A convenience decorator for wrapping data apis standardized linalg functions to provide + context keyward backward compatibility + Parameters + ---------- + func : a numpy-compatible array linalg function to be wrapped for context keyward change. + Returns + ------- + Function + A function wrapped with context keyward changes. + """ @functools.wraps(func) def _wrap_api_creation_func(*args, **kwargs): From 907c09d5154f53857c1633d3a6f77d17f46f8c16 Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Mon, 4 Oct 2021 11:04:15 +0800 Subject: [PATCH 13/21] delete 'vecdot' in __all__ --- python/mxnet/numpy/multiarray.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index d951c8a6ed52..aad2f83e21c7 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -73,7 +73,7 @@ 'flip', 'flipud', 'fliplr', 'around', 'round', 'round_', 'arctan2', 'hypot', 'triu_indices_from', 'triu_indices', 'tri', 'bitwise_and', 'bitwise_xor', 'bitwise_or', 'rad2deg', 'deg2rad', - 'unique', 'lcm', 'gcd', 'tril', 'triu', 'identity', 'take', 'ldexp', 'vecdot', 'vdot', 'inner', 'outer', + 'unique', 'lcm', 'gcd', 'tril', 'triu', 'identity', 'take', 'ldexp', 'vdot', 'inner', 'outer', 'cross', 'kron', 'equal', 'not_equal', 'interp', 'greater', 'less', 'greater_equal', 'less_equal', 'roll', 'rot90', 'einsum', 'true_divide', 'nonzero', 'quantile', 'percentile', 'shares_memory', 'may_share_memory', 'diff', 'ediff1d', 'resize', 'matmul', From 801a82349956b5f1c5dac306bb805ae28437afad Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Mon, 4 Oct 2021 20:25:26 +0800 Subject: [PATCH 14/21] fixed acosh doc --- python/mxnet/numpy/multiarray.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index aad2f83e21c7..d358742c40a1 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -5582,14 +5582,12 @@ def arccosh(x, out=None, **kwargs): acosh : ndarray Array of the same shape as `x`. This is a scalar if `x` is a scalar. - - Note - ------- - `acosh` is a alias for `arccosh`. It is a standard API in - https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#acosh-x - instead of an official NumPy operator. .. note:: + `acosh` is a alias for `arccosh`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#acosh-x + instead of an official NumPy operator. + `acosh` is a multivalued function: for each `x` there are infinitely many numbers `z` such that `cosh(z) = x`. From ead73f8f5cfbedce6e6ae946a5af0b4598a10ff1 Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Wed, 6 Oct 2021 09:15:00 +0800 Subject: [PATCH 15/21] fixed tensordot bug add vecdot notes --- python/mxnet/numpy/linalg.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/python/mxnet/numpy/linalg.py b/python/mxnet/numpy/linalg.py index 81466850327f..bfa90288c4bc 100644 --- a/python/mxnet/numpy/linalg.py +++ b/python/mxnet/numpy/linalg.py @@ -20,7 +20,7 @@ from ..ndarray import numpy as _mx_nd_np from ..util import wrap_data_api_linalg_func from .fallback_linalg import * # pylint: disable=wildcard-import,unused-wildcard-import -from . import fallback_linalg, tensordot +from . import fallback_linalg __all__ = ['norm', 'svd', 'cholesky', 'qr', 'inv', 'det', 'slogdet', 'solve', 'tensorinv', 'tensorsolve', 'pinv', 'eigvals', 'eig', 'eigvalsh', 'eigh', 'lstsq', 'matrix_rank', 'vecdot'] @@ -75,6 +75,12 @@ def vecdot(a, b, axis=None): it does *not* perform a matrix product, but flattens input arguments to 1-D vectors first. Consequently, it should only be used for vectors. + Notes + ---------- + `vecdot` is a alias for `vdot`. It is a standard API in + https://data-apis.org/array-api/latest/API_specification/linear_algebra_functions.html#vecdot-x1-x2-axis-1 + instead of an official NumPy operator. + Parameters ---------- a : ndarray @@ -105,14 +111,14 @@ def vecdot(a, b, axis=None): >>> a = np.array([[1, 4], [5, 6]]) >>> b = np.array([[4, 1], [2, 2]]) - >>> np.vecdot(a, b) + >>> np.linalg.vecdot(a, b) array(30.) - >>> np.vecdot(b, a) + >>> np.linalg.vecdot(b, a) array(30.) >>> 1*4 + 4*1 + 5*2 + 6*2 30 """ - return tensordot(a.flatten(), b.flatten(), axis) + return _mx_nd_np.tensordot(a.flatten(), b.flatten(), axis) def lstsq(a, b, rcond='warn'): From cebcbe2a070007c1f2c28d133799fd62d80997e2 Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Wed, 6 Oct 2021 14:37:34 +0800 Subject: [PATCH 16/21] add line in line 58 --- python/mxnet/numpy/multiarray.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index d358742c40a1..105199dafffd 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -55,6 +55,7 @@ from .fallback import * # pylint: disable=wildcard-import,unused-wildcard-import from . import fallback + __all__ = ['ndarray', 'empty', 'empty_like', 'array', 'shape', 'median', 'zeros', 'zeros_like', 'ones', 'ones_like', 'full', 'full_like', 'all', 'any', 'broadcast_to', 'add', 'subtract', 'multiply', 'divide', 'mod', 'remainder', 'fmod', 'pow', 'power', 'bitwise_not', From 8e053ef5c14a8911009b5dc51c07379510bba431 Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Wed, 6 Oct 2021 14:40:37 +0800 Subject: [PATCH 17/21] add line in line 4254 --- python/mxnet/numpy/multiarray.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index 105199dafffd..10e67de629db 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -4252,6 +4252,7 @@ def expm1(x, out=None, **kwargs): """ return _mx_nd_np.expm1(x, out=out, **kwargs) + @set_module('mxnet.numpy') @wrap_np_unary_func def arcsin(x, out=None, **kwargs): From 75fc59e9ee0e13dde01f68e3b3c8b377f3d888c7 Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Wed, 6 Oct 2021 14:43:23 +0800 Subject: [PATCH 18/21] add line in 5423,9080 in multiarray add line in 260 in test_numpy_op --- python/mxnet/numpy/multiarray.py | 2 ++ tests/python/unittest/test_numpy_op.py | 1 + 2 files changed, 3 insertions(+) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index 10e67de629db..92ffe1107561 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -5422,6 +5422,7 @@ def logical_not(x, out=None, **kwargs): """ return _mx_nd_np.logical_not(x, out=out, **kwargs) + @set_module('mxnet.numpy') @wrap_np_unary_func def arcsinh(x, out=None, **kwargs): @@ -9077,6 +9078,7 @@ def round_(x, decimals=0, out=None, **kwargs): """ return _mx_nd_np.round_(x, decimals, out=out, **kwargs) + @set_module('mxnet.numpy') @wrap_np_binary_func def arctan2(x1, x2, out=None, **kwargs): diff --git a/tests/python/unittest/test_numpy_op.py b/tests/python/unittest/test_numpy_op.py index a8a2e06bb5ec..fed62584877f 100644 --- a/tests/python/unittest/test_numpy_op.py +++ b/tests/python/unittest/test_numpy_op.py @@ -258,6 +258,7 @@ def test_np_dot_error(shape_a, shape_b): with pytest.raises(mx.base.MXNetError): mx_res = np.dot(a.as_np_ndarray(), b.as_np_ndarray()) + @use_np @pytest.mark.parametrize('shape', [(), (5,), (3, 3)]) @pytest.mark.parametrize('hybridize', [True, False]) From 70c7e37ccb9ec3c209d96e83b79600b046926b61 Mon Sep 17 00:00:00 2001 From: NathanYyc <39988193+NathanYyc@users.noreply.github.com> Date: Sat, 9 Oct 2021 14:42:07 +0800 Subject: [PATCH 19/21] Update python/mxnet/numpy/multiarray.py Co-authored-by: Zhenghui Jin <69359374+barry-jin@users.noreply.github.com> --- python/mxnet/numpy/multiarray.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/mxnet/numpy/multiarray.py b/python/mxnet/numpy/multiarray.py index 21836bb9647d..fadac105d69b 100644 --- a/python/mxnet/numpy/multiarray.py +++ b/python/mxnet/numpy/multiarray.py @@ -9211,7 +9211,7 @@ def arctan2(x1, x2, out=None, **kwargs): .. notes:: `atan2` is a alias for `arctan2`. It is a standard API in - https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#atan2-x + https://data-apis.org/array-api/latest/API_specification/elementwise_functions.html#atan2-x1-x2 instead of an official NumPy operator. *atan2* is identical to the ``atan2`` function of the underlying From 4bf327b77ca66ecb6005d3a527f25e2465c69ca5 Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Mon, 11 Oct 2021 10:10:19 +0800 Subject: [PATCH 20/21] solve typo --- python/mxnet/numpy/linalg.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/mxnet/numpy/linalg.py b/python/mxnet/numpy/linalg.py index 242f69360db0..7e78d2905506 100644 --- a/python/mxnet/numpy/linalg.py +++ b/python/mxnet/numpy/linalg.py @@ -53,7 +53,7 @@ def matrix_rank(M, tol=None, hermitian=False): hermitian : bool, optional If True, `M` is assumed to be Hermitian (symmetric if real-valued), enabling a more efficient method for finding singular values. - Defaults to False. + Default: False. Returns ------- From 21c9fd366feb5aeab001433973bb188b5a933a4e Mon Sep 17 00:00:00 2001 From: yuanyic <543248111@qq.com> Date: Tue, 12 Oct 2021 08:25:02 +0800 Subject: [PATCH 21/21] add wrap_data_api_linalg_func in line 1335 & 1205 --- python/mxnet/numpy/linalg.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/mxnet/numpy/linalg.py b/python/mxnet/numpy/linalg.py index 7e78d2905506..a9c0f9b38313 100644 --- a/python/mxnet/numpy/linalg.py +++ b/python/mxnet/numpy/linalg.py @@ -1202,6 +1202,7 @@ def eigvals(a): return _mx_nd_np.linalg.eigvals(a) +@wrap_data_api_linalg_func def eigvalsh(a, upper=False): r""" Compute the eigenvalues real symmetric matrix. @@ -1331,6 +1332,7 @@ def eig(a): return _mx_nd_np.linalg.eig(a) +@wrap_data_api_linalg_func def eigh(a, upper=False): r""" Return the eigenvalues and eigenvectors real symmetric matrix.