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.
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