Description of sopt_mltb_prox_L1
Description: sopt_mltb_prox_L1 - Proximal operator with L1 norm

Home > matlab > prox_operators > sopt_mltb_prox_L1.m

# sopt_mltb_prox_L1

## PURPOSE

sopt_mltb_prox_L1 - Proximal operator with L1 norm

## SYNOPSIS

function sol = sopt_mltb_prox_L1(x, lambda, param)

## DESCRIPTION

     sopt_mltb_prox_L1 - Proximal operator with L1 norm

     Compute the L1 proximal operator, i.e. solve

       min_{z} 0.5*||x - z||_2^2 + lambda * ||Psit x||_1 ,

     where x is the input vector and the solution z* is returned as sol.
     The structure param should contain the following fields:

       - Psit: Sparsifying transform (default = Identity).

       - Psi: Adjoint of Psit (default = Identity).

       - tight: 1 if Psit is a tight frame or 0 otherwise (default = 1).

       - nu: Bound on the norm^2 of the operator Psi, i.e.
           ||Psi x||^2 <= nu * ||x||^2 (default = 1).

       - max_iter: Maximum number of iterations (default = 200).

       - rel_obj: Minimum relative change of the objective value
           (default = 1e-4).  The algorithm stops if
               | ||x(t)||_1 - ||x(t-1)||_1 | / ||x(t)||_1 < rel_obj,
           where x(t) is the estimate of the solution at iteration t.

       - verbose: Verbosity level (0 = no log, 1 = summary at convergence,
           2 = print main steps; default = 1).

       - weights: Weights for a weighted L1-norm (default = 1).

       - pos: Positivity flag (1 = positive solution,
           0 = general complex case; default = 0).

     References:
     [1] M.J. Fadili and J-L. Starck, "Monotone operator splitting for
     optimization problems in sparse recovery" , IEEE ICIP, Cairo,
     Egypt, 2009.
     [2] Amir Beck and Marc Teboulle, "A Fast Iterative Shrinkage-Thresholding
     Algorithm for Linear Inverse Problems",  SIAM Journal on Imaging Sciences
     2 (2009), no. 1, 183--202.

## CROSS-REFERENCE INFORMATION

This function calls:

This function is called by:

