o
    iP                     @   s   d dl Z d dlZd dlZd dlZd dlmZ eZeddddZeddd	d
Z	dd Z
dd Zdd Zd$ddZd$ddZd%ddZeddddZeddddZd&d d!Zd'd"d#ZdS )(    N)_corezS x, raw T bins, int32 n_binszraw U yaD  
    if (x < bins[0] or bins[n_bins - 1] < x) {
        return;
    }
    int high = n_bins - 1;
    int low = 0;

    while (high - low > 1) {
        int mid = (high + low) / 2;
        if (bins[mid] <= x) {
            low = mid;
        } else {
            high = mid;
        }
    }
    atomicAdd(&y[low], U(1));
    cupy_histogram_kernelz,S x, raw T bins, int32 n_bins, raw W weightszraw Y yaM  
    if (x < bins[0] or bins[n_bins - 1] < x) {
        return;
    }
    int high = n_bins - 1;
    int low = 0;

    while (high - low > 1) {
        int mid = (high + low) / 2;
        if (bins[mid] <= x) {
            low = mid;
        } else {
            high = mid;
        }
    }
    atomicAdd(&y[low], (Y)weights[i]);
    cupy_weighted_histogram_kernelc                 C   s|   | j tjkrtjd| j tjtdd | tj} |dur6t	|tj
s(td|j| jkr2td| }|  } | |fS )z: Check a and weights have matching shapes, and ravel both z1Converting input from {} to {} for compatibility.   )
stacklevelNzweights must be a cupy.ndarrayz(weights should have the same shape as a.)dtypecupybool_warningswarnformatuint8RuntimeWarningastype
isinstancendarray
ValueErrorshaperavel)aweights r   W/home/ubuntu/veenaModal/venv/lib/python3.10/site-packages/cupy/_statistics/histogram.py_ravel_and_check_weights=   s    r   c                 C   s   |dur#|\}}||krt dt|rt|s"t d||n(| jdkr-d}d}nt|  }t|  }t|rCt|sKt d||||krW|d }|d }||fS )	z^
    Determine the outer bin edges to use, from either the data or the range
    argument
    Nz/max must be larger than min in range parameter.z(supplied range of [{}, {}] is not finiter   g        g      ?z,autodetected range of [{}, {}] is not finiteg      ?)	r   numpyisfiniter   sizefloatminmaxr   )r   range
first_edge	last_edger   r   r   _get_outer_edgesR   s8   
r#   c                 C   s4  d}d}t |trtdt |tjst|dkrFt |tjr#|}nt|}|dd |dd k r:t	dt |tjrEt|}n.t|dkrpzt
|}W n ty_   tdw |dk rht	dt| |\}}nt	d	|durt||| }t|tjrt|t}tj|||d d
|d}|S )a5  
    Computes the bins used internally by `histogram`.

    Args:
        a (ndarray): Ravelled data array
        bins (int or ndarray): Forwarded argument from `histogram`.
        range (None or tuple): Forwarded argument from `histogram`.

    Returns:
        bin_edges (ndarray): Array of bin edges
    Nz+only integer and array bins are implemented   z1`bins` must increase monotonically, when an arrayr   z0`bins` must be an integer, a string, or an arrayz(`bins` must be positive, when an integerz `bins` must be 1d, when an arrayT)endpointr   )r   strNotImplementedErrorr   r   r   ndimasarrayanyr   operatorindex	TypeErrorr#   result_type
issubdtypeintegerr   linspace)r   binsr    n_equal_bins	bin_edgesr!   r"   bin_typer   r   r   _get_bin_edgess   sL   



r7   
   Fc           	      C   sl  | j jdkr
