class_docstr: This attack was originally implemented by Goodfellow et al. (2015) with the infinity norm (and is known as the "Fast
  Gradient Sign Method"). This implementation extends the attack to other norms, and is therefore called the Fast
  Gradient Method.
  
  | Paper link: https://arxiv.org/abs/1412.6572
class_docstr_tok: ["This","attack","was","originally","implemented","by","Goodfellow","et","al",".","(","2015",")","with","the","infinity","norm","(","and","is","known","as","the","``","Fast","Gradient","Sign","Method","''",")",".","This","implementation","extends","the","attack","to","other","norms",",","and","is","therefore","called","the","Fast","Gradient","Method",".","|","Paper","link",":","https",":","\/\/arxiv.org\/abs\/1412.6572"]
docstr: Iteratively compute the minimal perturbation necessary to make the class prediction change. Stop when the
  first adversarial example was found.
  
  :param x: An array with the original inputs.
  :param y: Target values (class labels) one-hot-encoded of shape (nb_samples, nb_classes).
  :return: An array holding the adversarial examples.
docstr_tok: ["Iteratively","compute","the","minimal","perturbation","necessary","to","make","the","class","prediction","change",".","Stop","when","the","first","adversarial","example","was","found",".",":","param","x",":","An","array","with","the","original","inputs",".",":","param","y",":","Target","values","(","class","labels",")","one-hot-encoded","of","shape","(","nb_samples",",","nb_classes",")",".",":","return",":","An","array","holding","the","adversarial","examples","."]
code: def _minimal_perturbation(
      self, x: np.ndarray, y: np.ndarray, mask: np.ndarray
  ) -> np.ndarray:
      """
      Iteratively compute the minimal perturbation necessary to make the class prediction change. Stop when the
      first adversarial example was found.
  
      :param x: An array with the original inputs.
      :param y: Target values (class labels) one-hot-encoded of shape (nb_samples, nb_classes).
      :return: An array holding the adversarial examples.
      """
      adv_x = x.copy()
  
      # Compute perturbation with implicit batching
      for batch_id in range(
          int(np.ceil(adv_x.shape[0] / float(self.batch_size)))
      ):
          batch_index_1, batch_index_2 = (
              batch_id * self.batch_size,
              (batch_id + 1) * self.batch_size,
          )
          batch = adv_x[batch_index_1:batch_index_2]
          batch_labels = y[batch_index_1:batch_index_2]
  
          mask_batch = mask
          if mask is not None:
              # Here we need to make a distinction: if the masks are different for each input, we need to index
              # those for the current batch. Otherwise (i.e. mask is meant to be broadcasted), keep it as it is.
              if len(mask.shape) == len(x.shape):
                  mask_batch = mask[batch_index_1:batch_index_2]
  
          # Get perturbation
          perturbation = self._compute_perturbation(
              batch, batch_labels, mask_batch
          )
  
          # Get current predictions
          active_indices = np.arange(len(batch))
  
          current_eps: Union[int, float, np.ndarray]
          partial_stop_condition: Union[bool, np.ndarray]
  
          if isinstance(self.eps, np.ndarray) and isinstance(
              self.eps_step, np.ndarray
          ):
              if (
                  len(self.eps.shape) == len(x.shape)
                  and self.eps.shape[0] == x.shape[0]
              ):
                  current_eps = self.eps_step[
                      batch_index_1:batch_index_2
                  ]
                  partial_stop_condition = bool(
                      (
                          current_eps
                          <= self.eps[batch_index_1:batch_index_2]
                      ).all()
                  )
  
              else:
                  current_eps = self.eps_step
                  partial_stop_condition = bool(
                      (current_eps <= self.eps).all()
                  )
  
          else:
              current_eps = self.eps_step
              partial_stop_condition = current_eps <= self.eps
  
          while active_indices.size > 0 and partial_stop_condition:
              # Adversarial crafting
              current_x = self._apply_perturbation(
                  x[batch_index_1:batch_index_2],
                  perturbation,
                  current_eps,
              )
  
              # Update
              batch[active_indices] = current_x[active_indices]
              adv_preds = self.estimator.predict(batch)
  
              # If targeted active check to see whether we have hit the target, otherwise head to anything but
              if self.targeted:
                  active_indices = np.where(
                      np.argmax(batch_labels, axis=1)
                      != np.argmax(adv_preds, axis=1)
                  )[0]
              else:
                  active_indices = np.where(
                      np.argmax(batch_labels, axis=1)
                      == np.argmax(adv_preds, axis=1)
                  )[0]
  
              # Update current eps and check the stop condition
              if isinstance(self.eps, np.ndarray) and isinstance(
                  self.eps_step, np.ndarray
              ):
                  if (
                      len(self.eps.shape) == len(x.shape)
                      and self.eps.shape[0] == x.shape[0]
                  ):
                      current_eps = (
                          current_eps
                          + self.eps_step[batch_index_1:batch_index_2]
                      )
                      partial_stop_condition = bool(
                          (
                              current_eps
                              <= self.eps[batch_index_1:batch_index_2]
                          ).all()
                      )
  
                  else:
                      current_eps = current_eps + self.eps_step
                      partial_stop_condition = bool(
                          (current_eps <= self.eps).all()
                      )
  
              else:
                  current_eps = current_eps + self.eps_step
                  partial_stop_condition = current_eps <= self.eps
  
          adv_x[batch_index_1:batch_index_2] = batch
  
      return adv_x
  
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  from typing import Optional, Union, TYPE_CHECKING
  import numpy
  from art.config import ART_NUMPY_DTYPE
  from art.attacks.attack import EvasionAttack
  from art.estimators.estimator import BaseEstimator, LossGradientsMixin
  from art.estimators.classification.classifier import ClassifierMixin
  from art.utils import compute_success, get_labels_np_array, random_sphere, projection, check_and_transform_label_format
  from art.summary_writer import SummaryWriter
label_desc: Use image node_id 3 for calling the FastGradientMethod obj's underlying member method code with example usage: obj._minimal_perturbation(x, y, mask) and returns: adv_x