
    `ip                        d dl Z d dlZd dlZd dlmZ d dlmZ d0dZd Zd Zd Zd Z	d	 Z
d
 Zd Z ej        dddd          Z ej        dddd          Zd1dZ ej        dddd          Z	 	 d2dZd3dZd0dZd0dZd0dZd0dZd0dZd  Zd! Zd" Zd# Z	 	 	 d4d$Zd0d%Zd0d&Zd0d'Z d0d(Z!d0d)Z"d0d*Z#d0d+Z$	 d5d,Z%d0d-Z&ddd.d/Z'dS )6    N)_core)_utilc                 ^   t          | t          j                  st          d          | j        j        dv rt          d          |t          | j        d          }n.t          |t          j                  rt          j        |          }t          j
        |t                    }|j        | j        k    rt          d          |j        D ]}|dk    rt          d	          t          |t          j                  r"|j        | j        k    rt          d
          d}nCd}|%t          j        | j        t          j                  }nt          j        | j        |          }| j        dk    rd}n| j        dk    r2|                                 dk    rdnd}|                    |           nw|j        t          j        k    r%t          j        | j        t          j                  }n|}t)          | ||          }|j        t          j        k    rt+          j        ||           |r|S ||fS )a  Labels features in an array.

    Args:
        input (cupy.ndarray): The input array.
        structure (array_like or None): A structuring element that defines
            feature connections. ```structure``` must be centersymmetric. If
            None, structure is automatically generated with a squared
            connectivity equal to one.
        output (cupy.ndarray, dtype or None): The array in which to place the
            output.
    Returns:
        label (cupy.ndarray): An integer array where each unique feature in
        ```input``` has a unique label in the array.

        num_features (int): Number of features found.

    .. warning::

        This function may synchronize the device.

    .. seealso:: :func:`scipy.ndimage.label`
    input must be cupy.ndarrayFDzComplex type not supportedN   dtypez(structure and input must have equal rank   z'structure dimensions must be equal to 3zoutput shape not correctTFr   )
isinstancecupyndarray	TypeErrorr
   char_generate_binary_structurendimasnumpynumpyarrayboolRuntimeErrorshape
ValueErroremptyint32sizeitemfill_labelr   elementwise_copy)input	structureoutputicaller_provided_outputmaxlabelys          u/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/cupyx/scipy/ndimage/_measurements.pylabelr)   
   s   . eT\** 64555{44555.uz1==			It|	,	, ,L++	IT222I~##EFFF_ H H66FGGG  &$,'' 	5<5;&&7888!%!&>ZU[99FFZV44FzQ	q

))11qH<5;&&
5;44AAA%A..<5;&&"1f---  x    c                     |dk     rd}| dk     rt          j        dt                    S t          j        t          j        dg| z            dz
            }t           j                            |d          }||k    S )Nr   Tr	   r   r   )r   r   r   fabsindicesaddreduce)rankconnectivityr#   s      r(   r   r   Q   sv    aaxx{4t,,,,ZqcDj11A566FYfa((F\!!r*   c                     t          j        |dk              fdt           j                  D             d         }t          d j                  D ]}|dz  |         z   }t          j        |dk               d         } fd|D             }t	          j        |t           j                  }|j        d         }t	          j        |j        t           j                  }t	          j        dt           j                  }	 t                       |            t                      ||| j        ||j                    t                      ||	|j                   t          |	d                   }
t	          j        |
t           j                  } t                      ||	||j                    t!                      |
t	          j        |          ||j                   |
S )	Nr   c                 &    g | ]}|         d z
  S r    ).0dmelemss     r(   
<listcomp>z_label.<locals>.<listcomp>]   s!    222bE"IM222r*   r   r   c                 T    g | ]#fd t          j                  D             $S )c                 ,    g | ]}|                  S r5   r5   )r6   r7   drvecss     r(   r9   z%_label.<locals>.<listcomp>.<listcomp>b   s!    222bT"Xb\222r*   )ranger   )r6   r<   r=   xs    @r(   r9   z_label.<locals>.<listcomp>b   s:    CCCr22222E!&MM222CCCr*   r	      )r   )r   wherer>   r   r   r   r   r   zeros_kernel_init_kernel_connectr   _kernel_countintr   _kernel_labels_kernel_finalizesort)r?   r"   r'   offsetr7   indxsdirsndirsy_shapecountr&   labelsr8   r=   s   `           @@r(   r   r   [   s   K	Q''E2222E!&MM222D!WFAqv ' '!d2h&K
##A&ECCCCCUCCCD:d%+...DKNEj444GJq,,,ELNN1aOgtUAFAAFCCCCMOOAu16****58}}HZ444FNQvAF3333x6!2!2AAFCCCCOr*   c                  0    t          j        dddd          S )NzX xzY yz'if (x == 0) { y = -1; } else { y = i; }cupyx_scipy_ndimage_label_initr   ElementwiseKernelr5   r*   r(   rC   rC   q   s"    "u?(* * *r*   c                  0    t          j        dddd          S )Nz8raw int32 shape, raw int32 dirs, int32 ndirs, int32 ndimzraw Y yaq  
        if (y[i] < 0) continue;
        for (int dr = 0; dr < ndirs; dr++) {
            int j = i;
            int rest = j;
            int stride = 1;
            int k = 0;
            for (int dm = ndim-1; dm >= 0; dm--) {
                int pos = rest % shape[dm] + dirs[dm + dr * ndim];
                if (pos < 0 || pos >= shape[dm]) {
                    k = -1;
                    break;
                }
                k += pos * stride;
                rest /= shape[dm];
                stride *= shape[dm];
            }
            if (k < 0) continue;
            if (y[k] < 0) continue;
            while (1) {
                while (j != y[j]) { j = y[j]; }
                while (k != y[k]) { k = y[k]; }
                if (j == k) break;
                if (j < k) {
                    int old = atomicCAS( &y[k], k, j );
                    if (old == k) break;
                    k = old;
                }
                else {
                    int old = atomicCAS( &y[j], j, k );
                    if (old == j) break;
                    j = old;
                }
            }
        }
        !cupyx_scipy_ndimage_label_connectrS   r5   r*   r(   rD   rD   w   s)    "B#	H 	,O'- '- '-r*   c                  0    t          j        dddd          S )N zraw Y y, raw int32 countz
        if (y[i] < 0) continue;
        int j = i;
        while (j != y[j]) { j = y[j]; }
        if (j != i) y[i] = j;
        else atomicAdd(&count[0], 1);
        cupyx_scipy_ndimage_label_countrS   r5   r*   r(   rE   rE      s'    "
&	 	*	+ 	+ 	+r*   c                  0    t          j        dddd          S )NrX   z*raw Y y, raw int32 count, raw int32 labelszj
        if (y[i] != i) continue;
        int j = atomicAdd(&count[1], 1);
        labels[j] = i;
         cupyx_scipy_ndimage_label_labelsrS   r5   r*   r(   rG   rG      s'    "
8	
 	+, , ,r*   c                  0    t          j        dddd          S )Nzint32 maxlabelzraw int32 labels, raw Y ya  
        if (y[i] < 0) {
            y[i] = 0;
            continue;
        }
        int yi = y[i];
        int j_min = 0;
        int j_max = maxlabel - 1;
        int j = (j_min + j_max) / 2;
        while (j_min < j_max) {
            if (yi == labels[j]) break;
            if (yi < labels[j]) j_max = j - 1;
            else j_min = j + 1;
            j = (j_min + j_max) / 2;
        }
        y[i] = j + 1;
        "cupyx_scipy_ndimage_label_finalizerS   r5   r*   r(   rH   rH      s'    "5	" 	-'. . .r*   z=T input, R labels, raw X index, uint64 size, raw float64 meanzraw float64 outz
    for (ptrdiff_t j = 0; j < size; j++) {
      if (labels == index[j]) {
        atomicAdd(&out[j], (input - mean[j]) * (input - mean[j]));
        break;
      }
    }
    cupyx_scipy_ndimage_variancez+T input, R labels, raw X index, uint64 sizez
    for (ptrdiff_t j = 0; j < size; j++) {
      if (labels == index[j]) {
        atomicAdd(&out[j], input);
        break;
      }
    }
    cupyx_scipy_ndimage_sum   c                 D   t          d|j        |          D ]}|||||z                                dd| j        z  z             k    }t	          t          dd| j        z                       }t          j        || d                              |          ||||z   <   |S )Nr   r4   r   axis)r>   r   reshaper   tupler   rA   sum)r!   rP   indexsum_val
