
    i=                        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 dl
mZ d dlmZmZmZ d dlmZ  G d	 d
e      Z G d de      Zdededeeef   fdZdedededefdZdededefdZdedededefdZdededefdZd5dededefdZdedeeeef   fdZdedededeeeee   ee   ee   ee   ee   ee   ef	   fdZdededededed ed!ee   d"ee   dedefd#Zd$edefd%Z ded ed!ee   d&ee   d'ee   d"ee   d(ee   d)ee   ded*ee   defd+Z!	 	 	 d6deded,eee      d-eee      d.edeee   ee   f   fd/Z"	 d7dededed*ee   deeee   f   f
d0Z#	 	 	 d8dededed1   d2ed*eed3      deeeeef   f   fd4Z$y)9    )ListOptionalUnionN)Tensor)Literal) _check_data_shape_to_num_outputs)_check_same_shape)	_bincount_cumsumdim_zero_cat)EnumStrc                   2    e Zd ZdZdZdZdZedefd       Z	y)_MetricVariantzEnumerate for metric variants.abcreturnc                       y)Nvariant r       /Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/functional/regression/kendall.py_namez_MetricVariant._name!   s    r   N)
__name__
__module____qualname____doc__ABCstaticmethodstrr   r   r   r   r   r      s-    (AAA3  r   r   c                   2    e Zd ZdZdZdZdZedefd       Z	y)_TestAlternativez'Enumerate for test alternative options.	two-sidedlessgreaterr   c                       y)Nalternativer   r   r   r   r   z_TestAlternative._name-   s    r   N)
r   r   r   r   	TWO_SIDEDLESSGREATERr!   r"   r   r   r   r   r$   r$   &   s-    1IDG3  r   r$   xyr   c                    t        j                  |      }| j                  |j                  }} | j                         \  } }t	        | j
                  d         D ]  }||   ||      ||<    | 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is       r   _sort_on_first_sequencer8   2   sn     	AA33qAffhGAt1771:tDG}! 338Or   r7   c                     t        j                  | |   | |dz   d k  ||   ||dz   d k        j                  d      j                  d      S )z>Count a total number of concordant pairs in a single sequence.   Nr   )r0   logical_andsum	unsqueezer-   r.   r7   s      r   _concordant_element_sumr?   =   sR    QqTAq1uiL0!A$AE92EFJJ1MWWXYZZr   predstargetc           
          t        j                  t        | j                  d         D cg c]  }t	        | ||       c}      j                  d      S c c}w )z<Count a total number of concordant pairs in given sequences.r   )r0   catr4   r5   r?   r<   r@   rA   r7   s      r   _count_concordant_pairsrE   B   I    99u{{[\~I^_I^A-eVQ?I^_`ddefgg_   Ac           
         t        j                  t        j                  | |   | |dz   d kD  ||   ||dz   d k        t        j                  | |   | |dz   d k  ||   ||dz   d kD              j                  d      j	                  d      S )z?Count a total number of discordant pairs in a single sequences.r:   Nr   )r0   
logical_orr;   r<   r=   r>   s      r   _discordant_element_sumrJ   G   s     	adQAy\11Q4!QUI,3FGadQAy\11Q4!QUI,3FG	
 
Q	1r   c           
          t        j                  t        | j                  d         D cg c]  }t	        | ||       c}      j                  d      S c c}w )z<Count a total number of discordant pairs in given sequences.r   )r0   rC   r4   r5   rJ   r<   rD   s      r   _count_discordant_pairsrL   S   rF   rG   r3   c           	      0   |r| j                  d      j                  } t        j                  d| j                  d   t        j
                  | j                        }t        t        j                  || dd | dd k7  j                         gd      d      S )z&Convert a sequence to the rank tensor.r   )dimr:   dtypedeviceN)
r3   valuesr0   zerosr5   int32rQ   r   rC   int)r-   r3   _oness      r   _convert_sequence_to_dense_rankrX   X   sv     FFqFM  KK1771:U[[JE599eaeq"vo%:%:%<=1E1MMr   c                    t        j                  | j                  d   | j                  | j                        }t        j                  | j                  d   | j                  | j                        }t        j                  | j                  d   | j                  | j                        }t        | j                  d         D ]y  }t        | dd|f         }||dkD     }||dz
  z  dz  j                         ||<   ||dz
  z  |dz
  z  j                         ||<   ||dz
  z  d|z  dz   z  j                         ||<   { |||fS )zWGet a total number of ties and staistics for p-value calculation for  a given sequence.r:   rO   N         ?   )r0   rT   r5   rP   rQ   r4   r
   r<   )r-   tiesties_p1ties_p2rN   n_tiess         r   	_get_tiesra   a   s   ;;qwwqzBDkk!''!*AGGAHHEGkk!''!*AGGAHHEGQWWQZ 1QV9%
#vz*a/446S	&3,/6A:>CCE&3,/1v:>BGGI ! '!!r   r   c           	      l   t        | |      \  } }t        | |      }t        | |      }t        j                  | j
                  d   | j                        }dx}}dx}x}	x}
}|t        j                  k7  r6t        |       } t        |d      }t        |       \  }}}	t        |      \  }}
}|||||	||
||f	S )z,Obtain statistics to calculate metric value.r   )rQ   NT)r3   )r8   rE   rL   r0   tensorr5   rQ   r   r   rX   ra   )r@   rA   r   concordant_pairsdiscordant_pairsn_total
preds_tiestarget_tiespreds_ties_p1preds_ties_p2target_ties_p1target_ties_p2s               r   _get_metric_metadatarm   p   s     ,E6:ME6.uf=.uf=ll5;;q>%,,?G##JFJJMJMJN^."""/60dC3<U3C0
M=6?6G3^^
 
r   rd   re   con_min_dis_pairsrf   rg   rh   c	           	      F   |t         j                  k(  r|||z   z  S |t         j                  k(  r||dz
  z  dz  }	|,t        j                  d|	j
                  |	j                        }|,t        j                  d|	j
                  |	j                        }|	|z
  |	|z
  z  }
|t        j                  |
      z  S t        j                  | j                  D cg c]  }t        |j                                c}| j
                  | j                        }t        j                  |j                  D cg c]  }t        |j                                c}|j
                  |j                        }t        j                  ||      }d|z  |dz
  |z  |dz  z  z  S c c}w c c}w )z-Calculate Kendall's tau from metric metadata.r:   rZ           rO   )r   r   r   r0   rc   rP   rQ   sqrtr2   lenuniqueminimum)r@   rA   rd   re   rn   rf   rg   rh   r   total_combinationsdenominatorppreds_uniquettarget_uniquemin_classess                   r   _calculate_taur|      sl    .""" $47G$GHH."""%,!%<%Ac1C1I1IRdRkRklJ,,s2D2J2JSeSlSlmK)J6;MP[;[\ 5::k#:::<<%'' B'QQXXZ' B%++^c^j^jkLLL688!D8a#ahhj/8!DFLLagananoM--m<K  [1_$Cgqj$PQQ !C!Ds    F1 Ft_valuec                    | }t         j                  j                  j                  t        j                  dg      j                  |      t        j                  dg      j                  |            }| j                         }| j                         } |j                  |       }|j                  | t        j                  t        d      |j                  |j                              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``.

    rp   r[   nanrO   )r0   distributionsnormalNormalrc   toisnan
nan_to_numcdfwherefloatrP   rQ   )r}   rQ   normal_distis_nanp_values        r   "_get_p_value_for_t_value_from_distr      s     F%%,,33ELL#4G4J4J64RTYT`T`beafTgTjTjkqTrsK]]_F  "Goog&G==&%,,uU|7==Y`YgYg"hiir   ri   rj   rk   rl   r)   c
                 :   ||dz
  z  d|z  dz   z  }
|t         j                  k(  rd| z  t        j                  |
dz        z  }ne||dz
  z  }|
||ndz
  ||ndz
  dz  }|d||ndz  ||ndz  |z  z  }|||nd||ndz  d|z  |dz
  z  z  z  }| t        j                  |      z  }|	t        j
                  k(  rt        j                  |      }|	t        j
                  t        j                  fv r|dz  }t        |      }|	t        j
                  k(  r|dz  }|S )	z9Calculate p-value for Kendall's tau from metric metadata.r:   rZ   r\      r      	   rR   )	r   r   r0   rq   r$   r*   absr,   r   )rn   rf   rg   ri   rj   rh   rk   rl   r   r)   t_value_denominator_baser}   mt_value_denominatorr   s                  r   _calculate_p_valuer      sx     ''A+6!g+/J."""''%**5MPQ5Q*RRw{#$ - 9}qB!/!;~D 	'
 	z51=P[Pgmno  	 	+7]Q!/!;~D1u!$&	

 $ejj1D&EE&000))G$'113C3K3KLL209G&0001Nr   concat_predsconcat_targetnum_outputsc                     |xs g }|xs g }t        | |       t        | ||       |dk(  r"| j                  d      } |j                  d      }|j                  |        |j                  |       ||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

    r:   )r	   r   r=   append)r@   rA   r   r   r   s        r   _kendall_corrcoef_updater      s{    (  %2L!'RMeV$$UFK@a"!!!$ &&r   c                 $   t        | ||      \	  }}}}}}	}
}}||z
  }t        | |||||||	|	      }|rt        ||||||	|
