Source code for pyproximal.proximal.RelaxedMS
import numpy as np
from pyproximal.ProxOperator import _check_tau
from pyproximal import ProxOperator
from pyproximal.proximal.L1 import _current_sigma
def _l2(x, alpha):
r"""Scaling operation.
Applies the proximal of ``alpha||y - x||_2^2`` which is essentially a scaling operation.
Parameters
----------
x : :obj:`numpy.ndarray`
Vector
alpha : :obj:`float`
Scaling parameter
Returns
-------
y : :obj:`numpy.ndarray`
Scaled vector
"""
y = 1 / (1 + 2 * alpha) * x
return y
def _current_kappa(kappa, count):
if not callable(kappa):
return kappa
else:
return kappa(count)
[docs]class RelaxedMumfordShah(ProxOperator):
r"""Relaxed Mumford-Shah norm proximal operator.
Proximal operator of the relaxed Mumford-Shah norm:
:math:`\text{rMS}(x) = \min (\alpha\Vert x\Vert_2^2, \kappa)`.
Parameters
----------
sigma : :obj:`float` or :obj:`list` or :obj:`np.ndarray` or :obj:`func`, optional
Multiplicative coefficient of L2 norm that controls the smoothness of the solutuon.
This can be a constant number, a list of values (for multidimensional inputs, acting
on the second dimension) or a function that is called passing a counter which keeps
track of how many times the ``prox`` method has been invoked before and returns a
scalar (or a list of) ``sigma`` to be used.
kappa : :obj:`float` or :obj:`list` or :obj:`np.ndarray` or :obj:`func`, optional
Constant value in the rMS norm which essentially controls when the norm allows a jump. This can be a
constant number, a list of values (for multidimensional inputs, acting on the second dimension) or
a function that is called passing a counter which keeps track of how many
times the ``prox`` method has been invoked before and returns a scalar (or a list of)
``kappa`` to be used.
Notes
-----
The :math:`rMS` proximal operator is defined as [1]_:
.. math::
\text{prox}_{\tau \text{rMS}}(x) =
\begin{cases}
\frac{1}{1+2\tau\alpha}x & \text{ if } & \vert x\vert \leq \sqrt{\frac{\kappa}{\alpha}(1 + 2\tau\alpha)} \\
\kappa & \text{ else }
\end{cases}.
.. [1] Strekalovskiy, E., and D. Cremers, 2014, Real-time minimization of the piecewise smooth
Mumford-Shah functional: European Conference on Computer Vision, 127–141.
"""
def __init__(self, sigma=1., kappa=1.):
super().__init__(None, False)
self.sigma = sigma
self.kappa = kappa
self.count = 0
def __call__(self, x):
sigma = _current_sigma(self.sigma, self.count)
kappa = _current_sigma(self.kappa, self.count)
return np.minimum(sigma * np.linalg.norm(x) ** 2, kappa)
def _increment_count(func):
"""Increment counter
"""
def wrapped(self, *args, **kwargs):
self.count += 1
return func(self, *args, **kwargs)
return wrapped
@_increment_count
@_check_tau
def prox(self, x, tau):
sigma = _current_sigma(self.sigma, self.count)
kappa = _current_sigma(self.kappa, self.count)
x = np.where(np.abs(x) <= np.sqrt(kappa / sigma * (1 + 2 * tau * sigma)), _l2(x, tau * sigma), x)
return x