o
    yi                     @   sx   d dl mZmZ d dlZd dlmZmZmZ d dlmZ d dl	m
Z
 	ddeded	ee d
edeeeef f
ddZdS )    )OptionalTupleN)Tensorcumsumtensor)pad)"_check_retrieval_functional_inputsFpredstargetmax_k
adaptive_kreturnc              	   C   sN  t | |\} }t|tstd|du r| jd }t|tr"|dks&td|rQ|| jd krQtjd| jd d | jd}t	|d|| jd  fdt
| jd }ntjd|d | jd}| sqtj|| jdtj|| jd|fS || jt|| jd dd	d  
 }tt	|dtd|t| fdd
dd	}||  }|| }|||fS )a  Computes precision-recall pairs for different k (from 1 to `max_k`).

    In a ranked retrieval context, appropriate sets of retrieved documents are naturally given by
    the top k retrieved documents.

    Recall is the fraction of relevant documents retrieved among all the relevant documents.
    Precision is the fraction of relevant documents among all the retrieved documents.

    For each such set, precision and recall values can be plotted to give a recall-precision
    curve.

    ``preds`` and ``target`` should be of the same shape and live on the same device. If no ``target`` is ``True``,
    ``0`` is returned. ``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 being relevant or not.
        max_k: Calculate recall and precision for all possible top k from 1 to max_k
               (default: `None`, which considers all possible top k)
        adaptive_k: adjust `max_k` to `min(max_k, number of documents)` for each query

    Returns:
        tensor with the precision values for each k (at ``k``) from 1 to `max_k`
        tensor with the recall values for each k (at ``k``) from 1 to `max_k`
        tensor with all possibles k

    Raises:
        ValueError:
            If ``max_k`` is not `None` or an integer larger than 0.
        ValueError:
            If ``adaptive_k`` is not boolean.

    Example:
        >>> from  torchmetrics.functional import retrieval_precision_recall_curve
        >>> preds = tensor([0.2, 0.3, 0.5])
        >>> target = tensor([True, False, True])
        >>> precisions, recalls, top_k = retrieval_precision_recall_curve(preds, target, max_k=2)
        >>> precisions
        tensor([1.0000, 0.5000])
        >>> recalls
        tensor([0.5000, 0.5000])
        >>> top_k
        tensor([1, 2])
    z `adaptive_k` has to be a booleanNr   z,`max_k` has to be a positive integer or None   )deviceconstant)dimg        )r   
isinstancebool
ValueErrorshapeinttorcharanger   r   floatsumzerostopkminr   maxlen)r	   r
   r   r   r   relevantrecall	precision r$   l/home/ubuntu/.local/lib/python3.10/site-packages/torchmetrics/functional/retrieval/precision_recall_curve.py retrieval_precision_recall_curve   s$   0

("&(
r&   )NF)typingr   r   r   r   r   r   torch.nn.functionalr   torchmetrics.utilities.checksr   r   r   r&   r$   r$   r$   r%   <module>   s"   