o
    oi8                     @   s   d dl Z d dlmZ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 G dd de	ZG dd	 d	eZG d
d deZG dd deZG dd deZG dd deZdS )    N)AnyCallableListUnion)Tensor)Metric)dim_zero_catc                	       s   e Zd ZU dZeed< dZdZdZ	dde	e
ef de	eef de	eef d	ef fd
dZde	eef defddZde	eef ddfddZdefddZ  ZS )BaseAggregatora  Base class for aggregation metrics.

    Args:
        fn: string specifying the reduction function
        default_value: default tensor value to use for the metric state
        nan_strategy: options:
            - ``'error'``: if any `nan` values are encounted will give a RuntimeError
            - ``'warn'``: if any `nan` values are encounted will give a warning and continue
            - ``'ignore'``: all `nan` values are silently removed
            - a float: if a float is provided will impude any `nan` values with this value

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

    Raises:
        ValueError:
            If ``nan_strategy`` is not one of ``error``, ``warn``, ``ignore`` or a float
    valueNFerrorfndefault_valuenan_strategykwargsc                    sX   t  jdi | d}||vrt|tstd| d| d|| _| jd||d d S )N)r   warnignorez6Arg `nan_strategy` should either be a float or one of z	 but got .r
   defaultdist_reduce_fx )super__init__
isinstancefloat
ValueErrorr   	add_state)selfr   r   r   r   allowed_nan_strategy	__class__r   V/home/ubuntu/SoloSpeech/.venv/lib/python3.10/site-packages/torchmetrics/aggregation.pyr   0   s   zBaseAggregator.__init__xreturnc                 C   s   t |tstj|tj| jd}t|}| rH| jdkr!t	d| jdkr5t
dt ||  }| S | jdkrC||  }| S | j||< | S )zConverts input x to a tensor if not already and afterwards checks for nans that either give an error,
        warning or just ignored.)dtypedevicer   z Encounted `nan` values in tensorr   z2Encounted `nan` values in tensor. Will be removed.r   )r   r   torch	as_tensorfloat32r%   isnananyr   RuntimeErrorwarningsr   UserWarningr   )r   r"   nansr   r   r!   _cast_and_nan_check_inputB   s   







z(BaseAggregator._cast_and_nan_check_inputc                 C   s   dS )zOverwrite in child class.Nr   r   r
   r   r   r!   updateV   s   zBaseAggregator.updatec                 C   s   | j S zCompute the aggregated value.)r
   r   r   r   r!   computeZ   s   zBaseAggregator.compute)r   )__name__
__module____qualname____doc__r   __annotations__is_differentiablehigher_is_betterfull_state_updater   r   strr   r   r   r   r/   r1   r4   __classcell__r   r   r   r!   r	      s&   
 


r	   c                       T   e Zd ZdZdZ	ddeeef def fddZ	deee
f d	d
fddZ  ZS )	MaxMetrica"  Aggregate a stream of value into their maximum value.

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

    - ``value`` (:class:`~float` or :class:`~torch.Tensor`): a single float or an tensor of float values with
      arbitary shape ``(...,)``.

    As output of `forward` and `compute` the metric returns the following output

    - ``agg`` (:class:`~torch.Tensor`): scalar float tensor with aggregated maximum value over all inputs received

    Args:
        nan_strategy: options:
            - ``'error'``: if any `nan` values are encounted will give a RuntimeError
            - ``'warn'``: if any `nan` values are encounted will give a warning and continue
            - ``'ignore'``: all `nan` values are silently removed
            - a float: if a float is provided will impude any `nan` values with this value

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

    Raises:
        ValueError:
            If ``nan_strategy`` is not one of ``error``, ``warn``, ``ignore`` or a float

    Example:
        >>> import torch
        >>> from torchmetrics import MaxMetric
        >>> metric = MaxMetric()
        >>> metric.update(1)
        >>> metric.update(torch.tensor([2, 3]))
        >>> metric.compute()
        tensor(3.)
    Tr   r   r   c                    s(   t  jdttd |fi | d S )Nmaxinfr   r   r&   tensorr   r   r   r   r   r   r!   r      s   
