Description of sopt_mltb_fast_proj_B2
Description: sopt_mltb_fast_proj_B2 - Fast projection onto L2-ball

Home > matlab > prox_operators > sopt_mltb_fast_proj_B2.m

# sopt_mltb_fast_proj_B2

## PURPOSE

sopt_mltb_fast_proj_B2 - Fast projection onto L2-ball

## SYNOPSIS

function [sol, u] = sopt_mltb_fast_proj_B2(x, param)

## DESCRIPTION

     sopt_mltb_fast_proj_B2 - Fast 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).

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

       - real: Reality flag (1 = real solution,
           0 = general complex case; 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.
     [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, u] = sopt_mltb_fast_proj_B2(x, param)
    0002 % sopt_mltb_fast_proj_B2 - Fast 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 %   - pos: Positivity flag (1 = positive solution,
    0038 %       0 general complex case; default = 0).
    0039 %
    0040 %   - real: Reality flag (1 = real solution,
    0041 %       0 = general complex case; default = 0).
    0042 %
    0043 % Outputs:
    0044 %
    0045 %   - sol: Final solution.
    0046 %
    0047 %   - u: Final dual vector.
    0048 %
    0049 % References:
    0050 % [1] M.J. Fadili and J-L. Starck, "Monotone operator splitting for
    0051 % optimization problems in sparse recovery" , IEEE ICIP, Cairo,
    0052 % Egypt, 2009.
    0053 % [2] Amir Beck and Marc Teboulle, "A Fast Iterative Shrinkage-Thresholding
    0054 % Algorithm for Linear Inverse Problems",  SIAM Journal on Imaging Sciences
    0055 % 2 (2009), no. 1, 183--202.
    0056
    0057 % Optional input arguments
    0058 if ~isfield(param, 'y'), param.y = 0; end
    0059 if ~isfield(param, 'A'), param.A = @(x) x; end
    0060 if ~isfield(param, 'At'), param.At = @(x) x; end
    0061 if ~isfield(param, 'epsilon'), param.epsilon = 1e-3; end
    0062 if ~isfield(param, 'tight'), param.tight = 1; end
    0063 if ~isfield(param, 'tol'), param.tol = 1e-3; end
    0064 if ~isfield(param, 'verbose'), param.verbose = 1; end
    0065 if ~isfield(param, 'nu'), param.nu = 1; end
    0066 if ~isfield(param, 'max_iter'), param.max_iter = 200; end
    0067 if ~isfield(param, 'u'), param.u = zeros(size(param.y)); end
    0068 if ~isfield(param, 'pos'), param.pos = 0; end
    0069 if ~isfield(param, 'real'), param.real = 0; end
    0070
    0071 % Useful functions for the projection
    0072 sc = @(z) z*min(param.epsilon/norm(z(:)), 1); % scaling
    0073
    0074 % Projection
    0075 if (param.tight && ~(param.pos||param.real)) % TIGHT FRAME CASE
    0076
    0077     temp = param.A(x) - param.y;
    0078     sol = x + 1/param.nu * param.At(sc(temp)-temp);
    0079     crit_B2 = 'TOL_EPS'; iter = 0;
    0080     u = 0;
    0081
    0082 else % NON TIGHT FRAME CASE
    0083
    0084     % Initializations
    0085     sol = x; u = param.u; v = u;
    0086     iter = 1; true = 1; told = 1;
    0087
    0088     % Tolerance onto the L2 ball
    0089     epsilon_low = param.epsilon/(1+param.tol);
    0090     epsilon_up = param.epsilon/(1-param.tol);
    0091
    0092     % Check if we are in the L2 ball
    0093     dummy = param.A(sol);
    0094     norm_res = norm(param.y(:)-dummy(:), 2);
    0095     if norm_res <= epsilon_up
    0096         crit_B2 = 'TOL_EPS'; true = 0;
    0097     end
    0098
    0099     % Projection onto the L2-ball
    0100     % Init
    0101     if param.verbose > 1
    0102         fprintf('  Proj. B2:\n');
    0103     end
    0104     while true
    0105
    0106         % Residual
    0107         res = param.A(sol) - param.y; norm_res = norm(res(:), 2);
    0108
    0109         % Scaling for the projection
    0110         res = u*param.nu + res; norm_proj = norm(res(:), 2);
    0111
    0112         % Log
    0113         if param.verbose>1
    0114             fprintf('   Iter %i, epsilon = %e, ||y - Ax||_2 = %e\n', ...
    0115                 iter, param.epsilon, norm_res);
    0116         end
    0117
    0118         % Stopping criterion
    0119         if (norm_res>=epsilon_low && norm_res<=epsilon_up)
    0120             crit_B2 = 'TOL_EPS'; break;
    0121         elseif iter >= param.max_iter
    0122             crit_B2 = 'MAX_IT'; break;
    0123         end
    0124
    0125         % Projection onto the L2 ball
    0126         t = (1+sqrt(1+4*told^2))/2;
    0127         ratio = min(1, param.epsilon/norm_proj);
    0128         u = v;
    0129         v = 1/param.nu * (res - res*ratio);
    0130         u = v + (told-1)/t * (v - u);
    0131
    0132         % Current estimate
    0133         sol = x - param.At(u);
    0134
    0135         % Projection onto the non-negative orthant (positivity constraint)
    0136         if (param.pos)
    0137             sol = real(sol);
    0138             sol(sol<0) = 0;
    0139
    0140         end
    0141
    0142         % Projection onto the real orthant (reality constraint)
    0143         if (param.real)
    0144             sol = real(sol);
    0145         end
    0146
    0147         % Update number of iteration
    0148         told = t;
    0149
    0150         % Update number of iterations
    0151         iter = iter + 1;
    0152
    0153     end
    0154 end
    0155
    0156 % Log after the projection onto the L2-ball
    0157 if param.verbose >= 1
    0158     temp = param.A(sol);
    0159     fprintf(['  Proj. B2: epsilon = %e, ||y-Ax||_2 = %e,', ...
    0160         ' %s, iter = %i\n'], param.epsilon, norm(param.y(:)-temp(:)), ...
    0161         crit_B2, iter);
    0162 end
    0163
    0164
    0165 end