class_docstr: This class implements the black-box attack `SimBA`.
  
  | Paper link: https://arxiv.org/abs/1905.07121
class_docstr_tok: ["This","class","implements","the","black-box","attack","`","SimBA","`",".","|","Paper","link",":","https",":","\/\/arxiv.org\/abs\/1905.07121"]
docstr: Generate adversarial samples and return them in an array.
  
  :param x: An array with the original inputs to be attacked.
  :param y: An array with the true or target labels.
  :return: An array holding the adversarial examples.
docstr_tok: ["Generate","adversarial","samples","and","return","them","in","an","array",".",":","param","x",":","An","array","with","the","original","inputs","to","be","attacked",".",":","param","y",":","An","array","with","the","true","or","target","labels",".",":","return",":","An","array","holding","the","adversarial","examples","."]
code: def generate(
      self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs
  ) -> np.ndarray:
      """
      Generate adversarial samples and return them in an array.
  
      :param x: An array with the original inputs to be attacked.
      :param y: An array with the true or target labels.
      :return: An array holding the adversarial examples.
      """
      x = x.astype(ART_NUMPY_DTYPE)
      x_adv = x.copy()
  
      y_prob_pred = self.estimator.predict(
          x, batch_size=self.batch_size
      )
  
      if not is_probability(y_prob_pred[0]):
          raise ValueError(
              "This attack requires an estimator predicting probabilities. It looks like the current "
              "estimator is not predicting probabilities"
          )
  
      if self.estimator.nb_classes == 2 and y_prob_pred.shape[1] == 1:
          raise ValueError(
              "This attack has not yet been tested for binary classification with a single output classifier."
          )
  
      if divmod(x.shape[2] - self.freq_dim, self.stride)[1] != 0:
          raise ValueError(
              "Incompatible value combination in image height/width, freq_dim and stride detected. "
              "Adapt these parameters to fulfill the following conditions: "
              "divmod(image_height - freq_dim, stride)[1] == 0 "
              "and "
              "divmod(image_width - freq_dim, stride)[1] == 0"
          )
  
      if y is None:
          if self.targeted:
              raise ValueError(
                  "Target labels `y` need to be provided for a targeted attack."
              )
  
          # Use model predictions as correct outputs
          logger.info(
              "Using the model prediction as the correct label for SimBA."
          )
          y_i = np.argmax(y_prob_pred, axis=1)
      else:
          y_i = np.argmax(y, axis=1)
  
      for i_sample in trange(
          x.shape[0], desc="SimBA - sample", disable=not self.verbose
      ):
          desired_label = y_i[i_sample]
  
          current_label = np.argmax(y_prob_pred, axis=1)[i_sample]
          last_prob = y_prob_pred[i_sample].reshape(-1)[desired_label]
  
          if self.estimator.channels_first:
              nb_channels = x.shape[1]
          else:
              nb_channels = x.shape[3]
  
          n_dims = np.prod(x[[0]].shape)
  
          if self.attack == "px":
              if self.order == "diag":
                  indices = self.diagonal_order(
                      x.shape[2], nb_channels
                  )[: self.max_iter]
              elif self.order == "random":
                  indices = np.random.permutation(n_dims)[
                      : self.max_iter
                  ]
              indices_size = len(indices)
              while indices_size < self.max_iter:
                  if self.order == "diag":
                      tmp_indices = self.diagonal_order(
                          x.shape[2], nb_channels
                      )
                  elif self.order == "random":
                      tmp_indices = np.random.permutation(n_dims)
                  indices = np.hstack((indices, tmp_indices))[
                      : self.max_iter
                  ]
                  indices_size = len(indices)
          elif self.attack == "dct":
              indices = self._block_order(
                  x.shape[2],
                  nb_channels,
                  initial_size=self.freq_dim,
                  stride=self.stride,
              )[: self.max_iter]
              indices_size = len(indices)
              while indices_size < self.max_iter:
                  tmp_indices = self._block_order(
                      x.shape[2],
                      nb_channels,
                      initial_size=self.freq_dim,
                      stride=self.stride,
                  )
                  indices = np.hstack((indices, tmp_indices))[
                      : self.max_iter
                  ]
                  indices_size = len(indices)
  
              def trans(var_z):
                  return self._block_idct(var_z, block_size=x.shape[2])
  
          clip_min = -np.inf
          clip_max = np.inf
          if self.estimator.clip_values is not None:
              clip_min, clip_max = self.estimator.clip_values
  
          term_flag = 1
          if self.targeted:
              if desired_label != current_label:
                  term_flag = 0
          else:
              if desired_label == current_label:
                  term_flag = 0
  
          nb_iter = 0
          while term_flag == 0 and nb_iter < self.max_iter:
              diff = np.zeros(n_dims).astype(ART_NUMPY_DTYPE)
              diff[indices[nb_iter]] = self.epsilon
  
              if self.attack == "dct":
                  left_preds = self.estimator.predict(
                      np.clip(
                          x[[i_sample]]
                          - trans(diff.reshape(x[[i_sample]].shape)),
                          clip_min,
                          clip_max,
                      ),
                      batch_size=self.batch_size,
                  )
              elif self.attack == "px":
                  left_preds = self.estimator.predict(
                      np.clip(
                          x[[i_sample]]
                          - diff.reshape(x[[i_sample]].shape),
                          clip_min,
                          clip_max,
                      ),
                      batch_size=self.batch_size,
                  )
              left_prob = left_preds.reshape(-1)[desired_label]
  
              if self.attack == "dct":
                  right_preds = self.estimator.predict(
                      np.clip(
                          x[[i_sample]]
                          + trans(diff.reshape(x[[i_sample]].shape)),
                          clip_min,
                          clip_max,
                      ),
                      batch_size=self.batch_size,
                  )
              elif self.attack == "px":
                  right_preds = self.estimator.predict(
                      np.clip(
                          x[[i_sample]]
                          + diff.reshape(x[[i_sample]].shape),
                          clip_min,
                          clip_max,
                      ),
                      batch_size=self.batch_size,
                  )
              right_prob = right_preds.reshape(-1)[desired_label]
  
              # Use (2 * int(self.targeted) - 1) to shorten code?
              if self.targeted:
                  if left_prob > last_prob:
                      if left_prob > right_prob:
                          if self.attack == "dct":
                              x[[i_sample]] = np.clip(
                                  x[[i_sample]]
                                  - trans(
                                      diff.reshape(x[[i_sample]].shape)
                                  ),
                                  clip_min,
                                  clip_max,
                              )
                          elif self.attack == "px":
                              x[[i_sample]] = np.clip(
                                  x[[i_sample]]
                                  - diff.reshape(x[[i_sample]].shape),
                                  clip_min,
                                  clip_max,
                              )
                          last_prob = left_prob
                          current_label = np.argmax(left_preds, axis=1)[
                              0
                          ]
                      else:
                          if self.attack == "dct":
                              x[[i_sample]] = np.clip(
                                  x[[i_sample]]
                                  + trans(
                                      diff.reshape(x[[i_sample]].shape)
                                  ),
                                  clip_min,
                                  clip_max,
                              )
                          elif self.attack == "px":
                              x[[i_sample]] = np.clip(
                                  x[[i_sample]]
                                  + diff.reshape(x[[i_sample]].shape),
                                  clip_min,
                                  clip_max,
                              )
                          last_prob = right_prob
                          current_label = np.argmax(
                              right_preds, axis=1
                          )[0]
                  else:
                      if right_prob > last_prob:
                          if self.attack == "dct":
                              x[[i_sample]] = np.clip(
                                  x[[i_sample]]
                                  + trans(
                                      diff.reshape(x[[i_sample]].shape)
                                  ),
                                  clip_min,
                                  clip_max,
                              )
                          elif self.attack == "px":
                              x[[i_sample]] = np.clip(
                                  x[[i_sample]]
                                  + diff.reshape(x[[i_sample]].shape),
                                  clip_min,
                                  clip_max,
                              )
                          last_prob = right_prob
                          current_label = np.argmax(
                              right_preds, axis=1
                          )[0]
              else:
                  if left_prob < last_prob:
                      if left_prob < right_prob:
                          if self.attack == "dct":
                              x[[i_sample]] = np.clip(
                                  x[[i_sample]]
                                  - trans(
                                      diff.reshape(x[[i_sample]].shape)
                                  ),
                                  clip_min,
                                  clip_max,
                              )
                          elif self.attack == "px":
                              x[[i_sample]] = np.clip(
                                  x[[i_sample]]
                                  - diff.reshape(x[[i_sample]].shape),
                                  clip_min,
                                  clip_max,
                              )
                          last_prob = left_prob
                          current_label = np.argmax(left_preds, axis=1)[
                              0
                          ]
                      else:
                          if self.attack == "dct":
                              x[[i_sample]] = np.clip(
                                  x[[i_sample]]
                                  + trans(
                                      diff.reshape(x[[i_sample]].shape)
                                  ),
                                  clip_min,
                                  clip_max,
                              )
                          elif self.attack == "px":
                              x[[i_sample]] = np.clip(
                                  x[[i_sample]]
                                  + diff.reshape(x[[i_sample]].shape),
                                  clip_min,
                                  clip_max,
                              )
                          last_prob = right_prob
                          current_label = np.argmax(
                              right_preds, axis=1
                          )[0]
                  else:
                      if right_prob < last_prob:
                          if self.attack == "dct":
                              x[[i_sample]] = np.clip(
                                  x[[i_sample]]
                                  + trans(
                                      diff.reshape(x[[i_sample]].shape)
                                  ),
                                  clip_min,
                                  clip_max,
                              )
                          elif self.attack == "px":
                              x[[i_sample]] = np.clip(
                                  x[[i_sample]]
                                  + diff.reshape(x[[i_sample]].shape),
                                  clip_min,
                                  clip_max,
                              )
                          last_prob = right_prob
                          current_label = np.argmax(
                              right_preds, axis=1
                          )[0]
  
              if self.targeted:
                  if desired_label == current_label:
                      term_flag = 1
              else:
                  if desired_label != current_label:
                      term_flag = 1
  
              nb_iter = nb_iter + 1
  
          if nb_iter < self.max_iter:
              logger.info(
                  "SimBA (%s) %s attack succeed",
                  self.attack,
                  ["non-targeted", "targeted"][int(self.targeted)],
              )
          else:
              logger.info(
                  "SimBA (%s) %s attack failed",
                  self.attack,
                  ["non-targeted", "targeted"][int(self.targeted)],
              )
  
          x_adv[i_sample] = x[i_sample]
  
      return x_adv
  
file_path: adversarial-robustness-toolbox/art/attacks/evasion/simba.py
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  from typing import Optional, TYPE_CHECKING
  import numpy
  from scipy.fftpack import idct
  from tqdm.auto import trange
  from art.attacks.attack import EvasionAttack
  from art.estimators.estimator import BaseEstimator, NeuralNetworkMixin
  from art.estimators.classification.classifier import ClassifierMixin
  from art.config import ART_NUMPY_DTYPE
  from art.utils import is_probability
label_desc: Use image node_id 2 for calling the SimBA obj's underlying member method code with example usage: obj.generate(x, y) and returns: x_adv, self