class_docstr: Implements ``Wasserstein Adversarial Examples via Projected Sinkhorn Iterations`` as evasion attack.
  
  | Paper link: https://arxiv.org/abs/1902.07906
class_docstr_tok: ["Implements","``","Wasserstein","Adversarial","Examples","via","Projected","Sinkhorn","Iterations","``","as","evasion","attack",".","|","Paper","link",":","https",":","\/\/arxiv.org\/abs\/1902.07906"]
docstr: Apply projection on the ball of size `eps`.
  
  :param x: Current adversarial examples.
  :param x_init: An array with the original inputs.
  :param cost_matrix: A non-negative cost matrix.
  :param eps: Maximum perturbation that the attacker can introduce.
  :return: Adversarial examples.
docstr_tok: ["Apply","projection","on","the","ball","of","size","`","eps","`",".",":","param","x",":","Current","adversarial","examples",".",":","param","x_init",":","An","array","with","the","original","inputs",".",":","param","cost_matrix",":","A","non-negative","cost","matrix",".",":","param","eps",":","Maximum","perturbation","that","the","attacker","can","introduce",".",":","return",":","Adversarial","examples","."]
code: def _apply_projection(
      self,
      x: np.ndarray,
      x_init: np.ndarray,
      cost_matrix: np.ndarray,
      eps: np.ndarray,
  ) -> np.ndarray:
      """
      Apply projection on the ball of size `eps`.
  
      :param x: Current adversarial examples.
      :param x_init: An array with the original inputs.
      :param cost_matrix: A non-negative cost matrix.
      :param eps: Maximum perturbation that the attacker can introduce.
      :return: Adversarial examples.
      """
      # Pick a small scalar to avoid division by 0
      tol = 10e-8
  
      if self.ball == "2":
          values = x - x_init
          values_tmp = values.reshape((values.shape[0], -1))
  
          values_tmp = values_tmp * np.expand_dims(
              np.minimum(
                  1.0, eps / (np.linalg.norm(values_tmp, axis=1) + tol)
              ),
              axis=1,
          )
  
          values = values_tmp.reshape(values.shape)
  
          x_adv = values + x_init
  
      elif self.ball == "1":
          values = x - x_init
          values_tmp = values.reshape((values.shape[0], -1))
  
          values_tmp = values_tmp * np.expand_dims(
              np.minimum(
                  1.0,
                  eps
                  / (np.linalg.norm(values_tmp, axis=1, ord=1) + tol),
              ),
              axis=1,
          )
  
          values = values_tmp.reshape(values.shape)
          x_adv = values + x_init
  
      elif self.ball == "inf":
          values = x - x_init
          values_tmp = values.reshape((values.shape[0], -1))
  
          values_tmp = np.sign(values_tmp) * np.minimum(
              abs(values_tmp), np.expand_dims(eps, -1)
          )
  
          values = values_tmp.reshape(values.shape)
          x_adv = values + x_init
  
      elif self.ball == "wasserstein":
          x_adv = self._projected_sinkhorn(x, x_init, cost_matrix, eps)
  
      else:
          raise NotImplementedError(
              "Values of `ball` different from `1`, `2`, `inf` and `wasserstein` are currently not supported."
          )
  
      return x_adv
  
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  from typing import Optional, TYPE_CHECKING
  import numpy
  from scipy.special import lambertw
  from tqdm.auto import trange
  from art.config import ART_NUMPY_DTYPE
  from art.estimators.estimator import BaseEstimator, LossGradientsMixin
  from art.estimators.classification.classifier import ClassifierMixin
  from art.attacks.attack import EvasionAttack
  from art.utils import get_labels_np_array, check_and_transform_label_format
label_desc: Use image node_id 6 for calling the Wasserstein obj's underlying member method code with example usage: obj._apply_projection(x, x_init, cost_matrix, eps) and returns: x_adv