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"]
code: def _compute(
      self,
      x: np.ndarray,
      x_init: np.ndarray,
      y: np.ndarray,
      mask: Optional[np.ndarray],
      eps: Union[int, float, np.ndarray],
      eps_step: Union[int, float, np.ndarray],
      project: bool,
      random_init: bool,
      batch_id_ext: Optional[int] = None,
      decay: Optional[float] = None,
      momentum: Optional[np.ndarray] = None,
  ) -> np.ndarray:
      if random_init:
          n = x.shape[0]
          m = np.prod(x.shape[1:]).item()
          random_perturbation = (
              random_sphere(n, m, eps, self.norm)
              .reshape(x.shape)
              .astype(ART_NUMPY_DTYPE)
          )
          if mask is not None:
              random_perturbation = random_perturbation * (
                  mask.astype(ART_NUMPY_DTYPE)
              )
          x_adv = x.astype(ART_NUMPY_DTYPE) + random_perturbation
  
          if self.estimator.clip_values is not None:
              clip_min, clip_max = self.estimator.clip_values
              x_adv = np.clip(x_adv, clip_min, clip_max)
      else:
          if x.dtype == object:
              x_adv = x.copy()
          else:
              x_adv = x.astype(ART_NUMPY_DTYPE)
  
      # Compute perturbation with implicit batching
      for batch_id in range(
          int(np.ceil(x.shape[0] / float(self.batch_size)))
      ):
          if batch_id_ext is None:
              self._batch_id = batch_id
          else:
              self._batch_id = batch_id_ext
          batch_index_1, batch_index_2 = (
              batch_id * self.batch_size,
              (batch_id + 1) * self.batch_size,
          )
          batch_index_2 = min(batch_index_2, x.shape[0])
          batch = x_adv[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, decay, momentum
          )
  
          batch_eps: Union[int, float, np.ndarray]
          batch_eps_step: Union[int, float, np.ndarray]
  
          # Compute batch_eps and batch_eps_step
          if isinstance(eps, np.ndarray) and isinstance(
              eps_step, np.ndarray
          ):
              if (
                  len(eps.shape) == len(x.shape)
                  and eps.shape[0] == x.shape[0]
              ):
                  batch_eps = eps[batch_index_1:batch_index_2]
                  batch_eps_step = eps_step[batch_index_1:batch_index_2]
  
              else:
                  batch_eps = eps
                  batch_eps_step = eps_step
  
          else:
              batch_eps = eps
              batch_eps_step = eps_step
  
          # Apply perturbation and clip
          x_adv[batch_index_1:batch_index_2] = self._apply_perturbation(
              batch, perturbation, batch_eps_step
          )
  
          if project:
              if x_adv.dtype == object:
                  for i_sample in range(batch_index_1, batch_index_2):
                      if (
                          isinstance(batch_eps, np.ndarray)
                          and batch_eps.shape[0] == x_adv.shape[0]
                      ):
                          perturbation = projection(
                              x_adv[i_sample] - x_init[i_sample],
                              batch_eps[i_sample],
                              self.norm,
                          )
  
                      else:
                          perturbation = projection(
                              x_adv[i_sample] - x_init[i_sample],
                              batch_eps,
                              self.norm,
                          )
  
                      x_adv[i_sample] = x_init[i_sample] + perturbation
  
              else:
                  perturbation = projection(
                      x_adv[batch_index_1:batch_index_2]
                      - x_init[batch_index_1:batch_index_2],
                      batch_eps,
                      self.norm,
                  )
                  x_adv[batch_index_1:batch_index_2] = (
                      x_init[batch_index_1:batch_index_2] + perturbation
                  )
  
      return x_adv
  
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 8 for calling the FastGradientMethod obj's underlying member method code with example usage: obj._compute(x, x_init, y, mask, eps, eps_step, project, random_init, batch_id_ext, decay, momentum) and returns: x_adv