def __init__(
        self,
        estimator: "CLASSIFIER_TYPE",
        norm: int | float | str = np.inf,
        adv_criterion: Callable[[np.ndarray, np.ndarray], bool] | None = None,
        loss: Callable[[np.ndarray, np.ndarray], np.ndarray] | None = None,
        max_iter: int = 100,
        eps: float = 0.3,
        p_init: float = 0.8,
        nb_restarts: int = 1,
        batch_size: int = 128,
        verbose: bool = True,
    ):
        """
        Create a :class:`.SquareAttack` instance.

        :param estimator: A trained estimator.
        :param norm: The norm of the adversarial perturbation. Possible values: "inf", np.inf, 1 or 2.
        :param adv_criterion: The criterion which the attack should use in determining adversariality.
        :param loss: The loss function which the attack should use for optimization.
        :param max_iter: Maximum number of iterations.
        :param eps: Maximum perturbation that the attacker can introduce.
        :param p_init: Initial fraction of elements.
        :param nb_restarts: Number of restarts.
        :param batch_size: Batch size for estimator evaluations.
        :param verbose: Show progress bars.
        """
        super().__init__(estimator=estimator)

        self.norm = norm

        if adv_criterion is not None:
            self.adv_criterion = adv_criterion
        elif isinstance(self.estimator, ClassifierMixin):
            self.adv_criterion = lambda y_pred, y: np.argmax(y_pred, axis=1) != np.argmax(y, axis=1)
        else:  # pragma: no cover
            raise ValueError("No acceptable adversarial criterion available.")

        if loss is not None:
            self.loss = loss
        elif isinstance(self.estimator, ClassifierMixin):
            self.loss = self._get_logits_diff
        else:  # pragma: no cover
            raise ValueError("No acceptable loss available.")

        self.max_iter = max_iter
        self.eps = eps
        self.p_init = p_init
        self.nb_restarts = nb_restarts
        self.batch_size = batch_size
        self.verbose = verbose
        self._check_params()

        Create a :class:`.SquareAttack` instance.

        :param estimator: A trained estimator.
        :param norm: The norm of the adversarial perturbation. Possible values: "inf", np.inf, 1 or 2.
        :param adv_criterion: The criterion which the attack should use in determining adversariality.
        :param loss: The loss function which the attack should use for optimization.
        :param max_iter: Maximum number of iterations.
        :param eps: Maximum perturbation that the attacker can introduce.
        :param p_init: Initial fraction of elements.
        :param nb_restarts: Number of restarts.
        :param batch_size: Batch size for estimator evaluations.
        :param verbose: Show progress bars.
        
art/attacks/evasion/square_attack.py