sopt_mltb_proj_B2 - Projection onto L2-ball Compute the projection onto the L2 ball, i.e. solve min_{z} ||x - z||_2^2 s.t. ||y - A z||_2 < epsilon where x is the input vector and the solution z* is returned as sol. The structure param should contain the following fields: - y: Measurements (default = 0). - A: Forward operator (default = Identity). - At: Adjoint operator (default = Identity). - epsilon: Radius of the L2 ball (default = 1e-3). - tight: 1 if A is a tight frame or 0 otherwise (default = 1). - nu: Bound on the norm^2 of the operator A, i.e. ||A x||^2 <= nu * ||x||^2 (default = 1). - tol: Tolerance for the projection onto the L2 ball. The algorithms stops if epsilon/(1-tol) <= ||y - A z||_2 <= epsilon/(1+tol) (default = 1e-3). - max_iter: Maximum number of iterations (default: 200). - verbose: Verbosity level (0 = no log, 1 = summary at convergence, 2 = print main steps; default = 1). - u: Initial vector for the dual problem, same dimension as y (default = 0). Outputs: - sol: Final solution. - u: Final dual vector. References: [1] M.J. Fadili and J-L. Starck, "Monotone operator splitting for optimization problems in sparse recovery" , IEEE ICIP, Cairo, Egypt, 2009.
0001 function [sol, u] = sopt_mltb_proj_B2(x, param) 0002 % sopt_mltb_proj_B2 - Projection onto L2-ball 0003 % 0004 % Compute the projection onto the L2 ball, i.e. solve 0005 % 0006 % min_{z} ||x - z||_2^2 s.t. ||y - A z||_2 < epsilon 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 % - y: Measurements (default = 0). 0012 % 0013 % - A: Forward operator (default = Identity). 0014 % 0015 % - At: Adjoint operator (default = Identity). 0016 % 0017 % - epsilon: Radius of the L2 ball (default = 1e-3). 0018 % 0019 % - tight: 1 if A is a tight frame or 0 otherwise (default = 1). 0020 % 0021 % - nu: Bound on the norm^2 of the operator A, i.e. 0022 % ||A x||^2 <= nu * ||x||^2 (default = 1). 0023 % 0024 % - tol: Tolerance for the projection onto the L2 ball. The algorithms 0025 % stops if 0026 % epsilon/(1-tol) <= ||y - A z||_2 <= epsilon/(1+tol) 0027 % (default = 1e-3). 0028 % 0029 % - max_iter: Maximum number of iterations (default: 200). 0030 % 0031 % - verbose: Verbosity level (0 = no log, 1 = summary at convergence, 0032 % 2 = print main steps; default = 1). 0033 % 0034 % - u: Initial vector for the dual problem, same dimension as y 0035 % (default = 0). 0036 % 0037 % Outputs: 0038 % 0039 % - sol: Final solution. 0040 % 0041 % - u: Final dual vector. 0042 % 0043 % References: 0044 % [1] M.J. Fadili and J-L. Starck, "Monotone operator splitting for 0045 % optimization problems in sparse recovery" , IEEE ICIP, Cairo, 0046 % Egypt, 2009. 0047 0048 % Optional input arguments 0049 if ~isfield(param, 'y'), param.y = 0; end 0050 if ~isfield(param, 'A'), param.A = @(x) x; end 0051 if ~isfield(param, 'At'), param.At = @(x) x; end 0052 if ~isfield(param, 'epsilon'), param.epsilon = 1e-3; end 0053 if ~isfield(param, 'tight'), param.tight = 1; end 0054 if ~isfield(param, 'tol'), param.tol = 1e-3; end 0055 if ~isfield(param, 'verbose'), param.verbose = 1; end 0056 if ~isfield(param, 'nu'), param.nu = 1; end 0057 if ~isfield(param, 'max_iter'), param.max_iter = 200; end 0058 if ~isfield(param, 'u'), param.u = zeros(size(param.y)); end 0059 0060 % Useful functions for the projection 0061 sc = @(z) z*min(param.epsilon/norm(z(:)), 1); % scaling 0062 0063 % Projection 0064 if param.tight % TIGHT FRAME CASE 0065 0066 temp = param.A(x) - param.y; 0067 sol = x + 1/param.nu * param.At(sc(temp)-temp); 0068 crit_B2 = 'TOL_EPS'; iter = 0; u = NaN; 0069 0070 else % NON TIGHT FRAME CASE 0071 0072 % Initializations 0073 sol = x; u = param.u; 0074 iter = 1; true = 1; 0075 0076 % Tolerance onto the L2 ball 0077 epsilon_low = param.epsilon/(1+param.tol); 0078 epsilon_up = param.epsilon/(1-param.tol); 0079 0080 % Check if we are in the L2 ball 0081 norm_res = norm(param.y(:)-param.A(sol), 2); 0082 if norm_res <= epsilon_up 0083 crit_B2 = 'TOL_EPS'; true = 0; 0084 end 0085 0086 % Projection onto the L2-ball 0087 % Init 0088 if param.verbose > 1 0089 fprintf(' Proj. B2:\n'); 0090 end 0091 while true 0092 0093 % Residual 0094 res = param.A(sol) - param.y; norm_res = norm(res(:), 2); 0095 0096 % Scaling for the projection 0097 res = u*param.nu + res; norm_proj = norm(res(:), 2); 0098 0099 % Log 0100 if param.verbose>1 0101 fprintf(' Iter %i, epsilon = %e, ||y - Ax||_2 = %e\n', ... 0102 iter, param.epsilon, norm_res); 0103 end 0104 0105 % Stopping criterion 0106 if (norm_res>=epsilon_low && norm_res<=epsilon_up) 0107 crit_B2 = 'TOL_EPS'; break; 0108 elseif iter >= param.max_iter 0109 crit_B2 = 'MAX_IT'; break; 0110 end 0111 0112 % Projection onto the L2 ball 0113 ratio = min(1, param.epsilon/norm_proj); 0114 u = 1/param.nu * (res - res*ratio); 0115 0116 % Current estimate 0117 sol = x - param.At(u); 0118 0119 % Update number of iteration 0120 iter = iter + 1; 0121 0122 end 0123 end 0124 0125 % Log after the projection onto the L2-ball 0126 if param.verbose >= 1 0127 temp = param.A(sol); 0128 fprintf([' Proj. B2: epsilon = %e, ||y-Ax||_2 = %e,', ... 0129 ' %s, iter = %i\n'], param.epsilon, norm(param.y(:)-temp(:)), ... 0130 crit_B2, iter); 0131 end 0132 0133 end