Source code for pyproximal.proximal.Euclidean

import numpy as np
from pyproximal.ProxOperator import _check_tau
from pyproximal import ProxOperator
from pyproximal.projection import EuclideanBallProj


[docs]class Euclidean(ProxOperator): r"""Euclidean norm proximal operator. Proximal operator of the Euclidean norm: :math:`\sigma \|\mathbf{x}\|_2 = \sigma \sqrt{\sum x_i^2}`. Parameters ---------- sigma : :obj:`int`, optional Multiplicative coefficient of :math:`L_{2}` norm Notes ----- The Euclidean proximal operator is defined as: .. math:: \prox_{\tau \sigma \|\cdot\|_2}(\mathbf{x}) = \left(1 - \frac{\tau \sigma }{\max\{\|\mathbf{x}\|_2, \tau \sigma \}}\right) \mathbf{x} This operator is sometimes called *block soft thresholding*. Moreover, as the conjugate of the Euclidean norm is the orthogonal projection of its dual norm (i.e., Euclidean norm) onto a unit ball, its dual operator is defined as: .. math:: \prox^*_{\tau \sigma \|\cdot\|_2}(\mathbf{x}) = \frac{\sigma \mathbf{x}}{\max\{\|\mathbf{x}\|_2, \sigma\}} """ def __init__(self, sigma=1.): super().__init__(None, True) self.sigma = sigma def __call__(self, x): return self.sigma * np.linalg.norm(x) @_check_tau def prox(self, x, tau): x = (1. - (tau * self.sigma) / max(np.linalg.norm(x), tau * self.sigma)) * x return x @_check_tau def proxdual(self, x, tau): x = self.sigma * x / (max(np.linalg.norm(x), self.sigma)) return x def grad(self, x): return self.sigma * x / np.linalg.norm(x)
[docs]class EuclideanBall(ProxOperator): r"""Euclidean ball proximal operator. Proximal operator of the Euclidean ball: :math:`Eucl_{[c, r]} = \{ \mathbf{x}: ||\mathbf{x} - \mathbf{c}||_2 \leq r \}`. Parameters ---------- center : :obj:`np.ndarray` or :obj:`float` Center of the ball radius : :obj:`float` Radius Notes ----- As the Euclidean ball is an indicator function, the proximal operator corresponds to its orthogonal projection (see :class:`pyproximal.projection.EuclideanBallProj` for details. """ def __init__(self, center, radius): super().__init__(None, False) self.center = center self.radius = radius self.ball = EuclideanBallProj(self.center, self.radius) def __call__(self, x): return np.linalg.norm(x - self.center) <= self.radius @_check_tau def prox(self, x, tau): return self.ball(x)