
    i                         d dl mZ d dlmZmZmZmZ d dlmZm	Z	 d dl
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 d	lmZ d d
lmZmZ esdgZ G d de      Zy)    )Sequence)AnyListOptionalUnion)Tensortensor)Literal)_uqi_compute_uqi_update)Metric)rank_zero_warn)dim_zero_cat)_MATPLOTLIB_AVAILABLE)_AX_TYPE_PLOT_OUT_TYPEzUniversalImageQualityIndex.plotc                   "    e Zd ZU dZdZeed<   dZeed<   dZeed<   dZ	e
ed<   d	Ze
ed
<   ee   ed<   ee   ed<   eed<   eed<   	 	 	 ddee   dee
   ded   deddf
 fdZdededdfdZdefdZ	 ddeeeee   f      dee   defdZ xZS )UniversalImageQualityIndexa  Compute Universal Image Quality Index (UniversalImageQualityIndex_).

    As input to ``forward`` and ``update`` the metric accepts the following input

    - ``preds`` (:class:`~torch.Tensor`): Predictions from model of shape ``(N,C,H,W)``
    - ``target`` (:class:`~torch.Tensor`): Ground truth values of shape ``(N,C,H,W)``

    As output of `forward` and `compute` the metric returns the following output

    - ``uiqi`` (:class:`~torch.Tensor`): if ``reduction!='none'`` returns float scalar tensor with average UIQI value
      over sample else returns tensor of shape ``(N,)`` with UIQI values per sample

    Args:
        kernel_size: size of the gaussian kernel
        sigma: Standard deviation of the gaussian kernel
        reduction: a method to reduce metric score over labels.

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

        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Return:
        Tensor with UniversalImageQualityIndex score

    Example:
        >>> import torch
        >>> from torchmetrics.image import UniversalImageQualityIndex
        >>> preds = torch.rand([16, 1, 16, 16])
        >>> target = preds * 0.75
        >>> uqi = UniversalImageQualityIndex()
        >>> uqi(preds, target)
        tensor(0.9216)

    Tis_differentiablehigher_is_betterFfull_state_update        plot_lower_boundg      ?plot_upper_boundpredstargetsum_uqinumelkernel_sizesigma	reductionelementwise_meansumnoneNkwargsreturnNc                 ^   t        |   di | |dvrt        d| d      ||dk(  r4t        d       | j	                  dg d       | j	                  d	g d       n:| j	                  d
t        d      d       | j	                  dt        d      d       || _        || _        || _        y )Nr"   zThe `reduction` zI is not valid. Valid options are `elementwise_mean`, `sum`, `none`, None.r%   zMetric `UniversalImageQualityIndex` will save all targets and predictions in the buffer when using`reduction=None` or `reduction='none'. For large datasets, this may lead to a large memory footprint.r   cat)defaultdist_reduce_fxr   r   r   r$   )r+   r   r    )	super__init__
ValueErrorr   	add_stater	   r   r    r!   )selfr   r    r!   r&   	__class__s        k/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/image/uqi.pyr.   z#UniversalImageQualityIndex.__init__P   s     	"6"EE"9+-vw  	V 3x NN7BuNENN8RNFNN9fSk%NHNN7F1IeND&
"    c                    t        ||      \  }}| j                  | j                  dk(  r7| j                  j                  |       | j                  j                  |       yt        ||| j                  | j                  d      }| xj                  |z  c_        |j                  }| xj                  |d   |d   z  |d   | j                  d   z
  dz   z  |d   | j                  d   z
  dz   z  z  c_
        y)	z*Update state with predictions and targets.Nr%   r$   )r!   r            )r   r!   r   appendr   r   r   r    r   shaper   )r1   r   r   	uqi_scorepss        r3   updatez!UniversalImageQualityIndex.updatej   s    #E62v>>!T^^v%=JJe$KKv&$UFD4D4Ddjj\abILLI%LBJJ"Q%"Q%-2a543C3CA3F+F+JKrRSuW[WgWghiWjOjmnOnooJr4   c                 N   | j                   dk(  s| j                   Wt        | j                        }t        | j                        }t	        ||| j
                  | j                  | j                         S | j                   dk(  r| j                  | j                  z  S | j                  S )z&Compute explained variance over state.r%   r#   )	r!   r   r   r   r   r   r    r   r   )r1   r   r   s      r3   computez"UniversalImageQualityIndex.computev   s    >>V#t~~'= ,E!$++.Fvt/?/?T^^\\,0NN>P,Pt||djj(bVZVbVbbr4   valaxc                 &    | j                  ||      S )a  Plot a single or multiple values from the metric.

        Args:
            val: Either a single result from calling `metric.forward` or `metric.compute` or a list of these results.
                If no value is provided, will automatically call `metric.compute` and plot that result.
            ax: An matplotlib axis object. If provided will add plot to that axis

        Returns:
            Figure and Axes object

        Raises:
            ModuleNotFoundError:
                If `matplotlib` is not installed

        .. plot::
            :scale: 75

            >>> # Example plotting a single value
            >>> import torch
            >>> from torchmetrics.image import UniversalImageQualityIndex
            >>> preds = torch.rand([16, 1, 16, 16])
            >>> target = preds * 0.75
            >>> metric = UniversalImageQualityIndex()
            >>> metric.update(preds, target)
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

            >>> # Example plotting multiple values
            >>> import torch
            >>> from torchmetrics.image import UniversalImageQualityIndex
            >>> preds = torch.rand([16, 1, 16, 16])
            >>> target = preds * 0.75
            >>> metric = UniversalImageQualityIndex()
            >>> values = [ ]
            >>> for _ in range(10):
            ...     values.append(metric(preds, target))
            >>> fig_, ax_ = metric.plot(values)

        )_plot)r1   r@   rA   s      r3   plotzUniversalImageQualityIndex.plot~   s    X zz#r""r4   ))   rE   )      ?rF   r#   )NN)__name__
__module____qualname____doc__r   bool__annotations__r   r   r   floatr   r   r   r   intr
   r   r.   r=   r?   r   r   r   r   rD   __classcell__)r2   s   @r3   r   r      s   #J #t"!d!#t#!e!!e!<LOM &.!+FX	#c]# # BC	#
 # 
#4
pF 
pF 
pt 
pc c _c,#E&(6*:":;<,#IQRZI[,#	,#r4   r   N)collections.abcr   typingr   r   r   r   torchr   r	   typing_extensionsr
   !torchmetrics.functional.image.uqir   r   torchmetrics.metricr   torchmetrics.utilitiesr   torchmetrics.utilities.datar   torchmetrics.utilities.importsr   torchmetrics.utilities.plotr   r   __doctest_skip__r   r,   r4   r3   <module>r[      sB    % - -   % G & 1 4 @ @9:K# K#r4   