o
    װiL                     @   s4  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Zej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	 	d+ddZejjdd		 d,dd Zejjdd		 d,d!d"Zejjdd		 d-d#d$Zejjdd		 d-d%d&Zejjdd		 d,d'd(ZdS ).    N)_spline_prefilter_core)_spline_kernel_weights)_utilzS
// workaround for HIP: line begins with #include
#include <cupy/math_constants.h>
c              
   C   sT   g }| d |dkrd| nd}t| D ]}| d| d| d| d q|S )	a
  Extract target coordinate from coords array (for map_coordinates).

    Notes
    -----
    Assumes the following variables have been initialized on the device::

        coords (ndarray): array of shape (ncoords, ndim) containing the target
            coordinates.
        c_j: variables to hold the target coordinates

    computes::

        c_j = coords[i + j * ncoords];

    ncoords is determined by the size of the output array, y.
    y will be indexed by the CIndexer, _ind.
    Thus ncoords = _ind.size();

    z ptrdiff_t ncoords = _ind.size();r    + (W) 	
    W c_z = coords[i + z * ncoords];)appendrangendimnprepadopsprej r   W/home/ubuntu/.local/lib/python3.10/site-packages/cupyx/scipy/ndimage/_interp_kernels.py_get_coord_map   s   
r   c                 C   sV   g }|dkrd| nd}t | D ]}|d| d| d| d| d| d	 q|S )
a  Compute target coordinate based on a shift followed by a zoom.

    This version zooms from the center of the edge pixels.

    Notes
    -----
    Assumes the following variables have been initialized on the device::

        in_coord[ndim]: array containing the source coordinate
        zoom[ndim]: array containing the zoom for each axis
        shift[ndim]: array containing the zoom for each axis

    computes::

        c_j = zoom[j] * (in_coord[j] - shift[j])

    r   r   r   r    = zoom[] * ((W)in_coord[
] - shift[z])r   r
   r	   r   r   r   r   _get_coord_zoom_and_shift/   s   r   c                 C   P   g }|dkrd| nd}t | D ]}|d| d| d| d| d	 q|S )	a  Compute target coordinate based on a shift followed by a zoom.

    This version zooms from the outer edges of the grid pixels.

    Notes
    -----
    Assumes the following variables have been initialized on the device::

        in_coord[ndim]: array containing the source coordinate
        zoom[ndim]: array containing the zoom for each axis
        shift[ndim]: array containing the zoom for each axis

    computes::

        c_j = zoom[j] * (in_coord[j] - shift[j] + 0.5) - 0.5

    r   r   r   r   r   r   z] - shift[j] + 0.5) - 0.5r   r   r   r   r   r   _get_coord_zoom_and_shift_gridI   s   r   c                 C   r   )	a|  Compute target coordinate based on a zoom.

    This version zooms from the center of the edge pixels.

    Notes
    -----
    Assumes the following variables have been initialized on the device::

        in_coord[ndim]: array containing the source coordinate
        zoom[ndim]: array containing the zoom for each axis

    computes::

        c_j = zoom[j] * in_coord[j]

    r   r   r   r   r   ] * (W)in_coord[]r   r   r   r   r   r   _get_coord_zoomc      r   c                 C   r   )	a  Compute target coordinate based on a zoom (grid_mode=True version).

    This version zooms from the outer edges of the grid pixels.

    Notes
    -----
    Assumes the following variables have been initialized on the device::

        in_coord[ndim]: array containing the source coordinate
        zoom[ndim]: array containing the zoom for each axis

    computes::

        c_j = zoom[j] * (in_coord[j] + 0.5) - 0.5

    r   r   r   r   r   r   z] + 0.5) - 0.5r   r   r   r   r   r   _get_coord_zoom_grid|   r   r   c                 C   r   )	aC  Compute target coordinate based on a shift.

    Notes
    -----
    Assumes the following variables have been initialized on the device::

        in_coord[ndim]: array containing the source coordinate
        shift[ndim]: array containing the zoom for each axis

    computes::

        c_j = in_coord[j] - shift[j]

    r   r   r   r   z = (W)in_coord[r   r   r   r   r   r   r   r   _get_coord_shift   s   r    c                 C   s   g }|dkrd| nd}| d }t | D ]8}|d| d t | D ]}|d| d|| |  d	| d
 q$|d| d|| |   d| d q|S )a{  Compute target coordinate based on a homogeneous transformation matrix.

    The homogeneous matrix has shape (ndim, ndim + 1). It corresponds to
    affine matrix where the last row of the affine is assumed to be:
    ``[0] * ndim + [1]``.

    Notes
    -----
    Assumes the following variables have been initialized on the device::

        mat(array): array containing the (ndim, ndim + 1) transform matrix.
        in_coords(array): coordinates of the input

    For example, in 2D:

        c_0 = mat[0] * in_coords[0] + mat[1] * in_coords[1] + aff[2];
        c_1 = mat[3] * in_coords[0] + mat[4] * in_coords[1] + aff[5];

    r   r   r      z
            W c_z
 = (W)0.0;z
            c_z += mat[r   ];r   r   r   )r   r   r   r   ncolr   kr   r   r   _get_coord_affine   s.   


