






'''simple docstring'''



import datasets

from .evaluate import evaluate


SCREAMING_SNAKE_CASE						=	'\\n@inproceedings{Rajpurkar2016SQuAD10,\n  title={SQuAD: 100, 000+ Questions for Machine Comprehension of Text},\n  author={Pranav Rajpurkar and Jian Zhang and Konstantin Lopyrev and Percy Liang},\n  booktitle={EMNLP},\n  year={2016}\n}\n'

SCREAMING_SNAKE_CASE						=	'\nThis metric wrap the official scoring script for version 1 of the Stanford Question Answering Dataset (SQuAD).\n\nStanford Question Answering Dataset (SQuAD) is a reading comprehension dataset, consisting of questions posed by\ncrowdworkers on a set of Wikipedia articles, where the answer to every question is a segment of text, or span,\nfrom the corresponding reading passage, or the question might be unanswerable.\n'

SCREAMING_SNAKE_CASE						=	'\nComputes SQuAD scores (F1 and EM).\nArgs:\n    predictions: List of question-answers dictionaries with the following key-values:\n        - \'id\': id of the question-answer pair as given in the references (see below)\n        - \'prediction_text\': the text of the answer\n    references: List of question-answers dictionaries with the following key-values:\n        - \'id\': id of the question-answer pair (see above),\n        - \'answers\': a Dict in the SQuAD dataset format\n            {\n                \'text\': list of possible texts for the answer, as a list of strings\n                \'answer_start\': list of start positions for the answer, as a list of ints\n            }\n            Note that answer_start values are not taken into account to compute the metric.\nReturns:\n    \'exact_match\': Exact match (the normalized answer exactly match the gold answer)\n    \'f1\': The F-score of predicted tokens versus the gold answer\nExamples:\n\n    >>> predictions = [{\'prediction_text\': \'1976\', \'id\': \'56e10a3be3433e1400422b22\'}]\n    >>> references = [{\'answers\': {\'answer_start\': [97], \'text\': [\'1976\']}, \'id\': \'56e10a3be3433e1400422b22\'}]\n    >>> squad_metric = datasets.load_metric("squad")\n    >>> results = squad_metric.compute(predictions=predictions, references=references)\n    >>> print(results)\n    {\'exact_match\': 100.0, \'f1\': 100.0}\n'
@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION				,       _KWARGS_DESCRIPTION				)
class UpperCAmelCase_					(    datasets.Metric				):




      """simple docstring"""




      def 				A__      ( self			:		str		)  ->  List[str]:


       '''simple docstring'''

       return datasets.MetricInfo(
           description=_DESCRIPTION     ,      citation=_CITATION     ,      inputs_description=_KWARGS_DESCRIPTION     ,      features=datasets.Features(
               {
                   '''predictions''': {'''id''': datasets.Value('''string'''		), '''prediction_text''': datasets.Value('''string'''		)},
                   '''references''': {
                       '''id''': datasets.Value('''string'''		),
                       '''answers''': datasets.features.Sequence(
                           {
                               '''text''': datasets.Value('''string'''		),
                               '''answer_start''': datasets.Value('''int32'''		),
                           }		),
                   },
               }		)     ,      codebase_urls=['''https://rajpurkar.github.io/SQuAD-explorer/''']     ,      reference_urls=['''https://rajpurkar.github.io/SQuAD-explorer/''']     ,      )






      def 				A__      ( self			:		Dict     ,      UpperCAmelCase			:		Optional[Any]     ,      UpperCAmelCase			:		List[str]		)  ->  Tuple:


       '''simple docstring'''

       lowercase					:   str				  ={prediction['''id''']: prediction['''prediction_text'''] for prediction in predictions}
       lowercase					:   int				  =[
           {
               '''paragraphs''': [
                   {
                       '''qas''': [
                           {
                               '''answers''': [{'''text''': answer_text} for answer_text in ref['''answers''']['''text''']],
                               '''id''': ref['''id'''],
                           }
                           for ref in references
                       ]
                   }
               ]
           }
       ]
       lowercase					:   Union[str, Any]				  =evaluate(dataset=UpperCAmelCase     ,      predictions=UpperCAmelCase		)
       return score











'''simple docstring'''



