
    i\                     d   d dl mZ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mZmZmZmZmZmZmZmZ d dlmZmZmZ d dlmZmZ d dlmZ d d	lm Z  d d
l!m"Z" 	 	 	 d*deeee   f   deeee   f   deed      dee   de#defdZ$	 	 	 d+dee#   deee%e&e#   ef      dee%   ddfdZ'	 	 d,deee(eef   f   dee   dee#   de%def
dZ)	 	 	 	 d-dededee#   deee%e&e#   ef      dee%   de*defdZ+	 	 	 d.de%deed      deee%e&e#   ef      dee%   ddf
dZ,	 	 d/deee(eef   f   de%deed      dee   def
d Z-	 	 	 	 d0dedede%deed      deee%e&e#   ef      dee%   de*defd!Z.	 	 d1d"e%deed#      deee%e&e#   ef      dee%   ddf
d$Z/	 d2deee(eef   f   d"e%deed#      dee   dee%   defd%Z0	 	 	 	 d0deded"e%deed#      deee%e&e#   ef      dee%   de*defd&Z1	 	 	 	 	 	 	 d3deded'ed(   deee%e&e#   ef      dee%   d"ee%   deed      dee#   dee%   de*dee   fd)Z2y)4    )ListOptionalUnionN)Tensortensor)Literal)-_binary_precision_recall_curve_arg_validation%_binary_precision_recall_curve_format0_binary_precision_recall_curve_tensor_validation%_binary_precision_recall_curve_update1_multiclass_precision_recall_curve_arg_validation)_multiclass_precision_recall_curve_format4_multiclass_precision_recall_curve_tensor_validation)_multiclass_precision_recall_curve_update1_multilabel_precision_recall_curve_arg_validation)_multilabel_precision_recall_curve_format4_multilabel_precision_recall_curve_tensor_validation)_multilabel_precision_recall_curve_update)_binary_roc_compute_multiclass_roc_compute_multilabel_roc_compute)_auc_compute_without_check_safe_divide)	_bincount)ClassificationTask)rank_zero_warnfprtpraverage)macroweightednoneweights	directionreturnc                 V   t        | t              r t        |t              rt        | ||d      }n>t        j                  t        | |      D cg c]  \  }}t        |||       c}}      }||dk(  r|S t        j                  |      j                         rt        d| dt               t        j                  |       }|dk(  r||   j                         S |dk(  r8|6t        ||   ||   j                               }||   |z  j                         S t        d	      c c}}w )
z8Reduce multiple average precision score into one number.   )r$   axis)r$   r"   zUAverage precision score for one or more classes was `nan`. Ignoring these classes in z-averager    r!   zBReceived an incompatible combinations of inputs to make reduction.)
isinstancer   r   torchstackzipisnananyr   UserWarningmeanr   sum
ValueError)	r   r   r   r#   r$   resxyidxs	            /Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/functional/classification/auroc.py_reduce_aurocr8   -   s     #v:c6#:(cYQOkk]`adfi]jk]jUYUVXY5aiP]jkl'V+
{{3cdkclltu	
 ;;s
C'3x}}*!4ws|WS\-=-=-?@C7"''))
Y
ZZ ls   D%
max_fpr
thresholdsignore_indexc                 |    t        ||       | .t        | t              sd| cxk  rdk  rn y t        d|        y y y )Nr   r'   z@Arguments `max_fpr` should be a float in range (0, 1], but got: )r	   r)   floatr2   )r9   r:   r;   s      r7   _binary_auroc_arg_validationr>   I   sL    
 2*lK:gu#=!gBRQRBR[\c[deff CS#=    state	pos_labelc                    t        | ||      \  }}}|+|dk(  s&|j                         dk(  s|j                         dk(  rt        ||d      S t        |t              r|j
                  n|d   j
                  }t        ||      }t        j                  ||dd      }	|||	dz
     z
  ||	   ||	dz
     z
  z  }
