def _apply_norm(norm, grad, object_type=False):
            """Returns an x maximizing <grad, x> subject to ||x||_norm<=1."""
            if (grad.dtype != object and np.isinf(grad).any()) or np.isnan(  # pragma: no cover
                grad.astype(np.float32)
            ).any():
                logger.info("The loss gradient array contains at least one positive or negative infinity.")

            grad_2d = grad.reshape(1 if object_type else len(grad), -1)
            if norm in [np.inf, "inf"]:
                grad_2d = np.ones_like(grad_2d)
            elif norm == 1:
                i_max = np.argmax(np.abs(grad_2d), axis=1)
                grad_2d = np.zeros_like(grad_2d)
                grad_2d[range(len(grad_2d)), i_max] = 1
            elif norm > 1:
                conjugate = norm / (norm - 1)
                q_norm = np.linalg.norm(grad_2d, ord=conjugate, axis=1, keepdims=True)
                grad_2d = (np.abs(grad_2d) / np.where(q_norm, q_norm, np.inf)) ** (conjugate - 1)
            grad = grad_2d.reshape(grad.shape) * np.sign(grad)
            return grad
Returns an x maximizing <grad, x> subject to ||x||_norm<=1.
art/attacks/evasion/fast_gradient.py