Ë
    ýÿæiEO  ã                   ó  — 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mZmZmZ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dgZ" G d„ de«      Z# G d„ de«      Z$ G d„ de«      Z%y)é    )ÚSequence)ÚAnyÚOptionalÚUnionN)ÚTensor)ÚLiteral)Ú_ClassificationTaskWrapper)Ú_exact_match_reduceÚ_multiclass_exact_match_updateÚ_multilabel_exact_match_update)Ú&_multiclass_stat_scores_arg_validationÚ_multiclass_stat_scores_formatÚ)_multiclass_stat_scores_tensor_validationÚ&_multilabel_stat_scores_arg_validationÚ_multilabel_stat_scores_formatÚ)_multilabel_stat_scores_tensor_validation)ÚMetric)Údim_zero_cat)ÚClassificationTaskNoBinary)Ú_MATPLOTLIB_AVAILABLE)Ú_AX_TYPEÚ_PLOT_OUT_TYPEzMulticlassExactMatch.plotzMultilabelExactMatch.plotc                   ó  ‡ — e Zd ZU 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	<   d
Zeed<   dZeed<   	 	 	 ddeded   dee   de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 ) ÚMulticlassExactMatcha]  Compute Exact match (also known as subset accuracy) for multiclass tasks.

    Exact Match is a stricter version of accuracy where all labels have to match exactly for the sample to be
    correctly classified.

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

    - ``preds`` (:class:`~torch.Tensor`): An int tensor of shape ``(N, ...)`` or float tensor of shape ``(N, C, ..)``.
      If preds is a floating point we apply ``torch.argmax`` along the ``C`` dimension to automatically convert
      probabilities/logits into an int tensor.
    - ``target`` (:class:`~torch.Tensor`): An int tensor of shape ``(N, ...)``.

    As output to ``forward`` and ``compute`` the metric returns the following output:

    - ``mcem`` (:class:`~torch.Tensor`): A tensor whose returned shape depends on the ``multidim_average`` argument:

        - If ``multidim_average`` is set to ``global`` the output will be a scalar tensor
        - If ``multidim_average`` is set to ``samplewise`` the output will be a tensor of shape ``(N,)``

    If ``multidim_average`` is set to ``samplewise`` we expect at least one additional dimension ``...`` to be present,
    which the reduction will then be applied over instead of the sample dimension ``N``.

    Args:
        num_classes: Integer specifying the number of labels
        multidim_average:
            Defines how additionally dimensions ``...`` should be handled. Should be one of the following:

            - ``global``: Additional dimensions are flatted along the batch dimension
            - ``samplewise``: Statistic will be calculated independently for each sample on the ``N`` axis.
              The statistics in this case are calculated over the additional dimensions.

        ignore_index:
            Specifies a target value that is ignored and does not contribute to the metric calculation
        validate_args: bool indicating if input arguments and tensors should be validated for correctness.
            Set to ``False`` for faster computations.

    Example (multidim tensors):
        >>> from torch import tensor
        >>> from torchmetrics.classification import MulticlassExactMatch
        >>> target = tensor([[[0, 1], [2, 1], [0, 2]], [[1, 1], [2, 0], [1, 2]]])
        >>> preds = tensor([[[0, 1], [2, 1], [0, 2]], [[2, 2], [2, 1], [1, 0]]])
        >>> metric = MulticlassExactMatch(num_classes=3, multidim_average='global')
        >>> metric(preds, target)
        tensor(0.5000)

    Example (multidim tensors):
        >>> from torchmetrics.classification import MulticlassExactMatch
        >>> target = tensor([[[0, 1], [2, 1], [0, 2]], [[1, 1], [2, 0], [1, 2]]])
        >>> preds = tensor([[[0, 1], [2, 1], [0, 2]], [[2, 2], [2, 1], [1, 0]]])
        >>> metric = MulticlassExactMatch(num_classes=3, multidim_average='samplewise')
        >>> metric(preds, target)
        tensor([1., 0.])

    ÚtotalFÚis_differentiableTÚhigher_is_betterÚfull_state_updateç        Úplot_lower_boundç      ð?Úplot_upper_boundÚClassÚplot_legend_nameNÚnum_classesÚmultidim_average©ÚglobalÚ
