
    iU                        d dl mZ d dlmZmZmZ d dlZd dlmZ d dlm	Z
 d dlmZ d dlmZmZmZ d dlmZ d d	lmZ d
ededeeef   fdZ	 	 	 	 	 	 	 	 d%d
edededeeee   f   deeee   f   deeeeeef   f      dededededeeeeef   f   fdZ	 d&deded   defdZ	 	 	 	 	 	 	 	 	 d'd
edededeeee   f   deeee   f   ded   deeeeeef   f      dededededeeeeef   f   fdZ	 	 	 	 	 	 	 d(d
edededeeee   f   deeee   f   deeeeeef   f      dededeed      deeef   fdZ	 	 	 	 	 	 	 	 d)d
edededeeee   f   deeee   f   deeeeeef   f      dededeeeeeeef   eed f   f   deed      defd!Z	 d&d"eded   defd#Z	 	 	 	 	 	 	 	 	 d*d
edededeeee   f   deeee   f   ded   deeeeeef   f      dededeed f   deed      defd$Z y)+    )Sequence)ListOptionalUnionN)Tensor)
functional)Literal)_gaussian_kernel_2d_gaussian_kernel_3d_reflection_pad_3d)_check_same_shapereducepredstargetreturnc                    | j                   |j                   k7  r|j                  | j                         }t        | |       t        | j                        dvr&t        d| j                   d|j                   d      | |fS )zUpdate and returns variables required to compute Structural Similarity Index Measure.

    Args:
        preds: Predicted tensor
        target: Ground truth tensor

    )      zMExpected `preds` and `target` to have BxCxHxW or BxCxDxHxW shape. Got preds: z and target: .)dtypetor   lenshape
ValueError)r   r   s     w/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/functional/image/ssim.py_ssim_check_inputsr      sz     {{fll"5;;'eV$
5;;v% ;;-}V\\N!E
 	
 &=    gaussian_kernelsigmakernel_size
data_rangek1k2return_full_imagereturn_contrast_sensitivityc
                 X   | j                   dk(  }
t        |t              s|
rd|gz  nd|gz  }t        |t              s|
rd|gz  nd|gz  }t        |      t        |j                        dz
  k7  r-t        dt        |       dt        |j                               t        |      dvrt        dt        |             t        |      t        |j                        dz
  k7  r-t        dt        |       dt        |j                               t        |      dvrt        dt        |             |r|	rt        d      t        d	 |D              rt        d
| d      t        d |D              rt        d| d      |Kt        | j                         | j                         z
  |j                         |j                         z
        }nWt        |t              rGt        j                  | |d   |d         } t        j                  ||d   |d         }|d   |d   z
  }t        ||z  d      }t        ||z  d      }| j                  }| j                  d      }| j                  }|D cg c]  }t!        d|z  dz         dz  dz    }}|r|d   dz
  dz  }|d   dz
  dz  }n|d   dz
  dz  }|d   dz
  dz  }|
r9|d   dz
  dz  }t#        | |||      } t#        ||||      }|rYt%        |||||      }nIt'        j(                  | ||||fd      } t'        j(                  |||||fd      }|rt+        |||||      }|sIt        j,                  |dg|||      t        j.                  t        j0                  |||            z  }t        j2                  | || | z  ||z  | |z  f      }|
rt'        j4                  ||      nt'        j6                  ||      }|j9                  | j                  d         }|d   j                  d      }|d   j                  d      }|d   |d   z  }t        j                  |d   |z
  d      }t        j                  |d   |z
  d      }|d   |z
  }d|j;                  |      z  |z   }||z   j;                  |      |z   } d|z  |z   |z  ||z   |z   | z  z  }!|	r|| z  }"|
