a
    þd|  ã                   @   sæ   d dl mZmZ d dlZd dlmZ d dlmZ eeedœdd„Zeeedœdd	„Zeeed
œdd„Z	eee
 eeeeedœdd„Zeeeeef dœdd„Zdeeeeedœdd„Zdeeeedœdd„Zdeeeedœdd„ZdS )é    )ÚOptionalÚTupleN)ÚTensor)Ú_TORCH_GREATER_EQUAL_1_9)ÚxÚyÚreturnc                 C   s8   | j tjks|j tjkr.|  ¡ |j ¡   ¡ S | |j S )zSafe calculation of matrix multiplication.

    If input is float16, will cast to float32 for computation and back again.

    )ZdtypeÚtorchÚfloat16ÚfloatÚTZhalf©r   r   © r   úg/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/torchmetrics/utilities/compute.pyÚ_safe_matmul   s    r   c                 C   s   | t  |¡ }d|| dk< |S )z¦Compute x * log(y). Returns 0 if x=0.

    Example:
        >>> import torch
        >>> x = torch.zeros(1)
        >>> _safe_xlogy(x, 1/x)
        tensor([0.])

    ç        r   )r	   Úlog)r   r   Úresr   r   r   Ú_safe_xlogy!   s    
r   )ÚnumÚdenomr   c                 C   s<   d||dk< |   ¡ r| n|  ¡ } |  ¡ r,|n| ¡ }| | S )zSafe division, by preventing division by zero.

    Additionally casts to float if input is not already to secure backwards compatibility.

    é   r   )Zis_floating_pointr   )r   r   r   r   r   Ú_safe_divide0   s    r   )ÚscoreÚaverageÚ
multilabelÚtpÚfpÚfnr   c                 C   sf   |d u s|dkr| S |dkr&|| }n"t  | ¡}|sHd||| | dk< t||  |jdddƒ d¡S )NÚnoneZweightedr   r   éÿÿÿÿT)Zkeepdim)r	   Z	ones_liker   Úsum)r   r   r   r   r   r   Úweightsr   r   r   Ú_adjust_weights_safe_divide<   s    

r#   c                 C   sŒ   | j dkr|  ¡ n| } |j dkr(| ¡ n|}| j dks@|j dkrXtd| j › d|j › ƒ‚|  ¡ | ¡ kr„td|  ¡ › d| ¡ › ƒ‚| |fS )z Check that auc input is correct.r   zJExpected both `x` and `y` tensor to be 1d, but got tensors with dimension z and zHExpected the same number of elements in `x` and `y` tensor but received )ÚndimZsqueezeÚ
ValueErrorZnumelr   r   r   r   Ú_auc_format_inputsJ   s    ÿÿr&   r    )r   r   Ú	directionÚaxisr   c                 C   s@   t  ¡ $ t j|| |d| }W d  ƒ n1 s20    Y  |S )zrCompute area under the curve using the trapezoidal rule.

    Assumes increasing or decreasing order of `x`.

    )ZdimN)r	   Úno_gradZtrapz)r   r   r'   r(   Zauc_r   r   r   Ú_auc_compute_without_checkZ   s    
2r*   F)r   r   Úreorderr   c                 C   s¨   t  ¡ Œ |r6tr t j| ddnt  | ¡\} }|| }| dd … | d d…  }|dk  ¡ rv|dk ¡ rld}qztdƒ‚nd}t| ||ƒW  d   ƒ S 1 sš0    Y  d S )	NT)Zstabler   r    r   g      ð¿z_The `x` tensor is neither increasing or decreasing. Try setting the reorder argument to `True`.g      ð?)r	   r)   r   ÚsortÚanyÚallr%   r*   )r   r   r+   Zx_idxZdxr'   r   r   r   Ú_auc_computee   s    
 ÿr/   c                 C   s   t | |ƒ\} }t| ||dS )a8  Compute Area Under the Curve (AUC) using the trapezoidal rule.

    Args:
        x: x-coordinates, must be either increasing or decreasing
        y: y-coordinates
        reorder: if True, will reorder the arrays to make it either increasing or decreasing

    Return:
        Tensor containing AUC score

    )r+   )r&   r/   )r   r   r+   r   r   r   Úaucx   s    r0   )r    )F)F)Útypingr   r   r	   r   Ztorchmetrics.utilities.importsr   r   r   r   ÚstrÚboolr#   r&   r   Úintr*   r/   r0   r   r   r   r   Ú<module>   s   þ