o
    yi                     @   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ededeeeeeef fdd	Z		
ddededededede
defddZ	
ddedede
deeee f fddZdS )    )SequenceTupleUnionN)Tensor)_check_same_shape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 )zUpdates and returns variables required to compute Explained Variance. Checks for same shape of input
    tensors.

    Args:
        preds: Predicted tensor
        target: Ground truth tensor
    r   )dim)r   sizetorchsum)r   r   n_obs	sum_errordiffsum_squared_error
sum_targetsum_squared_target r   i/home/ubuntu/.local/lib/python3.10/site-packages/torchmetrics/functional/regression/explained_variance.py_explained_variance_update   s   
	
r   uniform_averager   r   r   r   r   multioutputc                 C   s   ||  }||  ||  }||  }||  ||  }	|dk}
|	dk}|
|@ }t |}d|| |	|   ||< d||
| @ < |dkrB|S |dkrKt |S |dkr]t |	}t |	| | S dS )a'  Computes 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        
raw_valuesr   variance_weightedN)r   	ones_likemeanr   )r   r   r   r   r   r   diff_avg	numerator
target_avgdenominatornonzero_numeratornonzero_denominatorvalid_scoreoutput_scores	denom_sumr   r   r   _explained_variance_compute,   s$   


r&   c                 C   s&   t | |\}}}}}t||||||S )a  Computes 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 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])
    )r   r&   )r   r   r   r   r   r   r   r   r   r   r   explained_varianced   s   r'   )r   )typingr   r   r   r   r   torchmetrics.utilities.checksr   intr   strr&   r'   r   r   r   r   <module>   s>   $
;