r|"d|| || | f   }"n|"d|| || f   }"|!j=                  |!j                  d   d      j?                  d      |"j=                  |"j                  d   d      j?                  d      fS |r0|!j=                  |!j                  d   d      j?                  d      |!fS |!j=                  |!j                  d   d      j?                  d      S c c}w )a%  Compute Structural Similarity Index Measure.

    Args:
        preds: estimated image
        target: ground truth image
        gaussian_kernel: If true (default), a gaussian kernel is used, if false a uniform kernel is used
        sigma: Standard deviation of the gaussian kernel, anisotropic kernels are possible.
            Ignored if a uniform kernel is used
        kernel_size: the size of the uniform kernel, anisotropic kernels are possible.
            Ignored if a Gaussian kernel is used
        data_range: Range of the image. If ``None``, it is determined from the image (max - min)
        k1: Parameter of SSIM.
        k2: Parameter of SSIM.
        return_full_image: If true, the full ``ssim`` image is returned as a second argument.
            Mutually exclusive with ``return_contrast_sensitivity``
        return_contrast_sensitivity: If true, the contrast term is returned as a second argument.
            The luminance term can be obtained with luminance=ssim/contrast
            Mutually exclusive with ``return_full_image``

    r         z`kernel_size` has dimension zD, but expected to be two less that target dimensionality, which is: )r)   r(   zMExpected `kernel_size` dimension to be 2 or 3. `kernel_size` dimensionality: zWArguments `return_full_image` and `return_contrast_sensitivity` are mutually exclusive.c              3   :   K   | ]  }|d z  dk(  xs |dk    yw)r)   r   N ).0xs     r   	<genexpr>z_ssim_update.<locals>.<genexpr>k   s%     
5A1q5A:as   z8Expected `kernel_size` to have odd positive number. Got r   c              3   &   K   | ]	  }|d k    yw)r   Nr+   )r,   ys     r   r.   z_ssim_update.<locals>.<genexpr>n   s     
!5a165s   z.Expected `sigma` to have positive number. Got r      )minmaxg      @g      ?reflect)mode)r   device)groupsg        )r2   r   .) ndim
isinstancer   r   r   r   anyr3   r2   tupletorchclamppowr6   sizer   intr   r   Fpadr
   onesprodtensorcatconv3dconv2dsplitr   reshapemean)#r   r   r   r    r!   r"   r#   r$   r%   r&   is_3dc1c2r6   channelr   sgauss_kernel_sizepad_hpad_wpad_dkernel
