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)