o
    0 i]T                     @   s   d dl Z d dlZd dlZd dlmZ d dlmZ d dlmZ d,ddZd,dd	Z	d,d
dZ
d,ddZd-ddZd-ddZd-ddZd-ddZejjddddZd.ddZd/ddZddd d!d"Zd0d#d$Zd1d&d'Zd,d(d)Zd-d*d+ZdS )2    N)_routines_math)_fusion_thread_local)internalFc                 C   N   t  r|r
td|du rtj}ntj}t j|| |||dS | ||||S )a  Returns the sum of an array along given axes.

    Args:
        a (cupy.ndarray): Array to take sum.
        axis (int or sequence of ints): Axes along which the sum is taken.
        dtype: Data type specifier.
        out (cupy.ndarray): Output array.
        keepdims (bool): If ``True``, the specified axes are remained as axes
            of length one.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.sum`

    z3cupy.sum does not support `keepdims` in fusion yet.Naxisdtypeout)r   	is_fusingNotImplementedError_mathZsum_auto_dtypeZ_sum_keep_dtypecall_reductionsumar   r   r	   keepdimsfunc r   ^/home/app/PaddleOCR-VL-test/.venv_paddleocr/lib/python3.10/site-packages/cupy/_math/sumprod.pyr         
r   c                 C   r   )a  Returns the product of an array along given axes.

    Args:
        a (cupy.ndarray): Array to take product.
        axis (int or sequence of ints): Axes along which the product is taken.
        dtype: Data type specifier.
        out (cupy.ndarray): Output array.
        keepdims (bool): If ``True``, the specified axes are remained as axes
            of length one.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.prod`

    z4cupy.prod does not support `keepdims` in fusion yet.Nr   )r   r
   r   r   Z_prod_auto_dtypeZ_prod_keep_dtyper   prodr   r   r   r   r   +   r   r   c                 C   sd   t  r)|r
td| jjdv rtj}n|du rtj}ntj}t j	|| |||dS t
| ||||S )a  Returns the sum of an array along given axes treating Not a Numbers
    (NaNs) as zero.

    Args:
        a (cupy.ndarray): Array to take sum.
        axis (int or sequence of ints): Axes along which the sum is taken.
        dtype: Data type specifier.
        out (cupy.ndarray): Output array.
        keepdims (bool): If ``True``, the specified axes are remained as axes
            of length one.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.nansum`

    z6cupy.nansum does not support `keepdims` in fusion yet.ZFDNr   )r   r
   r   r   charr   Z_nansum_complex_dtypeZ_nansum_auto_dtypeZ_nansum_keep_dtyper   Z_nansumr   r   r   r   nansumK   s   
r   c                 C   sP   t  r|r
td|du rtj}ntj}t j|| |||dS t| ||||S )a  Returns the product of an array along given axes treating Not a Numbers
    (NaNs) as zero.

    Args:
        a (cupy.ndarray): Array to take product.
        axis (int or sequence of ints): Axes along which the product is taken.
        dtype: Data type specifier.
        out (cupy.ndarray): Output array.
        keepdims (bool): If ``True``, the specified axes are remained as axes
            of length one.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.nanprod`

    z7cupy.nanprod does not support `keepdims` in fusion yet.Nr   )r   r
   r   r   Z_nanprod_auto_dtypeZ_nanprod_keep_dtyper   Z_nanprodr   r   r   r   nanprodn   s   
r   c                 C      t | |t jj||S )a  Returns the cumulative sum of an array along a given axis.

    Args:
        a (cupy.ndarray): Input array.
        axis (int): Axis along which the cumulative sum is taken. If it is not
            specified, the input is flattened.
        dtype: Data type specifier.
        out (cupy.ndarray): Output array.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.cumsum`

    )r   	scan_corescan_opZSCAN_SUMr   r   r   r	   r   r   r   cumsum      r   c                 C   r   )a  Returns the cumulative product of an array along a given axis.

    Args:
        a (cupy.ndarray): Input array.
        axis (int): Axis along which the cumulative product is taken. If it is
            not specified, the input is flattened.
        dtype: Data type specifier.
        out (cupy.ndarray): Output array.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.cumprod`

    )r   r   r   Z	SCAN_PRODr   r   r   r   cumprod   r   r    c                 C      t | d|d} t| |||dS )a  Returns the cumulative sum of an array along a given axis treating Not a
    Numbers (NaNs) as zero.

    Args:
        a (cupy.ndarray): Input array.
        axis (int): Axis along which the cumulative sum is taken. If it is not
            specified, the input is flattened.
        dtype: Data type specifier.
        out (cupy.ndarray): Output array.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.nancumsum`
    r   r	   r   )_replace_nanr   r   r   r   r   	nancumsum      r$   c                 C   r!   )a  Returns the cumulative product of an array along a given axis treating
    Not a Numbers (NaNs) as one.

    Args:
        a (cupy.ndarray): Input array.
        axis (int): Axis along which the cumulative product is taken. If it is
            not specified, the input is flattened.
        dtype: Data type specifier.
        out (cupy.ndarray): Output array.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.nancumprod`
       r"   r   )r#   r    r   r   r   r   
