@array_function_from_c_func_and_dispatcher(_multiarray_umath.dot)
def dot(a, b, out=None):
    "\n    dot(a, b, out=None)\n\n    Dot product of two arrays. Specifically,\n\n    - If both `a` and `b` are 1-D arrays, it is inner product of vectors\n      (without complex conjugation).\n\n    - If both `a` and `b` are 2-D arrays, it is matrix multiplication,\n      but using :func:`matmul` or ``a @ b`` is preferred.\n\n    - If either `a` or `b` is 0-D (scalar), it is equivalent to :func:`multiply`\n      and using ``numpy.multiply(a, b)`` or ``a * b`` is preferred.\n\n    - If `a` is an N-D array and `b` is a 1-D array, it is a sum product over\n      the last axis of `a` and `b`.\n\n    - If `a` is an N-D array and `b` is an M-D array (where ``M>=2``), it is a\n      sum product over the last axis of `a` and the second-to-last axis of `b`::\n\n        dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])\n\n    Parameters\n    ----------\n    a : array_like\n        First argument.\n    b : array_like\n        Second argument.\n    out : ndarray, optional\n        Output argument. This must have the exact kind that would be returned\n        if it was not used. In particular, it must have the right type, must be\n        C-contiguous, and its dtype must be the dtype that would be returned\n        for `dot(a,b)`. This is a performance feature. Therefore, if these\n        conditions are not met, an exception is raised, instead of attempting\n        to be flexible.\n\n    Returns\n    -------\n    output : ndarray\n        Returns the dot product of `a` and `b`.  If `a` and `b` are both\n        scalars or both 1-D arrays then a scalar is returned; otherwise\n        an array is returned.\n        If `out` is given, then it is returned.\n\n    Raises\n    ------\n    ValueError\n        If the last dimension of `a` is not the same size as\n        the second-to-last dimension of `b`.\n\n    See Also\n    --------\n    vdot : Complex-conjugating dot product.\n    tensordot : Sum products over arbitrary axes.\n    einsum : Einstein summation convention.\n    matmul : '@' operator as method with out parameter.\n\n    Examples\n    --------\n    >>> np.dot(3, 4)\n    12\n\n    Neither argument is complex-conjugated:\n\n    >>> np.dot([2j, 3j], [2j, 3j])\n    (-13+0j)\n\n    For 2-D arrays it is the matrix product:\n\n    >>> a = [[1, 0], [0, 1]]\n    >>> b = [[4, 1], [2, 2]]\n    >>> np.dot(a, b)\n    array([[4, 1],\n           [2, 2]])\n\n    >>> a = np.arange(3*4*5*6).reshape((3,4,5,6))\n    >>> b = np.arange(3*4*5*6)[::-1].reshape((5,4,6,3))\n    >>> np.dot(a, b)[2,3,2,1,2,2]\n    499128\n    >>> sum(a[2,3,2,:] * b[1,2,:,2])\n    499128\n\n    "
    return (a, b, out)
dot(a, b, out=None)

Dot product of two arrays. Specifically,

- If both `a` and `b` are 1-D arrays, it is inner product of vectors
  (without complex conjugation).

- If both `a` and `b` are 2-D arrays, it is matrix multiplication,
  but using :func:`matmul` or ``a @ b`` is preferred.

- If either `a` or `b` is 0-D (scalar), it is equivalent to :func:`multiply`
  and using ``numpy.multiply(a, b)`` or ``a * b`` is preferred.

- If `a` is an N-D array and `b` is a 1-D array, it is a sum product over
  the last axis of `a` and `b`.

- If `a` is an N-D array and `b` is an M-D array (where ``M>=2``), it is a
  sum product over the last axis of `a` and the second-to-last axis of `b`::

    dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])

Parameters
----------
a : array_like
    First argument.
b : array_like
    Second argument.
out : ndarray, optional
    Output argument. This must have the exact kind that would be returned
    if it was not used. In particular, it must have the right type, must be
    C-contiguous, and its dtype must be the dtype that would be returned
    for `dot(a,b)`. This is a performance feature. Therefore, if these
    conditions are not met, an exception is raised, instead of attempting
    to be flexible.

