a
    dH                  	   @   s   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Z
eeeeeeeef ddd	Zdeeef eeeeed edddZdeeed eeee f dddZdS )    )SequenceTupleUnionN)Tensor)Literal)_check_same_shape)
raw_valuesuniform_averageZvariance_weighted)predstargetreturnc                 C   sn   t | | | d}tj||  dd}||  }tj|| dd}tj|dd}tj|| dd}|||||fS )zUpdate and returns variables required to compute Explained Variance. Checks for same shape of input tensors.

    Args:
        preds: Predicted tensor
        target: Ground truth tensor

    r   )Zdim)r   sizetorchsum)r
   r   n_obs	sum_errordiffsum_squared_error
sum_targetsum_squared_target r   ~/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/torchmetrics/functional/regression/explained_variance.py_explained_variance_update   s    

r   r	   )r   r   r   r   r   multioutputr   c                 C   s   ||  }||  ||  }||  }||  ||  }	|dk}
|	dk}|
|@ }t |}d|| |	|   ||< d||
| @ < |dkr|S |dkrt |S t |	}t |	| | S )a'  Compute Explained Variance.

    Args:
        n_obs: Number of predictions or observations
        sum_error: Sum of errors over all observations
        sum_squared_error: Sum of square of errors over all observations
        sum_target: Sum of target values
        sum_squared_target: Sum of squares of target values
        multioutput: Defines aggregation in the case of multiple output scores. Can be one
            of the following strings:

            * ``'raw_values'`` returns full set of scores
            * ``'uniform_average'`` scores are uniformly averaged
            * ``'variance_weighted'`` scores are weighted by their individual variances

    Example:
        >>> target = torch.tensor([[0.5, 1], [-1, 1], [7, -6]])
        >>> preds = torch.tensor([[0, 2], [-1, 2], [8, -5]])
        >>> n_obs, sum_error, ss_error, sum_target, ss_target = _explained_variance_update(preds, target)
        >>> _explained_variance_compute(n_obs, sum_error, ss_error, sum_target, ss_target, multioutput='raw_values')
        tensor([0.9677, 1.0000])

    r   g      ?g        r   r	   )r   Z	ones_likemeanr   )r   r   r   r   r   r   Zdiff_avg	numeratorZ
target_avgdenominatorZnonzero_numeratorZnonzero_denominatorZvalid_scoreZoutput_scoresZ	denom_sumr   r   r   _explained_variance_compute.   s     


r   )r
   r   r   r   c                 C   s<   |t vrtdt  t| |\}}}}}t||||||S )a  Compute explained variance.

    Args:
        preds: estimated labels
        target: ground truth labels
        multioutput: Defines aggregation in the case of multiple output scores. Can be one
            of the following strings):

            * ``'raw_values'`` returns full set of scores
            * ``'uniform_average'`` scores are uniformly averaged
            * ``'variance_weighted'`` scores are weighted by their individual variances

    Example:
        >>> from torchmetrics.functional.regression import explained_variance
        >>> target = torch.tensor([3, -0.5, 2, 7])
        >>> preds = torch.tensor([2.5, 0.0, 2, 8])
        >>> explained_variance(preds, target)
        tensor(0.9572)

        >>> target = torch.tensor([[0.5, 1], [-1, 1], [7, -6]])
        >>> preds = torch.tensor([[0, 2], [-1, 2], [8, -5]])
        >>> explained_variance(preds, target, multioutput='raw_values')
        tensor([0.9677, 1.0000])

    zFInvalid input to argument `multioutput`. Choose one of the following: )ALLOWED_MULTIOUTPUT
ValueErrorr   r   )r
   r   r   r   r   r   r   r   r   r   r   explained_variancee   s    r    )r	   )r	   )typingr   r   r   r   r   Ztyping_extensionsr   Ztorchmetrics.utilities.checksr   r   intr   r   r    r   r   r   r   <module>   s.     
: 