o
    yi\5                     @   s   d dl mZmZ d dl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 d dlmZ G dd	 d	eZG d
d de	ZG dd de
ZG dd dZdS )    )AnyOptionalN)Tensor)Literal)BinaryConfusionMatrixMulticlassConfusionMatrixMultilabelConfusionMatrix)_jaccard_index_reduce(_multiclass_jaccard_index_arg_validation(_multilabel_jaccard_index_arg_validation)Metricc                       sv   e Zd ZU dZdZeed< dZeed< dZeed< 			dd	e	d
e
e dededdf
 fddZdefddZ  ZS )BinaryJaccardIndexa  Calculates the Jaccard index for binary tasks. The `Jaccard index`_ (also known as the intersetion over
    union or jaccard similarity coefficient) is an statistic that can be used to determine the similarity and
    diversity of a sample set. It is defined as the size of the intersection divided by the union of the sample
    sets:

    .. math:: J(A,B) = \frac{|A\cap B|}{|A\cup B|}

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

    - ``preds`` (:class:`~torch.Tensor`): A int or float tensor of shape ``(N, ...)``. 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.
      Addtionally, we convert to int tensor with thresholding using the value in ``threshold``.
    - ``target`` (:class:`~torch.Tensor`): An int tensor of shape ``(N, ...)``.

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

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

    - ``bji`` (:class:`~torch.Tensor`): A tensor containing the Binary Jaccard Index.

    Args:
        threshold: Threshold for transforming probability to binary (0,1) predictions
        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.
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

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

    Example (preds is float tensor):
        >>> from torchmetrics.classification import BinaryJaccardIndex
        >>> target = torch.tensor([1, 1, 0, 0])
        >>> preds = torch.tensor([0.35, 0.85, 0.48, 0.01])
        >>> metric = BinaryJaccardIndex()
        >>> metric(preds, target)
        tensor(0.5000)
    Fis_differentiableThigher_is_betterfull_state_update      ?N	thresholdignore_indexvalidate_argskwargsreturnc                    s    t  jd||d |d| d S )N)r   r   	normalizer    )super__init__)selfr   r   r   r   	__class__r   W/home/ubuntu/.local/lib/python3.10/site-packages/torchmetrics/classification/jaccard.pyr   O   s
   
zBinaryJaccardIndex.__init__c                 C   s   t | jddS )Nbinaryaverage)r	   confmatr   r   r   r   computeZ   s   zBinaryJaccardIndex.compute)r   NT)__name__
__module____qualname____doc__r   bool__annotations__r   r   floatr   intr   r   r   r$   __classcell__r   r   r   r   r      s(   
 -r   c                       s   e Zd ZU dZdZeed< dZeed< dZeed< 			dd	e	d
e
ed  de
e	 dededdf fddZdefddZ  ZS )MulticlassJaccardIndexa
  Calculates the Jaccard index for multiclass tasks. The `Jaccard index`_ (also known as the intersetion over
    union or jaccard similarity coefficient) is an statistic that can be used to determine the similarity and
    diversity of a sample set. It is defined as the size of the intersection divided by the union of the sample
    sets:

    .. math:: J(A,B) = \frac{|A\cap B|}{|A\cup B|}

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

    - ``preds`` (:class:`~torch.Tensor`): A 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, ...)``.

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

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

    - ``mcji`` (:class:`~torch.Tensor`): A tensor containing the Multi-class Jaccard Index.

    Args:
        num_classes: Integer specifing the number of classes
        ignore_index:
            Specifies a target value that is ignored and does not contribute to the metric calculation
        average:
            Defines the reduction that is applied over labels. Should be one of the following:

            - ``micro``: Sum statistics over all labels
            - ``macro``: Calculate statistics for each label and average them
            - ``weighted``: Calculates statistics for each label and computes weighted average using their support
            - ``"none"`` or ``None``: Calculates statistic for each label and applies no reduction

        validate_args: bool indicating if input arguments and tensors should be validated for correctness.
            Set to ``False`` for faster computations.
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Example (pred is integer tensor):
        >>> from torchmetrics.classification import MulticlassJaccardIndex
        >>> target = torch.tensor([2, 1, 0, 0])
        >>> preds = torch.tensor([2, 1, 0, 1])
        >>> metric = MulticlassJaccardIndex(num_classes=3)
        >>> metric(preds, target)
        tensor(0.6667)

    Example (pred is float tensor):
        >>> from torchmetrics.classification import MulticlassJaccardIndex
        >>> target = torch.tensor([2, 1, 0, 0])
        >>> preds = torch.tensor([
        ...   [0.16, 0.26, 0.58],
        ...   [0.22, 0.61, 0.17],
        ...   [0.71, 0.09, 0.20],
        ...   [0.05, 0.82, 0.13],
        ... ])
        >>> metric = MulticlassJaccardIndex(num_classes=3)
        >>> metric(preds, target)
        tensor(0.6667)
    Fr   Tr   r   macroNnum_classesr!   micror/   weightednoner   r   r   r   c                    s<   t  jd||d dd| |rt||| || _|| _d S )NF)r0   r   r   r   r   )r   r   r
   r   r!   )r   r0   r!   r   r   r   r   r   r   r      s   
