
    i}                        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Zde	dee	   dee
   dej                  d	eej                  ef   d
efdZdede	d
eeef   fdZddede	de	de	d
ef
dZddede	de	d
efdZdede	d
efdZde	dee	   dee
   dej                  d	ej                  d
efdZdede	de	de	d
ef
dZy)    )Sequence)UnionN)Tensor)
functionalkernel_sizesigmadtypedevicereturnc                     t        j                  d| z
  dz  d| z   dz  d||      }t        j                  t        j                  ||z  d       dz        }||j	                         z  j                  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gausss         x/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/functional/image/utils.py	_gaussianr   	   ss     <<q;!3!k/Q9NUV^clrsDIIuyyq11A56EEIIK**q*11    channelc                     t        |d   |d   ||      }t        |d   |d   ||      }t        j                  |j                         |      }|j	                  | 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kernels           r   _gaussian_kernel_2dr'      sn    2 "+a.%(E6J!+a.%(E6J\\+--/1BCF==![^[^DDr   inputswindow_sizec                     t        j                  dd||| j                  | j                        }||dz  z  }t        j                  d| j                  | j                        }||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_biass       r   _uniform_weight_bias_conv2dr/   <   sZ     JJq![+V\\Z`ZgZghM[!^#M++av||FMMJK+%%r   r   pad	outer_padc           	      ~   | j                   |   }t        j                  | |t        j                  |dz
  dd      j	                  | j
                              }t        j                  | |t        j                  |dz
  ||z
  |z
  d      j	                  | j
                              }t        j                  || |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   r0   r1   _maxxys          r   _single_dimension_padr;   M   s     <<D63S1Wb"(E(H(H(WXA63TAXtczI?UWY(Z(](]^d^k^k(lmA99a^S))r   c                 0    dD ]  }t        | |||      }  | 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      )r;   )r(   r0   r1   r   s       r   _reflection_pad_2dr>   `   s#     &vsCC Mr   c                     t        | |dz  |dz        } t        | |      \  }}t        j                  t	        | j
                  d         D cg c]1  }t        j                  | dd|f   j                  d      ||d      3 c}d      S c c}w )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   r   Nr   )paddingr   )	r>   r/   r   r7   ranger4   Fconv2dr   )r(   r)   r-   r.   r   s        r   _uniform_filterrD   q   s      q(8+/JF!<V[!QM;99 !a1	
1 HHVAwJ'11!4m[Z[\1	
  	
s   6Bc           	         t        |d   |d   ||      }t        |d   |d   ||      }t        |d   |d   ||      }t        j                  |j                         |      }t        j                  |j                  d      j                  dd|d         |j                  |d   |d   |d               }	|	j                  | 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   r3   )r   r   r!   r"   mulr   repeatr#   )
r   r   r   r	   r
   r$   r%   gaussian_kernel_z	kernel_xyr&   s
             r   _gaussian_kernel_3drJ      s     "+a.%(E6J!+a.%(E6J!+a.%(E6J.0024EFIYYB&&q![^<  QQQPF ==![^[^[QR^TTr   pad_hpad_wpad_dc           	      >    t        j                  | ||||||f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)rB   r0   )r(   rK   rL   rM   s       r   _reflection_pad_3drQ      s$     55%ueUC)TTr   )r   )collections.abcr   typingr   r   r   torch.nnr   rB   intfloatr	   r
   strr   r'   tupler/   r;   r>   rD   rJ   rQ    r   r   <module>rZ      s   $    $23 2u 2U[[ 2%PUP\P\^aPaJb 2gm 2&EE#E E?E ;;	E
 %,,#$E E@& &S &U6SY>EZ &"*& *s * * *U[ *&v C C  "F   .UU'}U5=e_UMR[[UbgbnbnUU0Uv Uc U# Uc Uf Ur   