Source code for pyproximal.projection.Nuclear

import numpy as np
from pyproximal.projection import L1BallProj

[docs]class NuclearBallProj(): r"""Nuclear ball projection Parameters ---------- n : :obj:`int` Number of elements of input vector radius : :obj:`float` Radius maxiter : :obj:`int`, optional Maximum number of iterations used by :func:`scipy.optimize.bisect` xtol : :obj:`float`, optional Absolute tolerance of :func:`scipy.optimize.bisect` Notes ----- Given a Nuclear ball defined as: .. math:: N_{r} = \{ \mathbf{X}: ||\mathbf{X}||_* \leq r \} its orthogonal projection is: .. math:: P_{N_{r}} (\mathbf{X}) = \mathbf{U} diag(P_{L1_{r}} (\sigma(\mathbf{X}))) \mathbf{V}^H where :math:`\mathbf{U} diag(\sigma(\mathbf{X})) \mathbf{V}^H` is the SVD decomposition of :math:`\mathbf{X}`. """ def __init__(self, n, radius, maxiter=100, xtol=1e-5): self.n = n self.radius = radius self.l1ball = L1BallProj(n, radius, maxiter, xtol) def __call__(self, X): U, S, Vh = np.linalg.svd(X, full_matrices=False) S = self.l1ball(S) return U @ np.diag(S) @ Vh