o
    .wi                     @   sd   d dl mZmZmZ d dlZd dlmZ d dlmZmZ d dl	m
Z
 d dlmZ G dd de
ZdS )	    )AnyListOptionalN)Tensor)_critical_success_index_compute_critical_success_index_update)Metric)dim_zero_catc                	       s   e Zd ZU dZdZeed< dZeed< eed< eed< eed< e	e ed	< e	e ed
< e	e ed< dde
dee deddf fddZdededdfddZdefddZ  ZS )CriticalSuccessIndexa=  Calculate critical success index (CSI).

    Critical success index (also known as the threat score) is a statistic used weather forecasting that measures
    forecast performance over inputs binarized at a specified threshold. It is defined as:

    .. math:: \text{CSI} = \frac{\text{TP}}{\text{TP}+\text{FN}+\text{FP}}

    Where :math:`\text{TP}`, :math:`\text{FN}` and :math:`\text{FP}` represent the number of true positives, false
    negatives and false positives respectively after binarizing the input tensors.

    Args:
        threshold: Values above or equal to threshold are replaced with 1, below by 0
        keep_sequence_dim: Index of the sequence dimension if the inputs are sequences of images. If specified,
            the score will be calculated separately for each image in the sequence. If ``None``, the score will be
            calculated across all dimensions.

    Example:
        >>> import torch
        >>> from torchmetrics.regression import CriticalSuccessIndex
        >>> x = torch.Tensor([[0.2, 0.7], [0.9, 0.3]])
        >>> y = torch.Tensor([[0.4, 0.2], [0.8, 0.6]])
        >>> csi = CriticalSuccessIndex(0.5)
        >>> csi(x, y)
        tensor(0.3333)

    Example:
        >>> import torch
        >>> from torchmetrics.regression import CriticalSuccessIndex
        >>> x = torch.Tensor([[[0.2, 0.7], [0.9, 0.3]], [[0.2, 0.7], [0.9, 0.3]]])
        >>> y = torch.Tensor([[[0.4, 0.2], [0.8, 0.6]], [[0.4, 0.2], [0.8, 0.6]]])
        >>> csi = CriticalSuccessIndex(0.5, keep_sequence_dim=0)
        >>> csi(x, y)
        tensor([0.3333, 0.3333])

    Fis_differentiableThigher_is_betterhitsmissesfalse_alarms	hits_listmisses_listfalse_alarms_listN	thresholdkeep_sequence_dimkwargsreturnc                    s   t  jdi | t|| _|r t|tr|dk r td| || _|d u rJ| jdt	
ddd | jdt	
ddd | jdt	
ddd d S | jdg d	d | jd
g d	d | jdg d	d d S )Nr   z@Expected keep_sequence_dim to be a non-negative integer but got r   sum)defaultdist_reduce_fxr   r   r   catr   r    )super__init__floatr   
isinstanceint
ValueErrorr   	add_statetorchtensor)selfr   r   r   	__class__r   X/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torchmetrics/regression/csi.pyr   G   s   
zCriticalSuccessIndex.__init__predstargetc                 C   sx   t ||| j| j\}}}| jdu r(|  j|7  _|  j|7  _|  j|7  _dS | j| | j| | j	| dS )z*Update state with predictions and targets.N)
r   r   r   r   r   r   r   appendr   r   )r%   r)   r*   r   r   r   r   r   r(   updateX   s   

zCriticalSuccessIndex.updatec                 C   sH   | j du r| j}| j}| j}nt| j}t| j}t| j}t|||S )z*Compute critical success index over state.N)	r   r   r   r   r	   r   r   r   r   )r%   r   r   r   r   r   r(   computef   s   



zCriticalSuccessIndex.compute)N)__name__
__module____qualname____doc__r   bool__annotations__r   r   r   r   r   r    r   r   r,   r-   __classcell__r   r   r&   r(   r
      s   
 $$r
   )typingr   r   r   r#   r   &torchmetrics.functional.regression.csir   r   torchmetrics.metricr   torchmetrics.utilitiesr	   r
   r   r   r   r(   <module>   s   