zMulticlassJaccardIndex.__init__c                 C   s   t | j| j| jdS )N)r!   r   )r	   r"   r!   r   r#   r   r   r   r$      s   zMulticlassJaccardIndex.compute)r/   NT)r%   r&   r'   r(   r   r)   r*   r   r   r,   r   r   r   r   r   r$   r-   r   r   r   r   r.   ^   s,   
 ;
r.   c                       s   e Zd ZU dZdZeed< dZeed< dZeed< 					dd
e	de
deed  dee	 dededd	f fddZdefddZ  ZS )MultilabelJaccardIndexa?  Calculates the Jaccard index for multilabel tasks. The `Jaccard index`_ (also known as the intersetion over
    union or jaccard similarity coefficient) is an statistic that can be used to determine the similarity and
    diversity of a sample set. It is defined as the size of the intersection divided by the union of the sample
    sets:

    .. math:: J(A,B) = \frac{|A\cap B|}{|A\cup B|}

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

    - ``preds`` (:class:`~torch.Tensor`): A 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. Addtionally, we convert to int tensor with thresholding using the value in ``threshold``.
    - ``target`` (:class:`~torch.Tensor`): An int tensor of shape ``(N, C, ...)``

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

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

    - ``mlji`` (:class:`~torch.Tensor`): A tensor containing the Multi-label Jaccard Index loss.

    Args:
        num_classes: Integer specifing the number of labels
        threshold: Threshold for transforming probability to binary (0,1) predictions
        ignore_index:
            Specifies a target value that is ignored and does not contribute to the metric calculation
        average:
            Defines the reduction that is applied over labels. Should be one of the following:

            - ``micro``: Sum statistics over all labels
            - ``macro``: Calculate statistics for each label and average them
            - ``weighted``: Calculates statistics for each label and computes weighted average using their support
            - ``"none"`` or ``None``: Calculates statistic for each label and applies no reduction

        validate_args: bool indicating if input arguments and tensors should be validated for correctness.
            Set to ``False`` for faster computations.
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

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

    Example (preds is float tensor):
        >>> from torchmetrics.classification import MultilabelJaccardIndex
        >>> target = torch.tensor([[0, 1, 0], [1, 0, 1]])
        >>> preds = torch.tensor([[0.11, 0.22, 0.84], [0.73, 0.33, 0.92]])
        >>> metric = MultilabelJaccardIndex(num_labels=3)
        >>> metric(preds, target)
        tensor(0.5000)
    Fr   Tr   r   r   r/   N
num_labelsr   r!   r1   r   r   r   r   c                    s@   t  jd|||d dd| |rt|||| || _|| _d S )NF)r6   r   r   r   r   r   )r   r   r   r   r!   )r   r6   r   r!   r   r   r   r   r   r   r      s   	
zMultilabelJaccardIndex.__init__c                 C   s   t | j| jdS )Nr    )r	   r"   r!   r#   r   r   r   r$     s   zMultilabelJaccardIndex.compute)r   r/   NT)r%   r&   r'   r(   r   r)   r*   r   r   r,   r+   r   r   r   r   r   r$   r-   r   r   r   r   r5      s2   
 7
r5   c                   @   sd   e Zd ZdZ						dded ded	ee d
ee deed  dee dede	de
fddZdS )JaccardIndexaB  Calculates the Jaccard index for multilabel tasks. The `Jaccard index`_ (also known as the intersetion over
    union or jaccard similarity coefficient) is an statistic that can be used to determine the similarity and
    diversity of a sample set. It is defined as the size of the intersection divided by the union of the sample
    sets:

    .. math:: J(A,B) = \frac{|A\cap B|}{|A\cup B|}

    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'``, ``'multiclass'`` or ``multilabel``. See the documentation of
    :mod:`BinaryJaccardIndex`, :mod:`MulticlassJaccardIndex` and :mod:`MultilabelJaccardIndex` for
    the specific details of each argument influence and examples.

    Legacy Example:
        >>> target = torch.randint(0, 2, (10, 25, 25))
        >>> pred = torch.tensor(target)
        >>> pred[2:5, 7:13, 9:15] = 1 - pred[2:5, 7:13, 9:15]
        >>> jaccard = JaccardIndex(task="multiclass", num_classes=2)
        >>> jaccard(pred, target)
        tensor(0.9660)
    r   Nr/   Ttask)r   
multiclass
multilabelr   r0   r6   r!   r1   r   r   r   r   c           	      K   s   | t||d |dkrt|fi |S |dkr)t|ts J t||fi |S |dkr>t|ts4J t|||fi |S td| )N)r   r   r   r9   r:   z[Expected argument `task` to either be `'binary'`, `'multiclass'` or `'multilabel'` but got )updatedictr   
isinstancer,   r.   r5   
ValueError)	clsr8   r   r0   r6   r!   r   r   r   r   r   r   __new__  s   zJaccardIndex.__new__)r   NNr/   NT)r%   r&   r'   r(   r   r+   r   r,   r)   r   r   r@   r   r   r   r   r7     s6    
	
r7   )typingr   r   torchr   typing_extensionsr   torchmetrics.classificationr   r   r   .torchmetrics.functional.classification.jaccardr	   r
   r   torchmetrics.metricr   r   r.   r5   r7   r   r   r   r   <module>   s   ATV