samplewiseÚignore_indexÚvalidate_argsÚkwargsÚreturnc                 óÖ  •— t        ‰| �  di |¤Ž d\  }}|rt        |||||«       || _        || _        || _        || _        | j                  d| j                  dk(  r%t        j                  dt        j                  ¬«      ng | j                  dk(  rdnd¬«       | j                  d	t        j                  dt        j                  ¬«      | j                  dk(  rd¬«       y d
¬«       y )N)é   NÚcorrectr(   r/   ©ÚdtypeÚsumÚcat©Údist_reduce_fxr   Úmean© )ÚsuperÚ__init__r   r%   r&   r*   r+   Ú	add_stateÚtorchÚzerosÚlong)	Úselfr%   r&   r*   r+   r,   Útop_kÚaverageÚ	__class__s	           €ú|/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/classification/exact_match.pyr:   zMulticlassExactMatch.__init__m   sä   ø€ ô 	‰ÑÑ"˜6Ò"Ø ‰ˆˆwÙÜ2°;ÀÀwÐP`ÐbnÔoØ&ˆÔØ 0ˆÔØ(ˆÔØ*ˆÔà�‰ØØ04×0EÑ0EÈÒ0QŒE�K‰K˜¤§¡Õ,ÐWYØ$(×$9Ñ$9¸XÒ$E™5È5ð 	ô 	
ð
 	�‰ØÜ�K‰K˜¤§¡Ô,Ø$(×$9Ñ$9¸XÒ$E˜5ð 	õ 	
ð LRð 	õ 	
ó    ÚpredsÚtargetc                 óÀ  — | j                   r-t        ||| j                  | j                  | j                  «       t        ||d«      \  }}t        ||| j                  | j                  «      \  }}| j                  dk(  rmt        | j                  t        «      st        d«      ‚| j                  j                  |«       t        | j                  t        «      st        d«      ‚|| _        yt        | j                  t        «      st        d«      ‚| xj                  |z  c_        t        | j                  t        «      st        d«      ‚| xj                  |z  c_        y)z2Update metric states with predictions and targets.r/   r)   ú8Expected `self.correct` to be a list in samplewise mode.ú8Expected `self.total` to be a Tensor in samplewise mode.ú6Expected `self.correct` to be a tensor in global mode.N)r+   r   r%   r&   r*   r   r   Ú
isinstancer0   ÚlistÚ	TypeErrorÚappendr   r   ©r?   rE   rF   r0   r   s        rC   ÚupdatezMulticlassExactMatch.update‰   s  € à×ÒÜ5Ø�v˜t×/Ñ/°×1FÑ1FÈ×HYÑHYôô 7°u¸fÀaÓH‰ˆˆvä7¸¸vÀt×G\ÑG\Ð^b×^oÑ^oÓp‰ˆ�Ø× Ñ  LÒ0Ü˜dŸl™l¬DÔ1ÜÐ ZÓ[Ð[Ø�L‰L×Ñ Ô(ä˜dŸj™j¬&Ô1ÜÐ ZÓ[Ð[ØˆD�Jä˜dŸl™l¬FÔ3ÜÐ XÓYÐYØ�LŠL˜GÑ#�Lä˜dŸj™j¬&Ô1ÜÐ ZÓ[Ð[Ø�JŠJ˜%ÑŽJrD   c                 ó  — t        | j                  t        «      rt        | j                  «      n| j                  }t        |t        «      rt        | j
                  t        «      st        d«      ‚t        || j
                  «      S ©zCompute metric.z>Expected `correct` and `total` to be tensors after processing.©rK   r0   rL   r   r   r   rM   r
   ©r?   r0   s     rC   ÚcomputezMulticlassExactMatch.compute£   ó\   € ä0:¸4¿<¹<ÌÔ0N”,˜tŸ|™|Ô,ÐTX×T`ÑT`ˆô ˜'¤6Ô*´*¸T¿Z¹ZÌÔ2PÜÐ\Ó]Ð]ä" 7¨D¯J©JÓ7Ð7rD   Ú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 object and Axes object

        Raises:
            ModuleNotFoundError:
                If `matplotlib` is not installed

        .. plot::
            :scale: 75

            >>> # Example plotting a single value per class
            >>> from torch import randint
            >>> from torchmetrics.classification import MulticlassExactMatch
            >>> metric = MulticlassExactMatch(num_classes=3)
            >>> metric.update(randint(3, (20,5)), randint(3, (20,5)))
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

            >>> from torch import randint
            >>> # Example plotting a multiple values per class
            >>> from torchmetrics.classification import MulticlassExactMatch
            >>> metric = MulticlassExactMatch(num_classes=3)
            >>> values = []
            >>> for _ in range(20):
            ...     values.append(metric(randint(3, (20,5)), randint(3, (20,5))))
            >>> fig_, ax_ = metric.plot(values)

        ©Ú_plot©r?   rW   rX   s      rC   ÚplotzMulticlassExactMatch.plot­   ó   € ðP �z‰z˜#˜rÓ"Ð"rD   )r(   NT©NN©Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ú__annotations__r   Úboolr   r   r    Úfloatr"   r$   ÚstrÚintr   r   r   r:   rP   rU   r   r   r   r   r]   Ú__classcell__©rB   s   @rC   r   r   -   s  ø… ñ5ðn ƒMØ#Ð�tÓ#Ø!Ð�dÓ!Ø#Ð�tÓ#Ø!Ð�eÓ!Ø!Ð�eÓ!Ø#Ð�cÓ#ð
 =EØ&*Ø"ñ
àð
ð "Ð"8Ñ9ð
ð ˜s‘mð	
ð
 ð
ð ð
ð 
õ
ð8 ˜Fð  ¨Fð  °tó  ð48˜ó 8ð _cñ(#Ø˜E &¨(°6Ñ*:Ð":Ñ;Ñ<ð(#ØIQÐRZÑI[ð(#à	÷(#rD   r   c                   ó
  ‡ — e Zd ZU 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	<   d
Zeed<   dZeed<   	 	 	 	 ddededed   dee   de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 )!ÚMultilabelExactMatcha;  Compute Exact match (also known as subset accuracy) for multilabel tasks.

    Exact Match is a stricter version of accuracy where all labels have to match exactly for the sample to be
    correctly classified.

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

    - ``preds`` (:class:`~torch.Tensor`): An int tensor or float tensor of shape ``(N, C, ..)``. If preds is a
      floating point tensor with values outside [0,1] range we consider the input to be logits and will auto apply
      sigmoid per element. Additionally, we convert to int tensor with thresholding using the value in ``threshold``.
    - ``target`` (:class:`~torch.Tensor`): An int tensor of shape ``(N, C, ...)``.

    As output to ``forward`` and ``compute`` the metric returns the following output:

    - ``mlem`` (:class:`~torch.Tensor`): A tensor whose returned shape depends on the ``multidim_average`` argument:

        - If ``multidim_average`` is set to ``global`` the output will be a scalar tensor
        - If ``multidim_average`` is set to ``samplewise`` the output will be a tensor of shape ``(N,)``

    If ``multidim_average`` is set to ``samplewise`` we expect at least one additional dimension ``...`` to be present,
    which the reduction will then be applied over instead of the sample dimension ``N``.

    Args:
        num_labels: Integer specifying the number of labels
        threshold: Threshold for transforming probability to binary (0,1) predictions
        multidim_average:
            Defines how additionally dimensions ``...`` should be handled. Should be one of the following:

            - ``global``: Additional dimensions are flatted along the batch dimension
            - ``samplewise``: Statistic will be calculated independently for each sample on the ``N`` axis.
              The statistics in this case are calculated over the additional dimensions.

        ignore_index:
            Specifies a target value that is ignored and does not contribute to the metric calculation
        validate_args: bool indicating if input arguments and tensors should be validated for correctness.
            Set to ``False`` for faster computations.

    Example (preds is int tensor):
        >>> from torch import tensor
        >>> from torchmetrics.classification import MultilabelExactMatch
        >>> target = tensor([[0, 1, 0], [1, 0, 1]])
        >>> preds = tensor([[0, 0, 1], [1, 0, 1]])
        >>> metric = MultilabelExactMatch(num_labels=3)
        >>> metric(preds, target)
        tensor(0.5000)

    Example (preds is float tensor):
        >>> from torchmetrics.classification import MultilabelExactMatch
        >>> target = tensor([[0, 1, 0], [1, 0, 1]])
        >>> preds = tensor([[0.11, 0.22, 0.84], [0.73, 0.33, 0.92]])
        >>> metric = MultilabelExactMatch(num_labels=3)
        >>> metric(preds, target)
        tensor(0.5000)

    Example (multidim tensors):
        >>> from torchmetrics.classification import MultilabelExactMatch
        >>> target = tensor([[[0, 1], [1, 0], [0, 1]], [[1, 1], [0, 0], [1, 0]]])
        >>> preds = tensor([[[0.59, 0.91], [0.91, 0.99], [0.63, 0.04]],
        ...                 [[0.38, 0.04], [0.86, 0.780], [0.45, 0.37]]])
        >>> metric = MultilabelExactMatch(num_labels=3, multidim_average='samplewise')
        >>> metric(preds, target)
        tensor([0., 0.])

    r   Fr   Tr   r   r   r    r!   r"   ÚLabelr$   NÚ
num_labelsÚ	thresholdr&   r'   r*   r+   r,   r-   c                 óÜ  •— t        ‰| �  di |¤Ž |rt        ||d ||¬«       || _        || _        || _        || _        || _        | j                  d| j
                  dk(  r%t        j                  dt        j                  ¬«      ng | j
                  dk(  rdnd¬«       | j                  d	t        j                  dt        j                  ¬«      | j
                  dk(  rd¬«       y d
¬«       y )N)rA   r&   r*   r0   r(   r/   r1   r3   r4   r5   r   r7   r8   )r9   r:   r   ro   rp   r&   r*   r+   r;   r<   r=   r>   )r?   ro   rp   r&   r*   r+   r,   rB   s          €rC   r:   zMultilabelExactMatch.__init__"  sæ   ø€ ô 	‰ÑÑ"˜6Ò"ÙÜ2Ø˜I¨tÐFVÐeqõð %ˆŒØ"ˆŒØ 0ˆÔØ(ˆÔØ*ˆÔà�‰ØØ04×0EÑ0EÈÒ0QŒE�K‰K˜¤§¡Õ,ÐWYØ$(×$9Ñ$9¸XÒ$E™5È5ð 	ô 	
ð
 	�‰ØÜ�K‰K˜¤§¡Ô,Ø$(×$9Ñ$9¸XÒ$E˜5ð 	õ 	
ð LRð 	õ 	
rD   rE   rF   c                 ó  — | j                   r-t        ||| j                  | j                  | j                  «       t        ||| j                  | j                  | j                  «      \  }}t        ||| j                  | j                  | j                  ¬«      \  }}| j                  dk(  rmt        | j                  t        «      st        d«      ‚| j                  j                  |«       t        | j                  t        «      st        d«      ‚|| _        yt        | j                  t        «      st        d«      ‚| xj                  |z  c_	        t        | j                  t        «      st        d«      ‚| xj                  |z  c_        y)z*Update state with predictions and targets.)rE   rF   ro   r&   r*   r)   rH   rI   rJ   N)r+   r   ro   r&   r*   r   rp   r   rK   r0   rL   rM   rN   r   r   rO   s        rC   rP   zMultilabelExactMatch.updateA  s3  € à×ÒÜ5Ø�v˜tŸ™°×0EÑ0EÀt×GXÑGXôô 7Ø�6˜4Ÿ?™?¨D¯N©N¸D×<MÑ<Mó
‰ˆˆvô 8ØØØ—‘Ø!×2Ñ2Ø×*Ñ*ô
‰ˆ�ð × Ñ  LÒ0Ü˜dŸl™l¬DÔ1ÜÐ ZÓ[Ð[Ø�L‰L×Ñ Ô(ä˜dŸj™j¬&Ô1ÜÐ ZÓ[Ð[ØˆD�Jä˜dŸl™l¬FÔ3ÜÐ XÓYÐYØ�LŠL˜GÑ#�Lä˜dŸj™j¬&Ô1ÜÐ ZÓ[Ð[Ø�JŠJ˜%ÑŽJrD   c                 ó  — t        | j                  t        «      rt        | j                  «      n| j                  }t        |t        «      rt        | j
                  t        «      st        d«      ‚t        || j
                  «      S rR   rS   rT   s     rC   rU   zMultilabelExactMatch.computec  rV   rD   rW   rX   c                 ó&   — | 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
            >>> from torch import rand, randint
            >>> from torchmetrics.classification import MultilabelExactMatch
            >>> metric = MultilabelExactMatch(num_labels=3)
            >>> metric.update(randint(2, (20, 3, 5)), randint(2, (20, 3, 5)))
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

            >>> # Example plotting multiple values
            >>> from torch import rand, randint
            >>> from torchmetrics.classification import MultilabelExactMatch
            >>> metric = MultilabelExactMatch(num_labels=3)
            >>> values = [ ]
            >>> for _ in range(10):
            ...     values.append(metric(randint(2, (20, 3, 5)), randint(2, (20, 3, 5))))
            >>> fig_, ax_ = metric.plot(values)

        rZ   r\   s      rC   r]   zMultilabelExactMatch.plotm  r^   rD   )ç      à?r(   NTr_   r`   rk   s   @rC   rm   rm   Ø   s  ø… ñ?ðB ƒMØ#Ð�tÓ#Ø!Ð�dÓ!Ø#Ð�tÓ#Ø!Ð�eÓ!Ø!Ð�eÓ!Ø#Ð�cÓ#ð
 Ø<DØ&*Ø"ñ
