
    it0                     $   d dl 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	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fdZd dedee   ddfdZd dededee   ddfdZdedededeeef   fdZ	 	 	 d!dedededee   dedefdZ	 	 	 d"dededed   dee   ddf
dZ	 d dedededee   ddf
dZ	 d#dedededed   deeef   f
dZ	 	 	 	 d$dededededed   dee   dedefdZ	 	 	 	 	 d%dededed   dee   deded   dee   dedefdZy)&    )OptionalN)Tensortensor)Literal)_binary_confusion_matrix_format*_binary_confusion_matrix_tensor_validation#_multiclass_confusion_matrix_format._multiclass_confusion_matrix_tensor_validation)normalize_logits_if_needed)	to_onehot)ClassificationTaskNoMultilabelmeasuretotalreturnc                     | |z  S N )r   r   s     /Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/functional/classification/hinge.py_hinge_loss_computer      s    U?    squaredignore_indexc                     t        | t              st        d|        |t        |t              st        d|       y y )Nz2Expected argument `squared` to be an bool but got zLExpected argument `ignore_index` to either be `None` or an integer, but got )
isinstancebool
ValueErrorint)r   r   s     r   !_binary_hinge_loss_arg_validationr   #   sL    gt$MgYWXX
<(Eghtguvww )Fr   predstargetc                 n    t        | ||       | j                         st        d| j                         y NzdExpected argument `preds` to be floating tensor with probabilities/logits but got tensor with dtype )r   is_floating_pointr   dtype)r   r    r   s      r   $_binary_hinge_loss_tensor_validationr%   *   s?    .uflK""$**/++8
 	
 %r   c                 >   |j                         }t        j                  |       }| |   ||<   | |     || <   d|z
  }t        j                  |d      }|r|j	                  d      }t        |j                  d   |j                        }|j                  d      |fS )N   r      devicedim)	r   torch
zeros_likeclamppowr   shaper*   sum)r   r    r   marginmeasuresr   s         r   _binary_hinge_loss_updater5   3   s    
 [[]Fe$F6]F6NfW~oFF7O6zH{{8Q'H<<?6<<?6==9E<<A<%%r   validate_argsc                     |rt        ||       t        | ||       t        | |d|d      \  } }t        | ||      \  }}t	        ||      S )a  Compute the mean `Hinge loss`_ typically used for Support Vector Machines (SVMs) for binary tasks.

    .. math::
        \text{Hinge loss} = \max(0, 1 - y \times \hat{y})

    Where :math:`y \in {-1, 1}` is the target, and :math:`\hat{y} \in \mathbb{R}` is the prediction.

    Accepts the following input tensors:

    - ``preds`` (float tensor): ``(N, ...)``. Preds should be a tensor containing probabilities or logits for each
      observation. If preds has values outside [0,1] range we consider the input to be logits and will auto apply
      sigmoid per element.
    - ``target`` (int tensor): ``(N, ...)``. Target should be a tensor containing ground truth labels, and therefore
      only contain {0,1} values (except if `ignore_index` is specified). The value 1 always encodes the positive class.

    Additional dimension ``...`` will be flattened into the batch dimension.

    Args:
        preds: Tensor with predictions
        target: Tensor with true labels
        squared:
            If True, this will compute the squared hinge loss. Otherwise, computes the regular hinge loss.
        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:
        >>> from torch import tensor
        >>> from torchmetrics.functional.classification import binary_hinge_loss
        >>> preds = tensor([0.25, 0.25, 0.55, 0.75, 0.75])
        >>> target = tensor([0, 0, 1, 1, 1])
        >>> binary_hinge_loss(preds, target)
        tensor(0.6900)
        >>> binary_hinge_loss(preds, target, squared=True)
        tensor(0.6905)

    g        F)	thresholdr   convert_to_labels)r   r%   r   r5   r   )r   r    r   r   r6   r4   r   s          r   binary_hinge_lossr:   G   sY    Z )'<@,UFLI3v<SXME6 0vwGOHex//r   num_classesmulticlass_modecrammer-singerz
