o
    .wik                  	   @   s   d dl mZmZ d dlmZmZmZmZmZ d dl	Z	d dl	m
Z
mZ d dlmZ d dlmZ d dlmZ d dlmZmZ 			dd
e
deed ef dee de
fddZG dd deeZdS )    )ABCabstractmethod)AnyCallableListOptionalUnionN)Tensortensor)Literal)Metric)_check_retrieval_inputs)_flexible_bincountdim_zero_catmeanvaluesaggregationr   medianminmaxdimreturnc                 C   s   |dkr|du r|   S | j |dS |dkr%|du r|  S | j|djS |dkr8|du r1|  S | j|djS |dkrK|du rD|  S | j|djS || |dS )z9Aggregate the final retrieval values into a single value.r   Nr   r   r   r   )r   r   r   r   r   )r   r   r    r   X/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/torchmetrics/retrieval/base.py_retrieval_aggregate   s   r   c                       s   e Zd ZU dZdZeed< dZeed< dZeed< e	e
 ed< e	e
 ed< e	e
 ed	< 	
		ddedee deed ef deddf
 fddZde
d	e
de
ddfddZde
fddZede
d	e
de
fddZ  ZS )RetrievalMetricaQ	  Works with binary target data. Accepts float predictions from a model output.

    As input to ``forward`` and ``update`` the metric accepts the following input:

    - ``preds`` (:class:`~torch.Tensor`): A float tensor of shape ``(N, ...)``
    - ``target`` (:class:`~torch.Tensor`): A long or bool tensor of shape ``(N, ...)``
    - ``indexes`` (:class:`~torch.Tensor`): A long tensor of shape ``(N, ...)`` which indicate to which query a
      prediction belongs

    .. hint::
        The ``indexes``, ``preds`` and ``target`` must have the same dimension and will be flattened
        to single dimension once provided.

    .. attention::
        Predictions will be first grouped by ``indexes`` and then the real metric, defined by overriding
        the `_metric` method, will be computed as the mean of the scores over each query.

    As output to ``forward`` and ``compute`` the metric returns the following output:

    - ``metric`` (:class:`~torch.Tensor`): A tensor as computed by ``_metric`` if the number of positive targets is
      at least 1, otherwise behave as specified by ``self.empty_target_action``.

    Args:
        empty_target_action:
            Specify what to do with queries that do not have at least a positive
            or negative (depend on metric) target. Choose from:

            - ``'neg'``: those queries count as ``0.0`` (default)
            - ``'pos'``: those queries count as ``1.0``
            - ``'skip'``: skip those queries; if all queries are skipped, ``0.0`` is returned
            - ``'error'``: raise a ``ValueError``

        ignore_index:
            Ignore predictions where the target is equal to this number.
        aggregation:
            Specify how to aggregate over indexes. Can either a custom callable function that takes in a single tensor
            and returns a scalar value or one of the following strings:

            - ``'mean'``: average value is returned
            - ``'median'``: median value is returned
            - ``'max'``: max value is returned
            - ``'min'``: min value is returned

        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Raises:
        ValueError:
            If ``empty_target_action`` is not one of ``error``, ``skip``, ``neg`` or ``pos``.
        ValueError:
            If ``ignore_index`` is not `None` or an integer.

    Fis_differentiableThigher_is_betterfull_state_updateindexespredstargetnegNr   empty_target_actionignore_indexr   r   kwargsr   c                    s   t  jdi | d| _d}||vrtd| d|| _|d ur*t|ts*td|| _|dv s=t|s=td| d|| _	| j
d	g d d
 | j
dg d d
 | j
dg d d
 d S )NF)errorskipr$   posz7Argument `empty_target_action` received a wrong value `z`.z3Argument `ignore_index` must be an integer or None.r   zArgument `aggregation` must be one of `mean`, `median`, `min`, `max` or a custom callable functionwhich takes tensor of values, but got .r!   )defaultdist_reduce_fxr"   r#   r   )super__init__allow_non_binary_target
ValueErrorr%   
isinstanceintr&   callabler   	add_state)selfr%   r&   r   r'   empty_target_action_options	__class__r   r   r/   i   s&   zRetrievalMetric.__init__c                 C   sT   |du rt dt|||| j| jd\}}}| j| | j| | j| dS )zGCheck shape, check and convert dtypes, flatten and add to accumulators.Nz!Argument `indexes` cannot be None)r0   r&   )r1   r   r0   r&   r!   appendr"   r#   )r6   r"   r#   r!   r   r   r   update   s   zRetrievalMetric.updatec                    s  t | j}t | j t | j}t|\}} |  || }t|  	 }g }t
tj |ddtj||ddD ]4\}}| sf| jdkrLtd| jdkrY|td q;| jdkre|td q;|| || q;|rtt fd	d
|D | jS td S )a  First concat state ``indexes``, ``preds`` and ``target`` since they were stored as lists.

        After that, compute list of groups that will help in keeping together predictions about the same query. Finally,
        for each group compute the ``_metric`` if the number of positive targets is at least 1, otherwise behave as
        specified by ``self.empty_target_action``.

        r   r   r(   zC`compute` method was provided with a query with no positive target.r*   g      ?r$   g        c                    s   g | ]}|  qS r   )to).0xr"   r   r   
<listcomp>   s    z+RetrievalMetric.compute.<locals>.<listcomp>)r   r!   r"   r#   torchsortr   detachcputolistzipsplitsumr%   r1   r:   r
   _metricr   stackr   r<   )r6   r!   r#   indicessplit_sizesres
mini_predsmini_targetr   r?   r   compute   s.   





 zRetrievalMetric.computec                 C   s   dS )zCompute a metric over a predictions and target of a single group.

        This method should be overridden by subclasses.

        Nr   )r6   r"   r#   r   r   r   rI      s    zRetrievalMetric._metric)r$   Nr   )__name__
__module____qualname____doc__r   bool__annotations__r   r    r   r	   strr   r3   r   r   r   r   r/   r;   rP   r   rI   __classcell__r   r   r8   r   r   +   s4   
 5% r   )r   N)abcr   r   typingr   r   r   r   r   rA   r	   r
   typing_extensionsr   torchmetricsr   torchmetrics.utilities.checksr   torchmetrics.utilities.datar   r   r3   r   r   r   r   r   r   <module>   s(   
