a
    dE;                     @   sx  d dl mZ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 dlmZ d dlmZmZmZ d dlmZ G d	d
 d
eZG dd deZeeeeef dddZeeeedddZeeedddZeeeedddZeeedddZd;eeedddZeeeeef ddd Zeeeeeeee ee ee ee ee ee ef	 d!d"d#Zeeeeeeee ee eed$
d%d&Zeed'd(d)Z eeee ee ee ee ee ee eee ed*d+d,Z!d<eeeee  eee  eeee ee f d.d/d0Z"d=eeeee eeee f d1d2d3Z#d>eeed6 eeed7  eeeeef f d8d9d:Z$dS )?    )ListOptionalTupleUnionN)Tensor)Literal) _check_data_shape_to_num_outputs)_check_same_shape)	_bincount_cumsumdim_zero_cat)EnumStrc                   @   s.   e Zd ZdZdZdZdZeedddZ	dS )	_MetricVariantzEnumerate for metric variants.abcreturnc                   C   s   dS )Nvariant r   r   r   s/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/torchmetrics/functional/regression/kendall.py_name!   s    z_MetricVariant._nameN)
__name__
__module____qualname____doc__ABCstaticmethodstrr   r   r   r   r   r      s   r   c                   @   s.   e Zd ZdZdZdZdZeedddZ	dS )	_TestAlternativez'Enumerate for test alternative options.	two-sidedlessgreaterr   c                   C   s   dS )Nalternativer   r   r   r   r   r   -   s    z_TestAlternative._nameN)
r   r   r   r   	TWO_SIDEDLESSGREATERr   r    r   r   r   r   r   r!   &   s   r!   )xyr   c                 C   sX   t |}| j|j } }|  \} }t| jd D ]}|| ||  ||< q2| j|jfS )zBSort sequences in an ascent order according to the sequence ``x``.r   )torchcloneTsortrangeshape)r)   r*   permir   r   r   _sort_on_first_sequence2   s    
r3   )r)   r*   r2   r   c                 C   s@   t | | | |d d k || ||d d k ddS )z>Count a total number of concordant pairs in a single sequence.   Nr   )r+   logical_andsum	unsqueezer)   r*   r2   r   r   r   _concordant_element_sum=   s    r9   )predstargetr   c                    s*   t  fddt jd D dS )z<Count a total number of concordant pairs in given sequences.c                    s   g | ]}t  |qS r   )r9   .0r2   r:   r;   r   r   
<listcomp>D       z+_count_concordant_pairs.<locals>.<listcomp>r   r+   catr/   r0   r6   r>   r   r>   r   _count_concordant_pairsB   s    rC   c              
   C   sx   t t | | | |d d k|| ||d d k t | | | |d d k || ||d d kddS )z?Count a total number of discordant pairs in a single sequences.r4   Nr   )r+   
logical_orr5   r6   r7   r8   r   r   r   _discordant_element_sumG   s    22rE   c                    s*   t  fddt jd D dS )z<Count a total number of discordant pairs in given sequences.c                    s   g | ]}t  |qS r   )rE   r<   r>   r   r   r?   U   r@   z+_count_discordant_pairs.<locals>.<listcomp>r   rA   r>   r   r>   r   _count_discordant_pairsS   s    rF   F)r)   r.   r   c                 C   s`   |r| j ddj} tjd| jd tj| jd}ttj|| dd | dd k	 gddddS )z&Convert a sequence to the rank tensor.r   )dimr4   dtypedeviceN)
r.   valuesr+   zerosr0   int32rJ   r   rB   int)r)   r.   Z_onesr   r   r   _convert_sequence_to_dense_rankX   s    rP   )r)   r   c                 C   s   t j| jd | j| jd}t j| jd | j| jd}t j| jd | j| jd}t| jd D ]x}t| dd|f }||dk }||d  d  ||< ||d  |d   ||< ||d  d| d   ||< q\|||fS )zWGet a total number of ties and staistics for p-value calculation for  a given sequence.r4   rH   N         ?   )r+   rM   r0   rI   rJ   r/   r
   r6   )r)   ZtiesZties_p1Zties_p2rG   Zn_tiesr   r   r   	_get_tiesa   s    "rT   )r:   r;   r   r   c              	   C   s   t | |\} }t| |}t| |}tj| jd | jd}d }}d } }	 }
}|tjkrt	| } t	|dd}t
| \}}}	t
|\}}
}|||||	||
||f	S )z,Obtain statistics to calculate metric value.r   )rJ   NT)r.   )r3   rC   rF   r+   tensorr0   rJ   r   r   rP   rT   )r:   r;   r   concordant_pairsdiscordant_pairsn_total
preds_tiestarget_tiespreds_ties_p1preds_ties_p2target_ties_p1target_ties_p2r   r   r   _get_metric_metadatap   s*    


r_   )
r:   r;   rV   rW   con_min_dis_pairsrX   rY   rZ   r   r   c	                 C   s   |t jkr|||  S |t jkrN||d  d }	|	| |	|  }
|t|
 S tjdd | jD | j| jd}tjdd |jD |j|jd}t	||}d| |d | |d   S )z-Calculate Kendall's tau from metric metadata.r4   rQ   c                 S   s   g | ]}t | qS r   lenunique)r=   pr   r   r   r?      r@   z"_calculate_tau.<locals>.<listcomp>rH   c                 S   s   g | ]}t | qS r   ra   )r=   tr   r   r   r?      r@   )
r   r   r   r+   sqrtrU   r-   rI   rJ   Zminimum)r:   r;   rV   rW   r`   rX   rY   rZ   r   Ztotal_combinationsdenominatorZpreds_uniqueZtarget_uniqueZmin_classesr   r   r   _calculate_tau   s    

  rh   )t_valuer   c                 C   sl   | }t jjt dg|t dg|}|  }|  } || }|	| t jt
