
    i              
           d dl mZ d dlZd dlmZ d dlmZ dedededefd	Zdeded
ededef
dZ	ddeded
ee   defdZ
y)    )OptionalN)Tensor)"_check_retrieval_functional_inputstargetpredsdiscount_cumsumreturnc                    t        j                  | dd      \  }}}t        j                  |t         j                        }|j	                  d|| j                  |j                               ||z  }|j                  d      dz
  }t        j                  |t         j                        }||d      |d<   ||   j                         |dd ||z  j                         S )aI  Translated version of sklearns `_tie_average_dcg` function.

    Args:
        target: ground truth about each document relevance.
        preds: estimated probabilities of each document to be relevant.
        discount_cumsum: cumulative sum of the discount.

    Returns:
        The cumulative gain of the tied elements.

    T)return_inversereturn_counts)dtyper   dim   N)
torchunique
zeros_likefloat32scatter_add_tor   cumsumdiffsum)	r   r   r   _invcountsrankedgroupsdiscount_sumss	            {/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/functional/retrieval/ndcg.py_tie_average_dcgr!      s     \\5&TRNAsFfEMM:F
3			 =>f_F]]q]!A%F$$V5==AM&vay1M!'/446M!"]"''))    top_kignore_tiesc                 8   dt        j                  t        j                  | j                  d   | j                        dz         z  }d||d |r,|j                  d      }| |   }||z  j                         }|S |j                  d	      }t        | ||      }|S )
ay  Translated version of sklearns `_dcg_sample_scores` function.

    Args:
        target: ground truth about each document relevance.
        preds: estimated probabilities of each document to be relevant.
        top_k: consider only the top k elements
        ignore_ties: If True, ties are ignored. If False, ties are averaged.

    Returns:
        The cumulative gain

    g      ?)deviceg       @g        NT)
descendingr   )	r   log2arangeshaper'   argsortr   r   r!   )	r   r   r#   r$   discountrankingr   cumulative_gainr   s	            r    _dcg_sample_scoresr0   -   s     ejjfll2.>v}}!UX[![\]HHUV--4-0#f,113  #//b/1*65/Jr"   c                    t        | |d      \  } }|| j                  d   n|}t        |t              r|dkD  st	        d      t        || |d      }t        |||d      }|dk(  }d||<   || xx   ||    z  cc<   |j                         S )a  Compute `Normalized Discounted Cumulative Gain`_ (for information retrieval).

    ``preds`` and ``target`` should be of the same shape and live on the same device.
    ``target`` must be either `bool` or `integers` and ``preds`` must be ``float``,
    otherwise an error is raised.

    Args:
        preds: estimated probabilities of each document to be relevant.
        target: ground truth about each document relevance.
        top_k: consider only the top k elements (default: ``None``, which considers them all)

    Return:
        A single-value tensor with the nDCG of the predictions ``preds`` w.r.t. the labels ``target``.

    Raises:
        ValueError:
            If ``top_k`` parameter is not `None` or an integer larger than 0

    Example:
        >>> from torchmetrics.functional.retrieval import retrieval_normalized_dcg
        >>> preds = torch.tensor([.1, .2, .3, 4, 70])
        >>> target = torch.tensor([10, 0, 0, 1, 5])
        >>> retrieval_normalized_dcg(preds, target)
        tensor(0.6957)

    T)allow_non_binary_targetr&   r   z,`top_k` has to be a positive integer or NoneF)r$   )r   r+   
isinstanceint
ValueErrorr0   mean)r   r   r#   gainnormalized_gainall_irrelevants         r    retrieval_normalized_dcgr:   G   s    6 7uf^bcME6$}EKKO%Euc"uqyGHHfeUFD(DQO %)ND._n_==99;r"   )N)typingr   r   r   torchmetrics.utilities.checksr   r!   r4   boolr0   r:    r"   r    <module>r?      s       L*V *F *V *PV *.v f S t X^ 4*F *F *8C= *\b *r"   