Source code for pyproximal.projection.L0

import warnings

import numpy as np
from pylops.utils.typing import NDArray


[docs]class L0BallProj: r""":math:`L_0` ball projection. Parameters ---------- radius : :obj:`int` Radius Notes ----- Given an L0 ball defined as: .. math:: L0_{r} = \{ \mathbf{x}: ||\mathbf{x}||_0 \leq r \} its orthogonal projection is computed by finding the :math:`r` highest largest entries of :math:`\mathbf{x}` (in absolute value), keeping those and zero-ing all the other entries. Note that this is the proximal operator of the corresponding indicator function :math:`\mathcal{I}_{L0_{r}}`. """ def __init__(self, radius: int) -> None: self.radius = int(radius) def __call__(self, x: NDArray) -> NDArray: xshape = x.shape xf = x.copy().flatten() xf[np.argsort(np.abs(xf))[: -self.radius]] = 0 return xf.reshape(xshape)
[docs]class L10BallProj: r""":math:`L_{1,0}` ball projection. Parameters ---------- radius : :obj:`int` Radius Notes ----- Given an :math:`L_{1,0}` ball defined as: .. math:: L_{1,0}^{r} = \{ \mathbf{x}: \text{count}([||\mathbf{x}_1||_1, ||\mathbf{x}_2||_1, ..., ||\mathbf{x}_1||_1] \ne 0) \leq r \} its orthogonal projection is computed by finding the :math:`r` highest largest entries of a vector obtained by applying the :math:`L_1` norm to each column of a matrix :math:`\mathbf{x}` (in absolute value), keeping those and zero-ing all the other entries. Note that this is the proximal operator of the corresponding indicator function :math:`\mathcal{I}_{L_{1,0}^{r}}`. """ def __init__(self, radius: int) -> None: self.radius = int(radius) def __call__(self, x: NDArray) -> NDArray: xc = x.copy() xf = np.linalg.norm(x, axis=0, ord=1) xc[:, np.argsort(np.abs(xf))[: -self.radius]] = 0 return xc
class L01BallProj(L10BallProj): def __init__(self, radius: int) -> None: warnings.warn( "The L01BallProj class has been renamed L10BallProj due " "to a mistake in the original choice of the name. As such " "L01BallProj will be deprecated in v1.0.0.", FutureWarning, ) super().__init__(radius)