def __get_gradients(self, samples: np.ndarray, perturbations: np.ndarray, targets: np.ndarray) -> np.ndarray:
        """
        Gradient of the objective function in regard to the data vector, i.e. sum of the classifier's loss gradient
        and weighted lp-space norm gradient, both in regard to data vector.

        :param samples: Base design matrix.
        :param perturbations: Perturbations of samples towards being adversarial.
        :param targets: The target labels for the attack.
        :return: Aggregate gradient of objective function.
        """
        clf_loss_grad = self.estimator.loss_gradient(
            (samples + perturbations).astype(np.float32), targets.astype(np.float32)
        )
        norm_grad = self.lambd * self.__weighted_lp_norm_gradient(perturbations)

        return clf_loss_grad + norm_grad

        Gradient of the objective function in regard to the data vector, i.e. sum of the classifier's loss gradient
        and weighted lp-space norm gradient, both in regard to data vector.

        :param samples: Base design matrix.
        :param perturbations: Perturbations of samples towards being adversarial.
        :param targets: The target labels for the attack.
        :return: Aggregate gradient of objective function.
        
art/attacks/evasion/lowprofool.py