text: # Licensed to the Apache Software Foundation (ASF) under one
  # or more contributor license agreements.  See the NOTICE file
  # distributed with this work for additional information
  # regarding copyright ownership.  The ASF licenses this file
  # to you under the Apache License, Version 2.0 (the
  # "License"); you may not use this file except in compliance
  # with the License.  You may obtain a copy of the License at
  #
  #   http://www.apache.org/licenses/LICENSE-2.0
  #
  # Unless required by applicable law or agreed to in writing,
  # software distributed under the License is distributed on an
  # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  # KIND, either express or implied.  See the License for the
  # specific language governing permissions and limitations
  # under the License.
  
  # pylint: disable=too-many-lines, unused-argument
  """numpy namespace for operators used in Gluon APIs dispatched by F=symbol module."""
  
  from __future__ import absolute_import
  import ctypes
  import numpy as _np
  from . import _op as _mx_np_op
  from ...base import _LIB, SymbolHandle, numeric_types, mx_uint
  from ...util import check_call, set_module
  from ...context import current_context
  from ..symbol import Symbol
  from .._internal import _set_np_symbol_class
  from . import _internal as _npi
  
  __all__ = ['zeros', 'ones', 'add', 'subtract', 'multiply', 'divide', 'mod', 'remainder', 'power', 'sin',
             'cos', 'tan', 'sinh', 'cosh', 'tanh', 'log10', 'sqrt', 'cbrt', 'abs', 'absolute', 'exp',
             'expm1', 'arcsin', 'arccos', 'arctan', 'sign', 'log', 'degrees', 'log2', 'log1p',
             'rint', 'radians', 'reciprocal', 'square', 'negative', 'fix', 'ceil', 'floor',
             'trunc', 'logical_not', 'arcsinh', 'arccosh', 'arctanh', 'tensordot',
             'linspace', 'expand_dims', 'tile', 'arange', 'split', 'concatenate', 'stack', 'mean',
             'maximum', 'minimum', 'swapaxes', 'clip', 'argmax', 'std', 'var', 'indices', 'copysign',
             'ravel']
  
  
  def _num_outputs(sym):
      return len(sym.as_nd_ndarray())
  
  
  @set_module('mxnet.symbol.numpy')
  class _Symbol(Symbol):
      def __getitem__(self, key):
          num_outputs = _num_outputs(self)
          if num_outputs == 1:
              raise NotImplementedError
          if not isinstance(key, int):
              raise NotImplementedError
          if key >= num_outputs:
              # Important, python determines the end by this exception
              raise IndexError
          handle = SymbolHandle()
          check_call(_LIB.MXSymbolGetOutput(
              self.handle, mx_uint(key), ctypes.byref(handle)))
          return _Symbol(handle=handle)
  
      def __setitem__(self, key, value):
          raise NotImplementedError
  
      def __iter__(self):
          raise AttributeError('_Symbol object has no attribute __iter__')
  
      def __add__(self, other):
          """x.__add__(y) <=> x + y"""
          return add(self, other)
  
      def __sub__(self, other):
          """x.__sub__(y) <=> x - y"""
          return subtract(self, other)
  
      def __rsub__(self, other):
          """x.__rsub__(y) <=> y - x"""
          return subtract(other, self)
  
      def __mul__(self, other):
          """x.__mul__(y) <=> x * y"""
          return multiply(self, other)
  
      def __rmul__(self, other):
          """x.__rmul__(y) <=> y * x"""
          return multiply(other, self)
  
      def __div__(self, other):
          raise AttributeError('_Symbol.__div__ is replaced by __truediv__. If you are using'
                               ' Python2, please use the statement from __future__ import division'
                               ' to change the / operator to mean true division throughout the'
                               ' module. If you are using Python3, this error should not have'
                               ' been encountered.')
  
      def __rdiv__(self, other):
          raise AttributeError('_Symbol.__rdiv__ is replaced by __rtruediv__. If you are using'
                               ' Python2, please use the statement from __future__ import division'
                               ' to change the / operator to mean true division throughout the'
                               ' module. If you are using Python3, this error should not have'
                               ' been encountered.')
  
      def __mod__(self, other):
          """x.__mod__(y) <=> x % y"""
          return mod(self, other)
  
      def __rmod__(self, other):
          """x.__rmod__(y) <=> y % x"""
          return mod(other, self)
  
      def __idiv__(self, other):
          raise NotImplementedError
  
      def __truediv__(self, other):
          """x.__truediv__(y) <=> x / y"""
          return divide(self, other)
  
      def __rtruediv__(self, other):
          """x.__rtruediv__(y) <=> y / x"""
          return divide(other, self)
  
      def __itruediv__(self, other):
          raise NotImplementedError
  
      def __pow__(self, other):
          """x.__pow__(y) <=> x ** y"""
          return power(self, other)
  
      def __rpow__(self, other):
          return power(other, self)
  
      def __neg__(self):
          """x.__neg__() <=> - x"""
          return self.__mul__(-1.0)
  
      def __deepcopy__(self, _):
          return super(_Symbol, self).as_np_ndarray()
  
      def __eq__(self, other):
          """x.__eq__(y) <=> x == y"""
          # TODO(junwu): Return boolean ndarray when dtype=bool_ is supported
          if isinstance(other, _Symbol):
              return _npi.equal(self, other)
          elif isinstance(other, numeric_types):
              return _npi.equal_scalar(self, float(other))
          else:
              raise TypeError("_Symbol does not support type {} as operand".format(str(type(other))))
  
      def __ne__(self, other):
          """x.__ne__(y) <=> x != y"""
          # TODO(junwu): Return boolean ndarray when dtype=bool_ is supported
          if isinstance(other, _Symbol):
              return _npi.not_equal(self, other)
          elif isinstance(other, numeric_types):
              return _npi.not_equal_scalar(self, float(other))
          else:
              raise TypeError("_Symbol does not support type {} as operand".format(str(type(other))))
  
      def __gt__(self, other):
          """x.__gt__(y) <=> x > y"""
          # TODO(junwu): Return boolean ndarray when dtype=bool_ is supported
          if isinstance(other, _Symbol):
              return _npi.greater(self, other)
          elif isinstance(other, numeric_types):
              return _npi.greater_scalar(self, float(other))
          else:
              raise TypeError("_Symbol does not support type {} as operand".format(str(type(other))))
  
      def __ge__(self, other):
          """x.__ge__(y) <=> x >= y"""
          # TODO(junwu): Return boolean ndarray when dtype=bool_ is supported
          if isinstance(other, _Symbol):
              return _npi.greater_equal(self, other)
          elif isinstance(other, numeric_types):
              return _npi.greater_equal_scalar(self, float(other))
          else:
              raise TypeError("_Symbol does not support type {} as operand".format(str(type(other))))
  
      def __lt__(self, other):
          """x.__lt__(y) <=> x < y"""
          # TODO(junwu): Return boolean ndarray when dtype=bool_ is supported
          if isinstance(other, _Symbol):
              return _npi.less(self, other)
          elif isinstance(other, numeric_types):
              return _npi.less_scalar(self, float(other))
          else:
              raise TypeError("_Symbol does not support type {} as operand".format(str(type(other))))
  
      def __le__(self, other):
          """x.__le__(y) <=> x <= y"""
          # TODO(junwu): Return boolean ndarray when dtype=bool_ is supported
          if isinstance(other, _Symbol):
              return _npi.less_equal(self, other)
          elif isinstance(other, numeric_types):
              return _npi.less_equal_scalar(self, float(other))
          else:
              raise TypeError("_Symbol does not support type {} as operand".format(str(type(other))))
  
      def __len__(self):
          raise NotImplementedError
  
      def as_nd_ndarray(self):
          """Convert _Symbol to mxnet.symbol.Symbol to use its convenience fluent methods."""
          hdl = SymbolHandle()
          check_call(_LIB.MXShallowCopySymbol(self.handle, ctypes.byref(hdl)))
          return Symbol(handle=hdl)
  
      def as_np_ndarray(self):
          """For the convenience of conversion between legacy and np symbols."""
          return self
  
      @property
      # pylint: disable= invalid-name, undefined-variable
      def T(self):
          """Same as self.transpose()."""
          return self.transpose()
      # pylint: enable= invalid-name, undefined-variable
  
      def astype(self, dtype, **kwargs):  # pylint: disable=arguments-differ
          raise NotImplementedError
  
      def dot(self, b, out=None):
          """Dot product of two arrays.
          Refer to ``numpy.dot`` for full documentation."""
          return _mx_np_op.dot(self, b, out=out)
  
      def reshape(self, *args, **kwargs):  # pylint: disable=arguments-differ
          """Returns a copy of the array with a new shape.
  
          Notes
          -----
          Unlike the free function `mxnet.numpy.reshape`, this method on `ndarray` allows
          the elements of the shape parameter to be passed in as separate arguments.
          For example, ``a.reshape(10, 11)`` is equivalent to
          ``a.reshape((10, 11))``.
          """
          order = 'C'
          if len(kwargs) > 1:
              raise TypeError('function takes at most 1 keyword argument')
          if len(kwargs) == 1:
              if 'order' not in kwargs:
                  raise TypeError('{} is an invalid keyword argument for this function'
                                  .format(kwargs.keys()[0]))
              order = kwargs.pop('order', 'C')
              if order != 'C':
                  raise NotImplementedError('only supports C-order,'
                                            ' while received {}'.format(order))
          if len(args) == 0:
              raise TypeError('reshape() takes exactly 1 argument (0 given)')
          if len(args) == 1 and isinstance(args[0], tuple):
              return _mx_np_op.reshape(self, newshape=args[0], order=order)
          else:
              return _mx_np_op.reshape(self, newshape=args, order=order)
  
      def argmax(self, axis=None, out=None):  # pylint: disable=arguments-differ
          """Return indices of the maximum values along the given axis.
          Refer to `mxnet.numpy.argmax` for full documentation."""
          return argmax(self, axis, out)
  
      def reshape_like(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`reshape_like`.
  
          The arguments are the same as for :py:func:`reshape_like`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute reshape_like')
  
      def zeros_like(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`zeros_like`.
  
          The arguments are the same as for :py:func:`zeros_like`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute zeros_like')
  
      def ones_like(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`ones_like`.
  
          The arguments are the same as for :py:func:`ones_like`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute ones_like')
  
      def broadcast_axes(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`broadcast_axes`.
  
          The arguments are the same as for :py:func:`broadcast_axes`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute broadcast_like')
  
      def repeat(self, repeats, axis=None):  # pylint: disable=arguments-differ
          """Repeat elements of an array."""
          return _mx_np_op.repeat(self, repeats=repeats, axis=axis)
  
      def pad(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`pad`.
  
          The arguments are the same as for :py:func:`pad`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute pad')
  
      def swapaxes(self, axis1, axis2):  # pylint: disable=arguments-differ
          """Return a copy of the array with axis1 and axis2 interchanged.
          Refer to `mxnet.numpy.swapaxes` for full documentation.
          """
          return swapaxes(self, axis1, axis2)
  
      def split(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`split`.
  
          The arguments are the same as for :py:func:`split`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute split')
  
      def split_v2(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`split_v2`.
  
          The arguments are the same as for :py:func:`split_v2`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute split_v2')
  
      def slice(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`slice`.
  
          The arguments are the same as for :py:func:`slice`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute slice')
  
      def slice_axis(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`slice_axis`.
  
          The arguments are the same as for :py:func:`slice_axis`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute slice_axis')
  
      def slice_like(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`slice_like`.
  
          The arguments are the same as for :py:func:`slice_like`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute slice_like')
  
      def take(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`take`.
  
          The arguments are the same as for :py:func:`take`, with
          this array as data.
          """
          raise NotImplementedError
  
      def one_hot(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`one_hot`.
  
          The arguments are the same as for :py:func:`one_hot`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute one_hot')
  
      def pick(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`pick`.
  
          The arguments are the same as for :py:func:`pick`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute pick')
  
      def sort(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`sort`.
  
          The arguments are the same as for :py:func:`sort`, with
          this array as data.
          """
          raise NotImplementedError
  
      def topk(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`topk`.
  
          The arguments are the same as for :py:func:`topk`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute topk')
  
      def argsort(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`argsort`.
  
          The arguments are the same as for :py:func:`argsort`, with
          this array as data.
          """
          raise NotImplementedError
  
      def argmax_channel(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`argmax_channel`.
  
          The arguments are the same as for :py:func:`argmax_channel`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute argmax_channel')
  
      def argmin(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`argmin`.
  
          The arguments are the same as for :py:func:`argmin`, with
          this array as data.
          """
          raise NotImplementedError
  
      def clip(self, min=None, max=None, out=None):  # pylint: disable=arguments-differ
          """Return an array whose values are limited to [min, max].
          One of max or min must be given.
          """
          return clip(self, min, max, out=out)
  
      def abs(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`abs`.
  
          The arguments are the same as for :py:func:`abs`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute abs')
  
      def sign(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`sign`.
  
          The arguments are the same as for :py:func:`sign`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute abs')
  
      def flatten(self, order='C'):  # pylint: disable=arguments-differ
          """Return a copy of the array collapsed into one dimension."""
          return self.reshape(-1, order=order)
  
      def shape_array(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`shape_array`.
  
          The arguments are the same as for :py:func:`shape_array`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute shape_array')
  
      def size_array(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`size_array`.
  
          The arguments are the same as for :py:func:`size_array`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute size_array')
  
      def expand_dims(self, *args, **kwargs):  # pylint: disable=arguments-differ,unused-argument
          """Convenience fluent method for :py:func:`expand_dims`.
  
          The arguments are the same as for :py:func:`expand_dims`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute expand_dims')
  
      def tile(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`tile`.
  
          The arguments are the same as for :py:func:`tile`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute tile')
  
      def transpose(self, *axes):  # pylint: disable=arguments-differ
          """The arguments are the same as for :py:func:`transpose`, with
          this array as data.
          """
          return _mx_np_op.transpose(self, axes=axes if len(axes) != 0 else None)
  
      def flip(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`flip`.
  
          The arguments are the same as for :py:func:`flip`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute flip')
  
      def depth_to_space(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`depth_to_space`.
  
          The arguments are the same as for :py:func:`depth_to_space`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute depth_to_space')
  
      def space_to_depth(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`space_to_depth`.
  
          The arguments are the same as for :py:func:`space_to_depth`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute space_to_depth')
  
      def diag(self, k=0, **kwargs):
          """Convenience fluent method for :py:func:`diag`.
  
          The arguments are the same as for :py:func:`diag`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute diag')
  
      def sum(self, axis=None, dtype=None, out=None, keepdims=False):  # pylint: disable=arguments-differ
          """Return the sum of the array elements over the given axis."""
          return _mx_np_op.sum(self, axis=axis, dtype=dtype, out=out, keepdims=keepdims)
  
      def nansum(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`nansum`.
  
          The arguments are the same as for :py:func:`nansum`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute nansum')
  
      def prod(self, axis=None, dtype=None, out=None, keepdims=False):  # pylint: disable=arguments-differ
          """Return the product of the array elements over the given axis."""
          return _mx_np_op.prod(self, axis=axis, dtype=dtype, keepdims=keepdims, out=out)
  
      def nanprod(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`nanprod`.
  
          The arguments are the same as for :py:func:`nanprod`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute nanprod')
  
      def mean(self, axis=None, dtype=None, out=None, keepdims=False):  # pylint: disable=arguments-differ
          """Returns the average of the array elements along given axis."""
          return mean(self, axis=axis, dtype=dtype, out=out, keepdims=keepdims)
  
      def std(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False):  # pylint: disable=arguments-differ,too-many-arguments
          """Returns the standard deviation of the array elements along given axis."""
          return std(self, axis=axis, dtype=dtype, ddof=ddof, keepdims=keepdims, out=out)
  
      def var(self, axis=None, dtype=None, out=None, ddof=0, keepdims=False):  # pylint: disable=arguments-differ,too-many-arguments
          """Returns the variance of the array elements, along given axis."""
          return var(self, axis=axis, dtype=dtype, out=out, ddof=ddof, keepdims=keepdims)
  
      def cumsum(self, axis=None, dtype=None, out=None):
          """Return the cumulative sum of the elements along the given axis."""
          return _mx_np_op.cumsum(self, axis=axis, dtype=dtype, out=out)
  
      def max(self, axis=None, out=None, keepdims=False):  # pylint: disable=arguments-differ
          """Return the maximum along a given axis."""
          return _mx_np_op.max(self, axis=axis, keepdims=keepdims, out=out)
  
      def min(self, axis=None, out=None, keepdims=False):  # pylint: disable=arguments-differ
          """Return the minimum along a given axis."""
          return _mx_np_op.min(self, axis=axis, keepdims=keepdims, out=out)
  
      def norm(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`norm`.
  
          The arguments are the same as for :py:func:`norm`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute norm')
  
      def round(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`round`.
  
          The arguments are the same as for :py:func:`round`, with
          this array as data.
          """
          raise NotImplementedError
  
      def rint(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`rint`.
  
          The arguments are the same as for :py:func:`rint`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute rint')
  
      def fix(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`fix`.
  
          The arguments are the same as for :py:func:`fix`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute fix')
  
      def floor(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`floor`.
  
          The arguments are the same as for :py:func:`floor`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute floor')
  
      def ceil(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`ceil`.
  
          The arguments are the same as for :py:func:`ceil`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute ceil')
  
      def trunc(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`trunc`.
  
          The arguments are the same as for :py:func:`trunc`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute trunc')
  
      def sin(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`sin`.
  
          The arguments are the same as for :py:func:`sin`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute sin')
  
      def cos(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`cos`.
  
          The arguments are the same as for :py:func:`cos`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute cos')
  
      def tan(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`tan`.
  
          The arguments are the same as for :py:func:`tan`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute tan')
  
      def arcsin(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`arcsin`.
  
          The arguments are the same as for :py:func:`arcsin`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute arcsin')
  
      def arccos(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`arccos`.
  
          The arguments are the same as for :py:func:`arccos`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute arccos')
  
      def arctan(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`arctan`.
  
          The arguments are the same as for :py:func:`arctan`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute arctan')
  
      def degrees(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`degrees`.
  
          The arguments are the same as for :py:func:`degrees`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute degrees')
  
      def radians(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`radians`.
  
          The arguments are the same as for :py:func:`radians`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute radians')
  
      def sinh(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`sinh`.
  
          The arguments are the same as for :py:func:`sinh`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute sinh')
  
      def cosh(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`cosh`.
  
          The arguments are the same as for :py:func:`cosh`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute cosh')
  
      def tanh(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`tanh`.
  
          The arguments are the same as for :py:func:`tanh`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute tanh')
  
      def arcsinh(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`arcsinh`.
  
          The arguments are the same as for :py:func:`arcsinh`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute arcsinh')
  
      def arccosh(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`arccosh`.
  
          The arguments are the same as for :py:func:`arccosh`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute arccosh')
  
      def arctanh(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`arctanh`.
  
          The arguments are the same as for :py:func:`arctanh`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute arctanh')
  
      def exp(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`exp`.
  
          The arguments are the same as for :py:func:`exp`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute exp')
  
      def expm1(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`expm1`.
  
          The arguments are the same as for :py:func:`expm1`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute expm1')
  
      def log(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`log`.
  
          The arguments are the same as for :py:func:`log`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute log')
  
      def log10(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`log10`.
  
          The arguments are the same as for :py:func:`log10`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute log10')
  
      def log2(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`log2`.
  
          The arguments are the same as for :py:func:`log2`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute log2')
  
      def log1p(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`log1p`.
  
          The arguments are the same as for :py:func:`log1p`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute log1p')
  
      def sqrt(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`sqrt`.
  
          The arguments are the same as for :py:func:`sqrt`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute sqrt')
  
      def rsqrt(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`rsqrt`.
  
          The arguments are the same as for :py:func:`rsqrt`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute rsqrt')
  
      def cbrt(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`cbrt`.
  
          The arguments are the same as for :py:func:`cbrt`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute cqrt')
  
      def rcbrt(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`rcbrt`.
  
          The arguments are the same as for :py:func:`rcbrt`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute rcqrt')
  
      def square(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`square`.
  
          The arguments are the same as for :py:func:`square`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute square')
  
      def reciprocal(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`reciprocal`.
  
          The arguments are the same as for :py:func:`reciprocal`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute reciprocal')
  
      def relu(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`relu`.
  
          The arguments are the same as for :py:func:`relu`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute relu')
  
      def sigmoid(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`sigmoid`.
  
          The arguments are the same as for :py:func:`sigmoid`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute sigmoid')
  
      def softmax(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`softmax`.
  
          The arguments are the same as for :py:func:`softmax`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute softmax')
  
      def log_softmax(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`log_softmax`.
  
          The arguments are the same as for :py:func:`log_softmax`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute log_softmax')
  
      def softmin(self, *args, **kwargs):
          """Convenience fluent method for :py:func:`softmin`.
  
          The arguments are the same as for :py:func:`softmin`, with
          this array as data.
          """
          raise AttributeError('_Symbol object has no attribute softmin')
  
      def squeeze(self, axis=None):  # pylint: disable=arguments-differ
          """Remove single-dimensional entries from the shape of a."""
          return _mx_np_op.squeeze(self, axis=axis)
  
      def broadcast_to(self, *args, **kwargs):
          raise AttributeError('_Symbol object has no attribute broadcast_to')
  
      def broadcast_like(self, *args, **kwargs):
          raise AttributeError('_Symbol object has no attribute broadcast_like')
  
  
  @set_module('mxnet.symbol.numpy')
  def zeros(shape, dtype=_np.float32, order='C', ctx=None):
      """Return a new array of given shape and type, filled with zeros.
      This function currently only supports storing multi-dimensional data
      in row-major (C-style).
  
      Parameters
      ----------
      shape : int or tuple of int
          The shape of the empty array.
      dtype : str or numpy.dtype, optional
          An optional value type. Default is `numpy.float32`. Note that this
          behavior is different from NumPy's `zeros` function  where `float64`
          is the default value, because `float32` is considered as the default
          data type in deep learning.
      order : {'C'}, optional, default: 'C'
          How to store multi-dimensional data in memory, currently only row-major
          (C-style) is supported.
      ctx : Context, optional
          An optional device context (default is the current default context).
  
      Returns
      -------
      out : Symbol
          Array of zeros with the given shape, dtype, and ctx.
      """
      if order != 'C':
          raise NotImplementedError
      if ctx is None:
          ctx = current_context()
      dtype = _np.float32 if dtype is None else dtype
      return _npi.zeros(shape=shape, ctx=ctx, dtype=dtype)
  
  
  @set_module('mxnet.symbol.numpy')
  def ones(shape, dtype=_np.float32, order='C', ctx=None):
      """Return a new array of given shape and type, filled with zeros.
      This function currently only supports storing multi-dimensional data
      in row-major (C-style).
  
      Parameters
      ----------
      shape : int or tuple of int
          The shape of the empty array.
      dtype : str or numpy.dtype, optional
          An optional value type. Default is `numpy.float32`. Note that this
          behavior is different from NumPy's `ones` function where `float64`
          is the default value, because `float32` is considered as the default
          data type in deep learning.
      order : {'C'}, optional, default: 'C'
          How to store multi-dimensional data in memory, currently only row-major
          (C-style) is supported.
      ctx : Context, optional
          An optional device context (default is the current default context).
  
      Returns
      -------
      out : ndarray
          Array of zeros with the given shape, dtype, and ctx.
      """
      if order != 'C':
          raise NotImplementedError
      if ctx is None:
          ctx = current_context()
      dtype = _np.float32 if dtype is None else dtype
      return _npi.ones(shape=shape, ctx=ctx, dtype=dtype)
  
  
  @set_module('mxnet.symbol.numpy')
  def full(shape, fill_value, dtype=None, order='C', ctx=None, out=None):  # pylint: disable=too-many-arguments
      """
      Return a new array of given shape and type, filled with `fill_value`.
      Parameters
      ----------
      shape : int or sequence of ints
          Shape of the new array, e.g., ``(2, 3)`` or ``2``.
      fill_value : scalar
          Fill value.
      dtype : data-type, optional
          The desired data-type for the array. The default, `None`, means
          `np.array(fill_value).dtype`.
      order : {'C'}, optional
          Whether to store multidimensional data in C- or Fortran-contiguous
          (row- or column-wise) order in memory. Currently only supports C order.
      ctx: to specify the device, e.g. the i-th GPU.
      out : ndarray or None, optional
          A location into which the result is stored.
          If provided, it must have the same shape and dtype as input ndarray.
          If not provided or `None`, a freshly-allocated array is returned.
      Returns
      -------
      out : ndarray
          Array of `fill_value` with the given shape, dtype, and order.
      Notes
      -----
      This function differs from the original `numpy.full
      https://docs.scipy.org/doc/numpy/reference/generated/numpy.full.html`_ in
      the following way(s):
      - Have an additional `ctx` argument to specify the device
      - Have an additional `out` argument
      - Currently does not support `order` selection
      See Also
      --------
      empty : Return a new uninitialized array.
      ones : Return a new array setting values to one.
      zeros : Return a new array setting values to zero.
      Examples
      --------
      >>> np.full((2, 2), 10)
      array([[10., 10.],
             [10., 10.]])
      >>> np.full((2, 2), 2, dtype=np.int32, ctx=mx.cpu(0))
      array([[2, 2],
             [2, 2]], dtype=int32)
      """
      if order != 'C':
          raise NotImplementedError
      if ctx is None:
          ctx = current_context()
      dtype = _np.float32 if dtype is None else dtype
      return _npi.full(shape=shape, value=fill_value, ctx=ctx, dtype=dtype, out=out)
  
  
  #pylint: disable= too-many-arguments, no-member, protected-access
  def _ufunc_helper(lhs, rhs, fn_array, fn_scalar, lfn_scalar, rfn_scalar=None, out=None):
      """ Helper function for element-wise operation.
      The function will perform numpy-like broadcasting if needed and call different functions.
  
      Parameters
      --------
      lhs : Symbol or numeric value
          Left-hand side operand.
  
      rhs : Symbol or numeric value
          Right-hand operand,
  
      fn_array : function
          Function to be called if both lhs and rhs are of ``Symbol`` type.
  
      fn_scalar : function
          Function to be called if both lhs and rhs are numeric values.
  
      lfn_scalar : function
          Function to be called if lhs is ``Symbol`` while rhs is numeric value
  
      rfn_scalar : function
          Function to be called if lhs is numeric value while rhs is ``Symbol``;
          if none is provided, then the function is commutative, so rfn_scalar is equal to lfn_scalar
  
      Returns
      --------
      mxnet.numpy.ndarray
          result array
      """
      if isinstance(lhs, numeric_types):
          if isinstance(rhs, numeric_types):
              return fn_scalar(lhs, rhs, out=out)
          else:
              if rfn_scalar is None:
                  # commutative function
                  return lfn_scalar(rhs, float(lhs), out=out)
              else:
                  return rfn_scalar(rhs, float(lhs), out=out)
      elif isinstance(rhs, numeric_types):
          return lfn_scalar(lhs, float(rhs), out=out)
      elif isinstance(rhs, Symbol):
          return fn_array(lhs, rhs, out=out)
      else:
          raise TypeError('type %s not supported' % str(type(rhs)))
  #pylint: enable= too-many-arguments, no-member, protected-access
  
  
  @set_module('mxnet.symbol.numpy')
  def add(x1, x2, out=None):
      return _ufunc_helper(x1, x2, _npi.add, _np.add, _npi.add_scalar, None, out)
  
  
  @set_module('mxnet.symbol.numpy')
  def subtract(x1, x2, out=None):
      return _ufunc_helper(x1, x2, _npi.subtract, _np.subtract, _npi.subtract_scalar,
                           _npi.rsubtract_scalar, out)
  
  
  @set_module('mxnet.symbol.numpy')
  def multiply(x1, x2, out=None):
      return _ufunc_helper(x1, x2, _npi.multiply, _np.multiply, _npi.multiply_scalar, None, out)
  
  
  @set_module('mxnet.symbol.numpy')
  def divide(x1, x2, out=None):
      return _ufunc_helper(x1, x2, _npi.true_divide, _np.divide, _npi.true_divide_scalar,
                           _npi.rtrue_divide_scalar, out)
  
  
  @set_module('mxnet.symbol.numpy')
  def mod(x1, x2, out=None):
      return _ufunc_helper(x1, x2, _npi.mod, _np.mod, _npi.mod_scalar, _npi.rmod_scalar, out)
  
  
  @set_module('mxnet.symbol.numpy')
  def remainder(x1, x2, out=None):
      return _ufunc_helper(x1, x2, _npi.mod, _np.mod, _npi.mod_scalar, _npi.rmod_scalar, out)
  
  
  @set_module('mxnet.symbol.numpy')
  def power(x1, x2, out=None):
      return _ufunc_helper(x1, x2, _npi.power, _np.power, _npi.power_scalar, _npi.rpower_scalar, out)
  
  
  @set_module('mxnet.symbol.numpy')
  def tensordot(a, b, axes=2):
      r"""
      tensordot(a, b, axes=2)
      Compute tensor dot product along specified axes for arrays >= 1-D.
      Given two tensors (arrays of dimension greater than or equal to one),
      `a` and `b`, and an ndarray object containing two ndarray
      objects, ``(a_axes, b_axes)``, sum the products of `a`'s and `b`'s
      elements (components) over the axes specified by ``a_axes`` and
      ``b_axes``. The third argument can be a single non-negative
      integer_like scalar, ``N``; if it is such, then the last ``N``
      dimensions of `a` and the first ``N`` dimensions of `b` are summed
      over.
      Parameters
      ----------
      a, b : _Symbol
          Tensors to "dot".
      axes : int or (2,) ndarray
          * integer_like
          If an int N, sum over the last N axes of `a` and the first N axes
          of `b` in order. The sizes of the corresponding axes must match.
          * (2,) array_like
          Or, a list of axes to be summed over, first sequence applying to `a`,
          second to `b`. Both elements array_like must be of the same length.
      Notes
      -----
      Three common use cases are:
          * ``axes = 0`` : tensor product :math:`a\otimes b`
          * ``axes = 1`` : tensor dot product :math:`a\cdot b`
          * ``axes = 2`` : (default) tensor double contraction :math:`a:b`
      When `axes` is integer_like, the sequence for evaluation will be: first
      the -Nth axis in `a` and 0th axis in `b`, and the -1th axis in `a` and
      Nth axis in `b` last.
      When there is more than one axis to sum over - and they are not the last
      (first) axes of `a` (`b`) - the argument `axes` should consist of
      two sequences of the same length, with the first axis to sum over given
      first in both sequences, the second axis second, and so forth.
      """
      if _np.isscalar(axes):
          return _npi.tensordot_int_axes(a, b, axes)
  
      if len(axes) != 2:
          raise ValueError('Axes must consist of two arrays.')
      a_axes_summed, b_axes_summed = axes
      if _np.isscalar(a_axes_summed):
          a_axes_summed = (a_axes_summed,)
      if _np.isscalar(b_axes_summed):
          b_axes_summed = (b_axes_summed,)
  
      if len(a_axes_summed) != len(b_axes_summed):
          raise ValueError('Axes length mismatch')
  
      return _npi.tensordot(a, b, a_axes_summed, b_axes_summed)
  
  
  @set_module('mxnet.symbol.numpy')
  def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None, axis=0, ctx=None): # pylint: disable=too-many-arguments
      r"""
      Return evenly spaced numbers over a specified interval.
  
      Returns num evenly spaced samples, calculated over the interval [start, stop].
      The endpoint of the interval can optionally be excluded.
  
      Parameters
      ----------
      start : real number
          The starting value of the sequence.
      stop : real number
          The end value of the sequence, unless endpoint is set to False. In
          that case, the sequence consists of all but the last of num + 1
          evenly spaced samples, so that stop is excluded. Note that the step
          size changes when endpoint is False.
      num : int, optional
          Number of samples to generate. Default is 50. Must be non-negative.
      endpoint : bool, optional
          If True, stop is the last sample. Otherwise, it is not included.
          Default is True.
      retstep : bool, optional
          If True, return (samples, step), where step is the spacing between samples.
      dtype : dtype, optional
          The type of the output array. If dtype is not given, infer the data
          type from the other input arguments.
      axis : int, optional
          The axis in the result to store the samples. Relevant only if start or
          stop are array-like. By default (0), the samples will be along a new
          axis inserted at the beginning. Use -1 to get an axis at the end.
  
      Returns
      -------
      samples : _Symbol
          There are num equally spaced samples in the closed interval
          `[start, stop]` or the half-open interval `[start, stop)`
          (depending on whether endpoint is True or False).
      step : float, optional
          Only returned if retstep is True
          Size of spacing between samples.
  
  
      See Also
      --------
      arange : Similar to `linspace`, but uses a step size (instead of the
               number of samples).
  
      Notes
      -----
  
      This function differs from the original `numpy.linspace
      <https://docs.scipy.org/doc/numpy/reference/generated/numpy.linspace.html>`_ in
      the following aspects:
  
      - `start` and `stop` do not support list, numpy ndarray and mxnet ndarray
      - axis could only be 0
      - There could be an additional `ctx` argument to specify the device, e.g. the i-th
        GPU.
      """
      if isinstance(start, (list, _np.ndarray)) or isinstance(stop, (list, _np.ndarray)):
          raise NotImplementedError('start and stop only support int')
      if axis != 0:
          raise NotImplementedError("the function only support axis 0")
      if ctx is None:
          ctx = current_context()
      if retstep:
          step = (stop - start) / (num - 1)
          return _npi.linspace(start=start, stop=stop, num=num, endpoint=endpoint, ctx=ctx, dtype=dtype), step
      else:
          return _npi.linspace(start=start, stop=stop, num=num, endpoint=endpoint, ctx=ctx, dtype=dtype)
  
  
  @set_module('mxnet.symbol.numpy')
  def expand_dims(a, axis):
      """Expand the shape of an array.
  
      Insert a new axis that will appear at the `axis` position in the expanded
  
      Parameters
      ----------
      a : _Symbol
          Input array.
      axis : int
          Position in the expanded axes where the new axis is placed.
  
      Returns
      -------
      res : _Symbol
          Output array. The number of dimensions is one greater than that of
          the input array.
      """
      return _npi.expand_dims(a, axis)
  
  
  def _unary_func_helper(x, fn_array, fn_scalar, out=None, **kwargs):
      """Helper function for unary operators.
  
      Parameters
      ----------
      x : _Symbol or scalar
          Input of the unary operator.
      fn_array : function
          Function to be called if x is of ``_Symbol`` type.
      fn_scalar : function
          Function to be called if x is a Python scalar.
      out : _Symbol
          Dummy parameter to keep the consistency with the ndarray counterpart.
  
      Returns
      -------
      out : _Symbol or scalar
          Result _Symbol or scalar.
      """
      if isinstance(x, numeric_types):
          return fn_scalar(x, **kwargs)
      elif isinstance(x, _Symbol):
          return fn_array(x, out=out, **kwargs)
      else:
          raise TypeError('type {} not supported'.format(str(type(x))))
  
  
  @set_module('mxnet.symbol.numpy')
  def sin(x, out=None, **kwargs):
      r"""Trigonometric sine, element-wise.
      Parameters
      ----------
      x : _Symbol or scalar
          Angle, in radians (:math:`2 \pi` rad equals 360 degrees).
      out : _Symbol or None
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      y : _Symbol
          The sine of each element of x.
          This is a scalar if `x` is a scalar.
      Notes
      ----
      This function only supports input type of float.
      """
      return _unary_func_helper(x, _npi.sin, _np.sin, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def cos(x, out=None, **kwargs):
      r"""Cosine, element-wise.
      Parameters
      ----------
      x : _Symbol or scalar
          Angle, in radians (:math:`2 \pi` rad equals 360 degrees).
      out : _Symbol or None
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      y : _Symbol
          The corresponding cosine values. This is a scalar if x is a scalar.
      Notes
      ----
      This function only supports input type of float.
      """
      return _unary_func_helper(x, _npi.cos, _np.cos, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def sinh(x, out=None, **kwargs):
      """Hyperbolic sine, element-wise.
      Equivalent to ``1/2 * (np.exp(x) - np.exp(-x))`` or ``-1j * np.sin(1j*x)``.
      Parameters
      ----------
      x : _Symbol or scalar
          Input array or scalar.
      out : _Symbol or None
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      y : _Symbol or scalar
          The corresponding hyperbolic sine values. This is a scalar if `x` is a scalar.
      Notes
      ----
      This function only supports input type of float.
      """
      return _unary_func_helper(x, _npi.sinh, _np.sinh, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def cosh(x, out=None, **kwargs):
      """Hyperbolic cosine, element-wise.
      Equivalent to ``1/2 * (np.exp(x) + np.exp(-x))`` and ``np.cos(1j*x)``.
      Parameters
      ----------
      x : _Symbol or scalar
          Input array or scalar.
      out : ndarray or None
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      y : _Symbol or scalar
          The corresponding hyperbolic cosine values. This is a scalar if `x` is a scalar.
      Notes
      ----
      This function only supports input type of float.
      """
      return _unary_func_helper(x, _npi.cosh, _np.cosh, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def tanh(x, out=None, **kwargs):
      """
      Compute hyperbolic tangent element-wise.
      Equivalent to ``np.sinh(x)/np.cosh(x)``.
      Parameters
      ----------
      x : _Symbol
          Input array.
      out : _Symbol or None
            Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      y : _Symbol
          The corresponding hyperbolic tangent values.
      Notes
      -----
      If `out` is provided, the function writes the result into it,
      and returns a reference to `out`.  (See Examples)
      - input x does not support complex computation (like imaginary number)
      >>> np.tanh(np.pi*1j)
      TypeError: type <type 'complex'> not supported
      Examples
      --------
      >>> np.tanh(np.array[0, np.pi]))
      array([0.       , 0.9962721])
      >>> np.tanh(np.pi)
      0.99627207622075
      >>> # Example of providing the optional output parameter illustrating
      >>> # that what is returned is a reference to said parameter
      >>> out1 = np.array(1)
      >>> out2 = np.tanh(np.array(0.1), out1)
      >>> out2 is out1
      True
      >>> # Example of ValueError due to provision of shape mis-matched `out`
      >>> np.tanh(np.zeros((3,3)),np.zeros((2,2)))
      mxnet.base.MXNetError:
      [07:17:36] ../src/ndarray/./../operator/tensor/../elemwise_op_common.h:135:
      Check failed: assign(&dattr, vec.at(i)): Incompatible attr in node
      at 0-th output: expected [3,3], got [2,2]
      """
      return _unary_func_helper(x, _npi.tanh, _np.tanh, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def log10(x, out=None, **kwargs):
      """Return the base 10 logarithm of the input array, element-wise.
      Parameters
      ----------
      x : _Symbol or scalar
          Input array or scalar.
      out : _Symbol or None
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      y : _Symbol or scalar
          The logarithm to the base 10 of `x`, element-wise. NaNs are
          returned where x is negative. This is a scalar if `x` is a scalar.
      Notes
      ----
      This function only supports input type of float.
      """
      return _unary_func_helper(x, _npi.log10, _np.log10, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def sqrt(x, out=None, **kwargs):
      """
      Return the non-negative square-root of an array, element-wise.
      Parameters
      ----------
      x : _Symbol or scalar
          The values whose square-roots are required.
      out : _Symbol, or None, optional
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      y : _Symbol or scalar
          An array of the same shape as `x`, containing the positive
          square-root of each element in `x`. This is a scalar if `x` is a scalar.
      Notes
      ----
      This function only supports input type of float.
      """
      return _unary_func_helper(x, _npi.sqrt, _np.sqrt, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def cbrt(x, out=None, **kwargs):
      r"""
      Return the cube-root of an array, element-wise.
      Parameters
      ----------
      x : _Symbol
          The values whose cube-roots are required.
      out : _Symbol or None
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      ----------
      y : _Symbol
          An array of the same shape as x, containing the cube cube-root of each element in x.
          If out was provided, y is a reference to it. This is a scalar if x is a scalar.
      """
      return _unary_func_helper(x, _npi.cbrt, _np.cbrt, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def abs(x, out=None, **kwargs):
      r"""abs(x, out=None, **kwargs)
      Calculate the absolute value element-wise.
      Parameters
      ----------
      x : _Symbol or scalar
          Input array.
      out : _Symbol or None
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      absolute : _Symbol
          An ndarray containing the absolute value of
          each element in `x`. This is a scalar if `x` is a scalar.
      """
      return _unary_func_helper(x, _npi.abs, _np.abs, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def absolute(x, out=None, **kwargs):
      r"""
      Calculate the absolute value element-wise.
      np.abs is a shorthand for this function.
      Parameters
      ----------
      x : _Symbol
          Input array.
      out : _Symbol or None
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      ----------
      absolute : _Symbol
          An ndarray containing the absolute value of each element in x.
      """
      return _unary_func_helper(x, _npi.absolute, _np.absolute, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def sign(x, out=None, **kwargs):
      r"""
      sign(x, out=None)
      Returns an element-wise indication of the sign of a number.
      The `sign` function returns ``-1 if x < 0, 0 if x==0, 1 if x > 0``. Only supports real number.
      Parameters
      ----------
      x : _Symbol or a scalar
          Input values.
      out : _Symbol or None, optional
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      y : _Symbol
          The sign of `x`.
          This is a scalar if `x` is a scalar.
      Note
      -------
      - Only supports real number as input elements.
      - Input type does not support Python native iterables(list, tuple, ...)
      - ``out`` param: cannot perform auto broadcasting. ``out`` symbol's shape must be the same as the expected output.
      - ``out`` param: cannot perform auto type cast. ``out`` symbol's dtype must be the same as the expected output.
      - ``out`` param does not support scalar input case.
      """
      return _unary_func_helper(x, _npi.sign, _np.sign, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def exp(x, out=None, **kwargs):
      r"""exp(x, out=None, **kwargs)
      Calculate the exponential of all elements in the input array.
      Parameters
      ----------
      x : _Symbol or scalar
          Input values.
      out : _Symbol or None
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      out : _Symbol
          Output array, element-wise exponential of `x`.
          This is a scalar if `x` is a scalar.
      """
      return _unary_func_helper(x, _npi.exp, _np.exp, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def expm1(x, out=None, **kwargs):
      r"""expm1(x, out=None, **kwargs)
      Calculate `exp(x) - 1` for all elements in the array.
      Parameters
      ----------
      x : _Symbol or scalar
          Input values.
      out : _Symbol or None
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      out : _Symbol
          Output array, .
          This is a scalar if `x` is a scalar.
      """
      return _unary_func_helper(x, _npi.expm1, _np.expm1, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def arcsin(x, out=None, **kwargs):
      r"""
      arcsin(x, out=None)
      Inverse sine, element-wise.
      Parameters
      ----------
      x : _Symbol or scalar
          The values whose reciprocals are required.
      out : _Symbol, or None, optional
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      angle : _Symbol or scalar
          Output array is same shape and type as x. This is a scalar if x is a scalar.
      Notes
      -----
      `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 `symbol` has the same `ctx` as the input `symbol`.
      This function differs from the original `numpy.arcsin
      <https://docs.scipy.org/doc/numpy/reference/generated/numpy.arcsin.html>`_ in
      the following aspects:
      - Only support _Symbol 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 _unary_func_helper(x, _npi.arcsin, _np.arcsin, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def arccos(x, out=None, **kwargs):
      r"""
      Trigonometric inverse cosine, element-wise.
      The inverse of cos so that, if y = cos(x), then x = arccos(y).
      Parameters
      ----------
      x : _Symbol
          x-coordinate on the unit circle. For real arguments, the domain is [-1, 1].
      out : _Symbol or None
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      ----------
      angle : _Symbol
          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.
      See also
      ----------
      cos, arctan, arcsin
      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.
      """
      return _unary_func_helper(x, _npi.arccos, _np.arccos, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def arctan(x, out=None, **kwargs):
      r"""arctan(x, out=None, **kwargs)
      Trigonometric inverse tangent, element-wise.
      The inverse of tan, so that if ``y = tan(x)`` then ``x = arctan(y)``.
      Parameters
      ----------
      x : _Symbol or scalar
          Input values.
      out : _Symbol or None
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      out : _Symbol
          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}.
      """
      return _unary_func_helper(x, _npi.arctan, _np.arctan, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def log(x, out=None, **kwargs):
      """
      log(x, out=None)
      Natural logarithm, element-wise.
      The natural logarithm `log` is the inverse of the exponential function,
      so that `log(exp(x)) = x`. The natural logarithm is logarithm in base
      `e`.
      Parameters
      ----------
      x : _Symbol
          Input value. Elements must be of real value.
      out : _Symbol or None, optional
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      y : _Symbol
          The natural logarithm of `x`, element-wise.
          This is a scalar if `x` is a scalar.
      Notes
      -----
       Currently only supports data of real values and ``inf`` as input. Returns data of real value, ``inf``, ``-inf`` and
      ``nan`` according to the input.
      This function differs from the original `numpy.log
      <https://docs.scipy.org/doc/numpy/reference/generated/numpy.log.html>`_ in
      the following aspects:
      - Does not support complex number for now
      - Input type does not support Python native iterables(list, tuple, ...). Only ndarray is supported.
      - ``out`` param: cannot perform auto braodcasting. ``out`` symbol's shape must be the same as the expected output.
      - ``out`` param: cannot perform auto type cast. ``out`` symbol's dtype must be the same as the expected output.
      - ``out`` param does not support scalar input case.
      """
      return _unary_func_helper(x, _npi.log, _np.log, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def degrees(x, out=None, **kwargs):
      """
      degrees(x, out=None)
      Convert angles from radians to degrees.
      Parameters
      ----------
      x : _Symbol
          Input value. Elements must be of real value.
      out : _Symbol or None, optional
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      y : _Symbol of floats
          The corresponding degree values; if `out` was supplied this is a
          reference to it.
          This is a scalar if `x` is a scalar.
      Notes
      -------
      This function differs from the original `numpy.degrees
      <https://docs.scipy.org/doc/numpy/reference/generated/numpy.degrees.html>`_ in
      the following aspects:
      - Input type does not support Python native iterables(list, tuple, ...). Only ndarray is supported.
      - ``out`` param: cannot perform auto broadcasting. ``out`` symbol's shape must be the same as the expected output.
      - ``out`` param: cannot perform auto type cast. ``out`` symbol's dtype must be the same as the expected output.
      - ``out`` param does not support scalar input case.
      """
      return _unary_func_helper(x, _npi.degrees, _np.degrees, out=out, **kwargs)
  
  
  def rint(x, out=None, **kwargs):
      """
      Round elements of the array to the nearest integer.
      Parameters
      ----------
      x : _Symbol or scalar
          Input array.
      out : _Symbol or None
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      out : _Symbol or scalar
          Output array is same shape and type as x. This is a scalar if x is a scalar.
      Notes
      -----
      This function differs from the original `numpy.rint
      <https://docs.scipy.org/doc/numpy/reference/generated/numpy.rint.html>`_ in
      the following way(s):
      - only _Symbol or scalar is accpted as valid input, tuple of _Symbol is not supported
       - broadcasting to `out` of different shape is currently not supported
      - when input is plain python numerics, the result will not be stored in the `out` param
      """
      return _unary_func_helper(x, _npi.rint, _np.rint, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def log2(x, out=None, **kwargs):
      """
      Base-2 logarithm of x.
      Parameters
      ----------
      x : _Symbol
          Input values.
      out : ndarray or None
          A location into which the result is stored.
          If provided, it must have the same shape and type as the input.
          If not provided or None, a freshly-allocated array is returned.
      Returns
      -------
      y : _Symbol
          The logarithm base two of `x`, element-wise.
          This is a scalar if `x` is a scalar.
      Notes
      -----
      This function differs from the original `numpy.log2
      <https://www.google.com/search?q=numpy+log2>`_ in
      the following way(s):
      - only ndarray or scalar is accpted as valid input, tuple of ndarray is not supported
      - broadcasting to `out` of different shape is currently not supported
      - when input is plain python numerics, the result will not be stored in the `out` param
      """
      return _unary_func_helper(x, _npi.log2, _np.log2, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def log1p(x, out=None, **kwargs):
      """
      Return the natural logarithm of one plus the input array, element-wise.
      Calculates ``log(1 + x)``.
      Parameters
      ----------
      x : _Symbol or scalar
          Input array.
      out : _Symbol or None
            Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      y : _Symbol or scalar
          Natural logarithm of 1 + x, element-wise. This is a scalar
          if x is a scalar.
      Notes
      -----
      For real-valued input, `log1p` is accurate also for `x` so small
      that `1 + x == 1` in floating-point accuracy.
      Logarithm is a multivalued function: for each `x` there is an infinite
      number of `z` such that `exp(z) = 1 + x`. The convention is to return
      the `z` whose imaginary part lies in `[-pi, pi]`.
      For real-valued input data types, `log1p` 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.
      cannot support complex-valued input.
      Examples
      --------
      >>> np.log1p(1e-99)
      1e-99
      >>> a = np.array([3, 4, 5])
      >>> np.log1p(a)
      array([1.3862944, 1.609438 , 1.7917595])
      """
      return _unary_func_helper(x, _npi.log1p, _np.log1p, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def radians(x, out=None, **kwargs):
      """
      Convert angles from degrees to radians.
      Parameters
      ----------
      x : _Symbol or scalar
          Input array in degrees.
      out : _Symbol or None
         Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      y : _Symbol
          The corresponding radian values. This is a scalar if x is a scalar.
      Notes
      -----
      This function differs from the original `numpy.radians
      <https://docs.scipy.org/doc/numpy/reference/generated/numpy.radians.html>`_ in
      the following way(s):
      - only _Symbol or scalar is accpted as valid input, tuple of _Symbol is not supported
      - broadcasting to `out` of different shape is currently not supported
      - when input is plain python numerics, the result will not be stored in the `out` param
      Examples
      --------
      >>> deg = np.arange(12.) * 30.
      >>> np.radians(deg)
      array([0.       , 0.5235988, 1.0471976, 1.5707964, 2.0943952, 2.6179938,
             3.1415927, 3.6651914, 4.1887903, 4.712389 , 5.2359877, 5.7595863],
             dtype=float32)
      """
      return _unary_func_helper(x, _npi.radians, _np.radians, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def reciprocal(x, out=None, **kwargs):
      r"""
      reciprocal(x, out=None)
      Return the reciprocal of the argument, element-wise.
      Calculates ``1/x``.
      Parameters
      ----------
      x : _Symbol or scalar
          The values whose reciprocals are required.
      out : _Symbol, or None, optional
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      y : _Symbol or scalar
          Output array is same shape and type as x. This is a scalar if x is a scalar.
      Notes
      -----
      .. note::
          This function is not designed to work with integers.
      For integer arguments with absolute value larger than 1 the result is
      always zero because of the way Python handles integer division.  For
      integer zero the result is an overflow.
      The output `symbol` has the same `ctx` as the input `symbol`.
      This function differs from the original `numpy.reciprocal
      <https://docs.scipy.org/doc/numpy/reference/generated/numpy.reciprocal.html>`_ in
      the following aspects:
      - Only support _Symbol and scalar now.
      - `where` argument is not supported.
      """
      return _unary_func_helper(x, _npi.reciprocal, _np.reciprocal, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def square(x, out=None, **kwargs):
      r"""
      square(x, out=None)
      Return the element-wise square of the input.
      Parameters
      ----------
      x : _Symbol or scalar
          The values whose reciprocals are required.
      out : _Symbol, or None, optional
          Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      y : _Symbol or scalar
          Output array is same shape and type as x. This is a scalar if x is a scalar.
      Notes
      -----
      The output `symbol` has the same `ctx` as the input `symbol`.
      This function differs from the original `numpy.square
      <https://docs.scipy.org/doc/numpy/reference/generated/numpy.square.html>`_ in
      the following aspects:
      - Only support _Symbol and scalar now.
      - `where` argument is not supported.
      """
      return _unary_func_helper(x, _npi.square, _np.square, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def negative(x, out=None, where=True, **kwargs):
      r"""
      negative(x, out=None, where=True)
      Numerical negative, element-wise.
      Parameters:
      ------------
      x : _Symbol or scalar
          Input array.
      out : _Symbol 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.
            A tuple (possible only as a keyword argument) must have length
            equal to the number of outputs.
      where : _Symbol or scalar, optional
              Values of True indicate to calculate the ufunc at that position,
              values of False indicate to leave the value in the output alone.
      Returns:
      -------
      y : _Symbol or scalar
          Returned array or scalar: y = -x. This is a scalar if x is a scalar.
      Examples:
      ---------
      >>> np.negative(1)
      -1
      """
      return _unary_func_helper(x, _npi.negative, _np.negative, out=out)
  
  
  @set_module('mxnet.symbol.numpy')
  def fix(x, out=None):
      """
      Round to nearest integer towards zero.
  
      Round an array of floats element-wise to nearest integer towards zero. The rounded values are returned as floats.
  
      Parameters:
      ----------
      x : _Symbol or scalar
          An array of floats to be rounded
      out : _Symbol or scalar, optional
            Output array
      Returns:
      ---------
      y : _Symbol or scalar
      Examples:
      ----------
      >>> np.fix(3.14)
      3
      """
      return _unary_func_helper(x, _npi.fix, _np.fix, out=out)
  
  
  @set_module('mxnet.symbol.numpy')
  def tan(x, out=None, where=True, **kwargs):
      r"""
      tan(x, out=None, where=True)
      Compute tangent element-wise.
      Equivalent to np.sin(x)/np.cos(x) element-wise.
  
      Parameters:
      ----------
      x : _Symbol or scalar
          Input array.
      out : _Symbol or scalar or None.
          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.
      where : array_like, optional
              Values of True indicate to calculate the ufunc at that position,
              values of False indicate to leave the value in the output alone.
      Returns:
      -------
      y : _Symbol or scalar
          The corresponding tangent values. This is a scalar if x is a scalar.
      """
  
      return _unary_func_helper(x, _npi.tan, _np.tan, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def ceil(x, out=None, **kwargs):
      r"""
      Return the ceiling of the input, element-wise.
      The ceil of the ndarray `x` is the smallest integer `i`, such that
      `i >= x`.  It is often denoted as :math:`\lceil x \rceil`.
      Parameters
      ----------
      x : _Symbol or scalar
          Input array.
      out : _Symbol or None
            Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      y :
          _Symbol or scalar
          The ceiling of each element in `x`, with `float` dtype.
          This is a scalar if `x` is a scalar.
      Examples
      --------
      >>> a = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0])
      >>> np.ceil(a)
      array([-1., -1., -0.,  1.,  2.,  2.,  2.])
      >>> #if you use parameter out, x and out must be ndarray. if not, you will get an error!
      >>> a = np.array(1)
      >>> np.ceil(np.array(3.5), a)
      array(4.)
      >>> a
      array(4.)
      """
      return _unary_func_helper(x, _npi.ceil, _np.ceil, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def floor(x, out=None, **kwargs):
      r"""
      Return the floor of the input, element-wise.
      The floor of the ndarray `x` is the largest integer `i`, such that
      `i <= x`.  It is often denoted as :math:`\lfloor x \rfloor`.
      Parameters
      ----------
      x : _Symbol or scalar
          Input array.
      out : _Symbol or None
            Dummy parameter to keep the consistency with the ndarray counterpart.
      Returns
      -------
      y :
          _Symbol or scalar
          The floor of each element in `x`, with `float` dtype.
          This is a scalar if `x` is a scalar.
      Examples
      --------
      >>> a = np.array([-1.7, -1.5, -0.2, 0.2, 1.5, 1.7, 2.0])
      >>> np.floor(a)
      array([-2., -2., -1.,  0.,  1.,  1.,  2.])
      >>> #if you use parameter out, x and out must be ndarray. if not, you will get an error!
      >>> a = np.array(1)
      >>> np.floor(np.array(3.5), a)
      array(3.)
      >>> a
      array(3.)
      """
      return _unary_func_helper(x, _npi.floor, _np.floor, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def trunc(x, out=None, **kwargs):
      r"""
      trunc(x, out=None)
      Return the truncated value of the input, element-wise.
      The truncated value of the scalar `x` is the nearest integer `i` which
      is closer to zero than `x` is. In short, the fractional part of the
      signed number `x` is discarded.
  
      Parameters
      ----------
      x : _Symbol or scalar
          Input data.
      out : _Symbol or None, optional
          Dummy parameter to keep the consistency with the ndarray counterpart.
  
      Returns
      -------
      y : _Symbol or scalar
          The truncated value of each element in `x`.
          This is a scalar if `x` is a scalar.
      Notes
      -----
      This function differs from the original numpy.trunc in the following aspects:
          - Do not support `where`, a parameter in numpy which indicates where to calculate.
          - 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.
      """
      return _unary_func_helper(x, _npi.trunc, _np.trunc, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def logical_not(x, out=None, **kwargs):
      r"""
      logical_not(x, out=None)
      Compute the truth value of NOT x element-wise.
      Parameters
      ----------
      x : _Symbol or scalar
          Logical NOT is applied to the elements of `x`.
      out : _Symbol or None, optional
          Dummy parameter to keep the consistency with the ndarray counterpart.
  
      Returns
      -------
      y : bool or _Symbol
          Boolean result with the same shape as `x` of the NOT operation
          on elements of `x`.
          This is a scalar if `x` is a scalar.
      Notes
      -----
      This function differs from the original numpy.logical_not in the following aspects:
          - Do not support `where`, a parameter in numpy which indicates where to calculate.
          - 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.
      """
      return _unary_func_helper(x, _npi.logical_not, _np.logical_not, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def arcsinh(x, out=None, **kwargs):
      r"""
      arcsinh(x, out=None)
      Inverse hyperbolic sine, element-wise.
      Parameters
      ----------
      x : _Symbol or scalar
          Input array.
      out : _Symbol or None, optional
          Dummy parameter to keep the consistency with the ndarray counterpart.
  
      Returns
      -------
      arcsinh : _Symbol
          Array of the same shape as `x`.
          This is a scalar if `x` is a scalar.
      Notes
      -----
      `arcsinh` is a multivalued function: for each `x` there are infinitely
      many numbers `z` such that `sinh(z) = x`.
  
      For real-valued input data types, `arcsinh` 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.
      """
      return _unary_func_helper(x, _npi.arcsinh, _np.arcsinh, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def arccosh(x, out=None, **kwargs):
      r"""
      arccosh(x, out=None)
      Inverse hyperbolic cosine, element-wise.
      Parameters
      ----------
      x : _Symbol or scalar
          Input array.
      out : _Symbol or None, optional
          Dummy parameter to keep the consistency with the ndarray counterpart.
  
      Returns
      -------
      arccosh : _Symbol
          Array of the same shape as `x`.
          This is a scalar if `x` is a scalar.
      Notes
      -----
      `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.
      """
      return _unary_func_helper(x, _npi.arccosh, _np.arccosh, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def arctanh(x, out=None, **kwargs):
      r"""
      arctanh(x, out=None)
      Inverse hyperbolic tangent, element-wise.
      Parameters
      ----------
      x : _Symbol or scalar
          Input array.
      out : _Symbol or None, optional
          Dummy parameter to keep the consistency with the ndarray counterpart.
  
      Returns
      -------
      arctanh : _Symbol
          Array of the same shape as `x`.
          This is a scalar if `x` is a scalar.
      Notes
      -----
      `arctanh` is a multivalued function: for each `x` there are infinitely
      many numbers `z` such that `tanh(z) = x`.
  
      For real-valued input data types, `arctanh` 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.
      """
      return _unary_func_helper(x, _npi.arctanh, _np.arctanh, out=out, **kwargs)
  
  
  @set_module('mxnet.symbol.numpy')
  def tile(A, reps):
      r"""
      Construct an array by repeating A the number of times given by reps.
  
      If `reps` has length ``d``, the result will have dimension of
      ``max(d, A.ndim)``.
  
      If ``A.ndim < d``, `A` is promoted to be d-dimensional by prepending new
      axes. So a shape (3,) array is promoted to (1, 3) for 2-D replication,
      or shape (1, 1, 3) for 3-D replication. If this is not the desired
      behavior, promote `A` to d-dimensions manually before calling this
      function.
  
      If ``A.ndim > d``, `reps` is promoted to `A`.ndim by pre-pending 1's to it.
      Thus for an `A` of shape (2, 3, 4, 5), a `reps` of (2, 2) is treated as
      (1, 1, 2, 2).
  
      Parameters
      ----------
      A : _Symbol or scalar
          An input array or a scalar to repeat.
      reps : a single integer or tuple of integers
          The number of repetitions of `x` along each axis.
  
      Returns
      -------
      c : _Symbol
          The tiled output array.
      """
      return _unary_func_helper(A, _npi.tile, _np.tile, reps=reps)
  
  
  @set_module('mxnet.symbol.numpy')
  def arange(start, stop=None, step=1, dtype=None, ctx=None):
      """Return evenly spaced values within a given interval.
  
      Values are generated within the half-open interval ``[start, stop)``
      (in other words, the interval including `start` but excluding `stop`).
      For integer arguments the function is equivalent to the Python built-in
      `range` function, but returns an ndarray rather than a list.
  
      Parameters
      ----------
      start : number, optional
          Start of interval. The interval includes this value.  The default
          start value is 0.
      stop : number
          End of interval. The interval does not include this value, except
          in some cases where `step` is not an integer and floating point
          round-off affects the length of `out`.
      step : number, optional
          Spacing between values. For any output `out`, this is the distance
          between two adjacent values, ``out[i+1] - out[i]``.  The default
          step size is 1.  If `step` is specified as a position argument,
          `start` must also be given.
      dtype : dtype
          The type of the output array. The default is `float32`.
  
      Returns
      -------
      arange : ndarray
          Array of evenly spaced values.
  
          For floating point arguments, the length of the result is
          ``ceil((stop - start)/step)``.  Because of floating point overflow,
          this rule may result in the last element of `out` being greater
          than `stop`.
      """
      if dtype is None:
          dtype = 'float32'
      if ctx is None:
          ctx = current_context()
      if stop is None:
          stop = start
          start = 0
      if step is None:
          step = 1
      if start is None and stop is None:
          raise ValueError('start and stop cannot be both None')
      if step == 0:
          raise ZeroDivisionError('step cannot be 0')
      return _npi.arange(start=start, stop=stop, step=step, dtype=dtype, ctx=ctx)
  
  
  # pylint: disable=redefined-outer-name
  @set_module('mxnet.symbol.numpy')
  def split(ary, indices_or_sections, axis=0):
      """Split an array into multiple sub-arrays.
      Parameters
      ----------
      ary : ndarray
          Array to be divided into sub-arrays.
      indices_or_sections : int or 1-D array
          If `indices_or_sections` is an integer, N, the array will be divided
          into N equal arrays along `axis`.  If such a split is not possible,
          an error is raised.
          If `indices_or_sections` is a 1-D array of sorted integers, the entries
          indicate where along `axis` the array is split.  For example,
          ``[2, 3]`` would, for ``axis=0``, result in
            - ary[:2]
            - ary[2:3]
            - ary[3:]
          If an index exceeds the dimension of the array along `axis`,
          an empty sub-array is returned correspondingly.
      axis : int, optional
          The axis along which to split, default is 0.
      Returns
      -------
      sub-arrays : list of ndarrays
          A list of sub-arrays.
      Raises
      ------
      ValueError
          If `indices_or_sections` is given as an integer, but
          a split does not result in equal division."""
      indices = []
      sections = 0
      if isinstance(indices_or_sections, int):
          sections = indices_or_sections
      elif isinstance(indices_or_sections, tuple):
          indices = [0] + list(indices_or_sections)
      else:
          raise ValueError('indices_or_sections must either int or tuple of ints')
      ret = _npi.split(ary, indices, axis, False, sections)
      return ret
  # pylint: enable=redefined-outer-name
  
  
  @set_module('mxnet.symbol.numpy')
  def concatenate(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.
      """
      return _npi.concatenate(*seq, dim=axis, out=out)
  
  
  @set_module('mxnet.symbol.numpy')
  def stack(arrays, axis=0, out=None):
      """Join a sequence of arrays along a new axis.
          The axis parameter specifies the index of the new axis in the dimensions of the result.
          For example, if `axis=0` it will be the first dimension and if `axis=-1` it will be the last dimension.
      Parameters
      ----------
      arrays : sequence of array_like
          Each array must have the same shape.
      axis : int, optional
          The axis in the result array along which the input arrays are stacked.
      out : ndarray, optional
          If provided, the destination to place the result. The shape must be correct,
          matching that of what stack would have returned if no out argument were specified.
      Returns
      -------
      stacked : ndarray
          The stacked array has one more dimension than the input arrays."""
      def get_list(arrays):
          if not hasattr(arrays, '__getitem__') and hasattr(arrays, '__iter__'):
              raise ValueError("expected iterable for arrays but got {}".format(type(arrays)))
          return [arr for arr in arrays]
  
      arrays = get_list(arrays)
      return _npi.stack(*arrays, axis=axis, out=out)
  
  
  @set_module('mxnet.symbol.numpy')
  def maximum(x1, x2, out=None):
      return _ufunc_helper(x1, x2, _npi.maximum, _np.maximum, _npi.maximum_scalar, None, out)
  
  
  @set_module('mxnet.symbol.numpy')
  def minimum(x1, x2, out=None):
      return _ufunc_helper(x1, x2, _npi.minimum, _np.minimum, _npi.minimum_scalar, None, out)
  
  
  @set_module('mxnet.symbol.numpy')
  def clip(a, a_min, a_max, out=None):
      """clip(a, a_min, a_max, out=None)
  
      Clip (limit) the values in an array.
      Given an interval, values outside the interval are clipped to
      the interval edges.  For example, if an interval of ``[0, 1]``
      is specified, values smaller than 0 become 0, and values larger
      than 1 become 1.
  
      Parameters
      ----------
      a : _Symbol
          Array containing elements to clip.
      a_min : scalar or `None`
          Minimum value. If `None`, clipping is not performed on lower
          interval edge. Not more than one of `a_min` and `a_max` may be
          `None`.
      a_max : scalar or `None`
          Maximum value. If `None`, clipping is not performed on upper
          interval edge. Not more than one of `a_min` and `a_max` may be
          `None`.
      out : _Symbol or `None`
          The results will be placed in this array. It may be the input
          array for in-place clipping.  `out` must be of the right shape
          to hold the output.  Its type is preserved.
  
      Returns
      -------
      clipped_array : _Symbol
          An array with the elements of `a`, but where values
          < `a_min` are replaced with `a_min`, and those > `a_max`
          with `a_max`.
  
      Notes
      -----
      array_like `a_min` and `a_max` are not supported.
      """
      if a_min is None and a_max is None:
          raise ValueError('array_clip: must set either max or min')
      if a_min is None:
          a_min = float('-inf')
      if a_max is None:
          a_max = float('inf')
      return _npi.clip(a, a_min, a_max, out=out)
  
  
  @set_module('mxnet.symbol.numpy')
  def swapaxes(a, axis1, axis2):
      """Interchange two axes of an array.
  
      Parameters
      ----------
      a : _Symbol
          Input array.
      axis1 : int
          First axis.
      axis2 : int
          Second axis.
  
      Returns
      -------
      a_swapped : _Symbol
          Swapped array symbol.
      """
      return _npi.swapaxes(a, dim1=axis1, dim2=axis2)
  
  
  @set_module('mxnet.symbol.numpy')
  def argmax(a, axis=None, out=None):
      r"""
      argmax(a, axis=None, out=None)
  
      Returns the indices of the maximum values along an axis.
  
      Parameters
      ----------
      a : _Symbol
          Input array. Only support dtype `float16`, `float32`, and `float64`.
      axis : int, optional
          By default, the index is into the flattened array, otherwise
          along the specified axis.
      out : _Symbol or None, optional
          Dummy parameter to keep the consistency with the ndarray counterpart.
  
      Returns
      -------
      index_array : _Symbol of indices whose dtype is same as the input ndarray.
          Array of indices into the array. It has the same shape as `a.shape`
          with the dimension along `axis` removed.
  
      Notes
      -----
      In case of multiple occurrences of the maximum values, the indices
      corresponding to the first occurrence are returned.
  
      This function differs from the original `numpy.argmax
      <https://docs.scipy.org/doc/numpy/reference/generated/numpy.argmax.html>`_ in
      the following aspects:
  
      - Input type does not support Python native iterables(list, tuple, ...).
      - Output has dtype that is same as the input ndarray.
      - ``out`` param: cannot perform auto broadcasting. ``out`` symbol's shape must be the same as the expected output.
      - ``out`` param: cannot perform auto type cast. ``out`` symnbol's dtype must be the same as the expected output.
      - ``out`` param does not support scalar input case.
  
      """
      return _npi.argmax(a, axis=axis, keepdims=False, out=out)
  
  
  @set_module('mxnet.symbol.numpy')
  def mean(a, axis=None, dtype=None, out=None, keepdims=False):  # pylint: disable=arguments-differ
      """
      mean(a, axis=None, dtype=None, out=None, keepdims=None)
  
      Compute the arithmetic mean along the specified axis.
      Returns the average of the array elements.
      The average is taken over the flattened array by default, otherwise over the specified axis.
  
      Parameters
      ----------
      a : `_Symbol`
          _Symbol containing numbers whose mean is desired.
      axis : None or int or tuple of ints, optional
          Axis or axes along which the means are computed. The default is to compute the mean of the flattened array.
          If this is a tuple of ints, a mean is performed over multiple axes,
          instead of a single axis or all the axes as before.
      dtype : data-type, optional
          Type to use in computing the mean. For integer inputs, the default is float32;
          for floating point inputs, it is the same as the input dtype.
      out : _Symbol, optional
          Dummy parameter to keep the consistency with the ndarray counterpart.
      keepdims : bool, optional
          If this is set to True, the axes which are reduced are left in the result
          as dimensions with size one. With this option, the result will broadcast correctly
          against the input array.
          If the default value is passed, then keepdims will not be passed through to the mean
          method of sub-classes of _Symbol, however any non-default value will be. If the sub-class
          method does not implement keepdims any exceptions will be raised.
  
      Returns
      -------
      m : _Symbol, see dtype parameter above
          If out=None, returns a new array containing the mean values,
          otherwise a reference to the output array is returned.
  
      Notes
      -----
      This function differs from the original `numpy.mean
      <https://docs.scipy.org/doc/numpy/reference/generated/numpy.mean.html>`_ in
      the following way(s):
  
      - only _Symbol is accepted as valid input, python iterables or scalar is not supported
      - default data type for integer input is float32
  
      Examples
      --------
      >>> a = np.array([[1, 2], [3, 4]])
      >>> np.mean(a)
      array(2.5)
      >>> a = np.zeros((2, 512*512), dtype=np.float32)
      >>> a[0,:] = 1.0
      >>> a[1,:] = 0.1
      >>> np.mean(a)
      array(0.55)
      >>> np.mean(a, dtype=np.float64)
      array(0.55)
      """
      return _npi.mean(a, axis=axis, dtype=dtype, keepdims=keepdims, out=out)
  
  
  @set_module('mxnet.symbol.numpy')
  def std(a, axis=None, dtype=None, out=None, ddof=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,
      of the array elements. The standard deviation is computed for the
      flattened array by default, otherwise over the specified axis.
  
      Parameters
      ----------
      a : `_Symbol`
          _Symbol containing numbers whose standard deviation is desired.
      axis : None or int or tuple of ints, optional
          Axis or axes along which the standard deviations are computed.
          The default is to compute the standard deviation of the flattened array.
          If this is a tuple of ints, computation is performed over multiple axes,
          instead of a single axis or all the axes as before.
      dtype : data-type, optional
          Type to use in computing the standard deviation. For integer inputs, the default is float32;
          for floating point inputs, it is the same as the input dtype.
      out : _Symbol, optional
          Dummy parameter to keep the consistency with the ndarray counterpart.
      keepdims : bool, optional
          If this is set to True, the axes which are reduced are left in the result
          as dimensions with size one. With this option, the result will broadcast correctly
          against the input array.
          If the default value is passed, then keepdims will not be passed through to the mean
          method of sub-classes of _Symbol, however any non-default value will be. If the sub-class
          method does not implement keepdims any exceptions will be raised.
  
      Returns
      -------
      m : _Symbol, see dtype parameter above
          If out=None, returns a new array containing the standard deviation values,
          otherwise a reference to the output array is returned.
  
      Notes
      -----
      This function differs from the original `numpy.std
      <https://docs.scipy.org/doc/numpy/reference/generated/numpy.mean.html>`_ in
      the following way(s):
  
      - only _Symbol is accepted as valid input, python iterables or scalar is not supported
      - default output data type for integer input is float32
  
      """
      return _npi.std(a, axis=axis, dtype=dtype, ddof=ddof, keepdims=keepdims, out=out)
  
  
  @set_module('mxnet.symbol.numpy')
  def var(a, axis=None, dtype=None, out=None, ddof=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
      distribution.  The variance is computed for the flattened array by
      default, otherwise over the specified axis.
  
      Parameters
      ----------
      a : `_Symbol`
          _Symbol containing numbers whose variance is desired.
      axis : None or int or tuple of ints, optional
          Axis or axes along which the variance is computed.
          The default is to compute the variance of the flattened array.
          If this is a tuple of ints, computation is performed over multiple axes,
          instead of a single axis or all the axes as before.
      dtype : data-type, optional
          Type to use in computing the variance. For integer inputs, the default is float32;
          for floating point inputs, it is the same as the input dtype.
      out : _Symbol, optional
          Dummy parameter to keep the consistency with the ndarray counterpart.
      keepdims : bool, optional
          If this is set to True, the axes which are reduced are left in the result
          as dimensions with size one. With this option, the result will broadcast correctly
          against the input array.
          If the default value is passed, then keepdims will not be passed through to the mean
          method of sub-classes of _Symbol, however any non-default value will be. If the sub-class
          method does not implement keepdims any exceptions will be raised.
  
      Returns
      -------
      m : _Symbol, see dtype parameter above
          If out=None, returns a new array containing the variance values,
          otherwise a reference to the output array is returned.
  
      Notes
      -----
      This function differs from the original `numpy.var
      <https://docs.scipy.org/doc/numpy/reference/generated/numpy.mean.html>`_ in
      the following way(s):
  
      - only _Symbol is accepted as valid input, python iterables or scalar is not supported
      - default output data type for integer input is float32
  
      """
      return _npi.var(a, axis=axis, dtype=dtype, ddof=ddof, keepdims=keepdims, out=out)
  
  
  # pylint: disable=redefined-outer-name
  @set_module('mxnet.symbol.numpy')
  def indices(dimensions, dtype=_np.int32, ctx=None):
      """Return an array representing the indices of a grid.
  
      Compute an array where the subarrays contain index values 0,1,...
      varying only along the corresponding axis.
  
      Parameters
      ----------
      dimensions : sequence of ints
          The shape of the grid.
      dtype : data-type, optional
          The desired data-type for the array. Default is `float32`.
      ctx : device context, optional
          Device context on which the memory is allocated. Default is
          `mxnet.context.current_context()`.
  
      Returns
      -------
      grid : _Symbol
          The array of grid indices,
          ``grid.shape = (len(dimensions),) + tuple(dimensions)``.
  
      Notes
      -----
      The output shape is obtained by prepending the number of dimensions
      in front of the tuple of dimensions, i.e. if `dimensions` is a tuple
      ``(r0, ..., rN-1)`` of length ``N``, the output shape is
      ``(N,r0,...,rN-1)``.
  
      The subarrays ``grid[k]`` contains the N-D array of indices along the
      ``k-th`` axis. Explicitly::
  
          grid[k,i0,i1,...,iN-1] = ik
  
      Examples
      --------
      >>> grid = np.indices((2, 3))
      >>> grid.shape
      (2, 2, 3)
      >>> grid[0]        # row indices
      array([[0, 0, 0],
             [1, 1, 1]])
      >>> grid[1]        # column indices
      array([[0, 0, 0],
             [1, 1, 1]], dtype=int32)
  
      The indices can be used as an index into an array.
  
      >>> x = np.arange(20).reshape(5, 4)
      >>> row, col = np.indices((2, 3))
      >>> x[row, col]
      array([[0., 1., 2.],
             [4., 5., 6.]])
  
      Note that it would be more straightforward in the above example to
      extract the required elements directly with ``x[:2, :3]``.
      """
      if isinstance(dimensions, (tuple, list)):
          if ctx is None:
              ctx = current_context()
          return _npi.indices(dimensions=dimensions, dtype=dtype, ctx=ctx)
      else:
          raise ValueError("The dimensions must be sequence of ints")
  # pylint: enable=redefined-outer-name
  
  
  @set_module('mxnet.symbol.numpy')
  def copysign(x1, x2, out=None):
      r"""copysign(x1, x2, out=None)
  
      Change the sign of x1 to that of x2, element-wise.
  
      If `x2` is a scalar, its sign will be copied to all elements of `x1`.
  
      Parameters
      ----------
      x1 : _Symbol or scalar
          Values to change the sign of.
      x2 : _Symbol or scalar
          The sign of `x2` is copied to `x1`.
      out : _Symbol or None
          Dummy parameter to keep the consistency with the ndarray counterpart.
  
      Returns
      -------
      out : _Symbol
          The values of `x1` with the sign of `x2`.
          This is a scalar if both `x1` and `x2` are scalars.
  
      Notes
      -------
      This function differs from the original `numpy.copysign
      <https://docs.scipy.org/doc/numpy/reference/generated/numpy.copysign.html>`_ in
      the following aspects:
  
      - ``where`` param is not supported.
      """
      return _ufunc_helper(x1, x2, _npi.copysign, _np.copysign, _npi.copysign_scalar, _npi.rcopysign_scalar, out)
  
  
  @set_module('mxnet.symbol.numpy')
  def ravel(x, order='C'):
      r"""
      ravel(x)
  
      Return a contiguous flattened array.
      A 1-D array, containing the elements of the input, is returned.  A copy is
      made only if needed.
  
      Parameters
      ----------
      x : ndarray
          Input array.  The elements in `x` are read in row-major, C-style order and
          packed as a 1-D array.
      order : `C`, optional
          Only support row-major, C-style order.
  
      Returns
      -------
      y : ndarray
          y is an array of the same subtype as `x`, with shape ``(x.size,)``.
          Note that matrices are special cased for backward compatibility, if `x`
          is a matrix, then y is a 1-D ndarray.
  
      Notes
      -----
      This function differs from the original numpy.arange in the following aspects:
          - Only support row-major, C-style order.
      """
      if order != 'C':
          raise NotImplementedError('order {} is not supported'.format(order))
      if isinstance(x, numeric_types):
          return _np.reshape(x, -1)
      elif isinstance(x, _Symbol):
          return _npi.reshape(x, -1)
      else:
          raise TypeError('type {} not supported'.format(str(type(x))))
  
  
  _set_np_symbol_class(_Symbol)
  