batch_sizer$   matchedsum_axess           r(   _ndimage_sum_kernel_2rn      s    1ej*--  E!A
N"23;;D5:%%' ' 'q!ej.1122$(Jwq$A$A$E$E %F % %!j. !!Nr*   z!raw float64 out, raw uint64 countz
    for (ptrdiff_t j = 0; j < size; j++) {
      if (labels == index[j]) {
        atomicAdd(&out[j], input);
        atomicAdd(&count[j], 1);
        break;
      }
    }
    cupyx_scipy_ndimage_meanFc                    t          j        |t           j                  }t          j        |t           j                  }t	          d|j        |          D ]}|||||z                                dd| j        z  z             k    }t          t	          dd| j        z                       }	|	                    |	          ||||z   <   t          j
        || d          	                    |	          ||||z   <   |r||z  |fS ||z  S )Nr	   r   rb   r4   r   rd   )r   
empty_likefloat64uint64r>   r   rf   r   rg   rh   rA   )
r!   rP   ri   rk   return_countrj   rO   r$   rl   	mean_axess
             r(   _ndimage_mean_kernel_2rv     s    oe4<888GOE555E1ej*--  E!A
N"23;;D5:%%' ' '%1uz>2233	")++9+"="=aJ$(Jwq$A$A$E$E %F % %!j. !! &%%U?r*   c                     |rt          | |||          S t          j        |t          j                  }t          j        |t          j                  }t          | |||j        ||          \  }}|r||z  |fS ||z  S )N)rt   r	   )rv   r   
zeros_likerr   rs   _ndimage_mean_kernelr   )r!   rP   ri   rt   use_kernoutrO   rh   s           r(   _mean_driverr|     s     A%eVU3?A A A 	A /%
.
.COE555E%e&,eUZeM MJC "U{E!!;r*   c           	         t          | t          j                  st          d          | j        t          j        t          j        fv r,t          d                    | j        j                            d}| j        t          j	        t          j
        t          j        t          j        t          j        t          j        t          j        fvr*t!          j        d| j         dt$          j                   d}d }| ||           S t          |t          j                  st          d	          t          j        | |          \  } }| || |d
k                       S t          j        |          r || ||k                       S t          |t          j                  sat          |t,                    st          d          | ||k                                                                 t          j        d          S t3          | ||d|          \  }}|rdgd t5          | j                  D             R }t          j        |d         ||         k    t          j        | ||         z
            d
                              t?          t5          d| j        dz                                 |z  S t          j         |t          j                  }tC          | |||j"        ||          |z  S )at  Calculates the variance of the values of an n-D image array, optionally
    at specified sub-regions.

    Args:
        input (cupy.ndarray): Nd-image data to process.
        labels (cupy.ndarray or None): Labels defining sub-regions in `input`.
            If not None, must be same shape as `input`.
        index (cupy.ndarray or None): `labels` to include in output. If None
            (default), all values where `labels` is non-zero are used.

    Returns:
        cupy.ndarray: Values of variance, for each sub-region if
        `labels` and `index` are specified.

    .. seealso:: :func:`scipy.ndimage.variance`
    r   z0cupyx.scipy.ndimage.variance doesn't support %{}Fz:Using the slower implementation because the provided type z is not supported by cupyx.scipy.ndimage.sum. Consider using an array of type int32, float16, float32, float64, uint32, uint64 as data types for the fast implementationTc                     | |                                  z
  }|j        }t          j        |                                          t          j        |                              t                    z  S N)meanr   r   squarerh   
