o
    .wi}                     @   sX  d dl mZ d dlmZ d dlZd dlmZ d dlmZ de	de
dejd	eejef d
ef
ddZde	dee	 dee
 dejd	eejef d
efddZdede	d
eeef fddZd$dede	de	de	d
ef
ddZd$dede	de	d
efddZdede	d
efddZde	dee	 dee
 dejd	ejd
efddZdede	d e	d!e	d
ef
d"d#ZdS )%    )Sequence)UnionN)Tensor)
functionalkernel_sizesigmadtypedevicereturnc                 C   sT   t jd|  d d|  d d||d}t t || d d }||  jddS )aY  Compute 1D gaussian kernel.

    Args:
        kernel_size: size of the gaussian kernel
        sigma: Standard deviation of the gaussian kernel
        dtype: data type of the output tensor
        device: device of the output tensor

    Example:
        >>> _gaussian(3, 1, torch.float, 'cpu')
        tensor([[0.2741, 0.4519, 0.2741]])

          )startendstepr   r	   r   dim)torcharangeexppowsum	unsqueeze)r   r   r   r	   distgauss r   `/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torchmetrics/functional/image/utils.py	_gaussian	   s   $r   channelc                 C   sT   t |d |d ||}t |d |d ||}t| |}|| d|d |d S )a  Compute 2D gaussian kernel.

    Args:
        channel: number of channels in the image
        kernel_size: size of the gaussian kernel as a tuple (h, w)
        sigma: Standard deviation of the gaussian kernel
        dtype: data type of the output tensor
        device: device of the output tensor

    Example:
        >>> _gaussian_kernel_2d(1, (5,5), (1,1), torch.float, "cpu")
        tensor([[[[0.0030, 0.0133, 0.0219, 0.0133, 0.0030],
                  [0.0133, 0.0596, 0.0983, 0.0596, 0.0133],
                  [0.0219, 0.0983, 0.1621, 0.0983, 0.0219],
                  [0.0133, 0.0596, 0.0983, 0.0596, 0.0133],
                  [0.0030, 0.0133, 0.0219, 0.0133, 0.0030]]]])

    r   r   )r   r   matmultexpand)r   r   r   r   r	   gaussian_kernel_xgaussian_kernel_ykernelr   r   r   _gaussian_kernel_2d   s   r$   inputswindow_sizec                 C   sB   t jdd||| j| jd}||d  }t jd| j| jd}||fS )zConstruct uniform weight and bias for a 2d convolution.

    Args:
        inputs: Input image
        window_size: size of convolutional kernel

    Return:
        The weight and bias for 2d convolution

    r   )r   r	   r   )r   onesr   r	   zeros)r%   r&   kernel_weightkernel_biasr   r   r   _uniform_weight_bias_conv2d<   s   r+   r   pad	outer_padc              	   C   sl   | j | }t| |t|d dd| j}t| |t|d || | d| j}t|| |f|S )a,  Apply single-dimension reflection padding to match scipy implementation.

    Args:
        inputs: Input image
        dim: A dimension the image should be padded over
        pad: Number of pads
        outer_pad: Number of outer pads

    Return:
        Image padded over a single dimension

    r   )shaper   index_selectr   tor	   cat)r%   r   r,   r-   _maxxyr   r   r   _single_dimension_padM   s   
$,r6   c                 C   s   dD ]	}t | |||} q| S )zApply reflection padding to the input image.

    Args:
        inputs: Input image
        pad: Number of pads
        outer_pad: Number of outer pads

    Return:
        Padded image

    )r      )r6   )r%   r,   r-   r   r   r   r   _reflection_pad_2d`   s   r8   c                    sL   t  |d |d  t |\tj fddt jd D ddS )zApply uniform filter with a window of a given size over the input image.

    Args:
        inputs: Input image
        window_size: Sliding window used for rmse calculation

    Return:
        Image transformed with the uniform input

    r   c                    s0   g | ]}t j d d |f dddqS )Nr   r   )padding)Fconv2dr   ).0r   r%   r*   r)   r   r   
<listcomp>   s    "z#_uniform_filter.<locals>.<listcomp>r   r   )r8   r+   r   r2   ranger/   )r%   r&   r   r=   r   _uniform_filterq   s   r@   c           
   	   C   s   t |d |d ||}t |d |d ||}t |d |d ||}t| |}t|ddd|d ||d |d |d }	|	| d|d |d |d S )a6  Compute 3D gaussian kernel.

    Args:
        channel: number of channels in the image
        kernel_size: size of the gaussian kernel as a tuple (h, w, d)
        sigma: Standard deviation of the gaussian kernel
        dtype: data type of the output tensor
        device: device of the output tensor

    r   r   r   r.   )r   r   r   r   mulr   repeatr    )
r   r   r   r   r	   r!   r"   gaussian_kernel_z	kernel_xyr#   r   r   r   _gaussian_kernel_3d   s   rE   pad_hpad_wpad_dc                 C   s   t j| ||||||fddS )aU  Reflective padding of 3d input.

    Args:
        inputs: tensor to pad, should be a 3D tensor of shape ``[N, C, H, W, D]``
        pad_w: amount of padding in the height dimension
        pad_h: amount of padding in the width dimension
        pad_d: amount of padding in the depth dimension

    Returns:
        padded input tensor

    reflect)mode)r:   r,   )r%   rF   rG   rH   r   r   r   _reflection_pad_3d   s   rK   )r   )collections.abcr   typingr   r   r   torch.nnr   r:   intfloatr   r	   strr   r$   tupler+   r6   r8   r@   rE   rK   r   r   r   r   <module>   sJ    *
  
"