o
    .wi                  
   @   s   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	d
Zdededededef
ddZ	ddededee defddZ
dS )    )OptionalN)Tensor)"_check_retrieval_functional_inputstargetpredsdiscount_cumsumreturnc           	      C   s   t j| ddd\}}}t j|t jd}|d|| j|jd || }|jddd }t j|t jd}||d  |d< ||  |dd< || 	 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_sums r   c/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torchmetrics/functional/retrieval/ndcg.py_tie_average_dcg   s   r    top_kignore_tiesc           	      C   st   dt t j| jd | jdd  }d||d< |r,|jdd}| | }||  }|S |jd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   r   r   r   _dcg_sample_scores-   s   $r-   c                 C   s   t | |dd\} }|du r| jd n|}t|tr|dks!tdt|| |dd}t|||dd}|dk}d||< ||   ||    < | 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_targetNr#   r   z,`top_k` has to be a positive integer or NoneF)r"   )r   r(   
isinstanceint
ValueErrorr-   mean)r   r   r!   gainnormalized_gainall_irrelevantr   r   r   retrieval_normalized_dcgG   s   r6   )N)typingr   r   r   torchmetrics.utilities.checksr   r    r0   boolr-   r6   r   r   r   r   <module>   s   $