Description of sopt_mltb_solve_BPDN
Description: sopt_mltb_solve_BPDN - Solve BPDN problem

Home > matlab > sopt_mltb_solve_BPDN.m

# sopt_mltb_solve_BPDN

## PURPOSE

sopt_mltb_solve_BPDN - Solve BPDN problem

## SYNOPSIS

function sol = sopt_mltb_solve_BPDN(y, epsilon, A, At, Psi, Psit, param)

## DESCRIPTION

     sopt_mltb_solve_BPDN - Solve BPDN problem

     Solve the Basis Pursuit Denoising (BPDN) problem

       min ||Psit x||_1   s.t.  ||y-A x||_2 < epsilon

     where y contains the measurements, A is the forward measurement operator
     and At the associated adjoint operator, Psit is a sparfying transform and
     Psi its adjoint. The structure param should contain the following fields:

       General parameters:

       - verbose: Verbosity level (0 = no log, 1 = summary at convergence,
           2 = print main steps; 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.

       - gamma: Convergence speed (weighting of L1 norm when solving for
           L1 proximal operator) (default = 1e-1).

       - initsol: Initial solution for a warmstart.

       Projection onto the L2-ball:

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

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

       - tol_B2: 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_B2: Maximum number of iterations for the projection onto the
           L2 ball (default = 200).

       - pos_B2: Positivity flag (1 to impose positivity, 0 otherwise;
           default = 0).

       - real_B2: Reality flag (1 to impose reality, 0 otherwise;
           default = 0).

       Proximal L1 operator:

       - rel_obj_L1: Used as stopping criterion for the proximal L1
           operator. Minimum relative change of the objective value between
           two successive estimates.

       - max_iter_L1: Used as stopping criterion for the proximal L1
           operator. Maximun number of iterations.

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

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

       - param.weights: Weights for a weighted L1-norm defined
           by sum_i{weights_i.*abs(x_i)} (default = 1).

       - pos_l1: Positivity flag (1 to impose positivity, 0 otherwise;
           default = 0).

     References:
     [1] P. L. Combettes and J-C. Pesquet, "A Douglas-Rachford Splitting
     Approach to Nonsmooth Convex Variational Signal Recovery", IEEE Journal
     of Selected Topics in Signal Processing, vol. 1, no. 4, pp. 564-574, 2007.

## CROSS-REFERENCE INFORMATION

This function calls:

This function is called by:

- Example_BPDN % Example_BPDN
- Example_weighted_BPDN % Exampled_weighted_L1
- Experiment1 % Experiment1
- Experiment2 % Experiment2
- Experiment3 % Experiement3
- sopt_mltb_solve_rwBPDN sopt_mltb_solve_rwBPDN - Solve reweighted BPDN problem

## SOURCE CODE

    0001 function sol = sopt_mltb_solve_BPDN(y, epsilon, A, At, Psi, Psit, param)
    0002 % sopt_mltb_solve_BPDN - Solve BPDN problem
    0003 %
    0004 % Solve the Basis Pursuit Denoising (BPDN) problem
    0005 %
    0006 %   min ||Psit x||_1   s.t.  ||y-A x||_2 < epsilon
    0007 %
    0008 % where y contains the measurements, A is the forward measurement operator
    0009 % and At the associated adjoint operator, Psit is a sparfying transform and
    0010 % Psi its adjoint. The structure param should contain the following fields:
    0011 %
    0012 %   General parameters:
    0013 %
    0014 %   - verbose: Verbosity level (0 = no log, 1 = summary at convergence,
    0015 %       2 = print main steps; default = 1).
    0016 %
    0017 %   - max_iter: Maximum number of iterations (default = 200).
    0018 %
    0019 %   - rel_obj: Minimum relative change of the objective value
    0020 %       (default = 1e-4).  The algorithm stops if
    0021 %           | ||x(t)||_1 - ||x(t-1)||_1 | / ||x(t)||_1 < rel_obj,
    0022 %       where x(t) is the estimate of the solution at iteration t.
    0023 %
    0024 %   - gamma: Convergence speed (weighting of L1 norm when solving for
    0025 %       L1 proximal operator) (default = 1e-1).
    0026 %
    0027 %   - initsol: Initial solution for a warmstart.
    0028 %
    0029 %   Projection onto the L2-ball:
    0030 %
    0031 %   - param.tight_B2: 1 if A is a tight frame or 0 otherwise (default = 1).
    0032 %
    0033 %   - nu_B2: Bound on the norm of the operator A, i.e.
    0034 %       ||A x||^2 <= nu * ||x||^2 (default = 1).
    0035 %
    0036 %   - tol_B2: Tolerance for the projection onto the L2 ball. The algorithms
    0037 %       stops if
    0038 %         epsilon/(1-tol) <= ||y - A z||_2 <= epsilon/(1+tol)
    0039 %       (default = 1e-3).
    0040 %
    0041 %   - max_iter_B2: Maximum number of iterations for the projection onto the
    0042 %       L2 ball (default = 200).
    0043 %
    0044 %   - pos_B2: Positivity flag (1 to impose positivity, 0 otherwise;
    0045 %       default = 0).
    0046 %
    0047 %   - real_B2: Reality flag (1 to impose reality, 0 otherwise;
    0048 %       default = 0).
    0049 %
    0050 %   Proximal L1 operator:
    0051 %
    0052 %   - rel_obj_L1: Used as stopping criterion for the proximal L1
    0053 %       operator. Minimum relative change of the objective value between
    0054 %       two successive estimates.
    0055 %
    0056 %   - max_iter_L1: Used as stopping criterion for the proximal L1
    0057 %       operator. Maximun number of iterations.
    0058 %
    0059 %   - param.nu_L1: Bound on the norm^2 of the operator Psi, i.e.
    0060 %       ||Psi x||^2 <= nu * ||x||^2 (default = 1).
    0061 %
    0062 %   - param.tight_L1: 1 if Psit is a tight frame, 0 otherwise
    0063 %       (default = 1).
    0064 %
    0065 %   - param.weights: Weights for a weighted L1-norm defined
    0066 %       by sum_i{weights_i.*abs(x_i)} (default = 1).
    0067 %
    0068 %   - pos_l1: Positivity flag (1 to impose positivity, 0 otherwise;
    0069 %       default = 0).
    0070 %
    0071 % References:
    0072 % [1] P. L. Combettes and J-C. Pesquet, "A Douglas-Rachford Splitting
    0073 % Approach to Nonsmooth Convex Variational Signal Recovery", IEEE Journal
    0074 % of Selected Topics in Signal Processing, vol. 1, no. 4, pp. 564-574, 2007.
    0075
    0076 % Optional input arguments
    0077 if ~isfield(param, 'verbose'), param.verbose = 1; end
    0078 if ~isfield(param, 'rel_obj'), param.rel_obj = 1e-4; end
    0079 if ~isfield(param, 'max_iter'), param.max_iter = 200; end
    0080 if ~isfield(param, 'gamma'), param.gamma = 1e-2; end
    0081 if ~isfield(param, 'pos_l1'), param.pos_l1 = 0; end
    0082
    0083 % Input arguments for projection onto the L2 ball
    0084 param_B2.A = A; param_B2.At = At;
    0085 param_B2.y = y; param_B2.epsilon = epsilon;
    0086 param_B2.verbose = param.verbose;
    0087 if isfield(param, 'nu_B2'), param_B2.nu = param.nu_B2; end
    0088 if isfield(param, 'tol_B2'), param_B2.tol = param.tol_B2; end
    0089 if isfield(param, 'tight_B2'), param_B2.tight = param.tight_B2; end
    0090 if isfield(param, 'max_iter_B2')
    0091     param_B2.max_iter = param.max_iter_B2;
    0092 end
    0093 if isfield(param,'pos_B2'), param_B2.pos=param.pos_B2; end
    0094 if isfield(param,'real_B2'), param_B2.real=param.real_B2; end
    0095
    0096 % Input arguments for prox L1
    0097 param_L1.Psi = Psi; param_L1.Psit = Psit; param_L1.pos = param.pos_l1;
    0098 param_L1.verbose = param.verbose;
    0099 %param_L1.verbose = 2;
    0100 param_L1.rel_obj = param.rel_obj;
    0101 if isfield(param, 'nu_L1')
    0102     param_L1.nu = param.nu_L1;
    0103 end
    0104 if isfield(param, 'tight_L1')
    0105     param_L1.tight = param.tight_L1;
    0106 end
    0107 if isfield(param, 'max_iter_L1')
    0108     param_L1.max_iter = param.max_iter_L1;
    0109 end
    0110 if isfield(param, 'rel_obj_L1')
    0111     param_L1.rel_obj = param.rel_obj_L1;
    0112 end
    0113 if isfield(param, 'weights')
    0114     param_L1.weights = param.weights;
    0115 else
    0116     param_L1.weights = 1;
    0117 end
    0118
    0119 % Initialization
    0120 if isfield(param,'initsol')
    0121     xhat = param.initsol;
    0122 else
    0123     xhat = At(y);
    0124 end
    0125
    0126 iter = 1; prev_norm = 0;
    0127
    0128 % Main loop
    0129 while 1
    0130
    0131     if param.verbose >= 1
    0132         fprintf('Iteration %i:\n', iter);
    0133     end
    0134
    0135     % Projection onto the L2-ball
    0136     [sol, param_B2.u] = sopt_mltb_fast_proj_B2(xhat, param_B2);
    0137
    0138     % Global stopping criterion
    0139     dummy = Psit(sol);
    0140     curr_norm = sum(param_L1.weights(:).*abs(dummy(:)));
    0141     rel_norm = abs(curr_norm - prev_norm)/curr_norm;
    0142     if param.verbose >= 1
    0143         fprintf('  ||x||_1 = %e, rel_norm = %e\n', ...
    0144             curr_norm, rel_norm);
    0145     end
    0146     if (rel_norm < param.rel_obj)
    0147         crit_BPDN = 'REL_NORM';
    0148         break;
    0149     elseif iter >= param.max_iter
    0150         crit_BPDN = 'MAX_IT';
    0151         break;
    0152     end
    0153
    0154     % Proximal L1 operator
    0155     xhat = 2*sol - xhat;
    0156     temp = sopt_mltb_prox_L1(xhat, param.gamma, param_L1);
    0157     xhat = temp + sol - xhat;
    0158
    0159     % Update variables
    0160     iter = iter + 1;
    0161     prev_norm = curr_norm;
    0162
    0163 end
    0164
    0165 % Log
    0166 if param.verbose >= 1
    0167
    0168     % L1 norm
    0169     fprintf('\n Solution found:\n');
    0170     fprintf(' Final L1 norm: %e\n', curr_norm);
    0171
    0172     % Residual
    0173     dummy = A(sol); res = norm(y(:)-dummy(:), 2);
    0174     fprintf(' epsilon = %e, ||y-Ax||_2=%e\n', epsilon, res);
    0175
    0176     % Stopping criterion
    0177     fprintf(' %i iterations\n', iter);
    0178     fprintf(' Stopping criterion: %s \n\n', crit_BPDN);
    0179
    0180 end
    0181
    0182 end