def METHOD_NAME(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> np.ndarray:
    """
    Generate adversarial samples and return them in a Numpy array.
    :param x: An array with the original inputs to be attacked.
    :param y: An array with the original labels to be predicted.
    :return: An array holding the adversarial examples.
    """
    x_adv = x.astype(ART_NUMPY_DTYPE)
    # Initialize variables
    y_pred = self.estimator.predict(x, batch_size=self.batch_size)
    pred_class = np.argmax(y_pred, axis=1)
    if self.estimator.nb_classes == 2 and y_pred.shape[1] == 1:  # pragma: no cover
        raise ValueError(
            "This attack has not yet been tested for binary classification with a single output classifier."
        )
    # Compute perturbation with implicit batching
    for batch_id in trange(
        int(np.ceil(x_adv.shape[0] / float(self.batch_size))), desc="NewtonFool", disable=not self.verbose
    ):
        batch_index_1, batch_index_2 = batch_id * self.batch_size, (batch_id + 1) * self.batch_size
        batch = x_adv[batch_index_1:batch_index_2]
        # Main algorithm for each batch
        norm_batch = np.linalg.norm(np.reshape(batch, (batch.shape[0], -1)), axis=1)
        l_batch = pred_class[batch_index_1:batch_index_2]
        l_b = to_categorical(l_batch, self.estimator.nb_classes).astype(bool)
        # Main loop of the algorithm
        for _ in range(self.max_iter):
            # Compute score
            score = self.estimator.predict(batch)[l_b]
            # Compute the gradients and norm
            grads = self.estimator.class_gradient(batch, label=l_batch)
            if grads.shape[1] == 1:
                grads = np.squeeze(grads, axis=1)
            norm_grad = np.linalg.norm(np.reshape(grads, (batch.shape[0], -1)), axis=1)
            # Theta
            theta = self._compute_theta(norm_batch, score, norm_grad)
            # Perturbation
            di_batch = self._compute_pert(theta, grads, norm_grad)
            # Update xi and perturbation
            batch += di_batch
        # Apply clip
        if self.estimator.clip_values is not None:
            clip_min, clip_max = self.estimator.clip_values
            x_adv[batch_index_1:batch_index_2] = np.clip(batch, clip_min, clip_max)
        else:
            x_adv[batch_index_1:batch_index_2] = batch
    return x_adv