one-vs-allc                     t        ||       t        | t              r| dk  rt        d|        d}||vrt        d| d| d      y )Nr(   zHExpected argument `num_classes` to be an integer larger than 1, but got r=   z1Expected argument `multiclass_mode` to be one of z
, but got .)r   r   r   r   )r;   r   r<   r   
allowed_mms        r   %_multiclass_hinge_loss_arg_validationrB   ~   sd     &g|<k3';?cdocpqrr1Jj(LZLXbcrbsstuvv )r   c                 p    t        | |||       | j                         st        d| j                         y r"   )r
   r#   r   r$   )r   r    r;   r   s       r   (_multiclass_hinge_loss_tensor_validationrD      sC     35&+|\""$**/++8
 	
 %r   c                 J   t        | d      } t        |t        d| j                  d               j	                         }|dk(  rD| |   }|t        j                  | |    j                  | j                  d   d      d      d   z  }n8|j	                         }t        j                  |       }| |   ||<   | |     || <   d|z
  }t        j                  |d      }|r|j                  d      }t        |j                  d   |j                        }|j                  d      |fS )	Nsoftmaxr(   r'   r>   r   r+   r)   )r   r   maxr1   r   r-   viewr.   r/   r0   r   r*   r2   )r   r    r   r<   r3   r4   r   s          r   _multiclass_hinge_loss_updaterJ      s    'ui8Evs1ekk!n56;;=F**v%))E6'N//ACKANN!!%(vv &>/w6zH{{8Q'H<<?6<<?6==9E<<A<%%r   c                     |rt        ||||       t        | |||       t        | ||d      \  } }t        | |||      \  }}t	        ||      S )a
  Compute the mean `Hinge loss`_ typically used for Support Vector Machines (SVMs) for multiclass tasks.

    The metric can be computed in two ways. Either, the definition by Crammer and Singer is used:

    .. math::
        \text{Hinge loss} = \max\left(0, 1 - \hat{y}_y + \max_{i \ne y} (\hat{y}_i)\right)

    Where :math:`y \in {0, ..., \mathrm{C}}` is the target class (where :math:`\mathrm{C}` is the number of classes),
    and :math:`\hat{y} \in \mathbb{R}^\mathrm{C}` is the predicted output per class. Alternatively, the metric can
    also be computed in one-vs-all approach, where each class is valued against all other classes in a binary fashion.

    Accepts the following input tensors:

    - ``preds`` (float tensor): ``(N, C, ...)``. Preds should be a tensor containing probabilities or logits for each
      observation. If preds has values outside [0,1] range we consider the input to be logits and will auto apply
      softmax per sample.
    - ``target`` (int tensor): ``(N, ...)``. Target should be a tensor containing ground truth labels, and therefore
      only contain values in the [0, n_classes-1] range (except if `ignore_index` is specified).

    Additional dimension ``...`` will be flattened into the batch dimension.

    Args:
        preds: Tensor with predictions
        target: Tensor with true labels
        num_classes: Integer specifying the number of classes
        squared:
            If True, this will compute the squared hinge loss. Otherwise, computes the regular hinge loss.
        multiclass_mode:
            Determines how to compute the metric
        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:
        >>> from torch import tensor
        >>> from torchmetrics.functional.classification import multiclass_hinge_loss
        >>> preds = tensor([[0.25, 0.20, 0.55],
        ...                 [0.55, 0.05, 0.40],
        ...                 [0.10, 0.30, 0.60],
        ...                 [0.90, 0.05, 0.05]])
        >>> target = tensor([0, 1, 2, 0])
        >>> multiclass_hinge_loss(preds, target, num_classes=3)
        tensor(0.9125)
        >>> multiclass_hinge_loss(preds, target, num_classes=3, squared=True)
        tensor(1.1131)
        >>> multiclass_hinge_loss(preds, target, num_classes=3, multiclass_mode='one-vs-all')
        tensor([0.8750, 1.1250, 1.1000])

    F)r9   )rB   rD   r	   rJ   r   )	r   r    r;   r   r<   r   r6   r4   r   s	            r   multiclass_hinge_lossrL      s[    v -k7OUab0\Z7v|glmME63E67O\OHex//r   task)binary
multiclassc           	      $   t        j                  |      }|t         j                  k(  rt        | ||||      S |t         j                  k(  r9t        |t              st        dt        |       d      t        | ||||||      S t        d|       )a  Compute the mean `Hinge loss`_ typically used for Support Vector Machines (SVMs).

    This function is a simple wrapper to get the task specific versions of this metric, which is done by setting the
    ``task`` argument to either ``'binary'`` or ``'multiclass'``. See the documentation of
    :func:`~torchmetrics.functional.classification.binary_hinge_loss` and
    :func:`~torchmetrics.functional.classification.multiclass_hinge_loss` for the specific details of
    each argument influence and examples.

    Legacy Example:
        >>> from torch import tensor
        >>> target = tensor([0, 1, 1])
        >>> preds = tensor([0.5, 0.7, 0.1])
        >>> hinge_loss(preds, target, task="binary")
        tensor(0.9000)

        >>> target = tensor([0, 1, 2])
        >>> preds = tensor([[-1.0, 0.9, 0.2], [0.5, -1.1, 0.8], [2.2, -0.5, 0.3]])
        >>> hinge_loss(preds, target, task="multiclass", num_classes=3)
        tensor(1.5551)

        >>> target = tensor([0, 1, 2])
        >>> preds = tensor([[-1.0, 0.9, 0.2], [0.5, -1.1, 0.8], [2.2, -0.5, 0.3]])
        >>> hinge_loss(preds, target, task="multiclass", num_classes=3, multiclass_mode="one-vs-all")
        tensor([1.3743, 1.1945, 1.2359])

    z+`num_classes` is expected to be `int` but `z was passed.`zNot handled value: )
r   from_strBINARYr:   
MULTICLASSr   r   r   typerL   )r   r    rM   r;   r   r<   r   r6   s           r   
hinge_lossrU      s    H *2248D-444 }UU-888+s+J4P[K\J]]jkll$UFK/[givww
*4&1
22r   r   )FNF)Fr>   N)r>   )Fr>   NF)NFr>   NT)typingr   r-   r   r   typing_extensionsr   7torchmetrics.functional.classification.confusion_matrixr   r   r	   r
   torchmetrics.utilities.computer   torchmetrics.utilities.datar   torchmetrics.utilities.enumsr   r   r   r   r   r%   tupler5   r:   rB   rD   rJ   rL   rU   r   r   r   <module>r]      s       %  F 1 G  6 xt x8C= x\` x
 
 
V^_bVc 
os 
&&& & 66>	&. "&404040 40 3-	40
 40 40r ?O"&	www ;<w 3-	w
 
w TX

!
03
CKC=
	
 @P	&&& & ;<	&
 66>&> ?O"&@0@0@0 @0 	@0
 ;<@0 3-@0 @0 @0N "&?O"&+3+3+3 (
)+3 #	+3
 +3 ;<+3 3-+3 +3 +3r   