a
    d?                     @   s   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 deeeeed ed	d
dZdeeeeeeedf f  eeef dddZdeeeeeeeef f  eed eeeeedf f  edddZdS )    )OptionalTupleUnionN)Tensortensor)Literal)rank_zero_warnreduce      $@elementwise_mean)r   sumnoneN)sum_squared_errorn_obs
data_rangebase	reductionreturnc                 C   s>   dt | t | |  }|dt t|  }t||dS )a  Compute peak signal-to-noise ratio.

    Args:
        sum_squared_error: Sum of square of errors over all observations
        n_obs: Number of predictions or observations
        data_range: the range of the data. If None, it is determined from the data (max - min).
           ``data_range`` must be given when ``dim`` is not None.
        base: a base of a logarithm to use
        reduction: a method to reduce metric score over labels.

            - ``'elementwise_mean'``: takes the mean (default)
            - ``'sum'``: takes the sum
            - ``'none'`` or ``None``: no reduction will be applied

    Example:
        >>> preds = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
        >>> target = torch.tensor([[3.0, 2.0], [1.0, 0.0]])
        >>> data_range = target.max() - target.min()
        >>> sum_squared_error, n_obs = _psnr_update(preds, target)
        >>> _psnr_compute(sum_squared_error, n_obs, data_range)
        tensor(2.5527)

       
   )r   )torchlogr   r	   )r   r   r   r   r   Zpsnr_base_eZ	psnr_vals r   k/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/torchmetrics/functional/image/psnr.py_psnr_compute   s    r   .)predstargetdimr   c                 C   s   |du r8t t | | d}t| |jd}||fS | | }t j|| |d}t|trb|gnt|}|st| |jd}n$t|	 |jd| 
 }||}||fS )aZ  Update and return variables required to compute peak signal-to-noise ratio.

    Args:
        preds: Predicted tensor
        target: Ground truth tensor
        dim: Dimensions to reduce PSNR scores over provided as either an integer or a list of integers.
            Default is None meaning scores will be reduced across all dimensions.

    Nr   )devicer   )r   r   powr   Znumelr   
isinstanceintlistsizeprodZ	expand_as)r   r   r   r   r   diffZdim_listr   r   r   _psnr_update:   s    
r'   )r   r   r   r   r   r   r   c                 C   s   |du r |dkr t d| d |du rJ|dur8td| |  }n\t|trtj| |d |d d} tj||d |d d}t|d |d  }ntt	|}t
| ||d	\}}t|||||d
S )a  Compute the peak signal-to-noise ratio.

    Args:
        preds: estimated signal
        target: groun truth signal
        data_range:
            the range of the data. If None, it is determined from the data (max - min). If a tuple is provided then
            the range is calculated as the difference and input is clamped between the values.
            The ``data_range`` must be given when ``dim`` is not None.
        base: a base of a logarithm to use
        reduction: a method to reduce metric score over labels.

            - ``'elementwise_mean'``: takes the mean (default)
            - ``'sum'``: takes the sum
            - ``'none'`` or None``: no reduction will be applied

        dim:
            Dimensions to reduce PSNR scores over provided as either an integer or a list of integers. Default is
            None meaning scores will be reduced across all dimensions.

    Return:
        Tensor with PSNR score

    Raises:
        ValueError:
            If ``dim`` is not ``None`` and ``data_range`` is not provided.

    Example:
        >>> from torchmetrics.functional.image import peak_signal_noise_ratio
        >>> pred = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
        >>> target = torch.tensor([[3.0, 2.0], [1.0, 0.0]])
        >>> peak_signal_noise_ratio(pred, target)
        tensor(2.5527)

    .. note::
        Half precision is only support on GPU for this metric

    Nr   zThe `reduction=z.` will not have any effect when `dim` is None.z6The `data_range` must be given when `dim` is not None.r      )minmaxr   )r   r   )r   
ValueErrorr*   r)   r!   tupler   clampr   floatr'   r   )r   r   r   r   r   r   r   r   r   r   r   peak_signal_noise_ratioZ   s    .
r/   )r
   r   )N)Nr
   r   N)typingr   r   r   r   r   r   Ztyping_extensionsr   Ztorchmetrics.utilitiesr   r	   r.   r   r"   r'   r/   r   r   r   r   <module>   sD     & 
#    