asanyarrayastypefloat)r!   vals_crO   s      r(    calc_var_with_intermediate_floatz2variance.<locals>.calc_var_with_intermediate_floatI  sV    % {6""&&((4?5+A+A+H+H+O+OOOr*   Nlabel must be cupy.ndarrayr   *index must be cupy.ndarray or a scalar intcopy.c              3   .   K   | ]}t           j        V  d S r   )r   newaxis)r6   _s     r(   	<genexpr>zvariance.<locals>.<genexpr>g  s$      CCA4<CCCCCCr*   )N.r   r	   )#r   r   r   r   r
   	complex64
complex128formattyper   float16float32rr   uint32rs   	ulonglongwarningswarnr   PerformanceWarningbroadcast_arraysisscalarrF   varr   r|   r>   r   rA   r   rh   rg   rx   _ndimage_variance_kernelr   )	r!   rP   ri   rz   r   mean_valrO   new_axisr{   s	            r(   variancer   $  s   " eT\** 64555{t~t777 !6%+"2335 5 	5 H{4:t|T\<dk>+ + + 	*K* * * ,1+C	E 	E 	E P P P ~//666fdl++ 64555)%88ME6}//fqj0ABBB}U H//fo0FGGGeT\** E%%% 	EHIII&E/*//1188>C 9 E E E #5&%xHHOHe JDCCuz1B1BCCCDDz&+uX>+ehx.@&@AA  SuQ
Q'?'?!@!@AAEJ 	J /%t|
4
4
4C#E65%*h$') )+01 1r*   c                    t          | t          j                  st          d          | j        t          j        t          j        fv r,t          d                    | j        j                            d}| j        t          j	        t          j
        t          j        t          j        t          j        t          j        t          j        fvr!t!          j        dt$          j                   d}||                                 S t          |t          j                  st          d          t          j        | |          \  } }|| |dk                                             S t          |t          j                  sBt          |t,                    st          d	          | ||k                                             S |j        dk    r t          j        g t          j        
          S t          j        |t          j        
          }| j        dk    r|j        dk    s|rt7          | |||          S t9          | |||j        |          S )as  Calculates the sum of the values of an n-D image array, optionally
       at specified sub-regions.

    Args:
        input (cupy.ndarray): Nd-image data to process.
        labels (cupy.ndarray or None): Labels defining sub-regions in `input`.
            If not None, must be same shape as `input`.
        index (cupy.ndarray or None): `labels` to include in output. If None
            (default), all values where `labels` is non-zero are used.

    Returns:
       sum (cupy.ndarray): sum of values, for each sub-region if
       `labels` and `index` are specified.

    .. seealso:: :func:`scipy.ndimage.sum_labels`
    r   z,cupyx.scipy.ndimage.sum does not support %{}FzUsing the slower implementation as cupyx.scipy.ndimage.sum supports int32, float16, float32, float64, uint32, uint64 as data typesfor the fast implmentationTNr   r   r   r	   i   r`   )r   r   r   r   r
   r   r   r   r   r   r   r   rr   r   rs   r   r   r   r   r   rh   r   rF   r   r   int64rx   rn   _ndimage_sum_kernel)r!   rP   ri   rz   r{   s        r(   
sum_labelsr   p  s   " eT\** 64555{t~t777FMMK    	 H{4:t|T\<dk>+ + + 	) +0*B		D 	D 	D
 ~yy{{fdl++ 64555)%88ME6}Vq[!%%'''eT\** 2%%% 	2HIII&E/*//111zQz"DJ////
/%t|
4
4
4C 	
fqX$UFE3???ufeUZEEEr*   c                 $    t          | ||          S )a  Calculates the sum of the values of an n-D image array, optionally
       at specified sub-regions.

    Args:
        input (cupy.ndarray): Nd-image data to process.
        labels (cupy.ndarray or None): Labels defining sub-regions in `input`.
            If not None, must be same shape as `input`.
        index (cupy.ndarray or None): `labels` to include in output. If None
            (default), all values where `labels` is non-zero are used.

    Returns:
       sum (cupy.ndarray): sum of values, for each sub-region if
       `labels` and `index` are specified.

    Notes:
        This is an alias for `cupyx.scipy.ndimage.sum_labels` kept for
        backwards compatibility reasons. For new code please prefer
        `sum_labels`.

    .. seealso:: :func:`scipy.ndimage.sum`
    )r   r!   rP   ri   s      r(   rh   rh     s    , eVU+++r*   c                    t          | t          j                  st          d          | j        t          j        t          j        fv r,t          d                    | j        j                            d}| j        t          j	        t          j
        t          j        t          j        t          j        t          j        t          j        fvr!t!          j        dt$          j                   d}d }| ||           S t          |t          j                  st          d          t          j        | |          \  } }| || |d	k                       S t          j        |          r || ||k                       S t          |t          j                  sNt          |t,                    st          d
          | ||k                                 t          j                  S t1          | |||          S )as  Calculates the mean of the values of an n-D image array, optionally
       at specified sub-regions.

    Args:
        input (cupy.ndarray): Nd-image data to process.
        labels (cupy.ndarray or None): Labels defining sub-regions in `input`.
            If not None, must be same shape as `input`.
        index (cupy.ndarray or None): `labels` to include in output. If None
            (default), all values where `labels` is non-zero are used.

    Returns:
        mean (cupy.ndarray): mean of values, for each sub-region if
        `labels` and `index` are specified.


    .. seealso:: :func:`scipy.ndimage.mean`
    r   z-cupyx.scipy.ndimage.mean does not support %{}FzUsing the slower implementation as cupyx.scipy.ndimage.mean supports int32, float16, float32, float64, uint32, uint64 as data types for the fast implmentationTc                     |                                  }| j        }|t          j        |                              t
                    z  S r   )rh   r   r   r   r   r   )r!   rh   rO   s      r(   !calc_mean_with_intermediate_floatz/mean.<locals>.calc_mean_with_intermediate_float  s;    iikk
 T_U++2259999r*   Nr   r   r   r	   )rz   )r   r   r   r   r
   r   r   r   r   r   r   r   rr   r   rs   r   r   r   r   r   r   r   rF   r   r|   )r!   rP   ri   rz   r   s        r(   r   r     s   $ eT\** 64555{t~t777GNNK    	 H{4:t|T\<dk>+ + + 	) +0*B		D 	D 	D
 : : : ~00777fdl++ 64555)%88ME6}00vz1BCCC}U I00v1GHHHeT\** E%%% 	EHIII&E/*00t|0DDDvux@@@@r*   c                 H    t          j        t          | ||                    S )a  Calculates the standard deviation of the values of an n-D image array,
    optionally at specified sub-regions.

    Args:
        input (cupy.ndarray): Nd-image data to process.
        labels (cupy.ndarray or None): Labels defining sub-regions in `input`.
            If not None, must be same shape as `input`.
        index (cupy.ndarray or None): `labels` to include in output. If None
            (default), all values where `labels` is non-zero are used.

    Returns:
        standard_deviation (cupy.ndarray): standard deviation of values, for
        each sub-region if `labels` and `index` are specified.

    .. seealso:: :func:`scipy.ndimage.standard_deviation`
    )r   sqrtr   r   s      r(   standard_deviationr     s     " 9XeVU33444r*   c                     t          j        t                    j        }t          j        | t           j                  o
| j        |k    p)t          j        | t           j                  o
| j        |k     }|S )zCTest whether the NumPy data type `dt` can be safely cast to an int.)r   r
   rF   itemsize
issubdtypesignedintegerunsignedinteger)dtint_sizesafes      r(   _safely_castable_to_intr      s`    z#'HD.//KBK84KP
/"d2
3
3
Nh8N 	 Kr*   c                 b    | d         j         t          j        fd| D                       S )ztConcatenated result of applying func to a list of arrays.

    func should be cupy.min, cupy.max or cupy.median
    r   c                 n    g | ]1}|j         d k    r |d          nt          j        d g          2S r   T)keepdimsr	   )r   r   asarray)r6   ar
   funcs     r(   r9   z_get_values.<locals>.<listcomp>0  s^     	
 	
 	
  v{{ DT"""" $aS > > >	
 	
 	
r*   )r
   r   concatenate)arraysr   r
   s    `@r(   _get_valuesr   )  sS    
 1IOE	
 	
 	
 	
 	
 	
 	
 	
  r*   c                 `    t          j        fdt          ||           D                       S )zpConcatenated positions from applying arg_func to arrays.

    arg_func should be cupy.argmin or cupy.argmax
    c                     g | ]?\  }}|j         d k    r| |d                   nt          j        d gt                    @S r   )r   r   r   rF   )r6   posr   arg_funcs      r(   r9   z"_get_positions.<locals>.<listcomp>>  sg     	
 	
 	
 Q v{{ T***++ $aS < < <	
 	
 	
r*   )r   r   zip)r   position_arraysr   s     `r(   _get_positionsr   8  sL    
 	
 	
 	
 	
 ov66	
 	
 	
  r*   c	                    |p|}	g }
g }|D ]@}||k    }|
                     | |                    |	r|                     ||                    Ag }|r|t          |
t          j                  gz  }|r|t	          |
|t          j                  gz  }|r|t          |
t          j                  gz  }|r|t	          |
|t          j                  gz  }|r|t          |
t          j                  gz  }|S )zInternal helper routine for _select.

    With relatively few labels it is faster to call this function rather than
    using the implementation based on cupy.lexsort.
    )	appendr   r   minr   argminmaxargmaxmedian)r!   rP   idxs	positionsfind_minfind_min_positionsfind_maxfind_max_positionsfind_medianfind_positionsr   r   r$   	label_idxresults                  r(   _select_via_loopingr   F  s!    (=+=N FO 9 9aK	eI&''' 	9""9Y#7888F 2;vtx0011 I>&/4;GGHH 2;vtx0011 I>&/4;GGHH 5;vt{3344Mr*   c                    p}d}	|r1t          j        | j                                      | j                  }	fd}
| |
| |	          S t          j        | |          \  } }|$|dk    }d}|r|	|         } |
| |         |          S t          j        |          r$||k    }d}|r|	|         } |
| |         |          S t          j        |          }t          |j	                  }|
                                }|                                }|r|dk     s||j        k    rIt          j        |d          \  }}t          j        ||          }d|||j        k    <   ||         |k    }n9t          j        |t                                                    }|dk    ||k    z  }|dz   || <   |                                 } |                                }|r|	                                }	t$          j        j        t           j                                        v }|r
|srd}nd}nd}|r*t-          |          |k    rt/          | |||		  	        S t          j        t          j        |                                 |                                f                    }| |         } ||         }|r|	|         }	t          j        |t          j        d|d	z                       }ssr
|dd
         }ssr|dd         dz
  }g }rYt          j        t          |                                          d	z   | j	                  }| |         |||         <   |||         gz  }r^t          j        |                                                                d	z   t                    }|	|         |||         <   |||         gz  }rYt          j        t          |                                          d	z   | j	                  }| |         |||         <   |||         gz  }r^t          j        |                                                                d	z   t                    }|	|         |||         <   |||         gz  }rLt          j        t-          |                    }t          j        t          |                                          d	z   t                    }||         |||         <   t          j        t          |                                          d	z   t                    } ||         | ||         <   ||         }| |         } | |z
  d	z  }!||!z  }| |!z  } | j	        j        dv rI|| |                             t<                    | |                              t<                    z   dz  gz  }n|| |         | |          z   dz  gz  }|S )a  Return one or more of: min, max, min position, max position, median.

    If neither `labels` or `index` is provided, these are the global values
    in `input`. If `index` is None, but `labels` is provided, a global value
    across all non-zero labels is given. When both `labels` and `index` are
    provided, lists of values are provided for each labeled region specified
    in `index`. See further details in :func:`cupyx.scipy.ndimage.minimum`,
    etc.

    Used by minimum, maximum, minimum_position, maximum_position, extrema.
    Nc                 P   g }r||                                  gz  }r(||| |                                  k             d         gz  }r||                                 gz  }r(||| |                                 k             d         gz  }r|t          j        |           gz  }|S Nr   )r   r   r   r   )valsr   r   r   r   r   r   r   s      r(   single_groupz_select.<locals>.single_group{  s     	#txxzzl"F 	9y!34Q788F 	#txxzzl"F 	9y!34Q788F 	*t{4(())Fr*   r   T)return_inverser         r@   rc   iubg       @)r   aranger   rf   r   r   r   r   r   r
   r   r   uniquesearchsortedr   rF   r   ravelr   _acceleratorACCELERATOR_CUBget_routine_acceleratorslenr   lexsortstackrB   r   kindr   r   )"r!   rP   ri   r   r   r   r   r   r   r   r   maskmasked_positionssafe_int	min_label	max_labelunique_labelsr   found	using_cubn_label_cutofforderlabel_change_index	min_index	max_indexr   minsminposmaxsmaxposlocslohisteps"      `````                          r(   _selectr  h  s3    (=+=NI AK
++33EK@@	         ~|E9--- )%88ME6}z 	/(|E$K)9:::}U ; 	/(|E$K)9:::LE&v|44H

I

I  2	AV[)@)@ $F4 H H Hv 66 ,-T]''(d#u, uc**//11ty01q=D%LKKMME\\^^F &OO%%	"2
++--.I    	 [ 	 NNNN 
#d))~55"64H6H(+
 
 	

 LU[[]]FLLNN$CDDEEE%LEE]F %e$	 *6+/;q)a-+H+HJ J ,% , ,&ss+	 /% / /&qrr*Q.	F z#fjjll++a/=="'	"2VI4:, !FJJLL--//!3S99$-i$8vi !6$<.  z#fjjll++a/=="'	"2VI4:, !FJJLL--//!3S99$-i$8vi !6$<.  6{3v;;''ZFJJLL))A-s33 $Y6)ZFJJLL))A-s33 $Y6)XX
 RA~
d

d
;u$$b	((//%)2B2B52I2II  FF b	E"I-455FMr*   c                 4    t          | ||d          d         S )a  Calculate the minimum of the values of an array over labeled regions.

    Args:
        input (cupy.ndarray):
            Array of values. For each region specified by `labels`, the
            minimal values of `input` over the region is computed.
        labels (cupy.ndarray, optional): An array of integers marking different
            regions over which the minimum value of `input` is to be computed.
            `labels` must have the same shape as `input`. If `labels` is not
            specified, the minimum over the whole array is returned.
        index (array_like, optional): A list of region labels that are taken
            into account for computing the minima. If `index` is None, the
            minimum over all elements where `labels` is non-zero is returned.

    Returns:
        cupy.ndarray: Array of minima of `input` over the regions
        determined by `labels` and whose index is in `index`. If `index` or
        `labels` are not specified, a 0-dimensional cupy.ndarray is
        returned: the minimal value of `input` if `labels` is None,
        and the minimal value of elements where `labels` is greater than
        zero if `index` is None.

    .. seealso:: :func:`scipy.ndimage.minimum`
    T)r   r   r  r   s      r(   minimumr         2 5&%$777::r*   c                 4    t          | ||d          d         S )a  Calculate the maximum of the values of an array over labeled regions.

    Args:
        input (cupy.ndarray):
            Array of values. For each region specified by `labels`, the
            maximal values of `input` over the region is computed.
        labels (cupy.ndarray, optional): An array of integers marking different
            regions over which the maximum value of `input` is to be computed.
            `labels` must have the same shape as `input`. If `labels` is not
            specified, the maximum over the whole array is returned.
        index (array_like, optional): A list of region labels that are taken
            into account for computing the maxima. If `index` is None, the
            maximum over all elements where `labels` is non-zero is returned.

    Returns:
        cupy.ndarray: Array of maxima of `input` over the regions
        determaxed by `labels` and whose index is in `index`. If `index` or
        `labels` are not specified, a 0-dimensional cupy.ndarray is
        returned: the maximal value of `input` if `labels` is None,
        and the maximal value of elements where `labels` is greater than
        zero if `index` is None.

    .. seealso:: :func:`scipy.ndimage.maximum`
    T)r   r   r  r   s      r(   maximumr  #  r  r*   c                 4    t          | ||d          d         S )a  Calculate the median of the values of an array over labeled regions.

    Args:
        input (cupy.ndarray):
            Array of values. For each region specified by `labels`, the
            median values of `input` over the region is computed.
        labels (cupy.ndarray, optional): An array of integers marking different
            regions over which the median value of `input` is to be computed.
            `labels` must have the same shape as `input`. If `labels` is not
            specified, the median over the whole array is returned.
        index (array_like, optional): A list of region labels that are taken
            into account for computing the medians. If `index` is None, the
            median over all elements where `labels` is non-zero is returned.

    Returns:
        cupy.ndarray: Array of medians of `input` over the regions
        determined by `labels` and whose index is in `index`. If `index` or
        `labels` are not specified, a 0-dimensional cupy.ndarray is
        returned: the median value of `input` if `labels` is None,
        and the median value of elements where `labels` is greater than
        zero if `index` is None.

    .. seealso:: :func:`scipy.ndimage.median`
    T)r   r   r  r   s      r(   r   r   ?  s     2 5&%T:::1==r*   c           	         t          j        | j                  }t          j        dgt	          |ddd                   z             ddd         }t          | ||d          d         }|j        dk    rt          |          }nt          j	        |          }t          j
        |          rt          ||z  |z            S d |                    dd          |z  |z  D             S )a  Find the positions of the minimums of the values of an array at labels.

    For each region specified by `labels`, the position of the minimum
    value of `input` within the region is returned.

    Args:
        input (cupy.ndarray):
            Array of values. For each region specified by `labels`, the
            minimal values of `input` over the region is computed.
        labels (cupy.ndarray, optional): An array of integers marking different
            regions over which the position of the minimum value of `input` is
            to be computed. `labels` must have the same shape as `input`. If
            `labels` is not specified, the location of the first minimum over
            the whole array is returned.

            The `labels` argument only works when `index` is specified.
        index (array_like, optional): A list of region labels that are taken
            into account for finding the location of the minima. If `index` is
            None, the ``first`` minimum over all elements where `labels` is
            non-zero is returned.

            The `index` argument only works when `labels` is specified.

    Returns:
        Tuple of ints or list of tuples of ints that specify the location of
        minima of `input` over the regions determined by `labels` and  whose
        index is in `index`.

        If `index` or `labels` are not specified, a tuple of ints is returned
        specifying the location of the first minimal value of `input`.

    .. note::
        When `input` has multiple identical minima within a labeled region,
        the coordinates returned are not guaranteed to match those returned by
        SciPy.

    .. seealso:: :func:`scipy.ndimage.minimum_position`
    r   Nr   rc   T)r   c                 ,    g | ]}t          |          S r5   rg   r6   vs     r(   r9   z$minimum_position.<locals>.<listcomp>      IIIE!HHIIIr*   r   r   r   cumprodlistr  r   rF   r   r   r   rg   rf   r!   rP   ri   dimsdim_prodr   s         r(   minimum_positionr  [      N =%%D}aS4UaU#4#4455ddd;HUFEdCCCAFF {aVf%%}V 2f(D0111IIv~~b!44@DHIIIIr*   c           	         t          j        | j                  }t          j        dgt	          |ddd                   z             ddd         }t          | ||d          d         }|j        dk    rt          |          }nt          j	        |          }t          j
        |          rt          ||z  |z            S d |                    dd          |z  |z  D             S )a  Find the positions of the maximums of the values of an array at labels.

    For each region specified by `labels`, the position of the maximum
    value of `input` within the region is returned.

    Args:
        input (cupy.ndarray):
            Array of values. For each region specified by `labels`, the
            maximal values of `input` over the region is computed.
        labels (cupy.ndarray, optional): An array of integers marking different
            regions over which the position of the maximum value of `input` is
            to be computed. `labels` must have the same shape as `input`. If
            `labels` is not specified, the location of the first maximum over
            the whole array is returned.

            The `labels` argument only works when `index` is specified.
        index (array_like, optional): A list of region labels that are taken
            into account for finding the location of the maxima. If `index` is
            None, the ``first`` maximum over all elements where `labels` is
            non-zero is returned.

            The `index` argument only works when `labels` is specified.

    Returns:
        Tuple of ints or list of tuples of ints that specify the location of
        maxima of `input` over the regions determaxed by `labels` and  whose
        index is in `index`.

        If `index` or `labels` are not specified, a tuple of ints is returned
        specifying the location of the first maximal value of `input`.

    .. note::
        When `input` has multiple identical maxima within a labeled region,
        the coordinates returned are not guaranteed to match those returned by
        SciPy.

    .. seealso:: :func:`scipy.ndimage.maximum_position`
    r   Nr   rc   T)r   c                 ,    g | ]}t          |          S r5   r  r  s     r(   r9   z$maximum_position.<locals>.<listcomp>  r  r*   r  r  s         r(   maximum_positionr    r  r*   c           	         t          j        | j                  }t          j        dgt	          |ddd                   z             ddd         }t          | ||dddd          \  }}}}|j        dk    rT|                                }|                                }||t          ||z  |z            t          ||z  |z            fS t          j
        |          }t          j
        |          }d |                    dd          |z  |z  D             }d |                    dd          |z  |z  D             }||||fS )	a  Calculate the minimums and maximums of the values of an array at labels,
    along with their positions.

    Args:
        input (cupy.ndarray): N-D image data to process.
        labels (cupy.ndarray, optional): Labels of features in input. If not
            None, must be same shape as `input`.
        index (int or sequence of ints, optional): Labels to include in output.
            If None (default), all values where non-zero `labels` are used.

    Returns:
        A tuple that contains the following values.

        **minimums (cupy.ndarray)**: Values of minimums in each feature.

        **maximums (cupy.ndarray)**: Values of maximums in each feature.

        **min_positions (tuple or list of tuples)**: Each tuple gives the N-D
        coordinates of the corresponding minimum.

        **max_positions (tuple or list of tuples)**: Each tuple gives the N-D
        coordinates of the corresponding maximum.

    .. seealso:: :func:`scipy.ndimage.extrema`
    r   Nr   rc   T)r   r   r   r   c                 ,    g | ]}t          |          S r5   r  r  s     r(   r9   zextrema.<locals>.<listcomp>  +       a  r*   c                 ,    g | ]}t          |          S r5   r  r  s     r(   r9   zextrema.<locals>.<listcomp>  r  r*   )r   r   r   r  r  r  r   r   rg   r   r   rf   )	r!   rP   ri   r  r  minimumsmin_positionsmaximumsmax_positionss	            r(   extremar#    s   4 ;u{##D}aS4UaU#4#4455ddd;H7>8 8 84HmX} Q%**,,%**,,=H,455=H,455	
 	
 L//ML//M (00Q778CtK  M (00Q778CtK  M X}m;;r*   c                     t                     t          j        d  j        D                       fdt	           j                  D             }t          |d         t          j                  o|d         j        dk    }|rt          d |D                       S d t          j	        |d          D             S )a  
    Calculate the center of mass of the values of an array at labels.

    Args:
        input (cupy.ndarray): Data from which to calculate center-of-mass. The
            masses can either be positive or negative.
        labels (cupy.ndarray, optional): Labels for objects in `input`, as
            enerated by `ndimage.label`. Only used with `index`. Dimensions
            must be the same as `input`.
        index (int or sequence of ints, optional): Labels for which to
            calculate centers-of-mass. If not specified, all labels greater
            than zero are used. Only used with `labels`.

    Returns:
        tuple or list of tuples: Coordinates of centers-of-mass.

    .. seealso:: :func:`scipy.ndimage.center_of_mass`
    c                 .    g | ]}t          d |          S )r   )slice)r6   r$   s     r(   r9   z"center_of_mass.<locals>.<listcomp>!  s     999a999r*   c                 z    g | ]7}t          |                             t                    z            z  8S r5   )rh   r   r   )r6   dirgridsri   r!   rP   
normalizers     r(   r9   z"center_of_mass.<locals>.<listcomp>#  sQ        	EE#J%%e,,,fe<<zI  r*   r   c              3      K   | ]}|V  d S r   r5   )r6   ress     r(   r   z!center_of_mass.<locals>.<genexpr>/  s"      ,,SS,,,,,,r*   c                     g | ]}|S r5   r5   r  s     r(   r9   z"center_of_mass.<locals>.<listcomp>1  s    444!A444r*   rc   rd   )
rh   r   ogridr   r>   r   r   r   rg   r   )r!   rP   ri   resultsis_0dim_arrayr)  r*  s   ```  @@r(   center_of_massr1    s    & UFE**JJ99U[999:E       $$  G 	71:t|,,EA1E   -,,G,,,,,,44tz'3334444r*   c                    t          j        |          }t          j        |           } |r1t          j        | j                                      | j                  }`|t          d          |s |                                           S  |                                 |                                          S 	 t          j	        |           \  } n# t          $ r t          d          w xY w|7|s | dk                       S  | dk             |dk                       S t          j
        |          }t          j        |                    j                                      |j                  |k              r t          d|j        dj        d          |                    j                  }|                                }	|                                }
|	k    |
k    z  }|         | |         } |r||         }                                }|         | |         } |r||         }|                                }||         fd}|t"          k    r!fd	t%          |j                  D             n=t          j        |j        |          j        j        d
v rt*          j        dd<   |s || g           n || |g           |t"          k    r5t          j        |          }fd|                                D             }n1t          j        |j        |          }|t          j        |          <   |r|d         }|S )a  Array resulting from applying ``func`` to each labeled region.

    Roughly equivalent to [func(input[labels == i]) for i in index].

    Sequentially applies an arbitrary function (that works on array_like input)
    to subsets of an N-D image array specified by `labels` and `index`.
    The option exists to provide the function with positional parameters as the
    second argument.

    Args:
        input (cupy.ndarray): Data from which to select `labels` to process.
        labels (cupy.ndarray or None):  Labels to objects in `input`. If not
            None, array must be same shape as `input`. If None, `func` is
            applied to raveled `input`.
        index (int, sequence of ints or None): Subset of `labels` to which to
            apply `func`. If a scalar, a single value is returned. If None,
            `func` is applied to all non-zero values of `labels`.
        func (callable): Python function to apply to `labels` from `input`.
        out_dtype (dtype): Dtype to use for `result`.
        default (int, float or None): Default return value when a element of
            `index` does not exist in `labels`.
        pass_positions (bool, optional): If True, pass linear indices to `func`
            as a second argument.

    Returns:
        cupy.ndarray: Result of applying `func` to each of `labels` to `input`
        in `index`.

    .. seealso:: :func:`scipy.ndimage.labeled_comprehension`
    Nzindex without defined labelszMinput and labels must have the same shape (excepting dimensions with width 1)r   z"Cannot convert index values from <z> to <z*> (labels.dtype) without loss of precisionc                     
j         }t          j        	
d          }t          j        	
d          }t          t	          |          ||          D ]"\  }k    r fd| D              ||<   #dS )zlabels must be sortedleft)siderightc                 $    g | ]}|         S r5   r5   )r6   inphighlows     r(   r9   z9labeled_comprehension.<locals>.do_map.<locals>.<listcomp>  s!    ???s3t8}???r*   N)r   r   r   r   r>   )inputsr#   nidxr   r   r$   r9  r:  r   rP   sorted_indexs         @@r(   do_mapz%labeled_comprehension.<locals>.do_map  s      v|&AAAv|'BBBdR44 	A 	ALAsDd{{????????@F1II	A 	Ar*   c                     i | ]}|S r5   r5   )r6   r$   defaults     r(   
<dictcomp>z)labeled_comprehension.<locals>.<dictcomp>  s    666q7666r*   fcc                      g | ]
}|         S r5   r5   )r6   r$   temps     r(   r9   z)labeled_comprehension.<locals>.<listcomp>  s    999a$q'999r*   )r   r   r   r   r   rf   r   r   r   r   
atleast_1danyr   r
   r   r   argsortobjectr>   r   r   r   nanr   rB   )r!   rP   ri   r   	out_dtyper@  pass_positions	as_scalarr   r   r   r   label_orderindex_orderr>  r#   r=  rD  s    ` ` `          @@r(   labeled_comprehensionrO  4  s   B e$$ILE AK
++33EK@@	~;<<< 	:4&&&4y'8'8999
-eV<<vv 
 
 
2
 
 	

 } 	B4fqj)***4fqj)9VaZ+@AAAOE""ExV\**11%+>>%GHH 
j {{{FLLL*
 
 	
 LL&&E 
B	BbLVr\*D D\F$KE $dO	 ..""KK F+E +k*	--//K%LA A A A A A A F6666E%*$5$5666z%+y11?tz$66iGQQQ )wy!4(((Fl;//9999;#6#6#8#8999EK33,0t|K(() Ms   C C7c           	      v    t          j        |||dz             fd}t          | |||t          dd          S )a  Calculate the histogram of the values of an array, optionally at labels.

    Histogram calculates the frequency of values in an array within bins
    determined by `min`, `max`, and `bins`. The `labels` and `index`
    keywords can limit the scope of the histogram to specified sub-regions
    within the array.

    Args:
        input (cupy.ndarray): Data for which to calculate histogram.
        min (int): Minimum values of range of histogram bins.
        max (int): Maximum values of range of histogram bins.
        bins (int): Number of bins.
        labels (cupy.ndarray, optional): Labels for objects in `input`. If not
            None, must be same shape as `input`.
        index (int or sequence of ints, optional): Label or labels for which to
            calculate histogram. If None, all values where label is greater
            than zero are used.

    Returns:
        cupy.ndarray: Histogram counts.

    .. seealso:: :func:`scipy.ndimage.histogram`
    r   c                 :    t          j        |           d         S r   )r   	histogram)r   _binss    r(   _histzhistogram.<locals>._hist  s    ~dE**1--r*   NF)rK  )r   linspacerO  rH  )r!   r   r   binsrP   ri   rT  rS  s          @r(   rR  rR    s]    0 M#sD1H--E. . . . . !vueVT%   r*   )ignore_valueadaptive_index_dtypec                  
 | j         j        dvrt          d          |rTt          j        t          | j                  dz              }t          j        t          | j                  dz              
| 	                    d          }t          j
        |          }t          j        |d          }|r|                    |d          }t          j        || j                  }|rt          
fd	|D                       }d
i }t          j        |          }t!          |          D ]<\  }	d
k    r|	|k    rz  t          fd|D                       ||	<   z  =|S )a,  
    Find indices of each distinct value in given array.

    Parameters
    ----------
    arr : ndarray of ints
        Array containing integer values.
    ignore_value : int, optional
        This value will be ignored in searching the `arr` array. If not
        given, all values found will be included in output. Default
        is None.
    adaptive_index_dtype : bool, optional
        If ``True``, instead of returning the default CuPy signed integer
        dtype, the smallest signed integer dtype capable of representing the
        image coordinate range will be used. This can substantially reduce
        memory usage and slightly reduce runtime. Note that this optional
        parameter is not available in the SciPy API.

    Returns
    -------
    indices : dictionary
        A Python dictionary of array indices for each distinct value. The
        dictionary is keyed by the distinct values, the entries are array
        index tuples covering all occurrences of the value within the
        array.

        This dictionary can occupy significant memory, often several times
        the size of the input array. To help reduce memory overhead, the
        argument `adaptive_index_dtype` can be set to ``True``.

    Notes
    -----
    For a small array with few distinct values, one might use
    `numpy.unique()` to find all possible values, and ``(arr == val)`` to
    locate each value within that array. However, for large arrays,
    with many distinct values, this can become extremely inefficient,
    as locating each value would require a new search through the entire
    array. Using this function, there is essentially one search, with
    the indices saved for all distinct values.

    This is useful when matching a categorical image (e.g. a segmentation
    or classification) to an associated image of other data, allowing
    any per-class statistic(s) to then be calculated. Provides a
    more flexible alternative to functions like ``scipy.ndimage.mean()``
    and ``scipy.ndimage.variance()``.

    Some other closely related functionality, with different strengths and
    weaknesses, can also be found in ``scipy.stats.binned_statistic()`` and
    the `scikit-image <https://scikit-image.org/>`_ function
    ``skimage.measure.regionprops()``.

    Note for IDL users: this provides functionality equivalent to IDL's
    REVERSE_INDICES option (as per the IDL documentation for the
    `HISTOGRAM <https://www.l3harrisgeospatial.com/docs/histogram.html>`_
    function).

    .. versionadded:: 1.10.0

    See Also
    --------
    label, maximum, median, minimum_position, extrema, sum, mean, variance,
    standard_deviation, cupy.where, cupy.unique

    Examples
    --------
    >>> import cupy
    >>> from cupyx.scipy import ndimage
    >>> a = cupy.zeros((6, 6), dtype=int)
    >>> a[2:4, 2:4] = 1
    >>> a[4, 4] = 1
    >>> a[:2, :3] = 2
    >>> a[0, 5] = 3
    >>> a
    array([[2, 2, 2, 0, 0, 3],
           [2, 2, 2, 0, 0, 0],
           [0, 0, 1, 1, 0, 0],
           [0, 0, 1, 1, 0, 0],
           [0, 0, 0, 0, 1, 0],
           [0, 0, 0, 0, 0, 0]])
    >>> val_indices = ndimage.value_indices(a)

    The dictionary `val_indices` will have an entry for each distinct
    value in the input array.

    >>> val_indices.keys()
    dict_keys([0, 1, 2, 3])

    The entry for each value is an index tuple, locating the elements
    with that value.

    >>> ndx1 = val_indices[1]
    >>> ndx1
    (array([2, 2, 3, 3, 4]), array([2, 3, 2, 3, 4]))

    This can be used to index into the original array, or any other
    array with the same shape.

    >>> a[ndx1]
    array([1, 1, 1, 1, 1])

    If the zeros were to be ignored, then the resulting dictionary
    would no longer have an entry for zero.

    >>> val_indices = ndimage.value_indices(a, ignore_value=0)
    >>> val_indices.keys()
    dict_keys([1, 2, 3])

    iuz(Parameter 'arr' must be an integer arrayr   rc   Nrd   Fr   c              3   F   K   | ]}|                     d           V  dS )Fr   N)r   )r6   ccoord_int_types     r(   r   z value_indices.<locals>.<genexpr>W  s3      LLqxxUx;;LLLLLLr*   r   c              3   2   K   | ]}|z            V  d S r   r5   )r6   r\  rO   rJ   s     r(   r   z value_indices.<locals>.<genexpr>b  s1      DD1VFUN23DDDDDDr*   )r
   r   r   r   min_scalar_typerF   r   r   r   rf   bincountrG  r   unravel_indexrg   r   	enumerate)arrrW  rX  raveled_int_typearr1dcountsisortcoordsr{   valuer]  rO   rJ   s             @@@r(   value_indicesrj    s   Z y~T!!EFFF E  /#ch--!2C0DEE-CI0B.CDDKKOOE]5!!FLT***E ;-E::sy11F MLLLLVLLLLLF
C\&!!F!&))  uA::l""eOFDDDDDVDDDDDE
%Jr*   )NN)r`   )r`   F)FF)NNFFFFF)F)(r   r   r   r   r   r)   r   r   rC   rD   rE   rG   rH   rT   r   r   rn   ry   rv   r|   r   r   rh   r   r   r   r   r   r   r  r  r  r   r  r  r#  r1  rO  rR  rj  r5   r*   r(   <module>rk     sX                 D  D  D  D N" " "  ,* * *(- (- (-V
+ 
+ 
+, , ,. . .. 352C #$ $  .e-1       /u.1'      =>(-       I1 I1 I1 I1X=F =F =F =F@, , , ,2@A @A @A @AF5 5 5 5(        D FK9>\ \ \ \~; ; ; ;8; ; ; ;8> > > >86J 6J 6J 6Jr6J 6J 6J 6Jr=< =< =< =<@$5 $5 $5 $5P DIA A A AH   D (,% J J J J J J Jr*   