àð
ð ð
ð "Ð"8Ñ9ð	
ð
 ˜s‘mð
ð ð
ð ð
ð 
õ
ð>  ˜Fð   ¨Fð   °tó   ðD8˜ó 8ð _cñ(#Ø˜E &¨(°6Ñ*:Ð":Ñ;Ñ<ð(#ØIQÐRZÑI[ð(#à	÷(#rD   rm   c                   ór   — e Zd ZdZ	 	 	 	 	 	 dded    ded   dedee   dee   d	ed
   dee   de	de
defd„Zy)Ú
ExactMatcha  Compute Exact match (also known as subset accuracy).

    Exact Match is a stricter version of accuracy where all labels have to match exactly for the sample to be
    correctly classified.

    This module is a simple wrapper to get the task specific versions of this metric, which is done by setting the
    ``task`` argument to either ``'multiclass'`` or ``'multilabel'``. See the documentation of
    :class:`~torchmetrics.classification.MulticlassExactMatch` and
    :class:`~torchmetrics.classification.MultilabelExactMatch` for the specific details of each argument influence and
    examples.

    Legacy Example:
        >>> from torch import tensor
        >>> target = tensor([[[0, 1], [2, 1], [0, 2]], [[1, 1], [2, 0], [1, 2]]])
        >>> preds = tensor([[[0, 1], [2, 1], [0, 2]], [[2, 2], [2, 1], [1, 0]]])
        >>> metric = ExactMatch(task="multiclass", num_classes=3, multidim_average='global')
        >>> metric(preds, target)
        tensor(0.5000)

        >>> target = tensor([[[0, 1], [2, 1], [0, 2]], [[1, 1], [2, 0], [1, 2]]])
        >>> preds = tensor([[[0, 1], [2, 1], [0, 2]], [[2, 2], [2, 1], [1, 0]]])
        >>> metric = ExactMatch(task="multiclass", num_classes=3, multidim_average='samplewise')
        >>> metric(preds, target)
        tensor([1., 0.])

    NÚclsÚtask)ÚbinaryÚ
