a
    þdš  ã                   @   s  d dl 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
 ee eedœdd„Zeee dœd	d
„Zdefee eee  e	e	e	e	eeegee f ee	e	f dœ	dd„Ze	e	e	e	eee ee	dœdd„Zdeeee f eeeee f  eeeee  e	dœdd„ZdS )é    )ÚCounter)ÚCallableÚOptionalÚSequenceÚTupleÚUnionN)ÚTensorÚtensor)Úngram_input_listÚn_gramÚreturnc                 C   s\   t ƒ }td|d ƒD ]B}tt| ƒ| d ƒD ](}t| ||| … ƒ}||  d7  < q,q|S )a  Count how many times each word appears in a given text with ngram.

    Args:
        ngram_input_list: A list of translated text or reference texts
        n_gram: gram value ranged 1 to 4

    Return:
        ngram_counter: a collections.Counter object of ngram

    é   )r   ÚrangeÚlenÚtuple)r
   r   Zngram_counterÚiÚjZ	ngram_key© r   új/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/torchmetrics/functional/text/bleu.pyÚ_count_ngram   s    r   )Úsentencer   c                 C   s   |   ¡ S )z‘Tokenizes sentence into list of words.

    Args:
        sentence: A sentence separated by white space.

    Return:
        List of words

    )Úsplit)r   r   r   r   Ú_tokenize_fn/   s    
r   é   )	ÚpredsÚtargetÚ	numeratorÚdenominatorÚ	preds_lenÚ
target_lenr   Ú	tokenizerr   c                    sþ   ‡fdd„|D ƒ}‡fdd„| D ƒ}	t |	|ƒD ]Æ\‰ }
|tˆ ƒ7 }dd„ |
D ƒ}‡ fdd„|D ƒ}||| t|ƒ¡ 7 }tˆ |ƒ}tƒ }|
D ]}|t||ƒO }qŒ||@ }|D ] }|t|ƒd   || 7  < q¬|D ] }|t|ƒd   || 7  < qÒq.||fS )a€  Update and returns variables required to compute the BLEU score.

    Args:
        preds: An iterable of machine translated corpus
        target: An iterable of iterables of reference corpus
        numerator: Numerator of precision score (true positives)
        denominator: Denominator of precision score (true positives + false positives)
        preds_len: count of words in a candidate prediction
        target_len: count of words in a reference translation
        target: count of words in a reference translation
        n_gram: gram value ranged 1 to 4
        tokenizer: A function that turns sentence into list of words

    c                    s   g | ]}‡ fd d„|D ƒ‘qS )c                    s   g | ]}|rˆ |ƒng ‘qS r   r   ©Ú.0Úline©r    r   r   Ú
<listcomp>T   ó    z1_bleu_score_update.<locals>.<listcomp>.<listcomp>r   )r"   Útr$   r   r   r%   T   r&   z&_bleu_score_update.<locals>.<listcomp>c                    s   g | ]}|rˆ |ƒng ‘qS r   r   r!   r$   r   r   r%   U   r&   c                 S   s   g | ]}t |ƒ‘qS r   )r   ©r"   Útgtr   r   r   r%   Y   r&   c                    s   g | ]}t tˆ ƒ| ƒ‘qS r   )Úabsr   )r"   Úx)Úpredr   r   r%   Z   r&   r   )Úzipr   ÚindexÚminr   r   )r   r   r   r   r   r   r   r    Útarget_Úpreds_ÚtargetsZtarget_len_listZtarget_len_diffZpreds_counterZtarget_counterr)   Zngram_counter_clipZcounter_clipÚcounterr   )r,   r    r   Ú_bleu_score_update<   s"    
 r4   )r   r   r   r   r   ÚweightsÚsmoothr   c              
   C   sÄ   |j }t|ƒdkrtd|dS |rht t |tj||d¡t |tj||d¡¡}|d |d  |d< n|| }t||dt |¡ }	t t 	|	¡¡}
| |krªtd|dnt d||   ¡}||
 S )aâ  Compute the BLEU score.

    Args:
        preds_len: count of words in a candidate translation
        target_len: count of words in a reference translation
        numerator: Numerator of precision score (true positives)
        denominator: Denominator of precision score (true positives + false positives)
        n_gram: gram value ranged 1 to 4
        weights: Weights used for unigrams, bigrams, etc. to calculate BLEU score.
        smooth: Whether to apply smoothing

    ç        )Údevicer   ç      ð?r   )
r8   r/   r	   ÚtorchÚdivÚaddZonesÚlogÚexpÚsum)r   r   r   r   r   r5   r6   r8   Zprecision_scoresZlog_precision_scoresZgeometric_meanZbrevity_penaltyr   r   r   Ú_bleu_score_computem   s    þ&r@   F)r   r   r   r6   r5   r   c              	   C   sâ   t | tƒr| gn| }dd„ |D ƒ}t|ƒt|ƒkrNtdt|ƒ› dt|ƒ› ƒ‚|durzt|ƒ|krztdt|ƒ› d|› ƒ‚|du rd| g| }t |¡}t |¡}tdƒ}	tdƒ}
t|||||	|
|tƒ\}	}
t	|	|
|||||ƒS )	a3  Calculate `BLEU score`_ of machine translated text with one or more references.

    Args:
        preds: An iterable of machine translated corpus
        target: An iterable of iterables of reference corpus
        n_gram: Gram value ranged from 1 to 4
        smooth: Whether to apply smoothing - see [2]
        weights:
            Weights used for unigrams, bigrams, etc. to calculate BLEU score.
            If not provided, uniform weights are used.

    Return:
        Tensor with BLEU Score

    Raises:
        ValueError: If ``preds`` and ``target`` corpus have different lengths.
        ValueError: If a length of a list of weights is not ``None`` and not equal to ``n_gram``.

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

    References:
        [1] BLEU: a Method for Automatic Evaluation of Machine Translation by Papineni,
        Kishore, Salim Roukos, Todd Ward, and Wei-Jing Zhu `BLEU`_

        [2] Automatic Evaluation of Machine Translation Quality Using Longest Common Subsequence
        and Skip-Bigram Statistics by Chin-Yew Lin and Franz Josef Och `Machine Translation Evolution`_

    c                 S   s    g | ]}t |tƒr|gn|‘qS r   )Ú
isinstanceÚstrr(   r   r   r   r%   ¾   r&   zbleu_score.<locals>.<listcomp>zCorpus has different size z != Nz5List of weights has different weights than `n_gram`: r9   r7   )
rA   rB   r   Ú
ValueErrorr:   Úzerosr	   r4   r   r@   )r   r   r   r6   r5   r1   r0   r   r   r   r   r   r   r   Ú
bleu_score•   s     (

ÿrE   )r   FN)Úcollectionsr   Útypingr   r   r   r   r   r:   r   r	   rB   Úintr   r   r4   ÚfloatÚboolr@   rE   r   r   r   r   Ú<module>   sL   ø

÷2ø+   û
ú