input_listoutputsoutput_list
mu_pred_sqmu_target_sqmu_pred_targetsigma_pred_sqsigma_target_sqsigma_pred_targetupperlowerssim_idx_full_imagecontrast_sensitivitys#                                      r   _ssim_updaterd   .   s#   @ JJ!OEk8,+0a;-'a;-6GeX&$UG!ug+
;3v||,q00*3{+;*< =fll+,.
 	
 ;v%[\_`k\l[mn
 	
 5zS&***3{+;*< =fll+,.
 	
 5z[\_`k\l[mn
 	
 8rss

5
55ST_S``abcc

!5
!!I%PQRSSuyy{2FJJL6::<4OP
	J	&Ez!}*Q-HVAJqMJ]Z]2
	R*_a	 B	R*_a	 B\\FjjmGKKE=BCUS1Ws]+a/!3UC"1%)a/"1%)a/Q!#)Q!#)Q!#)"5%>#FE5%@(2CUESYZFeeUE59	JvueU;)L(2CUESYZFWa6+6eFSV[V`V`LLE&AW
 
 E655=&6/5SY>Z[J>Cahhz6':R\^dmtIuG--A/KQ##A&Jq>%%a(L ^k!n4N KKA ;EMkk+a.<"?SIO#A7!$$U++b0E_,007"<E.3u<*|B[^`B`diAij"$u}#7UE6\5RWQW<Y^`e_eYe8e#f #7UE6\5RWQW<8W#X "**+>+D+DQ+GLQQRTUWkWsWs &&q)2X

$r( 	 "**+>+D+DQ+GLQQRTUWjjj&&':'@'@'CRHMMbQQy Ds   6V'similarities	reduction)elementwise_meansumnoneNc                     t        | |      S )a  Apply the specified reduction to pre-computed structural similarity.

    Args:
        similarities: per image similarities for a batch of images.
        reduction: a method to reduce metric score over individual batch scores

                - ``'elementwise_mean'``: takes the mean
                - ``'sum'``: takes the sum
                - ``'none'`` or ``None``: no reduction will be applied

    Returns:
        The reduced SSIM score

    r   )re   rf   s     r   _ssim_computerk      s    $ ,	**r   c                     t        | |      \  } }t        | ||||||||	|

      }t        |t              r|\  }}t	        ||      |fS |}t	        ||      S )a  Compute Structural Similarity Index Measure.

    Args:
        preds: estimated image
        target: ground truth image
        gaussian_kernel: If true (default), a gaussian kernel is used, if false a uniform kernel is used
        sigma: Standard deviation of the gaussian kernel, anisotropic kernels are possible.
            Ignored if a uniform kernel is used
        kernel_size: the size of the uniform kernel, anisotropic kernels are possible.
            Ignored if a Gaussian kernel is used
        reduction: a method to reduce metric score over labels.

            - ``'elementwise_mean'``: takes the mean
            - ``'sum'``: takes the sum
            - ``'none'`` or ``None``: no reduction will be applied

        data_range:
            the range of the data. If None, it is determined from the data (max - min). If a tuple is provided then
            the range is calculated as the difference and input is clamped between the values.
        k1: Parameter of SSIM.
        k2: Parameter of SSIM.
        return_full_image: If true, the full ``ssim`` image is returned as a second argument.
            Mutually exclusive with ``return_contrast_sensitivity``
        return_contrast_sensitivity: If true, the constant term is returned as a second argument.
            The luminance term can be obtained with luminance=ssim/contrast
            Mutually exclusive with ``return_full_image``

    Return:
        Tensor with SSIM score

    Raises:
        TypeError:
            If ``preds`` and ``target`` don't have the same data type.
        ValueError:
            If ``preds`` and ``target`` don't have ``BxCxHxW shape``.
        ValueError:
            If the length of ``kernel_size`` or ``sigma`` is not ``2``.
        ValueError:
            If one of the elements of ``kernel_size`` is not an ``odd positive number``.
        ValueError:
            If one of the elements of ``sigma`` is not a ``positive number``.

    Example:
        >>> from torchmetrics.functional.image import structural_similarity_index_measure
        >>> preds = torch.rand([3, 3, 256, 256])
        >>> target = preds * 0.75
        >>> structural_similarity_index_measure(preds, target)
        tensor(0.9219)

    )r   rd   r:   r<   rk   )r   r   r   r    r!   rf   r"   r#   r$   r%   r&   similarity_pack
similarityimages                 r   #structural_similarity_index_measurerp      sw    ~ 'uf5ME6"

#O /5)+
EZ3U:: JY//r   	normalizerelusimplec	                     t        | |||||||d	      \  }	}
|dk(  r*t        j                  |	      }	t        j                  |
      }
|	|
fS )NT)r&   rs   )rd   r=   rs   )r   r   r   r    r!   r"   r#   r$   rq   simrc   s              r   _get_normalized_sim_and_csrw   '  sb     !-

$(
!C	 Fjjo$zz*>?$$$r   betas.c
                 6   g }
| j                   dk(  }t        |t              s|rd|gz  nd|gz  }t        |t              s|rd|gz  nd|gz  }| j                         d   dt	        |      z  k  s"| j                         d   dt	        |      z  k  r't        dt	        |       ddt	        |      z   d      t        d	t	        |      d	z
        dz  }| j                         d   |z  |d
   d	z
  k  r*t        dt	        |       d|d
    d|d
   d	z
  |z   d      | j                         d   |z  |d	   d	z
  k  r*t        dt	        |       d|d	    d|d	   d	z
  |z   d      t        t	        |            D ]  }t        | ||||||||		      \  }}|
