docstr: Determines a set of two anchors by updating the upper bound for low empirical precision anchors and
  the lower bound for anchors with high empirical precision.
  
  Parameters
  ----------
  means
      Empirical mean result precisions.
  ub
      Upper bound on result precisions.
  lb
      Lower bound on result precisions.
  n_samples
      The number of samples drawn for each candidate result.
  delta
      Confidence budget, candidate anchors have close to optimal precisions with prob. `1 - delta`.
  top_n
      Number of arms to be selected.
  t
      Iteration number.
  
  Returns
  -------
  Upper and lower precision bound indices.
docstr_tok: ["Determines","a","set","of","two","anchors","by","updating","the","upper","bound","for","low","empirical","precision","anchors","and","the","lower","bound","for","anchors","with","high","empirical","precision",".","Parameters","--","--","--","--","--","means","Empirical","mean","result","precisions",".","ub","Upper","bound","on","result","precisions",".","lb","Lower","bound","on","result","precisions",".","n_samples","The","number","of","samples","drawn","for","each","candidate","result",".","delta","Confidence","budget",",","candidate","anchors","have","close","to","optimal","precisions","with","prob",".","`","1","-","delta","`",".","top_n","Number","of","arms","to","be","selected",".","t","Iteration","number",".","Returns","--","--","--","-","Upper","and","lower","precision","bound","indices","."]
code: def select_critical_arms(
      self,
      means: np.ndarray,
      ub: np.ndarray,
      lb: np.ndarray,
      n_samples: np.ndarray,
      delta: float,
      top_n: int,
      t: int,
  ):
      """
      Determines a set of two anchors by updating the upper bound for low empirical precision anchors and
      the lower bound for anchors with high empirical precision.
  
      Parameters
      ----------
      means
          Empirical mean result precisions.
      ub
          Upper bound on result precisions.
      lb
          Lower bound on result precisions.
      n_samples
          The number of samples drawn for each candidate result.
      delta
          Confidence budget, candidate anchors have close to optimal precisions with prob. `1 - delta`.
      top_n
          Number of arms to be selected.
      t
          Iteration number.
  
      Returns
      -------
      Upper and lower precision bound indices.
      """
  
      crit_arms = namedtuple("crit_arms", ["ut", "lt"])
  
      sorted_means = np.argsort(
          means
      )  # ascending sort of result candidates by precision
      beta = self.compute_beta(len(means), t, delta)
  
      # J = the beam width top result candidates with highest precision
      # not_J = the rest
      J = sorted_means[-top_n:]
      not_J = sorted_means[:-top_n]
  
      # update upper bound for lowest precision result candidates
      ub[not_J] = self.dup_bernoulli(
          means[not_J], beta / n_samples[not_J]
      )
      # update lower bound for highest precision result candidates
      lb[J] = self.dlow_bernoulli(means[J], beta / n_samples[J])
  
      # for the low precision result candidates, compute the upper precision bound and keep the index ...
      # ... of the result candidate with the highest upper precision value -> ut
      # for the high precision result candidates, compute the lower precision bound and keep the index ...
      # ... of the result candidate with the lowest lower precision value -> lt
      ut = not_J[np.argmax(ub[not_J])]
      lt = J[np.argmin(lb[J])]
  
      return crit_arms._make((ut, lt))
  
imports: import copy
  import logging
  from collections import defaultdict, namedtuple
  from typing import Callable, Dict, List, Optional, Set, Tuple
  import numpy
  from alibi.utils.distributions import kl_bernoulli
label_desc: Use image node_id 8 for calling the AnchorBaseBeam obj's underlying member method code with example usage: obj.select_critical_arms(means, ub, lb, n_samples, delta, top_n, t) and returns: crit_arms