import mpmath  # for roots of unity
import numpy as np
class UpperCAmelCase_					:




      """simple docstring"""




      def __init__( self			:		List[Any]     ,      UpperCAmelCase			:		Dict=None     ,      UpperCAmelCase			:		Optional[int]=None		)  ->  Optional[Any]:


       '''simple docstring'''

       lowercase					:   Any				  =list(poly_a or [0]		)[:]
       lowercase					:   Dict				  =list(poly_b or [0]		)[:]

       # Remove leading zero coefficients
       while self.polyA[-1] == 0:
        self.polyA.pop()
       lowercase					:   int				  =len(self.polyA		)

       while self.polyB[-1] == 0:
        self.polyB.pop()
       lowercase					:   List[str]				  =len(self.polyB		)

       # Add 0 to make lengths equal a power of 2
       lowercase					:   Tuple				  =int(
           2 ** np.ceil(np.loga(len(self.polyA		) + len(self.polyB		) - 1		)		)		)

       while len(self.polyA		) < self.c_max_length:
        self.polyA.append(0		)
       while len(self.polyB		) < self.c_max_length:
        self.polyB.append(0		)
       # A complex root used for the fourier transform
       lowercase					:   Optional[int]				  =complex(mpmath.root(x=1     ,      n=self.c_max_length     ,      k=1		)		)

       # The product
       lowercase					:   str				  =self.__multiply()






      def 				A__      ( self			:		Optional[Any]     ,      UpperCAmelCase			:		Union[str, Any]		)  ->  Tuple:


       '''simple docstring'''

       lowercase					:   Tuple				  =[[x] for x in self.polyA] if which == '''A''' else [[x] for x in self.polyB]
       # Corner case
       if len(UpperCAmelCase		) <= 1:
        return dft[0]
       #
       lowercase					:   List[Any]				  =self.c_max_length // 2
       while next_ncol > 0:
        lowercase					:   str				  =[[] for i in range(UpperCAmelCase		)]
        lowercase					:   List[str]				  =self.root**next_ncol

        # First half of next step
        lowercase					:   Union[str, Any]				  =1
        for j in range(self.c_max_length // (next_ncol * 2)		):
         for i in range(UpperCAmelCase		):
          new_dft[i].append(dft[i][j] + current_root * dft[i + next_ncol][j]		)
         current_root *= root
        # Second half of next step
        lowercase					:   Any				  =1
        for j in range(self.c_max_length // (next_ncol * 2)		):
         for i in range(UpperCAmelCase		):
          new_dft[i].append(dft[i][j] - current_root * dft[i + next_ncol][j]		)
         current_root *= root
        # Update
        lowercase					:   Tuple				  =new_dft
        lowercase					:   List[Any]				  =next_ncol // 2
       return dft[0]






      def 				A__      ( self			:		int		)  ->  str:


       '''simple docstring'''

       lowercase					:   List[Any]				  =self.__dft('''A'''		)
       lowercase					:   Union[str, Any]				  =self.__dft('''B'''		)
       lowercase					:   Any				  =[[dft_a[i] * dft_b[i] for i in range(self.c_max_length		)]]
       del dft_a
       del dft_b

       # Corner Case
       if len(inverce_c[0]		) <= 1:
        return inverce_c[0]
       # Inverse DFT
       lowercase					:   Tuple				  =2
       while next_ncol <= self.c_max_length:
        lowercase					:   Tuple				  =[[] for i in range(UpperCAmelCase		)]
        lowercase					:   Tuple				  =self.root ** (next_ncol // 2)
        lowercase					:   Optional[int]				  =1
        # First half of next step
        for j in range(self.c_max_length // next_ncol		):
         for i in range(next_ncol // 2		):
          # Even positions
          new_inverse_c[i].append(
              (
                  inverce_c[i][j]
                  + inverce_c[i][j + self.c_max_length // next_ncol]
              )
              / 2		)
          # Odd positions
          new_inverse_c[i + next_ncol // 2].append(
              (
                  inverce_c[i][j]
                  - inverce_c[i][j + self.c_max_length // next_ncol]
              )
              / (2 * current_root)		)
         current_root *= root
        # Update
        lowercase					:   List[Any]				  =new_inverse_c
        next_ncol *= 2
       # Unpack
       lowercase					:   List[str]				  =[round(x[0].real     ,      8		) + round(x[0].imag     ,      8		) * 1J for x in inverce_c]

       # Remove leading 0's
       while inverce_c[-1] == 0:
        inverce_c.pop()
       return inverce_c






      def __str__( self			:		Dict		)  ->  Optional[Any]:


       '''simple docstring'''

       lowercase					:   Optional[Any]				  ='''A = ''' + ''' + '''.join(
           f'{coef}*x^{i}' for coef, i in enumerate(self.polyA[: self.len_A]		)		)
       lowercase					:   List[str]				  ='''B = ''' + ''' + '''.join(
           f'{coef}*x^{i}' for coef, i in enumerate(self.polyB[: self.len_B]		)		)
       lowercase					:   Optional[Any]				  ='''A*B = ''' + ''' + '''.join(
           f'{coef}*x^{i}' for coef, i in enumerate(self.product		)		)

       return f'{a}\n{b}\n{c}'


# Unit tests
if __name__ == "__main__":
      import doctest

      doctest.testmod()