t        j                  ||	dz
     ||	   |
      }t        j                  |d |	 |j                  d      g      }t        j                  |d |	 |j                  d      g      }t        ||d      }d|dz  z  }dd||z
  ||z
  z  z   z  S )	Nr'   r         ?)deviceT)	out_int32rightg      ?   )r   r1   r   r)   r   rD   r   r*   	bucketizelerpcatview)r@   r:   r9   rA   r   r   __devicemax_areastopweight
interp_tprpartial_aucmin_areas                 r7   _binary_auroc_computerT   S   sO    &eZCKCa'Q,#'')q.CGGIN)#sC88&sF3cjjQGgg6H??8SDEDTAX&3t9s4!8}+DEFCqM3t9fEJ
))S$Z!34
5C
))S$Zq!12
3C -S#s;K Xq[(H!{X-(X2EFFGGr?   predstargetvalidate_argsc                     |rt        |||       t        | ||       t        | |||      \  } }}t        | ||      }t	        |||      S )a  Compute Area Under the Receiver Operating Characteristic Curve (`ROC AUC`_) for binary tasks.

    The AUROC score summarizes the ROC curve into an single number that describes the performance of a model for
    multiple thresholds at the same time. Notably, an AUROC score of 1 is a perfect score and an AUROC score of 0.5
    corresponds to random guessing.

    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.

    The implementation both supports calculating the metric in a non-binned but accurate version and a binned version
    that is less accurate but more memory efficient. Setting the `thresholds` argument to `None` will activate the
    non-binned  version that uses memory of size :math:`\mathcal{O}(n_{samples})` whereas setting the `thresholds`
    argument to either an integer, list or a 1d tensor will use a binned version that uses memory of
    size :math:`\mathcal{O}(n_{thresholds})` (constant memory).

    Args:
        preds: Tensor with predictions
        target: Tensor with true labels
        max_fpr: If not ``None``, calculates standardized partial AUC over the range ``[0, max_fpr]``.
        thresholds:
            Can be one of:

            - If set to `None`, will use a non-binned approach where thresholds are dynamically calculated from
              all the data. Most accurate but also most memory consuming approach.
            - If set to an `int` (larger than 1), will use that number of thresholds linearly spaced from
              0 to 1 as bins for the calculation.
            - If set to an `list` of floats, will use the indicated thresholds in the list as bins for the calculation
            - If set to an 1d `tensor` of floats, will use the indicated thresholds in the tensor as
              bins for the calculation.

        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.

    Returns:
        A single scalar with the auroc score

    Example:
        >>> from torchmetrics.functional.classification import binary_auroc
        >>> preds = torch.tensor([0, 0.5, 0.7, 0.8])
        >>> target = torch.tensor([0, 1, 1, 0])
        >>> binary_auroc(preds, target, thresholds=None)
        tensor(0.5000)
        >>> binary_auroc(preds, target, thresholds=5)
        tensor(0.5000)

    )r>   r   r
   r   rT   )rU   rV   r9   r:   r;   rW   r@   s          r7   binary_aurocrY   n   sV    ~ $Wj,G8U EeVU_am nE6:1%LE 
