o
    yis                     @   s|   d dl mZmZ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 dlmZ d dlmZ G dd	 d	eZdS )
    )AnyOptionalSequenceTupleUnionN)Tensortensor)Literal)_psnr_compute_psnr_update)Metric)rank_zero_warnc                       s   e Zd ZU dZdZeed< dZeed< dZeed< e	ed< e	ed< 			
			dde
e deded de
eeeedf f  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 )PeakSignalNoiseRatioa  Computes `Computes Peak Signal-to-Noise Ratio`_ (PSNR):

    .. math:: \text{PSNR}(I, J) = 10 * \log_{10} \left(\frac{\max(I)^2}{\text{MSE}(I, J)}\right)

    Where :math:`\text{MSE}` denotes the `mean-squared-error`_ function.

    As input to ``forward`` and ``update`` the metric accepts the following input

    - ``preds`` (:class:`~torch.Tensor`): Predictions from model of shape ``(N,C,H,W)``
    - ``target`` (:class:`~torch.Tensor`): Ground truth values of shape ``(N,C,H,W)``

    As output of `forward` and `compute` the metric returns the following output

    - ``psnr`` (:class:`~torch.Tensor`): if ``reduction!='none'`` returns float scalar tensor with average PSNR value
      over sample else returns tensor of shape ``(N,)`` with PSNR values per sample

    Args:
        data_range:
            the range of the data. If None, it is determined from the data (max - min).
            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 and all batches.
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

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

    Example:
        >>> from torchmetrics import PeakSignalNoiseRatio
        >>> psnr = PeakSignalNoiseRatio()
        >>> preds = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
        >>> target = torch.tensor([[3.0, 2.0], [1.0, 0.0]])
        >>> psnr(preds, target)
        tensor(2.5527)
    Tis_differentiablehigher_is_betterFfull_state_update
min_target
max_targetN      $@elementwise_mean
data_rangebase	reduction)r   sumnoneNdim.kwargsreturnc                    s  t  jdi | |d u r|dkrtd| d |d u r2| jdtddd | jdtd	dd n| jdg d
d | jdg d
d |d u rh|d urNtdd | _| jdtdtjd | jdtdtj	d n| jdtt
|dd || _|| _t|trt|| _d S || _d S )Nr   zThe `reduction=z.` will not have any effect when `dim` is None.sum_squared_errorg        r   )defaultdist_reduce_fxtotalr   catz6The `data_range` must be given when `dim` is not None.r   r   r   mean )super__init__r   	add_stater   
ValueErrorr   torchminmaxfloatr   r   
isinstancer   tupler   )selfr   r   r   r   r   	__class__r$   K/home/ubuntu/.local/lib/python3.10/site-packages/torchmetrics/image/psnr.pyr&   M   s$   "zPeakSignalNoiseRatio.__init__predstargetc                 C   s   t ||| jd\}}| jdu r6| jdu r&t| | j| _t| | j| _|  j|7  _|  j|7  _dS | j	| | j	| dS )z*Update state with predictions and targets.)r   N)
r   r   r   r*   r   r+   r   r   r!   append)r/   r3   r4   r   n_obsr$   r$   r2   updatep   s   

zPeakSignalNoiseRatio.updatec                 C   sx   | j dur	| j }n| j| j }| jdu r| j}| j}ntdd | jD }tdd | jD }t|||| j	| j
dS )z.Compute peak signal-to-noise ratio over state.Nc                 S      g | ]}|  qS r$   flatten.0valuesr$   r$   r2   
<listcomp>       z0PeakSignalNoiseRatio.compute.<locals>.<listcomp>c                 S   r8   r$   r9   r;   r$   r$   r2   r>      r?   )r   r   )r   r   r   r   r   r!   r)   r"   r
   r   r   )r/   r   r   r!   r$   r$   r2   compute   s   

zPeakSignalNoiseRatio.compute)Nr   r   N)__name__
__module____qualname____doc__r   bool__annotations__r   r   r   r   r,   r	   r   intr   r   r&   r7   r@   __classcell__r$   r$   r0   r2   r      s4   
 ,#r   )typingr   r   r   r   r   r)   r   r   typing_extensionsr	   "torchmetrics.functional.image.psnrr
   r   torchmetrics.metricr   torchmetrics.utilitiesr   r   r$   r$   r$   r2   <module>   s   