tdt| tjstdt| |\} }t| ||}|du r9tj	|j
d tjd}t| ||j
| nct|j tjpHt|j tj}|sOtd|j jdkrwtj	|j
d tjd}t| ||j
|j|j t| ||j
|j|j n%|j jdv rtj	|j
d td}ntj	|j
d tjd}t| ||j
|| |rtt|tj}|| |  |fS ||fS )	a3  Computes the histogram of a set of data.

    Args:
        x (cupy.ndarray): Input array.
        bins (int or cupy.ndarray): If ``bins`` is an int, it represents the
            number of bins. If ``bins`` is an :class:`~cupy.ndarray`, it
            represents a bin edges.
        range (2-tuple of float, optional): The lower and upper range of the
            bins.  If not provided, range is simply ``(x.min(), x.max())``.
            Values outside the range are ignored. The first element of the
            range must be less than or equal to the second. `range` affects the
            automatic bin computation as well. While bin width is computed to
            be optimal based on the actual data within `range`, the bin count
            will fill the entire range including portions containing no data.
        density (bool, optional): If False, the default, returns the number of
            samples in each bin. If True, returns the probability *density*
            function at the bin, ``bin_count / sample_count / bin_volume``.
        weights (cupy.ndarray, optional): An array of weights, of the same
            shape as `x`.  Each value in `x` only contributes its associated
            weight towards the bin count (instead of 1).
    Returns:
        tuple: ``(hist, bin_edges)`` where ``hist`` is a :class:`cupy.ndarray`
        storing the values of the histogram, and ``bin_edges`` is a
        :class:`cupy.ndarray` storing the bin edges.

    .. warning::

        This function may synchronize the device.

    .. seealso:: :func:`numpy.histogram`
    czcomplex number is not supportedzx must be a cupy.ndarrayNr$   r   zJonly weights with dtype that can be cast to float or complex are supportedbui)r   kindr(   r   r   r   r   r   r7   zerosr   int64_histogram_kernelcan_castfloat64
complex128_weighted_histogram_kernelrealimagintarraydiffsum)	xr3   r    r   densityr5   ysimple_weightsdbr   r   r   	histogram   sD   !rO   c                    s  t tjrjdkrddtjf j\}}ntjddj\}}t|t	}|dg  |dg }|dur?t
|}zt|}	|	|krLtdW n ty[   ||g }Y nw |du red| }n
t||krotdt|D ]}
t||
 dkr||
 dk rtd	|
tdd|
f ||
 \}}t	||
 d }t||| |
< n<t||
 dkrt ||
 tjstd
||
  |
<  |
 dd  |
 dd k rtd|
ntd|
t |
 d ||
< t |
 ||
< qst fddt|D }t|D ]}
dd|
f  |
 d k}||
 |  d8  < qt||}tj||t|d}||}|t}|tddf }|| }|rz| }t|D ]}
dg| }||
 d ||
< |||
 | }q\|| }t|jt
|d krtd| fS )a  Compute the multidimensional histogram of some data.

    Args:
        sample (cupy.ndarray): The data to be histogrammed. (N, D) or (D, N)
            array

            Note the unusual interpretation of sample when an array_like:

            * When an array, each row is a coordinate in a D-dimensional
              space - such as ``histogramdd(cupy.array([p1, p2, p3]))``.
            * When an array_like, each element is the list of values for single
              coordinate - such as ``histogramdd((X, Y, Z))``.

            The first form should be preferred.
        bins (int or tuple of int or cupy.ndarray): The bin specification:

            * A sequence of arrays describing the monotonically increasing bin
              edges along each dimension.
            * The number of bins for each dimension (nx, ny, ... =bins)
            * The number of bins for all dimensions (nx=ny=...=bins).
        range (sequence, optional): A sequence of length D, each an optional
            (lower, upper) tuple giving the outer bin edges to be used if the
            edges are not given explicitly in `bins`. An entry of None in the
            sequence results in the minimum and maximum values being used for
            the corresponding dimension. The default, None, is equivalent to
            passing a tuple of D None values.
        weights (cupy.ndarray): An array of values `w_i` weighing each sample
            `(x_i, y_i, z_i, ...)`. The values of the returned histogram are
            equal to the sum of the weights belonging to the samples falling
            into each bin.
        density (bool, optional): If False, the default, returns the number of
            samples in each bin. If True, returns the probability *density*
            function at the bin, ``bin_count / sample_count / bin_volume``.

    Returns:
        tuple:
        H (cupy.ndarray):
            The multidimensional histogram of sample x. See
            normed and weights for the different possible semantics.
        edges (list of cupy.ndarray):
            A list of D arrays describing the bin
            edges for each dimension.

    .. warning::

        This function may synchronize the device.

    .. seealso:: :func:`numpy.histogramdd`
    r$   Nr%   )axiszFThe dimension of bins must be equal to the dimension of the  sample x.)Nz0range argument must have one entry per dimensionr   z,`bins[{}]` must be positive, when an integerzarray-like bins not supportedz:`bins[{}]` must be monotonically increasing, when an arrayz'`bins[{}]` must be a scalar or 1d arrayc                 3   s0    | ]}t j | d d |f ddV  qd S )Nright)side)r   searchsorted).0iedgessampler   r   	<genexpr>k  s
    
zhistogramdd.<locals>.<genexpr>)	minlength   zInternal Shape Error)r   r   r   r)   newaxisr   stackr   emptyrF   r*   lenr   r.   _ranger   r#   r2   r+   rH   tupleravel_multi_indexbincountprodreshaper   r   slicerI   RuntimeError)rX   r3   r    r   rK   nsamplesr)   nbindedgesnbinsrU   sminsmaxnumncounton_edgexyhistcoresr   r   rV   r   histogramdd   s   2