r%   unsigned intc                 C   sh   t | }d| d| d| dg}t|d ddD ]}|d| |  d	| d
 q|d d|S )z
    declare a multi-index array in_coord and unravel the 1D index, i into it.
    This code assumes that the array is a C-ordered array.
    z	
        z
 in_coord[z];
        z s, t, idx = i;r!   r   z
        s = z(;
        t = idx / s;
        in_coord[z!] = idx - t * s;
        idx = t;z
        in_coord[0] = idx;
)lenr
   r	   join)shapeuint_tr   coder   r   r   r   _unravel_loop_index   s    


r.   r   Fc                  C   st  g }|rdnd}| | d |rd}d}nd}d}t|D ]}| d| d	| d
| d q| d| d|d  d t|d ddD ]}| d| d|d  d| d| d	 qG|
sh| t|| || ||	 }|tju rwd}n|tjkrd}n|tj krd}nd| d| }|dkrddd t|D }| d| d| d |dkrj|d kr| d! t|D ]l}|d kr| d"| d n| d#| d$| d%| d&| d'	 |dkr|d krd(}d)}nd*| }d+}| t||d,| || |d kr| d#| d$| d%| d- | d.| d/| d0| d1| d	 qd2d3d t|D }|d4kr\dd5d t|D }| d6| d7| d8| d9| d:	 n'| d;| d9| d n|dkrt|D ]}| d.| d$| d%| d&| d<| d=| d0| d>| d?| d@| dA| dB |d kr| dC| dD| dE n| d#| dF| d0| dG| dH| dI| d |dkr$|d krdJ}d)}ndK| }d+}| t||d,| || |d krdLndM| }| t||d,| || |d kr$| dN| dF| d%| dO| dH| d%| dP | dQg dR| dS| dT| dU| dV| dW| d/| dX| dY| dZ| d[| d\| d]| d1| d^| d_| d`| d\| da| d1| db qsn|dkr|d4krd}n|dckrdc}nt	
|}| dd| de t|D ]}| df| dg|d  d | t| j||dh |div r| dj| d d(}| t||d,| |d) ndk| }|d@ rdl}ndm}| |j|||dn do | | dp| dg|d  d t|d D ]&}dq| dg| dr}| d#| ds| d | t||d,| | q*| dt| du| d/| dv| dw| dx| dy| dz| d{| d|| d}| d~| d|| d| du q|dkrddd t|D }d2dd t|D }|d4ks|dkr|dkrddd t|D }| d6| d| d| d| d| d| d9| d| d| d n| d.| d| d9| d| d| d | d|  |dkr| d |r| d n| d d|}|dd}d||||ddd |D }|dkr6|d7 }||fS )aQ  
    Args:
        coord_func (function): generates code to do the coordinate
            transformation. See for example, `_get_coord_shift`.
        ndim (int): The number of dimensions.
        large_int (bool): If true use Py_ssize_t instead of int for indexing.
        yshape (tuple): Shape of the output array.
        mode (str): Signal extension mode to use at the array boundaries
        cval (float): constant value used when `mode == 'constant'`.
        name (str): base name for the interpolation kernel
        integer_output (bool): boolean indicating whether the output has an
            integer type.
        nprepad (int): integer indicating the amount of prepadding at the
            boundaries.

    Returns:
        operation (str): code body for the ElementwiseKernel
        name (str): name for the ElementwiseKernel
    doubleYz out = 0.0;size_t	ptrdiff_tr&   intzconst z xsize_z = x.shape()[r"   z sx_r!   z = 1;r   r'   z = sx_z	 * xsize_r   z(Y)CUDART_NANz(Y)CUDART_INFz(Y)(-CUDART_INF)()constantz || c              	   S   s$   g | ]}d | d| d| dqS )z(c_z < 0) || (c_z	 > xsize_z - 1)r   .0r   r   r   r   
<listcomp>  s   $ z+_generate_interp_custom.<locals>.<listcomp>z
        if (z)
        {
            out = z";
        }
        else
        {wrapzdouble dcoord;z
                dcoord = c_z
                z cf_z = (z)floor((double)c_z + 0.5);dcoordTcf_Fxsize_z)floor(dcoord + 0.5);z
            z ic_z = cf_z * sx_z + c                 S      g | ]}d | qS ic_r   r7   r   r   r   r9   E      zgrid-constantc                 S      g | ]}d | dqS z(ic_z < 0)r   r7   r   r   r   r9   G      z
            if (z) {
                out = z.;
            } else {
                out = (z)x[z];
            }z
            out = (z);
            z cc_z + 1;
            z n_z = (c_z == cf_z)) ? 1 : 2;  // points needed
            z$
                double dcoordf = c_z%;
                double dcoordc = c_z + 1;z cf_bounded_z;
                z cc_bounded_z = cc_dcoordfcf_bounded_dcoordccc_bounded_z
                    z&)floor(dcoordf);;
                    z*)floor(dcoordf + 1);;
                    r   z
            for (int s_z = 0; s_z < n_z; s_z.++)
                {
                    W w_z;
                    z;
                    if (s_z7 == 0)
                    {
                        w_z	 = (W)cc_z - c_z;
                        ic_z = cf_bounded_zM;
                    } else
                    {
                        w_z = c_z	 - (W)cf_z = cc_bounded_z;
                    }nearestz#
            W wx, wy;
            z start;z
            W weights_[)r   order)r:   zdouble dcoord = c_z
