o
    yi                     @   s   d dl mZ d dlZd dlmZ d dlmZ d dlmZ deded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
def
ddZdS )    )TupleN)Tensor)rank_zero_warn)_check_same_shapepredstargetreturnc                 C   st   t | | | jdkrtd| j tj|dd}tj|| dd}||  }tj|| dd}|d}||||fS )zUpdates and returns variables required to compute R2 score.

    Checks for same shape and 1D/2D input tensors.

    Args:
        preds: Predicted tensor
        target: Ground truth tensor
       z`Expected both prediction and target to be 1D or 2D tensors, but received tensors with dimension r   )dim)r   ndim
ValueErrorshapetorchsumsize)r   r   sum_obssum_squared_obsresidualrssn_obs r   Y/home/ubuntu/.local/lib/python3.10/site-packages/torchmetrics/functional/regression/r2.py_r2_score_update   s   



r   uniform_averager   r   r   r   adjustedmultioutputc                 C   s^  |dk rt d|| }| ||  }tj|t|dd }tj|t|dd }	||	@ }
t|}d||
 ||
   ||
< d|||	 @ < |dkrM|}n%|dkrWt|}n|d	krjt|}t|| | }nt d
| d|dk s{t|tst d|dkr||d krt	dt
 |S ||d krt	dt
 |S dd| |d  || d   }|S )a  Computes R2 score.

    Args:
        sum_squared_obs: Sum of square of all observations
        sum_obs: Sum of all observations
        rss: Residual sum of squares
        n_obs: Number of predictions or observations
        adjusted: number of independent regressors for calculating adjusted r2 score.
        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]])
        >>> sum_squared_obs, sum_obs, rss, n_obs = _r2_score_update(preds, target)
        >>> _r2_score_compute(sum_squared_obs, sum_obs, rss, n_obs, multioutput="raw_values")
        tensor([0.9654, 0.9082])
    r	   z1Needs at least two samples to calculate r2 score.g-C6?)atol   g        
raw_valuesr   variance_weightedzgArgument `multioutput` must be either `raw_values`, `uniform_average` or `variance_weighted`. Received .r   z?`adjusted` parameter should be an integer larger or equal to 0.zdMore independent regressions than data points in adjusted r2 score. Falls back to standard r2 score.zGDivision by zero in adjusted r2 score. Falls back to standard r2 score.)r   r   isclose
zeros_like	ones_likemeanr   
isinstanceintr   UserWarning)r   r   r   r   r   r   mean_obstsscond_rsscond_tsscond
raw_scoresr2tss_sumr   r   r   _r2_score_compute0   sH   

	
 r0   c                 C   s$   t | |\}}}}t||||||S )a  Computes r2 score also known as `R2 Score_Coefficient Determination`_:

    .. math:: R^2 = 1 - \frac{SS_{res}}{SS_{tot}}

    where :math:`SS_{res}=\sum_i (y_i - f(x_i))^2` is the sum of residual squares, and
    :math:`SS_{tot}=\sum_i (y_i - \bar{y})^2` is total sum of squares. Can also calculate
    adjusted r2 score given by

    .. math:: R^2_{adj} = 1 - \frac{(1-R^2)(n-1)}{n-k-1}

    where the parameter :math:`k` (the number of independent regressors) should
    be provided as the ``adjusted`` argument.

    Args:
        preds: estimated labels
        target: ground truth labels
        adjusted: number of independent regressors for calculating adjusted r2 score.
        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

    Raises:
        ValueError:
            If both ``preds`` and ``targets`` are not ``1D`` or ``2D`` tensors.
        ValueError:
            If ``len(preds)`` is less than ``2`` since at least ``2`` sampels are needed to calculate r2 score.
        ValueError:
            If ``multioutput`` is not one of ``raw_values``, ``uniform_average`` or ``variance_weighted``.
        ValueError:
            If ``adjusted`` is not an ``integer`` greater than ``0``.

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

        >>> target = torch.tensor([[0.5, 1], [-1, 1], [7, -6]])
        >>> preds = torch.tensor([[0, 2], [-1, 2], [8, -5]])
        >>> r2_score(preds, target, multioutput='raw_values')
        tensor([0.9654, 0.9082])
    )r   r0   )r   r   r   r   r   r   r   r   r   r   r   r2_scorez   s   3r1   )r   r   )typingr   r   r   torchmetrics.utilitiesr   torchmetrics.utilities.checksr   r   r&   strr0   r1   r   r   r   r   <module>   sH   "
M