j                  |       t	        |      dk(  r-t        j                  | d      } t        j                  |d      }ft	        |      dk(  r-t        j                  | d      } t        j                  |d      }t        d       |
d<   t        j                  |
      }|	dk(  r|d	z   dz  }t        j                  ||j                         j#                  dd	      }||z  }t        j$                  |d
      S )a  Compute Multi-Scale Structural Similarity Index Measure.

    Adapted from: https://github.com/jorge-pessoa/pytorch-msssim/blob/master/pytorch_msssim/__init__.py.

    Args:
        preds: estimated image
        target: ground truth image
        gaussian_kernel: If true, a gaussian kernel is used, if false a uniform kernel is used
        sigma: Standard deviation of the gaussian kernel
        kernel_size: size of the gaussian kernel
        reduction: a method to reduce metric score over labels.

            - ``'elementwise_mean'``: takes the mean
            - ``'sum'``: takes the sum
            - ``'none'`` or ``None``: no reduction will be applied

        data_range: Range of the image. If ``None``, it is determined from the image (max - min)
        k1: Parameter of structural similarity index measure.
        k2: Parameter of structural similarity index measure.
        betas: Exponent parameters for individual similarities and contrastive sensitives returned by different image
            resolutions.
        normalize: When MultiScaleSSIM loss is used for training, it is desirable to use normalizes to improve the
            training stability. This `normalize` argument is out of scope of the original implementation [1], and it is
            adapted from https://github.com/jorge-pessoa/pytorch-msssim instead.

    Raises:
        ValueError:
            If the image height or width is smaller then ``2 ** len(betas)``.
        ValueError:
            If the image height is smaller than ``(kernel_size[0] - 1) * max(1, (len(betas) - 1)) ** 2``.
        ValueError:
            If the image width is smaller than ``(kernel_size[0] - 1) * max(1, (len(betas) - 1)) ** 2``.

    r   r(   r)   r8   z)For a given number of `betas` parameters zH, the image height and width dimensions must be larger than or equal to r   r1   r   z and kernel size z', the image height must be larger than z&, the image width must be larger than )rq   )r)   r)   )r)   r)   r)   z(length of kernel_size is neither 2 nor 3rt   )r6   )axis)r9   r:   r   r@   r   r   r3   rangerw   appendrB   
avg_pool2d
avg_pool3dr=   stackrF   r6   viewrE   )r   r   r   r    r!   r"   r#   r$   rx   rq   mcs_listrM   
_betas_div_rv   rc   	mcs_stackmcs_weighteds                     r   _multiscale_ssim_updater   C  s   h  HJJ!OEk8,+0a;-'a;-6GeX&$UG!ug+zz|B!s5z/)UZZ\"-=SZ-O7E
| D(()SZ'8;
 	

 QUa)Q.Jzz|B:%Q!);;7E
|CTU`abUcTd e56A!nq6HJ5V4WWXZ
 	
 zz|B:%Q!);;7E
|CTU`abUcTd e45@^a5G:4U3VVWY
 	

 3u:$>6?E;
BPR^g%
!! 	,-{q LL/E\\&&1F"LL	2E\\&)4FGHH  HRLH%IH]a'	LLy'7'78==b!DEe#L::l++r   mcs_per_imagec                     t        | |      S )a  Apply the specified reduction to pre-computed multi-scale structural similarity.

    Args:
        mcs_per_image: per image similarities for a batch of images.
        reduction: a method to reduce metric score over individual batch scores

                - ``'elementwise_mean'``: takes the mean
                - ``'sum'``: takes the sum
                - ``'none'`` or ``None``: no reduction will be applied

    Returns:
        The reduced multi-scale structural similarity

    r   )r   rf   s     r   _multiscale_ssim_computer     s    $ -++r   c                    t        |	t              st        d      t        |	t              rt        d |	D              st        d      |
