
    i                     `   d dl mZ d dlmZ d dlmZmZmZ d dlZd dlm	Z	m
Z
 dee   dedefd	Zd
edee   fdZdefdee   deee      de	de	de	de	dedeegee   f   dee	e	f   fdZde	de	de	de	dedee   dede	fdZ	 	 	 ddeeee   f   deeeee   f      dededeee      de	fdZy)    )Counter)Sequence)CallableOptionalUnionN)Tensortensorngram_input_listn_gramreturnc                     t               }t        d|dz         D ]?  }t        t        |       |z
  dz         D ]   }t        | |||z          }||xx   dz  cc<   " A |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   ngram_counterij	ngram_keys         v/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/torchmetrics/functional/text/bleu.py_count_ngramr      sm     %YM1fqj!s+,q0145A.qAE;<I)$)$ 6 "
     sentencec                 "    | j                         S )zTokenizes sentence into list of words.

    Args:
        sentence: A sentence separated by white space.

    Return:
        List of words

    )split)r   s    r   _tokenize_fnr   0   s     >>r      predstarget	numeratordenominator	preds_len
target_len	tokenizerc           
         |D 	cg c]  }|D 	cg c]  }	|	r ||	      ng  c}	 }
}}	| D 	cg c]  }	|	r ||	      ng  }}	t        ||
      D ]  \  }}|t        |      z  }|D cg c]  }t        |       }}|D cg c]  }t        t        |      |z
         }}|||j                  t	        |               z  }t        ||      }t               }|D ]  }|t        ||      z  } ||z  }|D ]  }|t        |      dz
  xx   ||   z  cc<     |D ]  }|t        |      dz
  xx   ||   z  cc<      ||fS c c}	w c c}	}w c c}	w c c}w c c}w )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

    r   )zipr   absindexminr   r   )r   r   r    r!   r"   r#   r   r$   tlinetarget_preds_predtargetstgttarget_len_listxtarget_len_diffpreds_countertarget_counterngram_counter_clipcounter_clipcounters                          r   _bleu_score_updater9   =   s   0 lr1rkqfg_`2a_`W[d9T?PR3R_`2akqG1rSX&YSX4$yB'FSXF&YVW-gSY	/67w3s8w77FG!3s4y1}-Goo&;&;C<P&QRR
!-dF!;"))Cl377N  +^;.Lc,'!+,0B<0PP, / %GGq()]7-CC) %! .& j  - 3b1r&Y 8Gs&   	ED<EE'E?E<Eweightssmoothc           
      F   |j                   }t        |      dk(  rt        d|      S |rwt        j                  t        j
                  |t        j                  ||            t        j
                  |t        j                  ||                  }|d   |d   z  |d<   n||z  }t        ||      t        j                  |      z  }	t        j                  t        j                  |	            }
| |kD  rt        d|      nt        j                  d|| z  z
        }||
z  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   )
r>   r)   r	   torchdivaddoneslogexpsum)r"   r#   r    r!   r   r:   r;   r>   precision_scoreslog_precision_scoresgeometric_meanbrevity_penaltys               r   _bleu_score_computerK   n   s    * F
9~c&)) 99IIiF6!BCIIk5::fV#DE
 (l[^;${2!'&9EIIFV<WWYYuyy)=>?N4=
4JfS0PUPYPYZ[_ilu_uZvPwO^++r   c           
      ,   t        | t              r| gn| }|D cg c]  }t        |t              r|gn| }}t        |      t        |      k7  r#t        dt        |       dt        |             |(t        |      |k7  rt        dt        |       d|       |	d|z  g|z  }t	        j
                  |      }t	        j
                  |      }	t        d      }
t        d      }t        ||||	|
||t              \  }
}t        |
|||	|||      S c c}w )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`_

    zCorpus has different size z != z5List of weights has different weights than `n_gram`: r?   r=   )

isinstancestrr   
ValueErrorr@   zerosr	   r9   r   rK   )r   r   r   r;   r:   r-   r0   r,   r    r!   r"   r#   s               r   
bleu_scorerQ      s&   P #5#.eWEFAGH#
3,u#5GH
6{c'l"5c&k]$s7|nUVVs7|v5PQTU\Q]P^^bcibjkll<.6)F#I++f%KsIJ.KJP\Iz y*ifV]_eff' Is   D)r   FN)collectionsr   collections.abcr   typingr   r   r   r@   r   r	   rN   intr   r   r   r9   floatboolrK   rQ    r   r   <module>rY      s  &   $ , ,   8C= # ' *
3 
8C= 
( 0<.!C=.!Xc]#.! .! 	.!
 .! .! .! x},-.! 66>.!b%,%,%, %, 	%,
 %, e_%, %, %,V )-<ghsm#$<gU3-./<g <g 	<g
 huo&<g <gr   