
    Ph<                        d dl mZ d dlZd dlmZ erddlmZmZ g dZddZ	ddZ
d d	dd
Zddd	 	 	 	 	 	 	 	 	 ddZdd	 	 	 	 	 	 	 ddZddZddZy)    )annotationsN)TYPE_CHECKING   )Array
ModuleType)
atleast_ndcovcreate_diagonalexpand_dimskronsincc              f    | j                   |k  r!|j                  | d      } t        | ||      } | S )a_  
    Recursively expand the dimension of an array to at least `ndim`.

    Parameters
    ----------
    x : array
    ndim : int
        The minimum number of dimensions for the result.
    xp : array_namespace
        The standard-compatible namespace for `x`.

    Returns
    -------
    res : array
        An array with ``res.ndim`` >= `ndim`.
        If ``x.ndim`` >= `ndim`, `x` is returned.
        If ``x.ndim`` < `ndim`, `x` is expanded by prepending new axes
        until ``res.ndim`` equals `ndim`.

    Examples
    --------
    >>> import array_api_strict as xp
    >>> import array_api_extra as xpx
    >>> x = xp.asarray([1])
    >>> xpx.atleast_nd(x, ndim=3, xp=xp)
    Array([[[1]]], dtype=array_api_strict.int64)

    >>> x = xp.asarray([[[1, 2],
    ...                  [3, 4]]])
    >>> xpx.atleast_nd(x, ndim=1, xp=xp) is x
    True

    r   axisndimxp)r   r   r   )xr   r   s      lC:\Users\daisl\Desktop\realtime-object-detection\venv\Lib\site-packages\scipy/_lib/array_api_extra/_funcs.pyr   r      s5    D 	vv}NN11N%qt+H    c                 |j                  | d      } |j                  | j                  d      r|j                  n|j	                  | |j                        }t        | d|      } |j                  | |      } t        | d|      }| j                  d   dz
  }|dk  rt        j                  d	t        d
       d}| |dddf   z  } | j                  }|j                  |j                  d      r|j                  |      }| |z  }||z  }t        d t        |j                        D              }|j!                  ||      S )a  
    Estimate a covariance matrix.

    Covariance indicates the level to which two variables vary together.
    If we examine N-dimensional samples, :math:`X = [x_1, x_2, ... x_N]^T`,
    then the covariance matrix element :math:`C_{ij}` is the covariance of
    :math:`x_i` and :math:`x_j`. The element :math:`C_{ii}` is the variance
    of :math:`x_i`.

    This provides a subset of the functionality of ``numpy.cov``.

    Parameters
    ----------
    m : array
        A 1-D or 2-D array containing multiple variables and observations.
        Each row of `m` represents a variable, and each column a single
        observation of all those variables.
    xp : array_namespace
        The standard-compatible namespace for `m`.

    Returns
    -------
    res : array
        The covariance matrix of the variables.

    Examples
    --------
    >>> import array_api_strict as xp
    >>> import array_api_extra as xpx

    Consider two variables, :math:`x_0` and :math:`x_1`, which
    correlate perfectly, but in opposite directions:

    >>> x = xp.asarray([[0, 2], [1, 1], [2, 0]]).T
    >>> x
    Array([[0, 1, 2],
           [2, 1, 0]], dtype=array_api_strict.int64)

    Note how :math:`x_0` increases while :math:`x_1` decreases. The covariance
    matrix shows this clearly:

    >>> xpx.cov(x, xp=xp)
    Array([[ 1., -1.],
           [-1.,  1.]], dtype=array_api_strict.float64)


    Note that element :math:`C_{0,1}`, which shows the correlation between
    :math:`x_0` and :math:`x_1`, is negative.

    Further, note how `x` and `y` are combined:

    >>> x = xp.asarray([-2.1, -1,  4.3])
    >>> y = xp.asarray([3,  1.1,  0.12])
    >>> X = xp.stack((x, y), axis=0)
    >>> xpx.cov(X, xp=xp)
    Array([[11.71      , -4.286     ],
           [-4.286     ,  2.14413333]], dtype=array_api_strict.float64)

    >>> xpx.cov(x, xp=xp)
    Array(11.71, dtype=array_api_strict.float64)

    >>> xpx.cov(y, xp=xp)
    Array(2.14413333, dtype=array_api_strict.float64)

    T)copyintegral   r   r   r   r   r   z!Degrees of freedom <= 0 for slice)
