o
    yi                     @   sN  d dl mZmZmZ d dlZd dlmZ d dlmZ d dlm	Z	 de
deeeef  ddfd	d
ZdedefddZdededefddZdedefddZdededededef
ddZdedededeeef fddZdededededeeeef f
ddZ		d'ded eded! dee deeef f
d"d#Zd$e
ddfd%d&ZdS )(    )OptionalTupleUnionN)Tensor)Literalrank_zero_warnnan_strategynan_replace_valuereturnc                 C   sB   | dvrt d|  | dkrt|ttfst d| d S d S )NreplacedropzPArgument `nan_strategy` is expected to be one of `['replace', 'drop']`, but got r   zlArgument `nan_replace` is expected to be of a type `int` or `float` when `nan_strategy = 'replace`, but got )
ValueError
isinstanceintfloat)r	   r
    r   Y/home/ubuntu/.local/lib/python3.10/site-packages/torchmetrics/functional/nominal/utils.py_nominal_input_validation   s   r   confmatc                 C   s0   |  d|  d}}td|||    }|S )zDCompute the expected frequenceis from the provided confusion matrix.   r   z
r, c -> rc)sumtorcheinsum)r   margin_sum_rowsmargin_sum_colsexpected_freqsr   r   r   _compute_expected_freqs#   s   r   bias_correctionc                 C   s   t | }| t|j |j d }|dkrtjd| jdS |dkr=|r=||  }| }| |t	dt
| |  7 } t| | d | S )zChi-square test of independenc of variables in a confusion matrix table.

    Adapted from: https://github.com/scipy/scipy/blob/v1.9.2/scipy/stats/contingency.py.
    r   r           deviceg      ?   )r   numelr   shapendimr   tensorr"   signminimum	ones_likeabs)r   r   r   dfdiff	directionr   r   r   _compute_chi_squared*   s   "r/   c                 C   s0   | |  ddk } | dd|  ddkf } | S )a  Drop all rows and columns containing only zeros.

    Example:
        >>> import torch
        >>> from torchmetrics.functional.nominal.utils import _drop_empty_rows_and_cols
        >>> _ = torch.manual_seed(22)
        >>> matrix = torch.randint(10, size=(3, 3))
        >>> matrix[1, :] = matrix[:, 1] = 0
        >>> matrix
        tensor([[9, 0, 6],
                [0, 0, 0],
                [2, 0, 8]])
        >>> _drop_empty_rows_and_cols(matrix)
        tensor([[9, 6],
                [2, 8]])
    r   r   N)r   )r   r   r   r   _drop_empty_rows_and_cols=   s   r0   phi_squaredn_rowsn_colsconfmat_sumc                 C   s0   t t jd| jd| |d |d  |d   S )z#Compute bias-corrected Phi Squared.r    r!   r   )r   maxr'   r"   )r1   r2   r3   r4   r   r   r   _compute_phi_squared_correctedS   s   (r6   c                 C   s8   | | d d |d   }||d d |d   }||fS )z2Compute bias-corrected number of rows and columns.r   r#   r   )r2   r3   r4   rows_correctedcols_correctedr   r   r    _compute_rows_and_cols_corrected_   s   r9   c                 C   s(   t | |||}t|||\}}|||fS )zBCompute bias-corrected Phi Squared and number of rows and columns.)r6   r9   )r1   r2   r3   r4   phi_squared_correctedr7   r8   r   r   r   _compute_bias_corrected_valuesf   s   
r;   r   r    predstargetr   c                 C   sD   |dkr|  || |fS t|  | }| |  ||  fS )a/  Handle ``NaN`` values in input data.

    If ``nan_strategy = 'replace'``, all ``NaN`` values are replaced with ``nan_replace_value``.
    If ``nan_strategy = 'drop'``, all rows containing ``NaN`` in any of two vectors are dropped.

    Args:
        preds: 1D tensor of categorical (nominal) data
        target: 1D tensor of categorical (nominal) data
        nan_strategy: Indication of whether to replace or drop ``NaN`` values
        nan_replace_value: Value to replace ``NaN`s when ``nan_strategy = 'replace```

    Returns:
        Updated ``preds`` and ``target`` tensors which contain no ``Nan``

    Raises:
        ValueError: If ``nan_strategy`` is not from ``['replace', 'drop']``.
        ValueError: If ``nan_strategy = replace`` and ``nan_replace_value`` is not of a type ``int`` or ``float``.
    r   )
nan_to_numr   
logical_orisnan)r<   r=   r	   r
   rows_contain_nanr   r   r   _handle_nan_in_datao   s   rB   metric_namec                 C   s   t d|  d d S )NzUnable to compute zG using bias correction. Please consider to set `bias_correction=False`.r   )rC   r   r   r   &_unable_to_use_bias_correction_warning   s   
rD   )r   r    )typingr   r   r   r   r   typing_extensionsr   torchmetrics.utilities.printsr   strr   r   r   r   boolr/   r0   r6   r9   r;   rB   rD   r   r   r   r   <module>   s\   "
"