multiclassÚ
multilabelrp   r%   ro   r&   r'   r*   r+   r,   r-   c                 ó’  — t        j                  |«      }|j                  |||dœ«       |t         j                  k(  r4t	        |t
        «      st        dt        |«      › d�«      ‚t        |fi |¤ŽS |t         j                  k(  r5t	        |t
        «      st        dt        |«      › d�«      ‚t        ||fi |¤ŽS t        d|› d�«      ‚)zInitialize task metric.)r&   r*   r+   z+`num_classes` is expected to be `int` but `z was passed.`z*`num_labels` is expected to be `int` but `zTask z not supported!)r   Úfrom_strrP   Ú
MULTICLASSrK   ri   Ú
ValueErrorÚtyper   Ú
MULTILABELrm   )	rx   ry   rp   r%   ro   r&   r*   r+   r,   s	            rC   Ú__new__zExactMatch.__new__´  sÒ   € ô *×2Ñ2°4Ó8ˆØ�‰Ø 0Ø(Ø*ñ
ô 	ð
 Ô-×8Ñ8Ò8Ü˜k¬3Ô/Ü Ð#NÌtÐT_ÓO`ÐNaÐanÐ!oÓpÐpÜ'¨Ñ>°vÑ>Ð>ØÔ-×8Ñ8Ò8Ü˜j¬#Ô.Ü Ð#MÌdÐS]ÓN^ÐM_Ð_lÐ!mÓnÐnÜ'¨