stacklevelg        Ncomplex floatingc              3  2   K   | ]  \  }}|d k(  s|  yw)r   N ).0r   lengths      r   	<genexpr>zcov.<locals>.<genexpr>   s     L*<,$!*<s   r   )asarrayisdtypedtypefloat64result_typer   astype_meanshapewarningswarnRuntimeWarningTconjtuple	enumeratesqueeze)mr   r%   avgfactm_transposecaxess           r   r	   r	   4   s   D 	

14
 Ajj*5

2>>!RZZ;X 
 	11$A
		!UA
b
!C771:>Dqy9>VWXQWA##K	zz+##%78ggk*	KAIAL)AGG*<LLD::ad:##r   )offsetc              R   | j                   dk7  rd}t        |      | j                  d   t        |      z   }|j	                  |dz  | j
                        }|dk\  r|nt        |      |z  }| ||t        |||z
  z  |j                  d         |dz   <   |j                  |||f      S )a  
    Construct a diagonal array.

    Parameters
    ----------
    x : array
        A 1-D array
    offset : int, optional
        Offset from the leading diagonal (default is ``0``).
        Use positive ints for diagonals above the leading diagonal,
        and negative ints for diagonals below the leading diagonal.
    xp : array_namespace
        The standard-compatible namespace for `x`.

    Returns
    -------
    res : array
        A 2-D array with `x` on the diagonal (offset by `offset`).

    Examples
    --------
    >>> import array_api_strict as xp
    >>> import array_api_extra as xpx
    >>> x = xp.asarray([2, 4, 8])

    >>> xpx.create_diagonal(x, xp=xp)
    Array([[2, 0, 0],
           [0, 4, 0],
           [0, 0, 8]], dtype=array_api_strict.int64)

    >>> xpx.create_diagonal(x, offset=-2, xp=xp)
    Array([[0, 0, 0, 0, 0],
           [0, 0, 0, 0, 0],
           [2, 0, 0, 0, 0],
           [0, 4, 0, 0, 0],
           [0, 0, 8, 0, 0]], dtype=array_api_strict.int64)

    r   z`x` must be 1-dimensional.r   r   r%   )r   
ValueErrorr*   abszerosr%   minreshape)r   r9   r   err_msgndiagis          r   r
   r
      s    N 	vv{.!!	
S[ A88AqD8(DA+3v;?A=>DSa&j!4::a=1AE	9:::dQF##r   Fr   keepdimsc              $   |j                  | j                  d      ra|j                  |       }|j                  |       }|j	                  |||      }|j	                  |||      }|||j                  d      z  z   S |j	                  | ||      S )zJ
    Complex mean, https://github.com/data-apis/array-api/issues/846.
    r   rE   y              ?)r$   r%   realimagmeanr#   )r   r   rF   r   x_realx_imag	mean_real	mean_imags           r   r)   r)      s     
zz!''-.GGFGA	GGFGA	I

26777714(733r   )r   r   c                 t        |t              s|f}| j                  t        |      z   |dk7  r7t	        |       k  st        |      k\  rd| j                   }t        |      t        fd|D              }t        t        |            t        |      k7  rd}t        |      t        |      D ]  }|j                  | |      }  | S )a  
    Expand the shape of an array.

    Insert (a) new axis/axes that will appear at the position(s) specified by
    `axis` in the expanded array shape.

    This is ``xp.expand_dims`` for `axis` an int *or a tuple of ints*.
    Roughly equivalent to ``numpy.expand_dims`` for NumPy arrays.

    Parameters
    ----------
    a : array
    axis : int or tuple of ints, optional
        Position(s) in the expanded axes where the new axis (or axes) is/are placed.
        If multiple positions are provided, they should be unique (note that a position
        given by a positive index could also be referred to by a negative index -
        that will also result in an error).
        Default: ``(0,)``.
    xp : array_namespace
        The standard-compatible namespace for `a`.

    Returns
    -------
    res : array
        `a` with an expanded shape.

    Examples
    --------
    >>> import array_api_strict as xp
    >>> import array_api_extra as xpx
    >>> x = xp.asarray([1, 2])
    >>> x.shape
    (2,)

    The following is equivalent to ``x[xp.newaxis, :]`` or ``x[xp.newaxis]``:

    >>> y = xpx.expand_dims(x, axis=0, xp=xp)
    >>> y
    Array([[1, 2]], dtype=array_api_strict.int64)
    >>> y.shape
    (1, 2)

    The following is equivalent to ``x[:, xp.newaxis]``:

    >>> y = xpx.expand_dims(x, axis=1, xp=xp)
    >>> y
    Array([[1],
           [2]], dtype=array_api_strict.int64)
    >>> y.shape
    (2, 1)

    ``axis`` may also be a tuple:

    >>> y = xpx.expand_dims(x, axis=(0, 1), xp=xp)
    >>> y
    Array([[[1, 2]]], dtype=array_api_strict.int64)

    >>> y = xpx.expand_dims(x, axis=(2, 0), xp=xp)
    >>> y
    Array([[[1],
            [2]]], dtype=array_api_strict.int64)

    r   zAa provided axis position is out of bounds for array of dimension c              3  (   K   | ]	  }|z    y w)Nr   )r    dimr   s     r   r"   zexpand_dims.<locals>.<genexpr>  s     ,ttts   z)Duplicate dimensions specified in `axis`.r   )