G<<r?   num_classesc                 L    t        | ||       d}||vrt        d| d|       y )N)r    r!   r"   N)Expected argument `average` to be one of 	 but got )r   r2   )rZ   r   r:   r;   allowed_averages        r7    _multiclass_auroc_arg_validationr_      s?     6k:|\9Oo%D_DUU^_f^ghii &r?   c           
          t        | ||      \  }}}t        ||||#t        | d   |      j                               S | d   d d dd d f   j	                  d            S )Nr'   )	minlengthr   r#   )r   r8   r   r=   r1   )r@   rZ   r   r:   r   r   rL   s          r7   _multiclass_auroc_computerd      s|     *%jIKCaFPFX	%(k:@@B	  _dde^fghjkmngn^o^s^stv^w	 r?   c                     |rt        ||||       t        | |||       t        | ||||      \  } }}t        | |||      }t	        ||||      S )a  Compute Area Under the Receiver Operating Characteristic Curve (`ROC AUC`_) for multiclass tasks.

    The AUROC score summarizes the ROC curve into an single number that describes the performance of a model for
    multiple thresholds at the same time. Notably, an AUROC score of 1 is a perfect score and an AUROC score of 0.5
    corresponds to random guessing.

    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.

    The implementation both supports calculating the metric in a non-binned but accurate version and a binned version
    that is less accurate but more memory efficient. Setting the `thresholds` argument to `None` will activate the
    non-binned  version that uses memory of size :math:`\mathcal{O}(n_{samples})` whereas setting the `thresholds`
    argument to either an integer, list or a 1d tensor will use a binned version that uses memory of
    size :math:`\mathcal{O}(n_{thresholds} \times n_{classes})` (constant memory).

    Args:
        preds: Tensor with predictions
        target: Tensor with true labels
        num_classes: Integer specifying the number of classes
        average:
            Defines the reduction that is applied over classes. Should be one of the following:

            - ``macro``: Calculate score for each class and average them
            - ``weighted``: calculates score for each class and computes weighted average using their support
            - ``"none"`` or ``None``: calculates score for each class and applies no reduction
        thresholds:
            Can be one of:

            - If set to `None`, will use a non-binned approach where thresholds are dynamically calculated from
              all the data. Most accurate but also most memory consuming approach.
            - If set to an `int` (larger than 1), will use that number of thresholds linearly spaced from
              0 to 1 as bins for the calculation.
            - If set to an `list` of floats, will use the indicated thresholds in the list as bins for the calculation
            - If set to an 1d `tensor` of floats, will use the indicated thresholds in the tensor as
              bins for the calculation.

        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.

    Returns:
        If `average=None|"none"` then a 1d tensor of shape (n_classes, ) will be returned with auroc score per class.
        If `average="macro"|"weighted"` then a single scalar is returned.

    Example:
        >>> from torchmetrics.functional.classification import multiclass_auroc
        >>> preds = torch.tensor([[0.75, 0.05, 0.05, 0.05, 0.05],
        ...                       [0.05, 0.75, 0.05, 0.05, 0.05],
        ...                       [0.05, 0.05, 0.75, 0.05, 0.05],
        ...                       [0.05, 0.05, 0.05, 0.75, 0.05]])
        >>> target = torch.tensor([0, 1, 3, 2])
        >>> multiclass_auroc(preds, target, num_classes=5, average="macro", thresholds=None)
        tensor(0.5333)
        >>> multiclass_auroc(preds, target, num_classes=5, average=None, thresholds=None)
        tensor([1.0000, 1.0000, 0.3333, 0.3333, 0.0000])
        >>> multiclass_auroc(preds, target, num_classes=5, average="macro", thresholds=5)
        tensor(0.5333)
        >>> multiclass_auroc(preds, target, num_classes=5, average=None, thresholds=5)
        tensor([1.0000, 1.0000, 0.3333, 0.3333, 0.0000])

    )r_   r   r   r   rd   )rU   rV   rZ   r   r:   r;   rW   r@   s           r7   multiclass_aurocrf      se    \ (gz<X<UFKYef Iv{J!E6: 6eV[R\]E$UK*MMr?   
num_labels)micror    r!   r"   c                 L    t        | ||       d}||vrt        d| d|       y )N)rh   r    r!   r"   Nr\   r]   )r   r2   )rg   r   r:   r;   r^   s        r7    _multilabel_auroc_arg_validationrj   (  s?     6j*l[BOo%D_DUU^_f^ghii &r?   c           
         |dk(  rxt        | t              r|t        | j                  d      |d       S | d   j	                         }| d   j	                         }|||k(  }||    }||    }t        ||f|d       S t        | |||      \  }}	}
