o
    .wid*                     @   s   d dl mZ 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mZ d dlmZ d dlmZ d d	lmZmZ esAd
gZ	ddedededededede	d defddZG dd deZdS )    )Sequence)AnyOptionalUnionN)Tensor)Literal)_mean_squared_error_update+_normalized_root_mean_squared_error_compute)Metric)_MATPLOTLIB_AVAILABLE)_AX_TYPE_PLOT_OUT_TYPE#NormalizedRootMeanSquaredError.plotmeanmin_valmax_valmean_valvar_valtarget_squaredtotalnormalizationr   rangestdl2returnc                 C   s  t | dkr*|dkr|d S |dkr|d | d  S |dkr"|d S |dkr*|d S | d |d |d |d |d |d f\}}}	}
}}tdt | D ]r}| | || || || || || f\}}}}}}|| }||	 ||  | }|d | ||	  }|
||	 ||  || d  7 }
|d | ||  }||| ||  || d  7 }|
| }t||} t||}|| }qK|dkr|S |dkr||  S |dkr||  S | S )z_In the case of multiple devices we need to aggregate the statistics from the different devices.   r   r   r   r   r      )lenr   torchminmaxsqrt)r   r   r   r   r   r   r   	min_val_1	max_val_1
mean_val_1	var_val_1target_squared_1total_1i	min_val_2	max_val_2
mean_val_2	var_val_2target_squared_2total_2r   _tempvar r2   Z/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torchmetrics/regression/nrmse.py_final_aggregation!   sR   
	  
r4   c                	       s   e Zd ZU dZdZeed< dZeed< dZeed< dZ	e
ed< eed	< eed
< eed< eed< eed< eed< eed< 		d$ded d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	d%d eeeee f  d!ee defd"d#Z  ZS )&NormalizedRootMeanSquaredErrora  Calculates the `Normalized Root Mean Squared Error`_ (NRMSE) also know as scatter index.

    The metric is defined as:

    .. math::
        \text{NRMSE} = \frac{\text{RMSE}}{\text{denom}}

    where RMSE is the root mean squared error and `denom` is the normalization factor. The normalization factor can be
    either be the mean, range, standard deviation or L2 norm of the target, which can be set using the `normalization`
    argument.

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

    - ``preds`` (:class:`~torch.Tensor`): Predictions from model
    - ``target`` (:class:`~torch.Tensor`): Ground truth values

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

    - ``nrmse`` (:class:`~torch.Tensor`): A tensor with the mean squared error

    Args:
        normalization: type of normalization to be applied. Choose from "mean", "range", "std", "l2" which corresponds
          to normalizing the RMSE by the mean of the target, the range of the target, the standard deviation of the
          target or the L2 norm of the target.
        num_outputs: Number of outputs in multioutput setting
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Example::
        Single output normalized root mean squared error computation:

        >>> import torch
        >>> from torchmetrics import NormalizedRootMeanSquaredError
        >>> target = torch.tensor([2.5, 5.0, 4.0, 8.0])
        >>> preds = torch.tensor([3.0, 5.0, 2.5, 7.0])
        >>> nrmse = NormalizedRootMeanSquaredError(normalization="mean")
        >>> nrmse(preds, target)
        tensor(0.1919)
        >>> nrmse = NormalizedRootMeanSquaredError(normalization="range")
        >>> nrmse(preds, target)
        tensor(0.1701)

    Example::
        Multioutput normalized root mean squared error computation:

        >>> import torch
        >>> from torchmetrics import NormalizedRootMeanSquaredError
        >>> preds = torch.tensor([[0., 1], [2, 3], [4, 5], [6, 7]])
        >>> target = torch.tensor([[0., 1], [3, 3], [4, 5], [8, 9]])
        >>> nrmse = NormalizedRootMeanSquaredError(num_outputs=2)
        >>> nrmse(preds, target)
        tensor([0.2981, 0.2222])

    Tis_differentiableFhigher_is_betterfull_state_updateg        plot_lower_boundsum_squared_errorr   r   r   r   r   r   r   r   r   r   num_outputskwargsr   Nc                    s  t  jdi | |dvrtd| || _t|tr |dks'td| || _| jdt	|dd | jdt	|d d | jd	t
