class_docstr: Implementation of the HopSkipJump attack from Jianbo et al. (2019). This is a powerful black-box attack that
  only requires final class prediction, and is an advanced version of the boundary attack.
  
  | Paper link: https://arxiv.org/abs/1904.02144
docstr: Main function for the boundary attack.
  
  :param initial_sample: An initial adversarial example.
  :param original_sample: The original input.
  :param target: The target label.
  :param mask: An array with a mask to be applied to the adversarial perturbations. Shape needs to be
               broadcastable to the shape of x. Any features for which the mask is zero will not be adversarially
               perturbed.
  :param clip_min: Minimum value of an example.
  :param clip_max: Maximum value of an example.
  :return: an adversarial example.
docstr_tok: ["Main","function","for","the","boundary","attack",".",":","param","initial_sample",":","An","initial","adversarial","example",".",":","param","original_sample",":","The","original","input",".",":","param","target",":","The","target","label",".",":","param","mask",":","An","array","with","a","mask","to","be","applied","to","the","adversarial","perturbations",".","Shape","needs","to","be","broadcastable","to","the","shape","of","x",".","Any","features","for","which","the","mask","is","zero","will","not","be","adversarially","perturbed",".",":","param","clip_min",":","Minimum","value","of","an","example",".",":","param","clip_max",":","Maximum","value","of","an","example",".",":","return",":","an","adversarial","example","."]
code: def _attack(
      self,
      initial_sample: np.ndarray,
      original_sample: np.ndarray,
      target: int,
      mask: Optional[np.ndarray],
      clip_min: float,
      clip_max: float,
  ) -> np.ndarray:
      """
      Main function for the boundary attack.
  
      :param initial_sample: An initial adversarial example.
      :param original_sample: The original input.
      :param target: The target label.
      :param mask: An array with a mask to be applied to the adversarial perturbations. Shape needs to be
                   broadcastable to the shape of x. Any features for which the mask is zero will not be adversarially
                   perturbed.
      :param clip_min: Minimum value of an example.
      :param clip_max: Maximum value of an example.
      :return: an adversarial example.
      """
      # Set current perturbed image to the initial image
      current_sample = initial_sample
  
      # Main loop to wander around the boundary
      for _ in range(self.max_iter):
          # First compute delta
          delta = self._compute_delta(
              current_sample=current_sample,
              original_sample=original_sample,
              clip_min=clip_min,
              clip_max=clip_max,
          )
  
          # Then run binary search
          current_sample = self._binary_search(
              current_sample=current_sample,
              original_sample=original_sample,
              norm=self.norm,
              target=target,
              clip_min=clip_min,
              clip_max=clip_max,
          )
  
          # Next compute the number of evaluations and compute the update
          num_eval = min(
              int(self.init_eval * np.sqrt(self.curr_iter + 1)),
              self.max_eval,
          )
  
          update = self._compute_update(
              current_sample=current_sample,
              num_eval=num_eval,
              delta=delta,
              target=target,
              mask=mask,
              clip_min=clip_min,
              clip_max=clip_max,
          )
  
          # Finally run step size search by first computing epsilon
          if self.norm == 2:
              dist = np.linalg.norm(original_sample - current_sample)
          else:
              dist = np.max(abs(original_sample - current_sample))
  
          epsilon = 2.0 * dist / np.sqrt(self.curr_iter + 1)
          success = False
  
          while not success:
              epsilon /= 2.0
              potential_sample = current_sample + epsilon * update
              success = self._adversarial_satisfactory(  # type: ignore
                  samples=potential_sample[None],
                  target=target,
                  clip_min=clip_min,
                  clip_max=clip_max,
              )
  
          # Update current sample
          current_sample = np.clip(potential_sample, clip_min, clip_max)
  
          # Update current iteration
          self.curr_iter += 1
  
          # If attack failed. return original sample
          if np.isnan(current_sample).any():  # pragma: no cover
              logger.debug(
                  "NaN detected in sample, returning original sample."
              )
              return original_sample
  
      return current_sample
  
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  from typing import Optional, Tuple, Union, TYPE_CHECKING
  import numpy
  from tqdm.auto import tqdm
  from art.config import ART_NUMPY_DTYPE
  from art.attacks.attack import EvasionAttack
  from art.estimators.estimator import BaseEstimator
  from art.estimators.classification import ClassifierMixin
  from art.utils import compute_success, to_categorical, check_and_transform_label_format, get_labels_np_array
label_desc: Use image node_id 5 for calling the HopSkipJump obj's underlying member method code with example usage: obj._attack(initial_sample, original_sample, target, mask, clip_min, clip_max) and returns: current_sample, original_sample