class_docstr: Implementation of the Geometric Decision-based Attack (GeoDA), a black-box attack requiring class predictions.
  Based on reference implementation: https://github.com/thisisalirah/GeoDA
  
  | Paper link: https://arxiv.org/abs/2003.06468
class_docstr_tok: ["Implementation","of","the","Geometric","Decision-based","Attack","(","GeoDA",")",",","a","black-box","attack","requiring","class","predictions",".","Based","on","reference","implementation",":","https",":","\/\/github.com\/thisisalirah\/GeoDA","|","Paper","link",":","https",":","\/\/arxiv.org\/abs\/2003.06468"]
docstr: Generate adversarial samples.
  
  :param x: An array with the original inputs to be attacked.
  :param y: Target values (class labels) one-hot-encoded of shape (nb_samples, nb_classes) or indices of shape
            (nb_samples,). If `self.targeted` is true, then `y` represents the target labels.
  :return: The adversarial examples.
docstr_tok: ["Generate","adversarial","samples",".",":","param","x",":","An","array","with","the","original","inputs","to","be","attacked",".",":","param","y",":","Target","values","(","class","labels",")","one-hot-encoded","of","shape","(","nb_samples",",","nb_classes",")","or","indices","of","shape","(","nb_samples",",",")",".","If","`","self.targeted","`","is","true",",","then","`","y","`","represents","the","target","labels",".",":","return",":","The","adversarial","examples","."]
code: def generate(
      self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs
  ) -> np.ndarray:
      """
      Generate adversarial samples.
  
      :param x: An array with the original inputs to be attacked.
      :param y: Target values (class labels) one-hot-encoded of shape (nb_samples, nb_classes) or indices of shape
                (nb_samples,). If `self.targeted` is true, then `y` represents the target labels.
      :return: The adversarial examples.
      """
      if y is not None:
          y = check_and_transform_label_format(
              y,
              nb_classes=self.estimator.nb_classes,
              return_one_hot=True,
          )
  
      if (
          y is not None
          and self.estimator.nb_classes == 2
          and y.shape[1] == 1
      ):  # pragma: no cover
          raise ValueError(
              "This attack has not yet been tested for binary classification with a single output classifier."
          )
  
      x_adv = x.copy()
  
      if y is None:
          # Throw error if attack is targeted, but no targets are provided
          if self.targeted:  # pragma: no cover
              raise ValueError(
                  "Target labels `y` need to be provided for a targeted attack."
              )
  
          # Use model predictions as correct outputs
          y = get_labels_np_array(self.estimator.predict(x, batch_size=self.batch_size))  # type: ignore
  
      # Get clip_min and clip_max from the classifier or infer them from data
      if self.estimator.clip_values is not None:
          self.clip_min, self.clip_max = self.estimator.clip_values
      else:
          self.clip_min, self.clip_max = np.min(x), np.max(x)
  
      # Check for square input images
      if (
          self.estimator.channels_first and x.shape[2] != x.shape[3]
      ) or (  # pragma: no cover
          not self.estimator.channels_first and x.shape[1] != x.shape[2]
      ):
          raise ValueError("Input images `x` have to be square.")
  
      # Create or load DCT basis
      image_size = x.shape[2]
      logger.info("Create or load DCT basis.")
      path = f"2d_dct_basis_{self.sub_dim}_{image_size}.npy"
      if os.path.exists(path):
          self.sub_basis = np.load(path).astype(ART_NUMPY_DTYPE)
      else:
          self.sub_basis = self._generate_2d_dct_basis(
              sub_dim=self.sub_dim, res=image_size
          ).astype(ART_NUMPY_DTYPE)
          np.save(path, self.sub_basis)
  
      for i in trange(
          x.shape[0],
          desc="GeoDA - samples",
          disable=not self.verbose,
          position=0,
      ):
          x_i = x[[i]]
          y_i = y[[i]]
  
          # Reset number of calls
          self.nb_calls = 0
  
          # Random search
          x_random = self._find_random_adversarial(x=x_i, y=y_i)
          logger.info(
              "Random search adversarial example is adversarial: %r",
              self._is_adversarial(x_random, y_i),
          )
  
          # Binary search
          x_boundary = self._binary_search(
              x_i, y_i, x_random, tol=self.bin_search_tol
          )
          logger.info(
              "Binary search example at boundary is adversarial: %r",
              self._is_adversarial(x_boundary, y_i),
          )
  
          grad = np.zeros_like(x_i)
          x_adv_i = x_i
  
          for k in trange(
              self.iterate,
              desc="GeoDA - steps",
              disable=not self.verbose,
              position=1,
          ):
              grad_oi, _ = self._black_grad_batch(
                  x_boundary, self.q_opt_iter[k], self.batch_size, y_i
              )
              grad = grad_oi + grad
              x_adv_i = self._go_to_boundary(x_i, y_i, grad)
              x_adv_i = self._binary_search(
                  x_i, y_i, x_adv_i, tol=self.bin_search_tol
              )
              x_boundary = x_adv_i
  
          x_adv_i = np.clip(
              x_adv_i, a_min=self.clip_min, a_max=self.clip_max
          )
  
          x_adv[i] = x_adv_i
  
      return x_adv
  
imports: import os
  import math
  import logging
  from typing import List, Optional, Tuple, Union, TYPE_CHECKING
  import numpy
  from tqdm.auto import trange
  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 check_and_transform_label_format, get_labels_np_array
label_desc: Use image node_id 3 for calling the GeoDA obj's underlying member method code with example usage: obj.generate(x, y) and returns: x_adv