|||
      nd}|j                  d   dk(  r$|j	                         }||j	                         nd}|j                  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   r:   rR   )rm   r|   r   r5   squeezeclamp)r@   rA   r   r)   rd   re   rg   ri   rj   rh   rk   rl   rf   rn   taur   s                   r   _kendall_corrcoef_computer     s    : 	UFG4
(+;;
v')9;LgWacnpwC   		
  $ yy|qkkm'.':'//#99RW$$r   )r   r   r   t_test)r%   r&   r'   c                    t        |t              st        dt        |       d      |r|t        d      t        j                  t        |            }|rt        j                  t        |            nd}t        | |g g | j                  dk(  rdn| j                  d         \  }}t        t        |      t        |      ||      \  }	}
|
|	|
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`.r:   rR   )r   )
isinstancebool
ValueErrortyper   from_strr"   r$   r   ndimr5   r   r   )r@   rA   r   r   r)   _variant_alternative_preds_targetr   r   s              r   kendall_rank_corrcoefr   O  s    V fd#YZ^_eZfYgghijj+%^__&&s7|4HBH#,,S-=>dL.vr2

a1U[[QS_OFG -VW	LC G|Jr   )F)NNr:   )N)r   Fr%   )%typingr   r   r   r0   r   typing_extensionsr   (torchmetrics.functional.regression.utilsr   torchmetrics.utilities.checksr	   torchmetrics.utilities.datar
   r   r   torchmetrics.utilities.enumsr   r   r$   tupler8   rV   r?   rE   rJ   rL   r   rX   ra   rm   r|   r   r   r   r   r   r   r   r   <module>r      s   ) (   % U ; H H 0	W 		w 	v & U66>5J [v [& [S [V [
h6 h6 hf h
	v 	& 	S 	V 	h6 h6 hf h
Nv NT Nf N" "E&&&"89 "%%!%,:%


VVVVVV

%PRRR R 	R
 R R  R &!R R R:j j6 j(((  ( F#	(
 F#( &!( V$( V$( ( *+( (\ ,0,0!'!'!' 4<(!' DL)	!'
 !' 4<f%&!'P /3	9%9%9% 9% *+	9%
 68F##$9%~ '*EP___ ]#_ 	_
 '"@AB_ 65(()_r   