pyproximal.optimization.primal.HQS#

pyproximal.optimization.primal.HQS(proxf: ProxOperator, proxg: ProxOperator, x0: ndarray[tuple[Any, ...], dtype[_ScalarT]], tau: Union[float, ndarray[tuple[Any, ...], dtype[_ScalarT]]], niter: int = 10, z0: Optional[ndarray[tuple[Any, ...], dtype[_ScalarT]]] = None, gfirst: bool = True, callback: Optional[Callable[[...], None]] = None, callbackz: bool = False, show: bool = False) Tuple[ndarray[tuple[Any, ...], dtype[_ScalarT]], ndarray[tuple[Any, ...], dtype[_ScalarT]]][source]#

Half Quadratic splitting

Solves the following minimization problem using Half Quadratic splitting algorithm:

\[\begin{split}\mathbf{x},\mathbf{z} = \argmin_{\mathbf{x},\mathbf{z}} f(\mathbf{x}) + g(\mathbf{z}) \\ s.t. \; \mathbf{x}=\mathbf{z}\end{split}\]

where \(f(\mathbf{x})\) and \(g(\mathbf{z})\) are any convex function that has a known proximal operator.

Parameters
proxfpyproximal.ProxOperator

Proximal operator of f function

proxgpyproximal.ProxOperator

Proximal operator of g function

x0numpy.ndarray

Initial vector (not required when gfirst=False, can pass None)

taufloat or numpy.ndarray

Positive scalar weight, which should satisfy the following condition to guarantees convergence: \(\tau \in (0, 1/L]\) where L is the Lipschitz constant of \(\nabla f\). Finally note that \(\tau\) can be chosen to be a vector of size niter such that different \(\tau\) is used at different iterations (i.e., continuation strategy)

niterint

Number of iterations of iterative scheme

z0numpy.ndarray, optional

Initial z vector (not required when gfirst=True)

gfirstbool, optional

Apply Proximal of operator g first (True) or Proximal of operator f first (False)

callbackcallable, optional

Function with signature (callback(x)) to call after each iteration where x is the current model vector

callbackzbool, optional

Modify callback signature to (callback(x, z)) when callbackz=True

showbool, optional

Display iterations log

Returns
xnumpy.ndarray

Inverted model

znumpy.ndarray

Inverted second model

Raises
ValueError

If both x0 and z0 are set to None

Notes

The HQS algorithm can be expressed by the following recursion [1]:

\[\begin{split}\mathbf{z}^{k+1} = \prox_{\tau g}(\mathbf{x}^{k}) \\ \mathbf{x}^{k+1} = \prox_{\tau f}(\mathbf{z}^{k+1})\end{split}\]

for gfirst=False, or

\[\begin{split}\mathbf{x}^{k+1} = \prox_{\tau f}(\mathbf{z}^{k}) \\ \mathbf{z}^{k+1} = \prox_{\tau g}(\mathbf{x}^{k+1})\end{split}\]

for gfirst=False. Note that x and z converge to each other, however if iterations are stopped too early x is guaranteed to belong to the domain of f while z is guaranteed to belong to the domain of g. Depending on the problem either of the two may be the best solution.

1

D., Geman, and C., Yang, “Nonlinear image recovery with halfquadratic regularization”, IEEE Transactions on Image Processing, 4, 7, pp. 932-946, 1995.