zMaxMetric.__init__r
   r#   Nc                 C   0   |  |}| rt| jt|| _dS dS zUpdate state with data.

        Args:
            value: Either a float or tensor containing data. Additional tensor
                dimensions will be flattened
        N)r/   numelr&   rA   r
   r0   r   r   r!   r1         
zMaxMetric.updater   r5   r6   r7   r8   r<   r   r=   r   r   r   r   r1   r>   r   r   r   r!   r@   _       "
"r@   c                       r?   )	MinMetrica"  Aggregate a stream of value into their minimum value.

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

    - ``value`` (:class:`~float` or :class:`~torch.Tensor`): a single float or an tensor of float values with
      arbitary shape ``(...,)``.

    As output of `forward` and `compute` the metric returns the following output

    - ``agg`` (:class:`~torch.Tensor`): scalar float tensor with aggregated minimum value over all inputs received

    Args:
        nan_strategy: options:
            - ``'error'``: if any `nan` values are encounted will give a RuntimeError
            - ``'warn'``: if any `nan` values are encounted will give a warning and continue
            - ``'ignore'``: all `nan` values are silently removed
            - a float: if a float is provided will impude any `nan` values with this value

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

    Raises:
        ValueError:
            If ``nan_strategy`` is not one of ``error``, ``warn``, ``ignore`` or a float

    Example:
        >>> import torch
        >>> from torchmetrics import MinMetric
        >>> metric = MinMetric()
        >>> metric.update(1)
        >>> metric.update(torch.tensor([2, 3]))
        >>> metric.compute()
        tensor(1.)
    Tr   r   r   c                    s&   t  jdttd|fi | d S )NminrB   rC   rE   r   r   r!   r      s   
zMinMetric.__init__r
   r#   Nc                 C   rF   rG   )r/   rH   r&   rN   r
   r0   r   r   r!   r1      rI   zMinMetric.updaterJ   rK   r   r   r   r!   rM      rL   rM   c                       sP   e Zd ZdZ	ddeeef def fddZdeee	f dd	fd
dZ
  ZS )	SumMetrica  Aggregate a stream of value into their sum.

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

    - ``value`` (:class:`~float` or :class:`~torch.Tensor`): a single float or an tensor of float values with
      arbitary shape ``(...,)``.

    As output of `forward` and `compute` the metric returns the following output

    - ``agg`` (:class:`~torch.Tensor`): scalar float tensor with aggregated sum over all inputs received

    Args:
        nan_strategy: options:
            - ``'error'``: if any `nan` values are encounted will give a RuntimeError
            - ``'warn'``: if any `nan` values are encounted will give a warning and continue
            - ``'ignore'``: all `nan` values are silently removed
            - a float: if a float is provided will impude any `nan` values with this value

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

    Raises:
        ValueError:
            If ``nan_strategy`` is not one of ``error``, ``warn``, ``ignore`` or a float

    Example:
        >>> import torch
        >>> from torchmetrics import SumMetric
        >>> metric = SumMetric()
        >>> metric.update(1)
        >>> metric.update(torch.tensor([2, 3]))
        >>> metric.compute()
        tensor(6.)
    r   r   r   c                    s"   t  jdtd|fi | d S )Nsum        )r   r   r&   rD   rE   r   r   r!   r      s   
zSumMetric.__init__r
   r#   Nc                 C   s,   |  |}| r|  j| 7  _dS dS rG   )r/   rH   r
   rP   r0   r   r   r!   r1     s   
