
    i!                     Z   d dl Z d dlmZmZ d dlZd dlmZmZ d dlmZm	Z	 d dl
mZ d dlmZ d dlmZ ded	ed
ededeeeef   f
dZdedeeeedf   f   defdZdededefdZdededefdZded	ededeeeef   fdZded	ed
ededef
dZ	 	 	 dded	ed
ee   dedeed      defdZy)    N)OptionalUnion)Tensortensor)conv2dpad)Literal)_check_same_shape)reducepredstarget	hp_filterwindow_sizereturnc           
          | j                   |j                   k7  r|j                  | j                         }t        | |       | j                  dvr&t	        d| j
                   d|j
                   d      t        | j
                        dk(  r"| j                  d      } |j                  d      }|dkD  st	        d| d      || j                  d	      kD  s|| j                  d      kD  r3t	        d
| d| j                  d	       d| j                  d       d      | j                  t        j                        } |j                  t        j                        }|ddddf   j                  | j                   | j                        }| ||fS )a  Update and returns variables required to compute Spatial Correlation Coefficient.

    Args:
        preds: Predicted tensor
        target: Ground truth tensor
        hp_filter: High-pass filter tensor
        window_size: Local window size integer

    Return:
        Tuple of (preds, target, hp_filter) tensors

    Raises:
        ValueError:
            If ``preds`` and ``target`` have different number of channels
            If ``preds`` and ``target`` have different shapes
            If ``preds`` and ``target`` have invalid shapes
            If ``window_size`` is not a positive integer
            If ``window_size`` is greater than the size of the image

    )      zExpected `preds` and `target` to have batch of colored images with BxCxHxW shape  or batch of grayscale images of BxHxW shape. Got preds: z and target: .r      r   z5Expected `window_size` to be a positive integer. Got    z[Expected `window_size` to be less than or equal to the size of the image. Got window_size: z and image size: xN)dtypedevice)r   tor
   ndim