(double)c_zA
                start = ({int_t})floor({coord_var}) - {order_2};zG
                start = ({int_t})floor({coord_var} + 0.5) - {order_2};   )int_t	coord_varorder_2z ci_ci_r   z = start + z
            W w_z;
            z;
            for (int k_z = 0; k_z <= z; k_z,++)
                {
                    w_z = weights_z[k_z];
                    ic_z = ci_z] * sx_z * c                 S   r>   )w_r   r7   r   r   r   r9     rA   c                 S   r>   r?   r   r7   r   r   r   r9     rA   c                 S   rB   rC   r   r7   r   r   r   r9     rD   z) {
                out += z * (z)(z();
            } else {
                z val = (z!];
                out += val * (z);
            }z];
            out += val * (z);}zy = (Y)rint((double)out);zy = (Y)out;r(   -_z5cupyx_scipy_ndimage_interpolate_{}_order{}_{}_{}d_y{}c                 S   s   g | ]}| qS r   r   r7   r   r   r   r9     s    _i64)r	   r
   r.   numpynaninfr*   r    _generate_boundary_condition_opsr   _get_spline_modespline_weights_inlineformatreplace)
coord_funcr   	large_intyshapemodecvalrK   nameinteger_outputr   omit_in_coordr   internal_dtyper,   rM   r   _condixvarfloat_ix
_coord_idxspline_moderN   op_strr$   _weight	operationmode_strr   r   r   _generate_interp_custom   s   *



















7








 

	





rp   T)for_each_device        r!   c                 C   s>   d}d}	t t| |||||d||dd\}
}tj||	|
|tdS )Nzraw X x, raw W coordsY ymapT)r^   r   r_   r`   ra   rb   rK   rc   rd   r   re   preamble)rp   r   cupyElementwiseKernelmath_constants_preambler   r_   r`   ra   rb   rK   rd   r   	in_params
out_paramsrn   rc   r   r   r   _get_map_kernel  s$   
r}   c                 C   <   d}d}	t t| |||||d||d
\}
}tj||	|
|tdS )Nzraw X x, raw W shiftrs   shift
r^   r   r_   r`   ra   rb   rK   rc   rd   r   ru   )rp   r    rw   rx   ry   rz   r   r   r   _get_shift_kernel  "   
r   c	                 C   sR   d}	d}
|r	t }nt}t|| ||||||rdnd||d
\}}tj|	|
||tdS )Nz raw X x, raw W shift, raw W zoomrs   zoom_shift_grid
zoom_shiftr   ru   )r   r   rp   rw   rx   ry   )r   r_   r`   ra   rb   rK   rd   	grid_moder   r{   r|   zoom_shift_funcrn   rc   r   r   r   _get_zoom_shift_kernel  s(   

r   c	                 C   sL   d}	d}
t |r	tnt| ||||||rdnd||d
\}}tj|	|
||tdS )Nzraw X x, raw W zoomrs   	zoom_gridzoomr   ru   )rp   r   r   rw   rx   ry   )r   r_   r`   ra   rb   rK   rd   r   r   r{   r|   rn   rc   r   r   r   _get_zoom_kernel/  s"   


r   c                 C   r~   )Nzraw X x, raw W matrs   affiner   ru   )rp   r%   rw   rx   ry   rz   r   r   r   _get_affine_kernelD  r   r   )r   )r&   )r   Fr   F)rr   r!   Fr   )rr   r!   FFr   )rV   rw   cupy._core.internalcupyx.scipy.ndimager   r   r   ry   r[   r   r   r   r   r   r    r%   r.   rp   memoizer}   r   r   r   r   r   r   r   r   <module>   sR    







"
  