a
    d(                  	   @   s   d dl Z d dlmZmZmZ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mZmZ d dlmZ d dlmZmZ esdgZd	Zd
ZdZeeeef eeef eeef eeef eeef eeef f ZG dd deZdS )    N)AnyDictIteratorListOptionalSequenceTupleUnion)Tensortensor)Metric)_chrf_score_compute_chrf_score_update_prepare_n_grams_dicts)_MATPLOTLIB_AVAILABLE)_AX_TYPE_PLOT_OUT_TYPECHRFScore.plot)charword)predstargetZmatching)Ztotal_preds_char_n_gramsZtotal_preds_word_n_gramsZtotal_target_char_n_gramsZtotal_target_word_n_gramsZtotal_matching_char_n_gramsZtotal_matching_word_n_gramsc                
       sZ  e Zd ZU dZdZeed< dZeed< dZeed< dZ	e
ed< d	Ze
ed
< dZeee  ed< d)eee
eeeedd fddZee eee  ddddZeeeeef f dddZedddZeddddZeeeeddd Zeeeeed!d"d#Zeeeeef ef  dd$d%Z d*eeeee f  ee! e"d&d'd(Z#  Z$S )+	CHRFScorea  Calculate `chrf score`_ of machine translated text with one or more references.

    This implementation supports both ChrF score computation introduced in `chrF score`_ and `chrF++ score`_ introduced
    in `chrF++ score`_. This implementation follows the implmenetaions from https://github.com/m-popovic/chrF and
    https://github.com/mjpost/sacrebleu/blob/master/sacrebleu/metrics/chrf.py.

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

    - ``preds`` (:class:`~Sequence`): An iterable of hypothesis corpus
    - ``target`` (:class:`~Sequence`): An iterable of iterables of reference corpus

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

    - ``chrf`` (:class:`~torch.Tensor`): If `return_sentence_level_score=True` return a list of sentence-level
      chrF/chrF++ scores, else return a corpus-level chrF/chrF++ score

    Args:
        n_char_order: A character n-gram order. If ``n_char_order=6``, the metrics refers to the official chrF/chrF++.
        n_word_order: A word n-gram order. If ``n_word_order=2``, the metric refers to the official chrF++.
            If ``n_word_order=0``, the metric is equivalent to the original ChrF.
        beta: parameter determining an importance of recall w.r.t. precision. If ``beta=1``, their importance is equal.
        lowercase: An indication whether to enable case-insesitivity.
        whitespace: An indication whether keep whitespaces during n-gram extraction.
        return_sentence_level_score: An indication whether a sentence-level chrF/chrF++ score to be returned.
        kwargs: Additional keyword arguments, see :ref:`Metric kwargs` for more info.

    Raises:
        ValueError:
            If ``n_char_order`` is not an integer greater than or equal to 1.
        ValueError:
            If ``n_word_order`` is not an integer greater than or equal to 0.
        ValueError:
            If ``beta`` is smaller than 0.

    Example:
        >>> from torchmetrics.text import CHRFScore
        >>> preds = ['the cat is on the mat']
        >>> target = [['there is a cat on the mat', 'a cat is on the mat']]
        >>> chrf = CHRFScore()
        >>> chrf(preds, target)
        tensor(0.8640)

    Fis_differentiableThigher_is_betterfull_state_update        plot_lower_boundg      ?plot_upper_boundNsentence_chrf_score             @)n_char_ordern_word_orderbeta	lowercase
whitespacereturn_sentence_level_scorekwargsreturnc                    s   t  jf i | t|tr$|dk r,td|| _t|trD|dk rLtd|| _|dk rbtd|| _|| _|| _	|| _
t|| | _|  D ]B\\}}	}
td|	d D ]&}| |
||}| j|tddd qq| j
r| jd	g d
d d S )N   zMExpected argument `n_char_order` to be an integer greater than or equal to 1.r   zMExpected argument `n_word_order` to be an integer greater than or equal to 0.z.Expected argument `beta` to be greater than 0.r   sum)Zdist_reduce_fxr   cat)super__init__
isinstanceint
ValueErrorr#   r$   r%   r&   r'   r(   floatn_order_get_text_n_gram_iteratorrange_get_state_nameZ	add_stater   )selfr#   r$   r%   r&   r'   r(   r)   n_gram_leveln_gram_ordertextn
state_name	__class__ _/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/torchmetrics/text/chrf.pyr/   i   s(    
zCHRFScore.__init__)r   r   r*   c                 C   st   t ||g|  | j| j| j| j| j| j| jr@| j	ndR  }| 
|dd  | j	durp|d | _	dS )z*Update state with predictions and targets.N)r   _convert_states_to_dictsr#   r$   r4   r%   r&   r'   r(   r   _update_states_from_dicts)r8   r   r   n_grams_dicts_tupler@   r@   rA   update   s.    	