isinstancer0   r   lenr?   max
IndexErrorsetr<   sortedr   )ar   r   rA   rD   r   s        @r   r   r      s    D dE"w66CIDrzs4yD5(CI,=OPQPVPVxX 	 !!,t,,D
3t9~T"=!!D\NN11N% Hr   c         
        |j                  |      }d|j                  | j                  z
  z  }|j                  |j                  |       || j                  z         } |j                  | j                  }}t	        ||      }|dk(  s|dk(  r|j                  | |      S | j                  }|j                  }dt	        d||z
        z  |z   }dt	        d||z
        z  |z   }t        | t        t        ||z
              |      }	t        |t        t        ||z
              |      }
t        |	t        t        d|dz  d            |      }	t        |
t        t        d|dz  d            |      }
|j                  |	|
      }|j                  |      }|j                  |      }|j                  |t        |j                  ||                  S )a  
    Kronecker product of two arrays.

    Computes the Kronecker product, a composite array made of blocks of the
    second array scaled by the first.

    Equivalent to ``numpy.kron`` for NumPy arrays.

    Parameters
    ----------
    a, b : array
    xp : array_namespace
        The standard-compatible namespace for `a` and `b`.

    Returns
    -------
    res : array
        The Kronecker product of `a` and `b`.

    Notes
    -----
    The function assumes that the number of dimensions of `a` and `b`
    are the same, if necessary prepending the smallest with ones.
    If ``a.shape = (r0,r1,..,rN)`` and ``b.shape = (s0,s1,...,sN)``,
    the Kronecker product has shape ``(r0*s0, r1*s1, ..., rN*SN)``.
    The elements are products of elements from `a` and `b`, organized
    explicitly by::

        kron(a,b)[k0,k1,...,kN] = a[i0,i1,...,iN] * b[j0,j1,...,jN]

    where::

        kt = it * st + jt,  t = 0,...,N

    In the common 2-D case (N=1), the block structure can be visualized::

        [[ a[0,0]*b,   a[0,1]*b,  ... , a[0,-1]*b  ],
         [  ...                              ...   ],
         [ a[-1,0]*b,  a[-1,1]*b, ... , a[-1,-1]*b ]]


    Examples
    --------
    >>> import array_api_strict as xp
    >>> import array_api_extra as xpx
    >>> xpx.kron(xp.asarray([1, 10, 100]), xp.asarray([5, 6, 7]), xp=xp)
    Array([  5,   6,   7,  50,  60,  70, 500,
           600, 700], dtype=array_api_strict.int64)

    >>> xpx.kron(xp.asarray([5, 6, 7]), xp.asarray([1, 10, 100]), xp=xp)
    Array([  5,  50, 500,   6,  60, 600,   7,
            70, 700], dtype=array_api_strict.int64)

    >>> xpx.kron(xp.eye(2), xp.ones((2, 2)), xp=xp)
    Array([[1., 1., 0., 0.],
           [1., 1., 0., 0.],
           [0., 0., 1., 1.],
           [0., 0., 1., 1.]], dtype=array_api_strict.float64)


    >>> a = xp.reshape(xp.arange(100), (2, 5, 2, 5))
    >>> b = xp.reshape(xp.arange(24), (2, 3, 4))
    >>> c = xpx.kron(a, b, xp=xp)
    >>> c.shape
    (2, 10, 6, 20)
    >>> I = (1, 3, 0, 2)
    >>> J = (0, 2, 1)
    >>> J1 = (0,) + J             # extend to ndim=4
    >>> S1 = (1,) + b.shape
    >>> K = tuple(xp.asarray(I) * xp.asarray(S1) + xp.asarray(J1))
    >>> c[K] == a[I]*b[J]
    Array(True, dtype=array_api_strict.bool)

    )r   r   r   r   r   )