d|j|jdS )zObtain p-value for a given Tensor of t-values. Handle ``nan`` which cannot be passed into torch distributions.

    When t-value is ``nan``, a resulted p-value should be alson ``nan``.

    g        rR   nanrH   )r+   distributionsnormalZNormalrU   toisnanZ
nan_to_numZcdfwherefloatrI   rJ   )ri   rJ   Znormal_distis_nanp_valuer   r   r   "_get_p_value_for_t_value_from_dist   s    ,
rs   )r`   rX   rY   r[   r\   rZ   r]   r^   r   r%   r   c
                 C   s   ||d  d| d  }
|t jkr:d|  t|
d  }nZ||d  }|
| | d }|d| | | 7 }||| d| |d   7 }| t| }|	tjkrt|}|	tjtjfv r|d9 }t|}|	tjkr|d9 }|S )z9Calculate p-value for Kendall's tau from metric metadata.r4   rQ   rS         	   rK   )	r   r   r+   rf   r!   r&   absr(   rs   )r`   rX   rY   r[   r\   rZ   r]   r^   r   r%   Zt_value_denominator_baseri   mZt_value_denominatorrr   r   r   r   _calculate_p_value   s     



ry   r4   )r:   r;   concat_predsconcat_targetnum_outputsr   c                 C   s^   |pg }|pg }t | | t| || |dkrB| d} |d}||  || ||fS )a  Update variables required to compute Kendall rank correlation coefficient.

    Args:
        preds: Sequence of data
        target: Sequence of data
        concat_preds: List of batches of preds sequence to be concatenated
        concat_target: List of batches of target sequence to be concatenated
        num_outputs: Number of outputs in multioutput setting

    Raises:
        RuntimeError: If ``preds`` and ``target`` do not have the same shape

    r4   )r	   r   r7   append)r:   r;   rz   r{   r|   r   r   r   _kendall_corrcoef_update   s    




r~   )r:   r;   r   r%   r   c                 C   s   t | ||\	}}}}}}	}
}}|| }t| |||||||	|	}|r\t||||||	|
|||
nd}|jd dkr| }|dur| nd}|dd|fS )a/  Compute Kendall rank correlation coefficient, and optionally p-value of corresponding statistical test.

    Args:
        Args:
        preds: Sequence of data
        target: Sequence of data
        variant: Indication of which variant of Kendall's tau to be used
        alternative: Alternative hypothesis for for t-test. Possible values:
            - 'two-sided': the rank correlation is nonzero
            - 'less': the rank correlation is negative (less than zero)
            - 'greater':  the rank correlation is positive (greater than zero)

    Nr   r4   rK   )r_   rh   ry   r0   Zsqueezeclamp)r:   r;   r   r%   rV   rW   rY   r[   r\   rZ   r]   r^   rX   r`   taurr   r   r   r   _kendall_corrcoef_compute  sD    
r   r   r"   )r   r   r   )r"   r#   r$   )r:   r;   r   t_testr%   r   c                 C   s   t |tstdt| d|r2|du r2tdtt|}|rRtt|nd}t| |g g | j	dkrndn| j
d d\}}tt|t|||\}	}
|
dur|	|
fS |	S )a  Compute `Kendall Rank Correlation Coefficient`_.

    .. math::
        tau_a = \frac{C - D}{C + D}

    where :math:`C` represents concordant pairs, :math:`D` stands for discordant pairs.

    .. math::
        tau_b = \frac{C - D}{\sqrt{(C + D + T_{preds}) * (C + D + T_{target})}}

    where :math:`C` represents concordant pairs, :math:`D` stands for discordant pairs and :math:`T` represents
    a total number of ties.

    .. math::
        tau_c = 2 * \frac{C - D}{n^2 * \frac{m - 1}{m}}

    where :math:`C` represents concordant pairs, :math:`D` stands for discordant pairs, :math:`n` is a total number
    of observations and :math:`m` is a ``min`` of unique values in ``preds`` and ``target`` sequence.

    Definitions according to Definition according to `The Treatment of Ties in Ranking Problems`_.

    Args:
        preds: Sequence of data of either shape ``(N,)`` or ``(N,d)``
        target: Sequence of data of either shape ``(N,)`` or ``(N,d)``
        variant: Indication of which variant of Kendall's tau to be used
        t_test: Indication whether to run t-test
        alternative: Alternative hypothesis for t-test. Possible values:
            - 'two-sided': the rank correlation is nonzero
            - 'less': the rank correlation is negative (less than zero)
            - 'greater':  the rank correlation is positive (greater than zero)

    Return:
        Correlation tau statistic
        (Optional) p-value of corresponding statistical test (asymptotic)

    Raises:
        ValueError: If ``t_test`` is not of a type bool
        ValueError: If ``t_test=True`` and ``alternative=None``

    Example (single output regression):
        >>> from torchmetrics.functional.regression import kendall_rank_corrcoef
        >>> preds = torch.tensor([2.5, 0.0, 2, 8])
        >>> target = torch.tensor([3, -0.5, 2, 1])
        >>> kendall_rank_corrcoef(preds, target)
        tensor(0.3333)

    Example (multi output regression):
        >>> from torchmetrics.functional.regression import kendall_rank_corrcoef
        >>> preds = torch.tensor([[2.5, 0.0], [2, 8]])
        >>> target = torch.tensor([[3, -0.5], [2, 1]])
        >>> kendall_rank_corrcoef(preds, target)
        tensor([1., 1.])

    Example (single output regression with t-test)
        >>> from torchmetrics.functional.regression import kendall_rank_corrcoef
        >>> preds = torch.tensor([2.5, 0.0, 2, 8])
        >>> target = torch.tensor([3, -0.5, 2, 1])
        >>> kendall_rank_corrcoef(preds, target, t_test=True, alternative='two-sided')
        (tensor(0.3333), tensor(0.4969))

    Example (multi output regression with t-test):
        >>> from torchmetrics.functional.regression import kendall_rank_corrcoef
        >>> preds = torch.tensor([[2.5, 0.0], [2, 8]])
        >>> target = torch.tensor([[3, -0.5], [2, 1]])
        >>> kendall_rank_corrcoef(preds, target, t_test=True, alternative='two-sided')
            (tensor([1., 1.]), tensor([nan, nan]))

    z>Argument `t_test` is expected to be of a type `bool`, but got .NzCArgument `alternative` is required if `t_test=True` but got `None`.r4   rK   )r|   )
isinstancebool
ValueErrortyper   Zfrom_strr    r!   r~   ndimr0   r   r   )r:   r;   r   r   r%   Z_variantZ_alternative_preds_targetr   rr   r   r   r   kendall_rank_corrcoefA  s    K

r   )F)NNr4   )N)r   Fr"   )%typingr   r   r   r   r+   r   Ztyping_extensionsr   Z(torchmetrics.functional.regression.utilsr   Ztorchmetrics.utilities.checksr	   Ztorchmetrics.utilities.datar
   r   r   Ztorchmetrics.utilities.enumsr   r   r!   r3   rO   r9   rC   rE   rF   r   rP   rT   r_   rh   rs   ry   r~   r   r   r   r   r   r   <module>   s   	)$   

( ?   