zCHRFScore.update)r*   c                 C   sR   | j dur4tg |  | j| jR  t| j fS tg |  | j| jR  S )zCalculate chrF/chrF++ score.N)r   r   rC   r4   r%   torchr-   r8   r@   r@   rA   compute   s
    

zCHRFScore.computec                 C   sz   t ttt| j| j}|  D ]L\\}}}td|d D ]0}| ||}| 	|||}t
| ||| |< q:q t| S )z_Convert global metric states to the n-gram dictionaries to be passed in ``_chrf_score_update``.r+   )dictzip_DICT_STATES_NAMESr   r#   r$   r5   r6   _get_dict_namer7   getattrtuplevalues)r8   n_grams_dictsr9   r:   r;   r<   	dict_namer=   r@   r@   rA   rC      s    z"CHRFScore._convert_states_to_dicts)rE   r*   c           	      C   sj   t tt|}|  D ]N\\}}}td|d D ]2}| ||}| |||}t| ||| |  q0qdS )z]Update global metric states based on the n-gram dictionaries calculated on the current batch.r+   N)rJ   rK   rL   r5   r6   rM   r7   setattr)	r8   rE   rQ   r9   r:   r;   r<   rR   r=   r@   r@   rA   rD      s    z#CHRFScore._update_states_from_dicts)r;   r9   r*   c                 C   s   d|  d| dS )z*Return a dictionary name w.r.t input args.total__Z_n_gramsr@   )r;   r9   r@   r@   rA   rM      s    zCHRFScore._get_dict_name)r;   r9   r<   r*   c                 C   s   d|  d| d| dS )z,Return a metric state name w.r.t input args.rT   rU   Z_gramsr@   )r;   r9   r<   r@   r@   rA   r7      s    zCHRFScore._get_state_namec                 C   s   t tt| j| jgtS )zKGet iterator over char/word and reference/hypothesis/matching n-gram level.)	itertoolsproductrK   _N_GRAM_LEVELSr#   r$   _TEXT_LEVELSrH   r@   r@   rA   r5      s    z#CHRFScore._get_text_n_gram_iterator)valaxr*   c                 C   s   |  ||S )a  Plot a single or multiple values from the metric.

        Args:
            val: Either a single result from calling `metric.forward` or `metric.compute` or a list of these results.
                If no value is provided, will automatically call `metric.compute` and plot that result.
            ax: An matplotlib axis object. If provided will add plot to that axis

        Returns:
            Figure and Axes object

        Raises:
            ModuleNotFoundError:
                If `matplotlib` is not installed

        .. plot::
            :scale: 75

            >>> # Example plotting a single value
            >>> from torchmetrics.text import CHRFScore
            >>> metric = CHRFScore()
            >>> preds = ['the cat is on the mat']
            >>> target = [['there is a cat on the mat', 'a cat is on the mat']]
            >>> metric.update(preds, target)
            >>> fig_, ax_ = metric.plot()

        .. plot::
            :scale: 75

            >>> # Example plotting multiple values
            >>> from torchmetrics.text import CHRFScore
            >>> metric = CHRFScore()
            >>> preds = ['the cat is on the mat']
            >>> target = [['there is a cat on the mat', 'a cat is on the mat']]
            >>> values = [ ]
            >>> for _ in range(10):
            ...     values.append(metric(preds, target))
            >>> fig_, ax_ = metric.plot(values)

        )Z_plot)r8   rZ   r[   r@   r@   rA   plot   s    *r   )r    r!   r"   FFF)NN)%__name__
__module____qualname____doc__r   bool__annotations__r   r   r   r3   r   r   r   r   r
   r1   r   r/   r   strrF   r	   r   rI   _DICT_STATES_TYPESrC   rD   staticmethodrM   r7   r   r5   r   r   r\   __classcell__r@   r@   r>   rA   r   4   sJ   
,      $	
" r   )rV   typingr   r   r   r   r   r   r   r	   rG   r
   r   Ztorchmetricsr   Z!torchmetrics.functional.text.chrfr   r   r   Ztorchmetrics.utilities.importsr   Ztorchmetrics.utilities.plotr   r   Z__doctest_skip__rX   rY   rL   r1   rd   r   r@   r@   r@   rA   <module>   s    (	>