class_docstr: Implements the Sign-OPT attack `SignOPTAttack`. This is a query-efficient
  hard-label adversarial attack.
  
  Paper link: https://arxiv.org/pdf/1909.10773.pdf
docstr: Perform fine-grained line search plus binary search for finding a good starting direction
  
  :param x_0: An array with the original input to be attacked.
  :param y_0: Target value.
  :param theta: Initial query direction.
  :param initial_lbd: Previous solution.
  :param current_best: Current best solution.
  :param target: Target value. If `self.targeted` is true, it presents the targeted label. Defaults to None.
  :return: Optimal solution for finding starting direction; the number of query performed
docstr_tok: ["Perform","fine-grained","line","search","plus","binary","search","for","finding","a","good","starting","direction",":","param","x_0",":","An","array","with","the","original","input","to","be","attacked",".",":","param","y_0",":","Target","value",".",":","param","theta",":","Initial","query","direction",".",":","param","initial_lbd",":","Previous","solution",".",":","param","current_best",":","Current","best","solution",".",":","param","target",":","Target","value",".","If","`","self.targeted","`","is","true",",","it","presents","the","targeted","label",".","Defaults","to","None",".",":","return",":","Optimal","solution","for","finding","starting","direction",";","the","number","of","query","performed"]
code: def _fine_grained_binary_search(
      self,
      x_0: np.ndarray,
      y_0: int,
      theta: np.ndarray,
      initial_lbd: float,
      current_best: float,
      target: Optional[int] = None,
  ) -> Tuple[float, int]:
      """
      Perform fine-grained line search plus binary search for finding a good starting direction
  
      :param x_0: An array with the original input to be attacked.
      :param y_0: Target value.
      :param theta: Initial query direction.
      :param initial_lbd: Previous solution.
      :param current_best: Current best solution.
      :param target: Target value. If `self.targeted` is true, it presents the targeted label. Defaults to None.
      :return: Optimal solution for finding starting direction; the number of query performed
      """
      if self.targeted:
          tolerate = 1e-5
      else:
          tolerate = 1e-3
      nquery = 0
      if initial_lbd > current_best:
          if (
              self.targeted
              and not self._is_label(x_0 + current_best * theta, target)
          ) or (
              not self.targeted
              and self._is_label(x_0 + current_best * theta, y_0)
          ):
              nquery += 1
              return float("inf"), nquery
          lbd = current_best
      else:
          lbd = initial_lbd
  
      lbd_hi = lbd
      lbd_lo = 0.0
  
      while (lbd_hi - lbd_lo) > tolerate:
          lbd_mid = (lbd_lo + lbd_hi) / 2.0
          nquery += 1
          if not self._is_label(x_0 + lbd_mid * theta, y_0):
              if self.targeted:
                  lbd_lo = lbd_mid
              else:
                  lbd_hi = lbd_mid
          else:
              if self.targeted:
                  lbd_hi = lbd_mid
              else:
                  lbd_lo = lbd_mid
      return lbd_hi, nquery
  
imports: import logging
  from typing import Optional, TYPE_CHECKING, Tuple
  import time
  import numpy
  from tqdm.auto import tqdm
  from art.attacks.attack import EvasionAttack
  from art.config import ART_NUMPY_DTYPE
  from art.estimators.estimator import BaseEstimator
  from art.estimators.classification.classifier import ClassifierMixin
  from art.utils import compute_success, check_and_transform_label_format, get_labels_np_array
label_desc: Use image node_id 3 for calling the SignOPTAttack obj's underlying member method code with example usage: obj._fine_grained_binary_search(x_0, y_0, theta, initial_lbd, current_best, target) and returns: lbd_hi,  nquery, float,  nquery