r|
dvrt        d      t	        | |      \  } }t        | ||||||||	|

      }t        ||      S )ae
  Compute `MultiScaleSSIM`_, Multi-scale Structural Similarity Index Measure.

    This metric is a generalization of Structural Similarity Index Measure by incorporating image details at different
    resolution scores.

    Args:
        preds: Predictions from model of shape ``[N, C, H, W]``
        target: Ground truth values of shape ``[N, C, H, W]``
        gaussian_kernel: If true, a gaussian kernel is used, if false a uniform kernel is used
        sigma: Standard deviation of the gaussian kernel
        kernel_size: size of the gaussian kernel
        reduction: a method to reduce metric score over labels.

            - ``'elementwise_mean'``: takes the mean
            - ``'sum'``: takes the sum
            - ``'none'`` or ``None``: no reduction will be applied

        data_range:
            the range of the data. If None, it is determined from the data (max - min). If a tuple is provided then
            the range is calculated as the difference and input is clamped between the values.
        k1: Parameter of structural similarity index measure.
        k2: Parameter of structural similarity index measure.
        betas: Exponent parameters for individual similarities and contrastive sensitivities returned by different image
            resolutions.
        normalize: When MultiScaleSSIM loss is used for training, it is desirable to use normalizes to improve the
            training stability. This `normalize` argument is out of scope of the original implementation [1], and it is
            adapted from https://github.com/jorge-pessoa/pytorch-msssim instead.

    Return:
        Tensor with Multi-Scale SSIM score

    Raises:
        TypeError:
            If ``preds`` and ``target`` don't have the same data type.
        ValueError:
            If ``preds`` and ``target`` don't have ``BxCxHxW shape``.
        ValueError:
            If the length of ``kernel_size`` or ``sigma`` is not ``2``.
        ValueError:
            If one of the elements of ``kernel_size`` is not an ``odd positive number``.
        ValueError:
            If one of the elements of ``sigma`` is not a ``positive number``.

    Example:
        >>> from torch import rand
        >>> from torchmetrics.functional.image import multiscale_structural_similarity_index_measure
        >>> preds = rand([3, 3, 256, 256])
        >>> target = preds * 0.75
        >>> multiscale_structural_similarity_index_measure(preds, target, data_range=1.0)
        tensor(0.9628)

    References:
        [1] Multi-Scale Structural Similarity For Image Quality Assessment by Zhou Wang, Eero P. Simoncelli and Alan C.
        Bovik `MultiScaleSSIM`_

    z3Argument `betas` is expected to be of a type tuple.c              3   <   K   | ]  }t        |t                y w)N)r:   float)r,   betas     r   r.   zAmultiscale_structural_similarity_index_measure.<locals>.<genexpr>  s     +VPUJtU,CPUs   z5Argument `betas` is expected to be a tuple of floats.rr   zNArgument `normalize` to be expected either `None` or one of 'relu' or 'simple')r:   r<   r   allr   r   r   )r   r   r   r    r!   rf   r"   r#   r$   rx   rq   r   s               r   .multiscale_structural_similarity_index_measurer     s    J eU#NOO%+VPU+V(VPQQY&88ijj&uf5ME6+v{JBPUW`M $M9==r   )T      ?   N{Gz?Q?FF)rg   )	Tr   r   rg   Nr   r   FF)Tr   r   Nr   r   N)Tr   r   Nr   r   gǺ?g48EG?ga4?g??g9EGr?N)	Tr   r   rg   Nr   r   r   rs   )!collections.abcr   typingr   r   r   r=   r   torch.nnr   rB   typing_extensionsr	   #torchmetrics.functional.image.utilsr
   r   r   torchmetrics.utilities.checksr   "torchmetrics.utilities.distributedr   r<   r   boolr   rA   rd   rk   rp   rw   r   r   r   r+   r   r   <module>r      s/   % ( (   $ % l l ; 5f f vv~9N , !+.-/>B#(-LRLRLR LR '(	LR
 sHSM)*LR ueE5L&99:;LR 	LR 	LR LR "&LR 65(()LRb CU++>?+ +0 !+.-/BT>B#(-R0R0R0 R0 '(	R0
 sHSM)*R0 >?R0 ueE5L&99:;R0 	R0 	R0 R0 "&R0 65(()R0p !+.-/>B59%%% % '(	%
 sHSM)*% ueE5L&99:;% 	% 	%  012% 66>%> !+.-/>BQ 6:!f,f,f, f, '(	f,
 sHSM)*f, ueE5L&99:;f, 	f, 	f, ueUE5895;LLMf,   012!f," #f,V CU,,>?, ,0 !+.-/BT>BG5;P>P>P> P> '(	P>
 sHSM)*P> >?P> ueE5L&99:;P> 	P> 	P> P>  012P> P>r   