nancumprod   r%   r'   z
T a, T valzT outz(if (a == a) {out = a;} else {out = val;}Zcupy_replace_nanc                 C   s.   |d u s
| j |j krt| }t| || |S N)r   cupy
empty_like_replace_nan_kernel)r   valr	   r   r   r   r#      s   
r#   r&   c                 C   sz  |dkr| S |dk rt dt| t| } | j}t||}g }|durFt|}|jdkrAt| j}d||< t	|t
|}|| ||  |durot|}|jdkrjt| j}d||< t	|t
|}|| t|dkr{t||} tdg| }tdg| }	tdd||< tdd|	|< t
|}t
|	}	| jtjkrtjntj}
t|D ]}|
| | | |	 } q| S )a1  Calculate the n-th discrete difference along the given axis.

    Args:
        a (cupy.ndarray): Input array.
        n (int): The number of times values are differenced. If zero, the input
            is returned as-is.
        axis (int): The axis along which the difference is taken, default is
            the last axis.
        prepend (int, float, cupy.ndarray): Value to prepend to ``a``.
        append (int, float, cupy.ndarray): Value to append to ``a``.

    Returns:
        cupy.ndarray: The result array.

    .. seealso:: :func:`numpy.diff`
    r   z#order must be non-negative but got Nr&   r-   )
ValueErrorreprr)   
asanyarrayndimr   Z_normalize_axis_indexlistshapeZbroadcast_totupleappendlenZconcatenateslicer   numpyZbool_	not_equalsubtractrange)r   nr   prependr5   ndcombinedr3   slice1slice2op_r   r   r   diff   sJ   










rD   )r   
edge_orderc                G   st  t | } | j}tj||dd}t|}t|}|dkr"dg| }nm|dkr4t |d dkr4|| }n[||krt|}t|D ]I\}	}
t |
dkrLq@t |
dkrWtdt|
| j	||	  krftdt
|
jt
jrt|
t
j}
t |
}||d k r|d }|||	< q@ntd|d	krtd
g }tdg| }tdg| }tdg| }tdg| }| j}t
|t
jrnt
|t
jr| t
j} t
j}t||D ]\}}| j	| |d k rtdt j| |d}t |dk}tdd||< tdd||< tdd||< td	d||< |r)| t| | t|  d|  |t|< nU|dd }|dd }|| }| ||  }|| ||  }|||  }dg| }d||< t| |_	 |_	|_	|| t|  || t|   || t|   |t|< |dkrd||< d||< d||< |r|n|d }| t| | t|  | |t|< d||< d||< d||< |r|n|d }| t| | t|  | |t|< nd||< d||< d||< d	||< |rd| }d| }d| }n$|d }|d }|| }d| |  ||  }|||  }| ||  }|| t|  || t|   || t|   |t|< d||< d||< d||< d||< |rRd| }d| }d| }n#|d }|d }|| }|||  }| ||  }d| | ||  }|| t|  || t|   || t|   |t|< || td||< td||< td||< td||< q|dkr|d S |S )a  Return the gradient of an N-dimensional array.

    The gradient is computed using second order accurate central differences
    in the interior points and either first or second order accurate one-sides
    (forward or backwards) differences at the boundaries.
    The returned gradient hence has the same shape as the input array.

    Args:
        f (cupy.ndarray): An N-dimensional array containing samples of a scalar
            function.
        varargs (list of scalar or array, optional): Spacing between f values.
            Default unitary spacing for all dimensions. Spacing can be
            specified using:

            1. single scalar to specify a sample distance for all dimensions.
            2. N scalars to specify a constant sample distance for each
               dimension. i.e. `dx`, `dy`, `dz`, ...
            3. N arrays to specify the coordinates of the values along each
               dimension of F. The length of the array must match the size of
               the corresponding dimension
            4. Any combination of N scalars/arrays with the meaning of 2. and
               3.

            If `axis` is given, the number of varargs must equal the number of
            axes. Default: 1.
        edge_order ({1, 2}, optional): The gradient is calculated using N-th
            order accurate differences at the boundaries. Default: 1.
        axis (None or int or tuple of ints, optional): The gradient is
            calculated only along the given axis or axes. The default
            (axis = None) is to calculate the gradient for all the axes of the
            input array. axis may be negative, in which case it counts from the
            last to the first axis.

    Returns:
        gradient (cupy.ndarray or list of cupy.ndarray): A set of ndarrays
        (or a single ndarray if there is only one dimension) corresponding
        to the derivatives of f with respect to each dimension. Each
        derivative has the same shape as f.

    .. seealso:: :func:`numpy.gradient`
    F)Z	sort_axesr         ?r&   z&distances must be either scalars or 1dzGwhen 1d, distances must match the length of the corresponding dimensionzinvalid number of arguments   z)'edge_order' greater than 2 not supportedNzlShape of array too small to calculate a numerical gradient, at least (edge_order + 1) elements are required.r   r-          @g      g      g      ?g       g      ?)r)   r0   r1   r   Z_normalize_axis_indicesr6   r2   	enumerater.   r3   r8   Z
