o
    .wit0                     @   s  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dZd-dedee ddfddZd-dededee ddfddZdedededeeef fddZ			d.dedededee dedefddZ			d/dededed dee ddf
d d!Z	d-dedededee ddf
d"d#Z	d0dedededed deeef f
d$d%Z				d1dededededed dee dedefd&d'Z					(d2deded)ed* dee deded dee dedefd+d,ZdS )3    )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                 C   s   | | S N )r   r   r   r   i/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torchmetrics/functional/classification/hinge.py_hinge_loss_compute   s   r   squaredignore_indexc                 C   s@   t | tstd|  |d urt |tstd| d S d S )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   r   r   r   !_binary_hinge_loss_arg_validation#   s
   
r   predstargetc                 C   s(   t | || |  std| j d S NzdExpected argument `preds` to be floating tensor with probabilities/logits but got tensor with dtype )r   is_floating_pointr   dtype)r   r   r   r   r   r   $_binary_hinge_loss_tensor_validation*   s   r    c                 C   sv   |  }t| }| | ||< | |   || < d| }t|d}|r)|d}t|jd |jd}|jdd|fS )N   r      devicedim)	r   torch
zeros_likeclamppowr   shaper$   sum)r   r   r   marginmeasuresr   r   r   r   _binary_hinge_loss_update3   s   

r/   Fvalidate_argsc                 C   sJ   |rt || t| || t| |d|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   r/   r   )r   r   r   r   r0   r.   r   r   r   r   binary_hinge_lossG   s   -



r3   crammer-singernum_classesmulticlass_moder4   z
one-vs-allc                 C   sP   t || t| tr| dk rtd|  d}||vr&td| d| dd S )Nr"   zHExpected argument `num_classes` to be an integer larger than 1, but got r7   z1Expected argument `multiclass_mode` to be one of z
, but got .)r   r   r   r   )r5   r   r6   r   
allowed_mmr   r   r   %_multiclass_hinge_loss_arg_validation~   s   
r:   c                 C   s*   t | ||| |  std| j d S r   )r	   r   r   r   )r   r   r5   r   r   r   r   (_multiclass_hinge_loss_tensor_validation   s   r;   c                 C   s   t | d} t|td| jd  }|dkr0| | }|tj| |  | jd dddd 8 }n| }t| }| | ||< | |   || < d| }t|d}|rY|	d}t
|jd |jd}|jdd|fS )	Nsoftmaxr"   r!   r4   r   r%   r#   )r
   r   maxr+   r   r'   viewr(   r)   r*   r   r$   r,   )r   r   r   r6   r-   r.   r   r   r   r   _multiclass_hinge_loss_update   s   
,

r@   c           	      C   sP   |rt |||| t| ||| t| ||d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)r2   )r:   r;   r   r@   r   )	r   r   r5   r   r6   r   r0   r.   r   r   r   r   multiclass_hinge_loss   s   ;
rA   Ttask)binary
multiclassc                 C   sn   t |}|t jkrt| ||||S |t jkr0t|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BINARYr3   
MULTICLASSr   r   r   typerA   )r   r   rB   r5   r   r6   r   r0   r   r   r   
hinge_loss   s   
$


rI   r   )FNF)Fr4   N)r4   )Fr4   NF)NFr4   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    tupler/   r3   r:   r;   r@   rA   rI   r   r   r   r   <module>   s    	


9




G	