
    i                         d dl mZ d dlmZmZmZmZ d dl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mZ esdgZ G d de      Zy)    )Sequence)AnyListOptionalUnionN)Tensortensor)Literal)_total_variation_compute_total_variation_update)Metric)dim_zero_cat)_MATPLOTLIB_AVAILABLE)_AX_TYPE_PLOT_OUT_TYPEzTotalVariation.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<   eed	<   ee   ed
<   eed<   ddeed      deddf fdZ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 )TotalVariationa  Compute Total Variation loss (`TV`_).

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

    - ``img`` (:class:`~torch.Tensor`): A tensor of shape ``(N, C, H, W)`` consisting of images

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

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

    Args:
        reduction: a method to reduce metric score over samples

            - ``'mean'``: takes the mean over samples
            - ``'sum'``: takes the sum over samples
            - ``None`` or ``'none'``: return the score per sample

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

    Raises:
        ValueError:
            If ``reduction`` is not one of ``'sum'``, ``'mean'``, ``'none'`` or ``None``

    Example:
        >>> from torch import rand
        >>> from torchmetrics.image import TotalVariation
        >>> tv = TotalVariation()
        >>> img = torch.rand(5, 3, 28, 28)
        >>> tv(img)
        tensor(7546.8018)

    Ffull_state_updateTis_differentiablehigher_is_betterg        plot_lower_boundnum_elements
score_listscore	reduction)meansumnonekwargsreturnNc                 0   t        |   di | ||dvrt        d      || _        | j	                  dg d       | j	                  dt        dt        j                        d	       | j	                  d
t        dt        j                        d	       y )N)r   r   r   zHExpected argument `reduction` to either be 'sum', 'mean', 'none' or Noner   cat)defaultdist_reduce_fxr   r   )dtyper   r    )	super__init__
ValueErrorr   	add_stater	   torchfloatint)selfr   r   	__class__s      j/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/image/tv.pyr(   zTotalVariation.__init__K   s    "6" Y6M%Mghh"|RFwq(DUZ[~vauyy/IZ_`    imgc                     t        |      \  }}| j                  | j                  dk(  r| j                  j                  |       n#| xj                  |j                         z  c_        | xj                  |z  c_        y)z0Update current score with batch of input images.Nr   )r   r   r   appendr   r   r   )r.   r2   r   r   s       r0   updatezTotalVariation.updateU   s]    5c:|>>!T^^v%=OO""5)JJ%))+%J\)r1   c                     | j                   | j                   dk(  rt        | j                        n| j                  }t	        || j
                  | j                         S )zCompute final total variation.r   )r   r   r   r   r   r   )r.   r   s     r0   computezTotalVariation.compute^   sG    151G4>>]cKcT__-imisis't/@/@$..QQr1   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 TotalVariation
            >>> metric = TotalVariation()
            >>> metric.update(torch.rand(5, 3, 28, 28))
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

            >>> # Example plotting multiple values
            >>> import torch
            >>> from torchmetrics.image import TotalVariation
            >>> metric = TotalVariation()
            >>> values = [ ]
            >>> for _ in range(10):
            ...     values.append(metric(torch.rand(5, 3, 28, 28)))
            >>> fig_, ax_ = metric.plot(values)

        )_plot)r.   r8   r9   s      r0   plotzTotalVariation.plotc   s    P zz#r""r1   )r   )NN)__name__
__module____qualname____doc__r   bool__annotations__r   r   r   r,   r   r   r   r
   r   r(   r5   r7   r   r   r   r   r<   __classcell__)r/   s   @r0   r   r      s     D $t#"t""d"!e!VMa(73H+I"J a^a afj a*& *T *R R _c(#E&(6*:":;<(#IQRZI[(#	(#r1   r   )collections.abcr   typingr   r   r   r   r+   r   r	   typing_extensionsr
    torchmetrics.functional.image.tvr   r   torchmetrics.metricr   torchmetrics.utilities.datar   torchmetrics.utilities.importsr   torchmetrics.utilities.plotr   r   __doctest_skip__r   r&   r1   r0   <module>rM      sB    % - -    % ^ & 4 @ @-.l#V l#r1   