Returns
-------
output : ndarray
    Returns the dot product of `a` and `b`.  If `a` and `b` are both
    scalars or both 1-D arrays then a scalar is returned; otherwise
    an array is returned.
    If `out` is given, then it is returned.

Raises
------
ValueError
    If the last dimension of `a` is not the same size as
    the second-to-last dimension of `b`.

See Also
--------
vdot : Complex-conjugating dot product.
tensordot : Sum products over arbitrary axes.
einsum : Einstein summation convention.
matmul : '@' operator as method with out parameter.

Examples
--------
>>> np.dot(3, 4)
12

Neither argument is complex-conjugated:

>>> np.dot([2j, 3j], [2j, 3j])
(-13+0j)

For 2-D arrays it is the matrix product:

>>> a = [[1, 0], [0, 1]]
>>> b = [[4, 1], [2, 2]]
>>> np.dot(a, b)
array([[4, 1],
       [2, 2]])

>>> a = np.arange(3*4*5*6).reshape((3,4,5,6))
>>> b = np.arange(3*4*5*6)[::-1].reshape((5,4,6,3))
>>> np.dot(a, b)[2,3,2,1,2,2]
499128
>>> sum(a[2,3,2,:] * b[1,2,:,2])
499128
@array_function_from_c_func_and_dispatcher(_multiarray_umath.dot)
def dot(a, b, out=None):
    "\n    dot(a, b, out=None)\n\n    Dot product of two arrays. Specifically,\n\n    - If both `a` and `b` are 1-D arrays, it is inner product of vectors\n      (without complex conjugation).\n\n    - If both `a` and `b` are 2-D arrays, it is matrix multiplication,\n      but using :func:`matmul` or ``a @ b`` is preferred.\n\n    - If either `a` or `b` is 0-D (scalar), it is equivalent to :func:`multiply`\n      and using ``numpy.multiply(a, b)`` or ``a * b`` is preferred.\n\n    - If `a` is an N-D array and `b` is a 1-D array, it is a sum product over\n      the last axis of `a` and `b`.\n\n    - If `a` is an N-D array and `b` is an M-D array (where ``M>=2``), it is a\n      sum product over the last axis of `a` and the second-to-last axis of `b`::\n\n        dot(a, b)[i,j,k,m] = sum(a[i,j,:] * b[k,:,m])\n\n    Parameters\n    ----------\n    a : array_like\n        First argument.\n    b : array_like\n        Second argument.\n    out : ndarray, optional\n        Output argument. This must have the exact kind that would be returned\n        if it was not used. In particular, it must have the right type, must be\n        C-contiguous, and its dtype must be the dtype that would be returned\n        for `dot(a,b)`. This is a performance feature. Therefore, if these\n        conditions are not met, an exception is raised, instead of attempting\n        to be flexible.\n\n    Returns\n    -------\n    output : ndarray\n        Returns the dot product of `a` and `b`.  If `a` and `b` are both\n        scalars or both 1-D arrays then a scalar is returned; otherwise\n        an array is returned.\n        If `out` is given, then it is returned.\n\n    Raises\n    ------\n    ValueError\n        If the last dimension of `a` is not the same size as\n        the second-to-last dimension of `b`.\n\n    See Also\n    --------\n    vdot : Complex-conjugating dot product.\n    tensordot : Sum products over arbitrary axes.\n    einsum : Einstein summation convention.\n    matmul : '@' operator as method with out parameter.\n\n    Examples\n    --------\n    >>> np.dot(3, 4)\n    12\n\n    Neither argument is complex-conjugated:\n\n    >>> np.dot([2j, 3j], [2j, 3j])\n    (-13+0j)\n\n    For 2-D arrays it is the matrix product:\n\n    >>> a = [[1, 0], [0, 1]]\n    >>> b = [[4, 1], [2, 2]]\n    >>> np.dot(a, b)\n    array([[4, 1],\n           [2, 2]])\n\n    >>> a = np.arange(3*4*5*6).reshape((3,4,5,6))\n    >>> b = np.arange(3*4*5*6)[::-1].reshape((5,4,6,3))\n    >>> np.dot(a, b)[2,3,2,1,2,2]\n    499128\n    >>> sum(a[2,3,2,:] * b[1,2,:,2])\n    499128\n\n    "
    return (a, b, out)