





'''simple docstring'''


import datasets

from .evaluate import (
    apply_no_ans_threshold,
    find_all_best_thresh,
    get_raw_scores,
    make_eval_dict,
    make_qid_to_has_ans,
    merge_eval,
)


A_				     =							"\\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"

A_				     =							"\nThis metric wrap the official scoring script for version 2 of the Stanford Question\nAnswering 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\nSQuAD2.0 combines the 100,000 questions in SQuAD1.1 with over 50,000 unanswerable questions\nwritten adversarially by crowdworkers to look similar to answerable ones.\nTo do well on SQuAD2.0, systems must not only answer questions when possible, but also\ndetermine when no answer is supported by the paragraph and abstain from answering.\n"

A_				     =							"\nComputes SQuAD v2 scores (F1 and EM).\nArgs:\n    predictions: List of triple for question-answers to score with the following elements:\n        - the question-answer 'id' field as given in the references (see below)\n        - the text of the answer\n        - the probability that the question has no 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 list of Dict {'text': text of the answer as a string}\n    no_answer_threshold: float\n        Probability threshold to decide that a question has no answer.\nReturns:\n    'exact': Exact match (the normalized answer exactly match the gold answer)\n    'f1': The F-score of predicted tokens versus the gold answer\n    'total': Number of score considered\n    'HasAns_exact': Exact match (the normalized answer exactly match the gold answer)\n    'HasAns_f1': The F-score of predicted tokens versus the gold answer\n    'HasAns_total': Number of score considered\n    'NoAns_exact': Exact match (the normalized answer exactly match the gold answer)\n    'NoAns_f1': The F-score of predicted tokens versus the gold answer\n    'NoAns_total': Number of score considered\n    'best_exact': Best exact match (with varying threshold)\n    'best_exact_thresh': No-answer probability threshold associated to the best exact match\n    'best_f1': Best F1 (with varying threshold)\n    'best_f1_thresh': No-answer probability threshold associated to the best F1\nExamples:\n\n    >>> predictions = [{'prediction_text': '1976', 'id': '56e10a3be3433e1400422b22', 'no_answer_probability': 0.}]\n    >>> references = [{'answers': {'answer_start': [97], 'text': ['1976']}, 'id': '56e10a3be3433e1400422b22'}]\n    >>> squad_v2_metric = datasets.load_metric(\"squad_v2\")\n    >>> results = squad_v2_metric.compute(predictions=predictions, references=references)\n    >>> print(results)\n    {'exact': 100.0, 'f1': 100.0, 'total': 1, 'HasAns_exact': 100.0, 'HasAns_f1': 100.0, 'HasAns_total': 1, 'best_exact': 100.0, 'best_exact_thresh': 0.0, 'best_f1': 100.0, 'best_f1_thresh': 0.0}\n"