zSumMetric.updaterJ   )r5   r6   r7   r8   r   r=   r   r   r   r   r1   r>   r   r   r   r!   rO      s    $
"rO   c                       s^   e Zd ZdZ	ddeeef def fddZdeee	f dd	fd
dZ
de	fddZ  ZS )	CatMetrica  Concatenate a stream of values.

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

    - ``value`` (:class:`~float` or :class:`~torch.Tensor`): a single float or an tensor of float values with
      arbitary shape ``(...,)``.

    As output of `forward` and `compute` the metric returns the following output

    - ``agg`` (:class:`~torch.Tensor`): scalar float tensor with concatenated values over all input received

    Args:
        nan_strategy: options:
            - ``'error'``: if any `nan` values are encounted will give a RuntimeError
            - ``'warn'``: if any `nan` values are encounted will give a warning and continue
            - ``'ignore'``: all `nan` values are silently removed
            - a float: if a float is provided will impude any `nan` values with this value

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

    Raises:
        ValueError:
            If ``nan_strategy`` is not one of ``error``, ``warn``, ``ignore`` or a float

    Example:
        >>> import torch
        >>> from torchmetrics import CatMetric
        >>> metric = CatMetric()
        >>> metric.update(1)
        >>> metric.update(torch.tensor([2, 3]))
        >>> metric.compute()
        tensor([1., 2., 3.])
    r   r   r   c                    s   t  jdg |fi | d S )Ncat)r   r   rE   r   r   r!   r   7  s   zCatMetric.__init__r
   r#   Nc                 C   s&   |  |}| r| j| dS dS rG   )r/   rH   r
   appendr0   r   r   r!   r1   >  s   
zCatMetric.updatec                 C   s"   t | jtr| jrt| jS | jS r2   )r   r
   listr   r3   r   r   r!   r4   I  s   
zCatMetric.computerJ   r5   r6   r7   r8   r   r=   r   r   r   r   r1   r4   r>   r   r   r   r!   rR     s    $
rR   c                       sl   e Zd ZdZ	ddeeef def fddZddeee	f d	eee	f d
dfddZ
d
e	fddZ  ZS )
MeanMetrica  Aggregate a stream of value into their mean value.

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

    - ``value`` (:class:`~float` or :class:`~torch.Tensor`): a single float or an tensor of float values with
      arbitary shape ``(...,)``.
    - ``weight`` (:class:`~float` or :class:`~torch.Tensor`): a single float or an tensor of float value with
      arbitary shape ``(...,)``. Needs to be broadcastable with the shape of ``value`` tensor.

    As output of `forward` and `compute` the metric returns the following output

    - ``agg`` (:class:`~torch.Tensor`): scalar float tensor with aggregated (weighted) mean over all inputs received

    Args:
       nan_strategy: options:
            - ``'error'``: if any `nan` values are encounted will give a RuntimeError
            - ``'warn'``: if any `nan` values are encounted will give a warning and continue
            - ``'ignore'``: all `nan` values are silently removed
            - a float: if a float is provided will impude any `nan` values with this value

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

    Raises:
        ValueError:
            If ``nan_strategy`` is not one of ``error``, ``warn``, ``ignore`` or a float

    Example:
        >>> from torchmetrics import MeanMetric
        >>> metric = MeanMetric()
        >>> metric.update(1)
        >>> metric.update(torch.tensor([2, 3]))
        >>> metric.compute()
        tensor(2.)
    r   r   r   c                    s8   t  jdtd|fi | | jdtddd d S )NrP   rQ   weightr   )r   r   r&   rD   r   rE   r   r   r!   r   t  s   zMeanMetric.__init__      ?r
   rX   r#   Nc                 C   s^   |  |}|  |}| dkrdS t||j}|  j||  7  _|  j| 7  _dS )a  Update state with data.

        Args:
            value: Either a float or tensor containing data. Additional tensor
                dimensions will be flattened
            weight: Either a float or tensor containing weights for calculating
                the average. Shape of weight should be able to broadcast with
                the shape of `value`. Default to `1.0` corresponding to simple
                harmonic average.
        r   N)r/   rH   r&   broadcast_toshaper
   rP   rX   )r   r
   rX   r   r   r!   r1     s   

zMeanMetric.updatec                 C   s   | j | j S r2   )r
   rX   r3   r   r   r!   r4     s   zMeanMetric.computerJ   )rY   rV   r   r   r   r!   rW   P  s    %
(rW   )r,   typingr   r   r   r   r&   r   torchmetrics.metricr   torchmetrics.utilities.datar   r	   r@   rM   rO   rR   rW   r   r   r   r!   <module>   s   G==;<