t        ||	||+| d   dk(  j                  d      j                               S | d   d d dd d f   j                  d            S )Nrh   r'   )r9   r   )dimrb   rc   )r)   r   rT   r1   flattenr   r8   r=   )r@   rg   r   r:   r;   rU   rV   r6   r   r   rL   s              r7   _multilabel_auroc_computern   4  s    'eV$)?(1z4PPa  "q!!##L(C3$KESD\F$eV_j$OO)%ZVKCa6@6HqQ###*002	  OTTUhWXZ[]^W^N_NcNcdfNg	 r?   c                     |rt        ||||       t        | |||       t        | ||||      \  } }}t        | |||      }t	        |||||      S )al  Compute Area Under the Receiver Operating Characteristic Curve (`ROC AUC`_) for multilabel tasks.

    The AUROC score summarizes the ROC curve into an single number that describes the performance of a model for
    multiple thresholds at the same time. Notably, an AUROC score of 1 is a perfect score and an AUROC score of 0.5
    corresponds to random guessing.

    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
      sigmoid per element.
    - ``target`` (int tensor): ``(N, C, ...)``. Target should be a tensor containing ground truth labels, and therefore
      only contain {0,1} values (except if `ignore_index` is specified).

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

    The implementation both supports calculating the metric in a non-binned but accurate version and a binned version
    that is less accurate but more memory efficient. Setting the `thresholds` argument to `None` will activate the
    non-binned  version that uses memory of size :math:`\mathcal{O}(n_{samples})` whereas setting the `thresholds`
    argument to either an integer, list or a 1d tensor will use a binned version that uses memory of
    size :math:`\mathcal{O}(n_{thresholds} \times n_{labels})` (constant memory).

    Args:
        preds: Tensor with predictions
        target: Tensor with true labels
        num_labels: Integer specifying the number of labels
        average:
            Defines the reduction that is applied over labels. Should be one of the following:

            - ``micro``: Sum score over all labels
            - ``macro``: Calculate score for each label and average them
            - ``weighted``: calculates score for each label and computes weighted average using their support
            - ``"none"`` or ``None``: calculates score for each label and applies no reduction
        thresholds:
            Can be one of:

            - If set to `None`, will use a non-binned approach where thresholds are dynamically calculated from
              all the data. Most accurate but also most memory consuming approach.
            - If set to an `int` (larger than 1), will use that number of thresholds linearly spaced from
              0 to 1 as bins for the calculation.
            - If set to an `list` of floats, will use the indicated thresholds in the list as bins for the calculation
            - If set to an 1d `tensor` of floats, will use the indicated thresholds in the tensor as
              bins for the calculation.

        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.

    Returns:
        If `average=None|"none"` then a 1d tensor of shape (n_classes, ) will be returned with auroc score per class.
        If `average="micro|macro"|"weighted"` then a single scalar is returned.

    Example:
        >>> from torchmetrics.functional.classification import multilabel_auroc
        >>> preds = torch.tensor([[0.75, 0.05, 0.35],
        ...                       [0.45, 0.75, 0.05],
        ...                       [0.05, 0.55, 0.75],
        ...                       [0.05, 0.65, 0.05]])
        >>> target = torch.tensor([[1, 0, 1],
        ...                        [0, 0, 0],
        ...                        [0, 1, 1],
        ...                        [1, 1, 1]])
        >>> multilabel_auroc(preds, target, num_labels=3, average="macro", thresholds=None)
        tensor(0.6528)
        >>> multilabel_auroc(preds, target, num_labels=3, average=None, thresholds=None)
        tensor([0.6250, 0.5000, 0.8333])
        >>> multilabel_auroc(preds, target, num_labels=3, average="macro", thresholds=5)
        tensor(0.6528)
        >>> multilabel_auroc(preds, target, num_labels=3, average=None, thresholds=5)
        tensor([0.6250, 0.5000, 0.8333])

    )rj   r   r   r   rn   )rU   rV   rg   r   r:   r;   rW   r@   s           r7   multilabel_aurocrp   P  sg    d (Wj,W<UFJXde Ivz:|!E6: 6eVZQ[\E$UJ\ZZr?   task)binary
multiclass
multilabelc
           	         t        j                  |      }|t         j                  k(  rt        | |||||	      S |t         j                  k(  r9t        |t              st        dt        |       d      t        | ||||||	      S |t         j                  k(  r9t        |t              st        dt        |       d      t        | ||||||	      S y)a  Compute Area Under the Receiver Operating Characteristic Curve (`ROC AUC`_).

    The AUROC score summarizes the ROC curve into an single number that describes the performance of a model for
    multiple thresholds at the same time. Notably, an AUROC score of 1 is a perfect score and an AUROC score of 0.5
    corresponds to random guessing.

    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
    :func:`~torchmetrics.functional.classification.binary_auroc`,
    :func:`~torchmetrics.functional.classification.multiclass_auroc` and
    :func:`~torchmetrics.functional.classification.multilabel_auroc` for the specific details of
    each argument influence and examples.

    Legacy Example:
        >>> preds = torch.tensor([0.13, 0.26, 0.08, 0.19, 0.34])
        >>> target = torch.tensor([0, 0, 1, 1, 1])
        >>> auroc(preds, target, task='binary')
        tensor(0.5000)

        >>> preds = torch.tensor([[0.90, 0.05, 0.05],
        ...                       [0.05, 0.90, 0.05],
        ...                       [0.05, 0.05, 0.90],
        ...                       [0.85, 0.05, 0.10],
        ...                       [0.10, 0.10, 0.80]])
        >>> target = torch.tensor([0, 1, 1, 2, 2])
        >>> auroc(preds, target, task='multiclass', num_classes=3)
        tensor(0.7778)

    z+`num_classes` is expected to be `int` but `z was passed.`z*`num_labels` is expected to be `int` but `N)r   from_strBINARYrY   
MULTICLASSr)   intr2   typerf   
MULTILABELrp   )
rU   rV   rq   r:   rZ   rg   r   r9   r;   rW   s
             r7   aurocr|     s    R &&t,D!(((E67Jm\\!,,,+s+J4P[K\J]]jkllv{GZQ]_lmm!,,,*c*I$zJZI[[hijjvz7JP\^kllr?   )r    NrC   )NNN)Nr'   )NNNT)r    NN)r    N)r    NNT)NN)N)NNNr    NNT)3typingr   r   r   r*   r   r   typing_extensionsr   =torchmetrics.functional.classification.precision_recall_curver	   r
   r   r   r   r   r   r   r   r   r   r   *torchmetrics.functional.classification.rocr   r   r   torchmetrics.utilities.computer   r   torchmetrics.utilities.datar   torchmetrics.utilities.enumsr   torchmetrics.utilities.printsr   r=   r8   ry   listr>   tuplerT   boolrY   r_   rd   rf   rj   rn   rp   r|    r?   r7   <module>r      sv   ) (    %    
 T 1 ; 8 ?F $[	vtF|#	$[	vtF|#	$[ g9:;[ f	[
 [ [:  $<@"&ge_gsDK789g 3-g 
	g  $	Hvv~../H H e_H 	H
 H<  $<@"&D=D=D= e_D= sDK789	D=
 3-D= D= D=R ?F<@"&		j	jg9:;	j sDK789	j 3-		j
 
	j ?F#'	vv~../ g9:;  	
 & ?F<@"&UNUNUN UN g9:;	UN
 sDK789UN 3-UN UN UNv =A"&		j	jgBCD	j sDK789	j 3-		j
 
	j" #'vv~../ gBCD  	
 3- @ HO<@"&Y[Y[Y[ Y[ gBCD	Y[
 sDK789Y[ 3-Y[ Y[ Y[@ =A!% $>E#"&444 6
74 sDK789	4
 #4 4 g9:;4 e_4 3-4 4 f4r?   