@datasets.utils.file_utils.add_start_docstrings(_DESCRIPTION	,	_KWARGS_DESCRIPTION							)
class 		UpperCamelCase__     (       datasets.Metric							):
      '''simple docstring'''






      def 	snake_case  (     self )				->  List[Any]:
        return datasets.MetricInfo(
            description=_DESCRIPTION     , citation=_CITATION     , inputs_description=_KWARGS_DESCRIPTION     , features=datasets.Features(
                {
                    'predictions': {
                        'id': datasets.Value('string' ),
                        'prediction_text': datasets.Value('string' ),
                        'no_answer_probability': datasets.Value('float32' ),
                    },
                    '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 	snake_case  (     self     , SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE=1.0 )				->  Tuple:
        __lowerCAmelCase		:    Optional[int]			     =  {p['id']: p['no_answer_probability'] for p in predictions}
        __lowerCAmelCase		:    Optional[Any]			     =  [{'paragraphs': [{'qas': references}]}]
        __lowerCAmelCase		:    str			     =  {p['id']: p['prediction_text'] for p in predictions}

        __lowerCAmelCase		:    Union[str, Any]			     =  make_qid_to_has_ans(SCREAMING_SNAKE_CASE )  # maps qid to True/False
        __lowerCAmelCase		:    List[str]			     =  [k for k, v in qid_to_has_ans.items() if v]
        __lowerCAmelCase		:    Tuple			     =  [k for k, v in qid_to_has_ans.items() if not v]

        __lowerCAmelCase     ,					__lowerCAmelCase		:    List[str]			     =  get_raw_scores(SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE )
        __lowerCAmelCase		:    Dict			     =  apply_no_ans_threshold(SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE )
        __lowerCAmelCase		:    Optional[int]			     =  apply_no_ans_threshold(SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE )
        __lowerCAmelCase		:    Dict			     =  make_eval_dict(SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE )

        if has_ans_qids:
          __lowerCAmelCase		:    str			     =  make_eval_dict(SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE     , qid_list=SCREAMING_SNAKE_CASE )
          merge_eval(SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE     , 'HasAns' )
        if no_ans_qids:
          __lowerCAmelCase		:    Tuple			     =  make_eval_dict(SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE     , qid_list=SCREAMING_SNAKE_CASE )
          merge_eval(SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE     , 'NoAns' )
        find_all_best_thresh(SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE )
        return dict(SCREAMING_SNAKE_CASE )












'''simple docstring'''


from typing import Any

import numpy as np


class 		UpperCamelCase__     :
      '''simple docstring'''






      def __init__(     self     , SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE )				->  None:
        # Check if RHS is negative
        if np.any(tableau[:, -1]     , where=tableau[:, -1] < 0 ):
          raise ValueError('RHS must be > 0' )

        __lowerCAmelCase		:    Any			     =  tableau
        __lowerCAmelCase     ,					__lowerCAmelCase		:    Optional[int]			     =  tableau.shape

        # Number of decision variables x1, x2, x3...
        __lowerCAmelCase		:    Any			     =  n_vars

        # Number of artificial variables to be minimised
        __lowerCAmelCase		:    str			     =  len(np.where(tableau[self.n_vars : -1] == -1 )[0] )

        # 2 if there are >= or == constraints (nonstandard), 1 otherwise (std)
        __lowerCAmelCase		:    Union[str, Any]			     =  (self.n_art_vars > 0) + 1

        # Number of slack variables added to make inequalities into equalities
        __lowerCAmelCase		:    Any			     =  self.n_rows - self.n_stages

        # Objectives for each stage
        __lowerCAmelCase		:    List[Any]			     =  ['max']

        # In two stage simplex, first minimise then maximise
        if self.n_art_vars:
          self.objectives.append('min' )

        __lowerCAmelCase		:    Optional[Any]			     =  ['']

        # Index of current pivot row and column
        __lowerCAmelCase		:    List[Any]			     =  None
        __lowerCAmelCase		:    Dict			     =  None

        # Does objective row only contain (non)-negative values?
        __lowerCAmelCase		:    Any			     =  False




      @staticmethod
      def 	snake_case  (     *SCREAMING_SNAKE_CASE )				->  list[str]:
        if len(SCREAMING_SNAKE_CASE ) != 3:
          raise ValueError('Must provide n_vars, n_slack, and n_art_vars' )

        if not all(x >= 0 and isinstance(SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE ) for x in args ):
          raise ValueError('All arguments must be non-negative integers' )

        # decision | slack | artificial
        __lowerCAmelCase		:    int			     =  ['x', 's', 'a']
        __lowerCAmelCase		:    Tuple			     =  []
        for i in range(3 ):
          for j in range(args[i] ):
            titles.append(string_starts[i] + str(j + 1 ) )
        titles.append('RHS' )
        return titles




      def 	snake_case  (     self     , SCREAMING_SNAKE_CASE )				->  tuple[Any, Any]:
        __lowerCAmelCase		:    List[Any]			     =  self.objectives[-1]

        # Find entries of highest magnitude in objective rows
        __lowerCAmelCase		:    List[Any]			     =  (objective == 'min') - (objective == 'max')
        __lowerCAmelCase		:    Dict			     =  np.argmax(sign * tableau[0, : self.n_vars] )

        # Choice is only valid if below 0 for maximise, and above for minimise
        if sign * self.tableau[0, col_idx] <= 0:
          __lowerCAmelCase		:    Dict			     =  True
          return 0, 0

        # Pivot row is chosen as having the lowest quotient when elements of
        # the pivot column divide the right-hand side

        # Slice excluding the objective rows
        __lowerCAmelCase		:    str			     =  slice(self.n_stages     , self.n_rows )

        # RHS
        __lowerCAmelCase		:    Union[str, Any]			     =  tableau[s, -1]

        # Elements of pivot column within slice
        __lowerCAmelCase		:    Optional[Any]			     =  tableau[s, col_idx]

        # Array filled with nans
        __lowerCAmelCase		:    Optional[Any]			     =  np.full(self.n_rows - self.n_stages     , np.nan )

        # If element in pivot column is greater than zeron_stages, return
        # quotient or nan otherwise
        __lowerCAmelCase		:    Tuple			     =  np.divide(SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE     , out=SCREAMING_SNAKE_CASE     , where=divisor > 0 )

        # Arg of minimum quotient excluding the nan values. n_stages is added
        # to compensate for earlier exclusion of objective columns
        __lowerCAmelCase		:    Any			     =  np.nanargmin(SCREAMING_SNAKE_CASE ) + self.n_stages
        return row_idx, col_idx




      def 	snake_case  (     self     , SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE )				->  np.ndarray:
        __lowerCAmelCase		:    Tuple			     =  tableau[row_idx].copy()

        __lowerCAmelCase		:    Optional[int]			     =  piv_row[col_idx]

        # Entry becomes 1
        piv_row *= 1 / piv_val

        # Variable in pivot column becomes basic, ie the only non-zero entry
        for idx, coeff in enumerate(tableau[:, col_idx] ):
          tableau[idx] += -coeff * piv_row
        __lowerCAmelCase		:    str			     =  piv_row
        return tableau




      def 	snake_case  (     self     , SCREAMING_SNAKE_CASE )				->  np.ndarray:
        self.objectives.pop()

        if not self.objectives:
          return tableau

        # Slice containing ids for artificial columns
        __lowerCAmelCase		:    Optional[Any]			     =  slice(-self.n_art_vars - 1     , -1 )

        # Delete the artificial variable columns
        __lowerCAmelCase		:    str			     =  np.delete(SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE     , axis=1 )

        # Delete the objective row of the first stage
        __lowerCAmelCase		:    Optional[int]			     =  np.delete(SCREAMING_SNAKE_CASE     , 0     , axis=0 )

        __lowerCAmelCase		:    Tuple			     =  1
        self.n_rows -= 1
        __lowerCAmelCase		:    str			     =  0
        __lowerCAmelCase		:    Any			     =  False
        return tableau




      def 	snake_case  (     self )				->  dict[Any, Any]:
        # Stop simplex algorithm from cycling.
        for _ in range(1_00 ):
          # Completion of each stage removes an objective. If both stages
          # are complete, then no objectives are left
          if not self.objectives:
            __lowerCAmelCase		:    Any			     =  self.generate_col_titles(
                self.n_vars     , self.n_slack     , self.n_art_vars )

            # Find the values of each variable at optimal solution
            return self.interpret_tableau(self.tableau     , self.col_titles )

          __lowerCAmelCase     ,					__lowerCAmelCase		:    Tuple			     =  self.find_pivot(self.tableau )

          # If there are no more negative values in objective row
          if self.stop_iter:
            # Delete artificial variable columns and rows. Update attributes
            __lowerCAmelCase		:    Dict			     =  self.change_stage(self.tableau )
          else:
            __lowerCAmelCase		:    Optional[Any]			     =  self.pivot(self.tableau     , SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE )
        return {}







      def 	snake_case  (     self     , SCREAMING_SNAKE_CASE     , SCREAMING_SNAKE_CASE )				->  dict[str, float]:
        __lowerCAmelCase		:    List[Any]			     =  {'P': abs(tableau[0, -1] )}

        for i in range(self.n_vars ):
          # Gives ids of nonzero entries in the ith column
          __lowerCAmelCase		:    str			     =  np.nonzero(tableau[:, i] )
          __lowerCAmelCase		:    Union[str, Any]			     =  len(nonzero[0] )

          # First entry in the nonzero ids
          __lowerCAmelCase		:    Optional[Any]			     =  nonzero[0][0]
          __lowerCAmelCase		:    str			     =  tableau[nonzero_rowidx, i]

          # If there is only one nonzero value in column, which is one
          if n_nonzero == nonzero_val == 1:
            __lowerCAmelCase		:    Dict			     =  tableau[nonzero_rowidx, -1]
            __lowerCAmelCase		:    List[Any]			     =  rhs_val

        # Check for basic variables
        for title in col_titles:
          # Don't add RHS or slack variables to output dict
          if title[0] not in "R-s-a":
            output_dict.setdefault(SCREAMING_SNAKE_CASE     , 0 )
        return output_dict


if __name__ == "__main__":
    import doctest

    doctest.testmod()





