o
    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_mathsum_auto_dtype_sum_keep_dtypecall_reductionsumar   r   r	   keepdimsfunc r   O/home/ubuntu/veenaModal/venv/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   _prod_auto_dtype_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.FDNr   )r   r
   r   r   charr   _nansum_complex_dtype_nansum_auto_dtype_nansum_keep_dtyper   _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   _nanprod_auto_dtype_nanprod_keep_dtyper   _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_op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(   	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      r2   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`
       r0   r   )r1   r.   r*   r   r   r   
nancumprod   r3   r5   z
T a, T valzT outz(if (a == a) {out = a;} else {out = val;}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   r1      s   
r1   r4   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 Nr4   r<   )
ValueErrorreprr8   
asanyarrayndimr   _normalize_axis_indexlistshapebroadcast_totupleappendlenconcatenateslicer   numpybool_	not_equalsubtractrange)r   nr   prependrF   ndcombinedrC   slice1slice2op_r   r   r   diff   sJ   










rW   )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)	sort_axesr         ?r4   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      ?)r8   r?   r@   r   _normalize_axis_indicesrG   rB   	enumerater=   rC   rJ   
issubdtyper   integerastypefloat64rW   all	TypeErrorrI   inexactzipr9   rE   rF   )fr   rX   varargsr@   axeslen_axesrO   dxi	distancesdiffxoutvalsrS   rT   slice3slice4otypeax_dxr	   uniform_spacingdx1dx2dx_sumr   bcrC   dx_0dx_nr   r   r   gradient*  s   
*




$&



r   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.ndarrayNr4   r<   r   z)`to_begin` should be of type cupy.ndarray	same_kind)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.r\   )
isinstancer8   ndarrayrg   ravelr   can_castrG   maxemptyrM   )arrto_endto_begin	dtype_reql_beginl_endl_diffresultr   r   r   ediff1d   s<   *r   rZ   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.ndarrayr4   r   )r   r<   r^   )r   r8   r   rg   r@   rW   rC   reshaperI   rE   r   r=   addreduce)yxrn   r   drC   rQ   rS   rT   productretr   r   r   trapzF  s2   
 r   c                 C   s   t dt t| ||||S )NzPlease use `prod` instead.)warningswarnDeprecationWarningr   )r   r   r   r	   r   r   r   r   r   w  s   r   c                 C   s   t dt t| |||S )NzPlease use `cumprod` instead.)r   r   r   r.   r*   r   r   r   
cumproduct|  s   r   )NNNF)NNNr7   )r4   r<   NN)NN)NrZ   r<   )r   rJ   r8   
cupy._corer   r   r   r   r   r   r!   r%   r+   r.   r2   r5   _core_kernelElementwiseKernelr:   r1   rW   r   r   r   r   r   r   r   r   r   <module>   s4    

 
 
#
!




A 
W
F
1