a
    dP0                     @   s  d dl 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
mZmZ d dlmZ d dlmZ eeedd	d
Zd+eee ddddZd,eeee ddddZeeeeeef dddZd-eeeee eedddZd.eeed ee ddddZd/eeeee ddddZd0eeeed eeef d d!d"Zd1eeeeed ee eed#d$d%Zd2eeed' ee eed ee eed(	d)d*ZdS )3    )OptionalTupleN)Tensortensor)Literal)_binary_confusion_matrix_format*_binary_confusion_matrix_tensor_validation#_multiclass_confusion_matrix_format._multiclass_confusion_matrix_tensor_validation)	to_onehot)ClassificationTaskNoMultilabel)measuretotalreturnc                 C   s   | | S )N )r   r   r   r   u/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/torchmetrics/functional/classification/hinge.py_hinge_loss_compute   s    r   )squaredignore_indexr   c                 C   s<   t | tstd|  |d ur8t |ts8td| 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targetr   r   c                 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   )r   r   r   r   c                 C   sv   |  }t| }| | ||< | |   || < d| }t|d}|rR|d}t|jd |jd}|jdd|fS )N   r      deviceZdim)	r   torch
zeros_likeclamppowr   shaper#   sum)r   r   r   marginmeasuresr   r   r   r   _binary_hinge_loss_update2   s    

r-   F)r   r   r   r   validate_argsr   c                 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   r.   r,   r   r   r   r   binary_hinge_lossF   s    -


r1   crammer-singerr2   z
one-vs-all)num_classesr   multiclass_moder   r   c                 C   sP   t || t| tr| dk r*td|  d}||vrLtd| d| dd S )Nr!   zHExpected argument `num_classes` to be an integer larger than 1, but got r3   z1Expected argument `multiclass_mode` to be one of z
, but got .)r   r   r   r   )r4   r   r5   r   Z
allowed_mmr   r   r   %_multiclass_hinge_loss_arg_validation}   s    
r7   )r   r   r4   r   r   c                 C   s*   t | ||| |  s&td| j d S r   )r
   r   r   r   )r   r   r4   r   r   r   r   (_multiclass_hinge_loss_tensor_validation   s    r8   )r   r   r   r5   r   c                 C   s   t | dk| dk s | d} t|td| jd  }|dkrv| | }|t j| |  | jd dddd 8 }n0| }t | }| | ||< | |   || < d| }t 	|d}|r|
d}t|jd |jd}|jdd|fS )Nr   r    r!   r2   r$   r"   )r%   allZsoftmaxr   maxr)   r   viewr&   r'   r(   r   r#   r*   )r   r   r   r5   r+   r,   r   r   r   r   _multiclass_hinge_loss_update   s     
,

r=   )r   r   r4   r   r5   r   r.   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 specifing 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)r0   )r7   r8   r	   r=   r   )	r   r   r4   r   r5   r   r.   r,   r   r   r   r   multiclass_hinge_loss   s    ;r>   T)binaryZ
multiclass)	r   r   taskr4   r   r5   r   r.   r   c                 C   sr   t |}|t jkr$t| ||||S |t jkr`t|tsLtdt| dt	| ||||||S td| dS )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: N)
r   Zfrom_strBINARYr1   Z
MULTICLASSr   r   r   typer>   )r   r   r@   r4   r   r5   r   r.   r   r   r   
hinge_loss   s    $



rC   )N)N)FNF)Fr2   N)N)r2   )Fr2   NF)NFr2   NT)typingr   r   r%   r   r   Ztyping_extensionsr   Z7torchmetrics.functional.classification.confusion_matrixr   r   r	   r
   Ztorchmetrics.utilities.datar   Ztorchmetrics.utilities.enumsr   r   r   r   r   r   r-   r1   r7   r8   r=   r>   rC   r   r   r   r   <module>   s   

   9     
!    G     