$	


ru   c                 C   s   zt |}W n ty   d}Y nw |dkr-|dkr-t|tjr)| }}||g}ntdt| |g||||\}	}
|	|
d |
d fS )a  Compute the bi-dimensional histogram of two data samples.

    Args:
        x (cupy.ndarray): The first array of samples to be histogrammed.
        y (cupy.ndarray): The second array of samples to be histogrammed.
        bins (int or tuple of int or cupy.ndarray): The bin specification:

            * A sequence of arrays describing the monotonically increasing bin
              edges along each dimension.
            * The number of bins for each dimension (nx, ny)
            * The number of bins for all dimensions (nx=ny=bins).
        range (sequence, optional): A sequence of length two, each an optional
            (lower, upper) tuple giving the outer bin edges to be used if the
            edges are not given explicitly in `bins`. An entry of None in the
            sequence results in the minimum and maximum values being used for
            the corresponding dimension. The default, None, is equivalent to
            passing a tuple of two None values.
        weights (cupy.ndarray): An array of values `w_i` weighing each sample
            `(x_i, y_i)`. The values of the returned histogram are equal to the
            sum of the weights belonging to the samples falling into each bin.
        density (bool, optional): If False, the default, returns the number of
            samples in each bin. If True, returns the probability *density*
            function at the bin, ``bin_count / sample_count / bin_volume``.

    Returns:
        tuple:
        H (cupy.ndarray):
            The multidimensional histogram of sample x. See
            normed and weights for the different possible semantics.
        edges0 (tuple of cupy.ndarray):
            A list of D arrays describing the bin
            edges for the first dimension.
        edges1 (tuple of cupy.ndarray):
            A list of D arrays describing the bin
            edges for the second dimension.

    .. warning::

        This function may synchronize the device.

    .. seealso:: :func:`numpy.histogram2d`
    r$   r[   z%array-like bins not supported in CuPyr   )r_   r.   r   r   r   r   ru   )rJ   rL   r3   r    r   rK   nxedgesyedgesrr   rW   r   r   r   histogram2d  s   +
ry   zS xz	raw U binzatomicAdd(&bin[x], U(1))cupy_bincount_kernelzS x, T wzatomicAdd(&bin[x], w) cupy_bincount_with_weight_kernelc                 C   s   | j dkr	td| j dk rtd| jjdkrtd| dk  r&td|dur4| j|jkr4td	|durDt|}|dk rDtd
tt	| d }|durVt	||}|du rjtj
|ftjd}t| | |S tj
|ftjd}t| || |S )a,  Count number of occurrences of each value in array of non-negative ints.

    Args:
        x (cupy.ndarray): Input array.
        weights (cupy.ndarray): Weights array which has the same shape as
            ``x``.
        minlength (int): A minimum number of bins for the output array.

    Returns:
        cupy.ndarray: The result of binning the input array. The length of
        output is equal to ``max(cupy.max(x) + 1, minlength)``.

    .. warning::

        This function may synchronize the device.

    .. seealso:: :func:`numpy.bincount`

    r$   !object too deep for desired array+object of too small depth for desired arrayfzx must be int arrayr   z3The first argument of bincount must be non-negativeNz0The weights and list don't have the same length.zminlength must be non-negativer:   )r)   r   r   r<   r.   r+   r   rF   r   r   r=   r   intp_bincount_kernelrA   _bincount_with_weight_kernel)rJ   r   rZ   r   br   r   r   rc     s0   



rc   c                 C   sZ   | j jdkr
td|jdkrtd|jdk rtd|r dnd}tjj|| |dd	S )
a~  Finds the indices of the bins to which each value in input array belongs.

    .. note::

        In order to avoid device synchronization, digitize does not raise
        an exception when the array is not monotonic

    Args:
        x (cupy.ndarray): Input array.
        bins (cupy.ndarray): Array of bins.
            It has to be 1-dimensional and monotonic increasing or decreasing.
        right (bool):
            Indicates whether the intervals include the right or the left bin
            edge.

    Returns:
        cupy.ndarray: Output array of indices, of same shape as ``x``.

    .. seealso:: :func:`numpy.digitize`
    r9   zx may not be complexr$   r|   r}   leftrQ   NF)	r   r<   r.   r)   r   r   _sortingsearch_searchsorted)rJ   r3   rQ   rR   r   r   r   digitize  s   

r   )r8   NNF)r8   NNN)NN)F)r,   r
   r   r   r   r    r`   ElementwiseKernelr?   rC   r   r#   r7   rO   ru   ry   r   r   rc   r   r   r   r   r   <module>   sJ    !
;
O 
;
4