d
t| j d d | jdt
d
 t| j d d | jdt	| jd d | jdt	| jd d | jdt	| jd d d S )Nr   zRArgument `normalization` should be either 'mean', 'range', 'std' or 'l2', but got r   z6Expected num_outputs to be a positive integer but got r:   sum)defaultdist_reduce_fxr   r   Infr   r   r   r   r2   )super__init__
ValueErrorr   
isinstanceintr;   	add_stater   zerosfloatones)selfr   r;   r<   	__class__r2   r3   rB      s     "z'NormalizedRootMeanSquaredError.__init__predstargetc                 C   s   t ||| j\}}|  j|7  _| jdkr|dn|}t|jddj| j| _t	|j
ddj| j| _|  j|d jdd7  _| j| j |jdd | j|  }|  j|7  _|| || j  jdd}|| _|  j|7  _dS )zjUpdate state with predictions and targets.

        See `mean_squared_error_update` for details.

        r   r   dimr   N)r   r;   r:   viewr   minimumr    valuesr   maximumr!   r   r   r=   r   r   r   )rJ   rM   rN   r:   num_obsnew_meannew_varr2   r2   r3   update   s   "z%NormalizedRootMeanSquaredError.updatec              	   C   s   | j dkr| j dks| j dkr3| jjdkr3t| j| j| j| j| j| j	| j
d}| j	 jdd}n-| j
dkr<| j}n!| j
dkrH| j| j }n| j
dkrWt| j| j	 }nt| j}| j	}t| j||S )z[Computes NRMSE over state.

        See `mean_squared_error_compute` for details.

        r   )r   r   r   r   r   r   r   r   rP   r   r   r   )r;   r   numelndimr4   r   r   r   r   r   r   squeezer=   r   r"   r	   r:   )rJ   denomr   r2   r2   r3   compute   s(   .	


z&NormalizedRootMeanSquaredError.computevalaxc                 C   s   |  ||S )aG  Plot a single or multiple values from the metric.

        Args:
            val: Either a single result from calling `metric.forward` or `metric.compute` or a list of these results.
                If no value is provided, will automatically call `metric.compute` and plot that result.
            ax: An matplotlib axis object. If provided will add plot to that axis

        Returns:
            Figure and Axes object

        Raises:
            ModuleNotFoundError:
                If `matplotlib` is not installed

        .. plot::
            :scale: 75

            >>> from torch import randn
            >>> # Example plotting a single value
            >>> from torchmetrics.regression import NormalizedRootMeanSquaredError
            >>> metric = NormalizedRootMeanSquaredError()
            >>> metric.update(randn(10,), randn(10,))
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

            >>> from torch import randn
            >>> # Example plotting multiple values
            >>> from torchmetrics.regression import NormalizedRootMeanSquaredError
            >>> metric = NormalizedRootMeanSquaredError()
            >>> values = []
            >>> for _ in range(10):
            ...     values.append(metric(randn(10,), randn(10,)))
            >>> fig, ax = metric.plot(values)

        )_plot)rJ   r_   r`   r2   r2   r3   plot   s   (r   )r   r   )NN)__name__
__module____qualname____doc__r6   bool__annotations__r7   r8   r9   rH   r   r   rE   r   rB   rY   r^   r   r   r   r   r   rb   __classcell__r2   r2   rK   r3   r5   _   sD   
 6r5   )r   )collections.abcr   typingr   r   r   r   r   typing_extensionsr   (torchmetrics.functional.regression.nrmser   r	   torchmetrics.metricr
   torchmetrics.utilities.importsr   torchmetrics.utilities.plotr   r   __doctest_skip__r4   r5   r2   r2   r2   r3   <module>   s<   

>