## SOURCE CODE

    0001 function sol = sopt_mltb_prox_L1(x, lambda, param)
    0002 % sopt_mltb_prox_L1 - Proximal operator with L1 norm
    0003 %
    0004 % Compute the L1 proximal operator, i.e. solve
    0005 %
    0006 %   min_{z} 0.5*||x - z||_2^2 + lambda * ||Psit x||_1 ,
    0007 %
    0008 % where x is the input vector and the solution z* is returned as sol.
    0009 % The structure param should contain the following fields:
    0010 %
    0011 %   - Psit: Sparsifying transform (default = Identity).
    0012 %
    0013 %   - Psi: Adjoint of Psit (default = Identity).
    0014 %
    0015 %   - tight: 1 if Psit is a tight frame or 0 otherwise (default = 1).
    0016 %
    0017 %   - nu: Bound on the norm^2 of the operator Psi, i.e.
    0018 %       ||Psi x||^2 <= nu * ||x||^2 (default = 1).
    0019 %
    0020 %   - max_iter: Maximum number of iterations (default = 200).
    0021 %
    0022 %   - rel_obj: Minimum relative change of the objective value
    0023 %       (default = 1e-4).  The algorithm stops if
    0024 %           | ||x(t)||_1 - ||x(t-1)||_1 | / ||x(t)||_1 < rel_obj,
    0025 %       where x(t) is the estimate of the solution at iteration t.
    0026 %
    0027 %   - verbose: Verbosity level (0 = no log, 1 = summary at convergence,
    0028 %       2 = print main steps; default = 1).
    0029 %
    0030 %   - weights: Weights for a weighted L1-norm (default = 1).
    0031 %
    0032 %   - pos: Positivity flag (1 = positive solution,
    0033 %       0 = general complex case; default = 0).
    0034 %
    0035 % References:
    0036 % [1] M.J. Fadili and J-L. Starck, "Monotone operator splitting for
    0037 % optimization problems in sparse recovery" , IEEE ICIP, Cairo,
    0038 % Egypt, 2009.
    0039 % [2] Amir Beck and Marc Teboulle, "A Fast Iterative Shrinkage-Thresholding
    0040 % Algorithm for Linear Inverse Problems",  SIAM Journal on Imaging Sciences
    0041 % 2 (2009), no. 1, 183--202.
    0042
    0043 % Optional input arguments
    0044 if ~isfield(param, 'verbose'), param.verbose = 1; end
    0045 if ~isfield(param, 'Psit'), param.Psi = @(x) x; param.Psit = @(x) x; end
    0046 if ~isfield(param, 'tight'), param.tight = 1; end
    0047 if ~isfield(param, 'nu'), param.nu = 1; end
    0048 if ~isfield(param, 'rel_obj'), param.rel_obj = 1e-4; end
    0049 if ~isfield(param, 'max_iter'), param.max_iter = 200; end
    0050 if ~isfield(param, 'Psit'), param.Psit = @(x) x; end
    0051 if ~isfield(param, 'Psi'), param.Psi = @(x) x; end
    0052 if ~isfield(param, 'weights'), param.weights = 1; end
    0053 if ~isfield(param, 'pos'), param.pos = 0; end
    0054
    0055 % Useful functions
    0056 soft = @(z, T) sign(z).*max(abs(z)-T, 0);
    0057
    0058 % Projection
    0059 if param.tight && ~param.pos % TIGHT FRAME CASE
    0060
    0061     temp = param.Psit(x);
    0062     sol = x + 1/param.nu * param.Psi(soft(temp, ...
    0063         lambda*param.nu*param.weights)-temp);
    0064     crit_L1 = 'REL_OBJ'; iter_L1 = 1;
    0065     dummy = param.Psit(sol);
    0066     norm_l1 = sum(param.weights(:).*abs(dummy(:)));
    0067
    0068 else % NON TIGHT FRAME CASE OR CONSTRAINT INVOLVED
    0069
    0070     % Initializations
    0071     u_l1 = zeros(size(param.Psit(x)));
    0072     sol = x - param.Psi(u_l1);
    0073     prev_l1 = 0; iter_L1 = 0;
    0074
    0075     % Soft-thresholding
    0076     % Init
    0077     if param.verbose > 1
    0078         fprintf('  Proximal l1 operator:\n');
    0079     end
    0080     while 1
    0081
    0082         % L1 norm of the estimate
    0083         dummy = param.Psit(sol);
    0084
    0085         norm_l1 = .5*norm(x(:) - sol(:), 2)^2 + lambda * ...
    0086             sum(param.weights(:).*abs(dummy(:)));
    0087         rel_l1 = abs(norm_l1-prev_l1)/norm_l1;
    0088
    0089         % Log
    0090         if param.verbose>1
    0091             fprintf('   Iter %i, ||Psit x||_1 = %e, rel_l1 = %e\n', ...
    0092                 iter_L1, norm_l1, rel_l1);
    0093         end
    0094
    0095         % Stopping criterion
    0096         if (rel_l1 < param.rel_obj)
    0097             crit_L1 = 'REL_OB'; break;
    0098         elseif iter_L1 >= param.max_iter
    0099             crit_L1 = 'MAX_IT'; break;
    0100         end
    0101
    0102         % Soft-thresholding
    0103         res = u_l1*param.nu + param.Psit(sol);
    0104         dummy = soft(res, lambda*param.nu*param.weights);
    0105         if param.pos
    0106             dummy = real(dummy); dummy(dummy<0) = 0;
    0107         end
    0108         u_l1 = 1/param.nu * (res - dummy);
    0109         sol = x - param.Psi(u_l1);
    0110
    0111         % Update
    0112         prev_l1 = norm_l1;
    0113         iter_L1 = iter_L1 + 1;
    0114
    0115     end
    0116 end
    0117
    0118 % Log after the projection onto the L2-ball
    0119 if param.verbose >= 1
    0120     fprintf(['  prox_L1: ||Psi x||_1 = %e,', ...
    0121         ' %s, iter = %i\n'], norm_l1, crit_L1, iter_L1);
    0122 end
    0123
    0124 end