issubdtyper   integerZastypeZfloat64rD   all	TypeErrorr7   Zinexactzipr*   r4   r5   )fr   rE   varargsr1   ZaxesZlen_axesr<   dxiZ	distancesZdiffxZoutvalsr@   rA   Zslice3Zslice4ZotypeZax_dxr	   Zuniform_spacingZdx1Zdx2Zdx_sumr   bcr3   Zdx_0Zdx_nr   r   r   gradient*  s   
*




$&



rW   c                 C   sb  t | tjs
td|  } | j}|du r%|du r%| dd | dd  S |du r,d}nt |tjs6tdtj||ddsBtd	| }t|}|du rQd}nt |tjs[td
tj||ddsgtd| }t|}tt| d d}tj	|| | | jd}|dkr||d|< |dkr|||| d< t
| dd | dd ||||   |S )a  
    Calculates the difference between consecutive elements of an array.

    Args:
        arr (cupy.ndarray): Input array.
        to_end (cupy.ndarray, optional): Numbers to append at the end
            of the returned differences.
        to_begin (cupy.ndarray, optional): Numbers to prepend at the
            beginning of the returned differences.

    Returns:
        cupy.ndarray: New array consisting differences among succeeding
        elements.

    .. seealso:: :func:`numpy.ediff1d`
    z$`arr` should be of type cupy.ndarrayNr&   r-   r   z)`to_begin` should be of type cupy.ndarrayZ	same_kind)ZcastingzSdtype of `to_begin` must be compatible with input `arr` under the `same_kind` rule.z'`to_end` should be of type cupy.ndarrayzQdtype of `to_end` must be compatible with input `arr` under the `same_kind` rule.rH   )
isinstancer)   ndarrayrO   Zravelr   Zcan_castr6   maxemptyr:   )ZarrZto_endZto_beginZ	dtype_reqZl_beginZl_endZl_diffresultr   r   r   ediff1d   s<   *r]   rF   c                 C   s  t | tjs
td|du r|}n,t |tjstd|jdkr7t|}dg| j }|jd ||< ||}nt||d}| j}tdg| }tdg| }tdd||< tdd||< || t	| | t	|   d }	z|	
|}
W |
S  ty   tj|	|}
Y |
S w )	a  
    Integrate along the given axis using the composite trapezoidal rule.
    Integrate `y` (`x`) along the given axis.

    Args:
        y (cupy.ndarray): Input array to integrate.
        x (cupy.ndarray): Sample points over which to integrate. If None equal
            spacing `dx` is assumed.
        dx (float): Spacing between sample points, used if `x` is None, default
            is 1.
        axis (int): The axis along which the integral is taken, default is
            the last axis.

    Returns:
        cupy.ndarray: Definite integral as approximated by the trapezoidal
        rule.

    .. seealso:: :func:`numpy.trapz`
    z"`y` should be of type cupy.ndarrayNz"`x` should be of type cupy.ndarrayr&   r   )r   r-   rJ   )rX   r)   rY   rO   r1   rD   r3   Zreshaper7   r4   r   r.   addreduce)yxrS   r   dr3   r>   r@   rA   productretr   r   r   trapzF  s2   
 re   c                 C   s   t dt t| ||||S )NzPlease use `prod` instead.)warningswarnDeprecationWarningr   )r   r   r   r	   r   r   r   r   rc   w  s   rc   c                 C   s   t dt t| |||S )NzPlease use `cumprod` instead.)rf   rg   rh   r    r   r   r   r   
cumproduct|  s   ri   )NNNF)NNNr(   )r&   r-   NN)NN)NrF   r-   )rf   r8   r)   Z
cupy._corer   r   r   r   r   r   r   r   r   r    r$   r'   Z_coreZ_kernelZElementwiseKernelr+   r#   rD   rW   r]   re   rc   ri   r   r   r   r   <module>   s4    

 
 
#
!




A 
W
F
1