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mZ d dl	m
Z
 dededed	ed
ededeeeeeeef fddZG dd de
ZdS )    )AnyListTupleN)Tensor)_pearson_corrcoef_compute_pearson_corrcoef_update)Metricmeans_xmeans_yvars_xvars_ycorrs_xynbsreturnc                 C   s<  t | dkr| d |d |d |d |d |d fS | d |d |d |d |d |d f\}}}}	}
}tdt | D ]}| | || || || || || f\}}}}}}|| }|| ||  | }|| ||  | }|d | ||  }||| ||  || d  7 }|d | ||  }||| ||  || d  7 }|| }|d | ||  }|	|| ||  || d  7 }	|d | ||  }||| ||  || d  7 }|	| }|
|| ||  || ||   7 }
||| ||  || ||   7 }|
| }||||||f\}}}}	}
}q;||||||fS )zAggregate the statistics from multiple devices.

    Formula taken from here: `Aggregate the statistics from multiple devices`_
       r      )lenrange)r	   r
   r   r   r   r   mx1my1vx1vy1cxy1n1imx2my2vx2vy2cxy2n2nbmean_xmean_y
element_x1
element_x2var_x
element_y1
element_y2var_ycorr_xy r+   S/home/ubuntu/.local/lib/python3.10/site-packages/torchmetrics/regression/pearson.py_final_aggregation   s.   (44    $$r-   c                       s   e Zd ZU dZdZdZdZeed< e	e
 ed< e	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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 )PearsonCorrCoefa  Computes `Pearson Correlation Coefficient`_:

    .. math::
        P_{corr}(x,y) = \frac{cov(x,y)}{\sigma_x \sigma_y}

    Where :math:`y` is a tensor of target values, and :math:`x` is a tensor of predictions.

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

    - ``preds`` (:class:`~torch.Tensor`): either single output float tensor with shape ``(N,)``
      or multioutput float tensor of shape ``(N,d)``
    - ``target`` (:class:`~torch.Tensor`): either single output tensor with shape ``(N,)``
      or multioutput tensor of shape ``(N,d)``

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

    - ``pearson`` (:class:`~torch.Tensor`): A tensor with the Pearson Correlation Coefficient

    Args:
        num_outputs: Number of outputs in multioutput setting
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Example (single output regression):
        >>> from torchmetrics import PearsonCorrCoef
        >>> target = torch.tensor([3, -0.5, 2, 7])
        >>> preds = torch.tensor([2.5, 0.0, 2, 8])
        >>> pearson = PearsonCorrCoef()
        >>> pearson(preds, target)
        tensor(0.9849)

    Example (multi output regression):
        >>> from torchmetrics import PearsonCorrCoef
        >>> target = torch.tensor([[3, -0.5], [2, 7]])
        >>> preds = torch.tensor([[2.5, 0.0], [2, 8]])
        >>> pearson = PearsonCorrCoef(num_outputs=2)
        >>> pearson(preds, target)
        tensor([1., 1.])
    TNfull_state_updatepredstargetr"   r#   r&   r)   r*   n_totalr   num_outputskwargsr   c                    s   t  jd
i | t|ts|dk rtd|| _| jdt| jd d | jdt| jd d | j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   zQExpected argument `num_outputs` to be an int larger than 0, but got {num_outputs}r"   )defaultdist_reduce_fxr#   r&   r)   r*   r2   r+   )	super__init__
isinstanceint
ValueErrorr3   	add_statetorchzeros)selfr3   r4   	__class__r+   r,   r8   v   s   zPearsonCorrCoef.__init__c              
   C   sB   t ||| j| j| j| j| j| j| j	\| _| _| _| _| _| _dS )z*Update state with predictions and targets.N)r   r"   r#   r&   r)   r*   r2   r3   )r?   r0   r1   r+   r+   r,   update   s    zPearsonCorrCoef.updatec                 C   s   | j dkr| j dks| j dkr-| jjdkr-t| j| j| j| j| j| j	\}}}}}}n| j}| j}| j}| j	}t
||||S )z4Computes pearson correlation coefficient over state.r   )r3   r"   numelndimr-   r#   r&   r)   r*   r2   r   )r?   _r&   r)   r*   r2   r+   r+   r,   compute   s   .zPearsonCorrCoef.compute)r   )__name__
__module____qualname____doc__is_differentiablehigher_is_betterr/   bool__annotations__r   r   r:   r   r8   rB   rF   __classcell__r+   r+   r@   r,   r.   C   s.   
 &r.   )typingr   r   r   r=   r   *torchmetrics.functional.regression.pearsonr   r   torchmetrics.metricr   r-   r.   r+   r+   r+   r,   <module>   s*   
,