r#   r   broadcast_tor*   rT   multiplyr   r0   ranger@   )rX   br   
singletonsnd_bnd_and_maxa_shapeb_shapea_arrb_arrresults               r   r   r   '  s   X 	

1A!&&)J


1zAGG';<A$Dt_FqyDAI{{1a  ggGggG SD4K((72GSD4K((72G eD4K&8 9bAEeD4K&8 9bAE E%6A:q*A$BrJEE%6A:q*A$BrJE[[&F jj!Gjj!G::feBKK$ABCCr   c         
     8   |j                  | j                  d      sd}t        |      |j                  |j	                  | | |j                  |j                  | j                        j                  | j                              z  }|j                  |      |z  S )a
  
    Return the normalized sinc function.

    The sinc function is equal to :math:`\sin(\pi x)/(\pi x)` for any argument
    :math:`x\ne 0`. ``sinc(0)`` takes the limit value 1, making ``sinc`` not
    only everywhere continuous but also infinitely differentiable.

    .. note::

        Note the normalization factor of ``pi`` used in the definition.
        This is the most commonly used definition in signal processing.
        Use ``sinc(x / xp.pi)`` to obtain the unnormalized sinc function
        :math:`\sin(x)/x` that is more common in mathematics.

    Parameters
    ----------
    x : array
        Array (possibly multi-dimensional) of values for which to calculate
        ``sinc(x)``. Must have a real floating point dtype.
    xp : array_namespace
        The standard-compatible namespace for `x`.

    Returns
    -------
    res : array
        ``sinc(x)`` calculated elementwise, which has the same shape as the input.

    Notes
    -----
    The name sinc is short for "sine cardinal" or "sinus cardinalis".

    The sinc function is used in various signal processing applications,
    including in anti-aliasing, in the construction of a Lanczos resampling
    filter, and in interpolation.

    For bandlimited interpolation of discrete-time signals, the ideal
    interpolation kernel is proportional to the sinc function.

    References
    ----------
    .. [1] Weisstein, Eric W. "Sinc Function." From MathWorld--A Wolfram Web
           Resource. https://mathworld.wolfram.com/SincFunction.html
    .. [2] Wikipedia, "Sinc function",
           https://en.wikipedia.org/wiki/Sinc_function

    Examples
    --------
    >>> import array_api_strict as xp
    >>> import array_api_extra as xpx
    >>> x = xp.linspace(-4, 4, 41)
    >>> xpx.sinc(x, xp=xp)
    Array([-3.89817183e-17, -4.92362781e-02,
           -8.40918587e-02, -8.90384387e-02,
           -5.84680802e-02,  3.89817183e-17,
            6.68206631e-02,  1.16434881e-01,
            1.26137788e-01,  8.50444803e-02,
           -3.89817183e-17, -1.03943254e-01,
           -1.89206682e-01, -2.16236208e-01,
           -1.55914881e-01,  3.89817183e-17,
            2.33872321e-01,  5.04551152e-01,
            7.56826729e-01,  9.35489284e-01,
            1.00000000e+00,  9.35489284e-01,
            7.56826729e-01,  5.04551152e-01,
            2.33872321e-01,  3.89817183e-17,
           -1.55914881e-01, -2.16236208e-01,
           -1.89206682e-01, -1.03943254e-01,
           -3.89817183e-17,  8.50444803e-02,
            1.26137788e-01,  1.16434881e-01,
            6.68206631e-02,  3.89817183e-17,
           -5.84680802e-02, -8.90384387e-02,
           -8.40918587e-02, -4.92362781e-02,
           -3.89817183e-17], dtype=array_api_strict.float64)

    zreal floatingz(`x` must have a real floating data type.r;   )	r$   r%   r<   piwherer#   finfosmallest_normalsin)r   r   rA   ys       r   r   r     s    V ::agg/<!!
	1bjj!''*::!''jJ 	A 66!9q=r   )r   r   r   intr   r   returnr   )r3   r   r   r   ro   r   )r   r   r9   rn   r   r   ro   r   )
r   r   r   zint | tuple[int, ...] | NonerF   boolr   r   ro   r   )rX   r   r   zint | tuple[int, ...]r   r   ro   r   )rX   r   r]   r   r   r   ro   r   )r   r   r   r   ro   r   )
__future__r   r+   typingr   _typingr   r   __all__r   r	   r
   r)   r   r   r   r   r   r   <module>ru      s    "   *
Q%PX$v 34 .$j *.44 '	4
 4 	4 4* 37PP/P<FP
PfhDVRr   