°IÑHÀÑHÐHÜ˜5   oÐ6Ó7Ð7rD   )ru   NNr(   NT)ra   rb   rc   rd   r�   r   rg   r   ri   rf   r   r   rƒ   r8   rD   rC   rw   rw   ˜  s�   „ ñð< Ø%)Ø$(Ø<DØ&*Ø"ñ8Ø�,Ñð8àÐ:Ñ;ð8ð ð8ð ˜c‘]ð	8ð
 ˜S‘Mð8ð "Ð"8Ñ9ð8ð ˜s‘mð8ð ð8ð ð8ð 
ô8rD   rw   )&Úcollections.abcr   Útypingr   r   r   r<   r   Útyping_extensionsr   Ú torchmetrics.classification.baser	   Ú2torchmetrics.functional.classification.exact_matchr
   r   r   Ú2torchmetrics.functional.classification.stat_scoresr   r   r   r   r   r   Útorchmetrics.metricr   Útorchmetrics.utilities.datar   Útorchmetrics.utilities.enumsr   Útorchmetrics.utilities.importsr   Útorchmetrics.utilities.plotr   r   Ú__doctest_skip__r   rm   rw   r8   rD   rC   Ú<module>r�      s{   ðõ %ß 'Ñ 'ã Ý Ý %å G÷ñ ÷
÷ õ 'Ý 4Ý CÝ @ß @áØ3Ð5PÐQÐôh#˜6ô h#ôV}#˜6ô }#ô@68Ð+õ 68rD   