ValueErrorshapelen	unsqueezesizetorchfloat32r   )r   r   r   r   s       v/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/functional/image/scc.py_scc_updater$      sq   * {{fll"5;;'eV$zz ;;-}V\\N!E
 	
 5;;1"!!!$?PQ\P]]^_``UZZ]"kEJJqM&A!!,->uzz!}oQuzzZ[}o]^`
 	

 HHU]]#EYYu}}%F$a-(++%++ell+SI&)##    	input_imgr   .c                    t        |t              r||||f}t        |      dk7  rt        dt        |             | ddddddd|d   f   j	                  dg      }| dddddd|d    df   j	                  dg      }t        j                  || |gd      }|ddddd|d	   ddf   j	                  d	g      }|dddd|d    dddf   j	                  d	g      }t        j                  |||gd	      S )
zlApplies symmetric padding to the 2D image tensor input using ``reflect`` mode (d c b a | a b c d | d c b a).r   z+Expected padding to have length 4, but got Nr   r   )dimsr   dimr   )
isinstanceintr   r   flipr!   cat)r&   r   left_pad	right_padpaddedtop_pad
bottom_pads          r#   _symmetric_reflect_pad_2dr4   L   s   #sCc"
3x1}Fs3xjQRRAq!c!f*,-222<H!QCF79,-222<IYY)Y7Q?FQ1s1v:q()..QC.8G1s1vgi*+00qc0:J99gvz2::r%   kernelc                    t        j                  |j                  d      dz
  dz        }t        j                  |j                  d      dz
  dz        }t        j                  |j                  d      dz
  dz        }t        j                  |j                  d      dz
  dz        }t	        | ||||f      }|j                  ddg      }t        ||dd      S )zHApplies 2D signal convolution to the input tensor with the given kernel.r   r   r   )r   r   stridepadding)mathfloorr    ceilr4   r-   r   )r&   r5   left_paddingright_paddingtop_paddingbottom_paddingr1   s          r#   _signal_convolve_2drA   \   s    ::v{{1~1Q67LIIv{{1~1Q67M**fkk!nq0A56KYYA 2a78N&y|]T_ao6pqF[[!Q F&&A66r%   c                      t        | |      dz  S )zOApplies 2-D Laplace filter to the input tensor with the given high pass filter.g       @)rA   )r&   r5   s     r#   _hp_2d_laplacianrC   h   s    y&1C77r%   windowc                    t        j                  |j                  d      dz
  dz        }t        j                  |j                  d      dz
  dz        }t	        | ||||f      } t	        |||||f      }t        | |dd      }t        ||dd      }t        | dz  |dd      |dz  z
  }t        |dz  |dd      |dz  z
  }t        || z  |dd      ||z  z
  }	|||	fS )z<Computes local variance and covariance of the input tensors.r   r   r   r   r7   )r:   r<   r    r;   r   r   )
r   r   rD   r=   r>   
preds_meantarget_mean	preds_var
target_vartarget_preds_covs
             r#   _local_variance_covariancerK   m   s    
 99fkk!nq0A56LJJA 2a78Mm\=QRE,|]STFva;J1=Kuax1=
AMI	6!Q?+q.PJfunfQJ[[eMeej"222r%   c                 p   | j                   }| j                  }t        j                  dd||f||      |dz  z  }t	        | |      }t	        ||      }t        |||      \  }	}
}d|	|	dk  <   d|
|
dk  <   t        j                  |
      t        j                  |	      z  }|dk(  }d||dk(  <   ||z  }d||<   |S )a[  Computes per channel Spatial Correlation Coefficient.

    Args:
        preds: estimated image of Bx1xHxW shape.
        target: ground truth image of Bx1xHxW shape.
        hp_filter: 2D high-pass filter.
        window_size: size of window for local mean calculation.

    Return:
        Tensor with Spatial Correlation Coefficient score

    r   )r    r   r   r   r   )r   r   r!   onesrC   rK   sqrt)r   r   r   r   r   r   rD   preds_hp	target_hprH   rI   rJ   denidxsccs                  r#   _scc_per_channel_computerT      s     KKE\\F
 ZZaK=USYZ^ikl^lmFy1H 3I.HS\^d.e+Iz+ Ii!m!"JzA~
**Z
 5::i#8
8C
(CCqM
S
 CCHJr%   	reduction)meannoneNc                    |t        g dg dg dg      }|d}|dvrt        d|       t        | |||      \  } }}t        | j	                  d            D cg c]H  }t        | dd|ddddf   j                  d      |dd|ddddf   j                  d      ||      J }}|dk(  r.t        j                  t        j                  |d      g d	      S |d
k(  r"t        t        j                  |d      d      S yc c}w )a  Compute Spatial Correlation Coefficient (SCC_).

    Args:
        preds: predicted images of shape ``(N,C,H,W)`` or ``(N,H,W)``.
        target: ground truth images of shape ``(N,C,H,W)`` or ``(N,H,W)``.
        hp_filter: High-pass filter tensor. default: tensor([[-1,-1,-1],[-1,8,-1],[-1,-1,-1]])
        window_size: Local window size integer. default: 8,
        reduction: Reduction method for output tensor. If ``None`` or ``"none"``,
                   returns a tensor with the per sample results. default: ``"mean"``.

    Return:
        Tensor with scc score

    Example:
        >>> from torch import randn
        >>> from torchmetrics.functional.image import spatial_correlation_coefficient as scc
        >>> x = randn(5, 3, 16, 16)
        >>> scc(x, x)
        tensor(1.)
        >>> x = randn(5, 16, 16)
        >>> scc(x, x)
        tensor(1.)
        >>> x = randn(5, 3, 16, 16)
        >>> y = randn(5, 3, 16, 16)
        >>> scc(x, y, reduction="none")
        tensor([0.0223, 0.0256, 0.0616, 0.0159, 0.0170])

    N)rY   rY   )rY      rY   rW   )rV   rW   z3Expected reduction to be 'mean' or 'none', but got r   r)   )r   r   r   rV   elementwise_mean)rU   )r   r   r$   ranger    rT   r   r!   rV   r.   r   )r   r   r   r   rU   iper_channels          r#   spatial_correlation_coefficientr_      s   F L+|DE		((NykZ[[*5&)[QE69 uzz!}%	 &A 	!!Q1*''*F1aA:,>,H,H,KYXc	
 &	   Fzz%))KQ7YGGFeii3?QRRs   AD)NrZ   rV   )r:   typingr   r   r!   r   r   torch.nn.functionalr   r   typing_extensionsr	   torchmetrics.utilities.checksr
   "torchmetrics.utilities.distributedr   r,   tupler$   r4   rA   rC   rK   rT   r_    r%   r#   <module>rg      sm    "    + % ; 5/$v /$v /$& /$s /$W\]cekms]sWt /$d; ;eCsCx<P6Q ;V\ ; 	76 	76 	7f 	78 8 86 8
3f 3f 3f 3QVW]_egmWmQn 3*"F "F "v "\_ "dj "P #'9?555 5 	5
  4565 5r%   