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

Generated on Fri 22-Feb-2013 15:54:47 by m2html © 2005