BPDN_homotopy_function

PURPOSE ^

BPDN_homotopy_function.m

SYNOPSIS ^

function out = BPDN_homotopy_function(A, y, in)

DESCRIPTION ^

 BPDN_homotopy_function.m

 Solves the following basis pursuit denoising (BPDN) problem
 min_x  \tau ||x||_1 + 1/2*||y-Ax||_2^2

 Inputs:
 A - m x n measurement matrix
 y - measurement vector
 in - input parameters 
         tau - final value of regularization parameter
         maxiter - maximum number of homotopy iterations
         x_orig - original signal for error computation
         record - for recording history
         delx_mode - rank-one update using matrix inversion lemma (mil) or qr factorization (qr)
         Te - maximum number of non-zero elements allowed

 Outputs: 
   out
     x_out - output for BPDN
     gamma - support of the solution
     iter - number of homotopy iterations taken by the solver
     time - time taken by the solver

 Example usage: 
     in = [];
     in.tau = tau; % regularization parameter
     in.maxiter = maxiter; % maximum allowed iterations
     in.x_orig = x; % original signal for error computation
     in.record = 1; % to record history
     in.delx_mode = 'mil'; % rank-one update using matrix inversion lemma (mil) or qr factorization (qr)
     in.Te = Te; % maximum number of non-zero elements allowed
     out = BPDN_homotopy_function(A, y, in); % solve BPDN using matrix A and measurements y
     xh = out.x_out; % output solution
     gamma = out.gamma; % support of the solution
     iter = out.iter; % number of homotopy iterations used
     time = out.time; % computation time

 Written by: Salman Asif, Georgia Tech
 Email: sasif@gatech.edu

 Modified
 May 2012: Added qr update feature

-------------------------------------------+
 Copyright (c) 2007.  Muhammad Salman Asif
-------------------------------------------+

CROSS-REFERENCE INFORMATION ^

This function calls: This function is called by:

SOURCE CODE ^

0001 % BPDN_homotopy_function.m
0002 %
0003 % Solves the following basis pursuit denoising (BPDN) problem
0004 % min_x  \tau ||x||_1 + 1/2*||y-Ax||_2^2
0005 %
0006 % Inputs:
0007 % A - m x n measurement matrix
0008 % y - measurement vector
0009 % in - input parameters
0010 %         tau - final value of regularization parameter
0011 %         maxiter - maximum number of homotopy iterations
0012 %         x_orig - original signal for error computation
0013 %         record - for recording history
0014 %         delx_mode - rank-one update using matrix inversion lemma (mil) or qr factorization (qr)
0015 %         Te - maximum number of non-zero elements allowed
0016 %
0017 % Outputs:
0018 %   out
0019 %     x_out - output for BPDN
0020 %     gamma - support of the solution
0021 %     iter - number of homotopy iterations taken by the solver
0022 %     time - time taken by the solver
0023 %
0024 % Example usage:
0025 %     in = [];
0026 %     in.tau = tau; % regularization parameter
0027 %     in.maxiter = maxiter; % maximum allowed iterations
0028 %     in.x_orig = x; % original signal for error computation
0029 %     in.record = 1; % to record history
0030 %     in.delx_mode = 'mil'; % rank-one update using matrix inversion lemma (mil) or qr factorization (qr)
0031 %     in.Te = Te; % maximum number of non-zero elements allowed
0032 %     out = BPDN_homotopy_function(A, y, in); % solve BPDN using matrix A and measurements y
0033 %     xh = out.x_out; % output solution
0034 %     gamma = out.gamma; % support of the solution
0035 %     iter = out.iter; % number of homotopy iterations used
0036 %     time = out.time; % computation time
0037 %
0038 % Written by: Salman Asif, Georgia Tech
0039 % Email: sasif@gatech.edu
0040 %
0041 % Modified
0042 % May 2012: Added qr update feature
0043 %
0044 %-------------------------------------------+
0045 % Copyright (c) 2007.  Muhammad Salman Asif
0046 %-------------------------------------------+
0047 
0048 function out = BPDN_homotopy_function(A, y, in)
0049 
0050 % fprintf('Rewrite this function to add qrupdate \n');
0051 
0052 t0 = cputime;
0053 N = size(A,2);
0054 M = size(A,1);
0055 
0056 tau = in.tau;
0057 Te = inf;
0058 if isfield(in,'Te')
0059     Te = in.Te;
0060 end
0061 maxiter = 4*N;
0062 if isfield(in,'maxiter');
0063     maxiter = in.maxiter;
0064 end
0065 early_terminate = 0;
0066 if isfield(in,'early_terminate')
0067     early_terminate = in.early_terminate;
0068 end
0069 x_orig = in.x_orig;
0070 err_record = in.record;
0071 
0072 % Initialization of sign and support
0073 xk_1 = zeros(N,1);
0074 pk_old = -A'*y;
0075 [c idelta] = max(abs(pk_old));
0076 
0077 gamma_xh = idelta;
0078 temp_gamma = zeros(N,1);
0079 temp_gamma(gamma_xh) = gamma_xh;
0080 gamma_xc = find([1:N]' ~= temp_gamma);
0081 
0082 epsilon = c;
0083 z_x = zeros(N,1);
0084 z_x(gamma_xh) = -sign(pk_old(gamma_xh));
0085 pk_old(gamma_xh) = sign(pk_old(gamma_xh))*epsilon;
0086 
0087 % loop parameters
0088 done = 0;
0089 iter = 0;
0090 itr_history = [];
0091 error_table = [];
0092 obj = [];
0093 
0094 % initialize delx
0095 in_delx = [];
0096 delx_mode = in.delx_mode;
0097 update_mode = 'init0';
0098 rhs = z_x;
0099 update_delx;
0100 
0101 if err_record
0102     error_table = [epsilon norm(xk_1-x_orig)/norm(x_orig) 1];
0103     % obj = 1/2*norm(A*xk_1-y)^2+epsilon*norm(xk_1,1);
0104 end
0105 
0106 while iter < maxiter
0107     iter = iter+1;
0108     % warning('off','MATLAB:divideByZero')
0109     
0110     x_k = xk_1;
0111     
0112     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0113     %%%% update support of x %%%%
0114     %%%%%%%%%%%%%%%%%%%%%%%%%%%%%
0115     % update direction
0116     delx_vec = zeros(N,1);
0117     delx_vec(gamma_xh) = delx;
0118     
0119     if sign(delx_vec(idelta)) == sign(pk_old(idelta)) && iter > 1
0120         delta = 0; flag = 0;
0121     else
0122         pk = pk_old;
0123         % dk = A'*(A(:,gamma_xh)*delx);
0124         dk = A'*(A*delx_vec);
0125         
0126         %%%--- compute step size
0127         in = [];
0128         
0129         % Setting shrinkage_flag to zero shrinks new active constraint towards the
0130         % final value instantly if doing so doesn't disturb the active set
0131         in.delta_flag = 2;
0132         in.pk = pk; in.dk = dk;
0133         in.ak = epsilon; in.bk = -1;
0134         in.gamma = gamma_xh; in.gamma_c = gamma_xc;
0135         in.delx_vec = delx_vec; in.x = xk_1;
0136         out = compute_delta(in);
0137         delta = out.delta; idelta = out.idelta;
0138         flag = out.flag;
0139     end
0140     
0141     xk_1 = x_k+delta*delx_vec;
0142     pk_old = pk+delta*dk;
0143     epsilon_old = epsilon;
0144     epsilon = epsilon-delta;
0145     
0146     if epsilon <= tau;
0147         xk_1 = x_k + (epsilon_old-tau)*delx_vec;
0148         total_time= cputime-t0;
0149         break;
0150     end
0151     if length(gamma_xh) >= Te
0152         total_time = cputime-t0;
0153         break;
0154     end
0155     
0156     % disp(sprintf(['iter = %d, delta = %3.4g, idelta = %d, flag = %d'], iter, delta, idelta, flag));
0157     itr_history = [itr_history; idelta delta flag];
0158     
0159     %% Check convergence criterion
0160     if early_terminate
0161         if length(gamma_x) < M/2
0162             xhat = zeros(N,1);
0163             rhs = A(:,gamma_xh)'*y;
0164             update_mode = 'recompute';
0165             delx_update;
0166             xhat(gamma_x) = out;
0167             if norm(y-A*xhat) < tau
0168                 xk_1 = xhat;
0169                 break;
0170             end
0171         end
0172     end
0173     
0174     % update support
0175     update_supp;
0176     
0177     pk_old([gamma_xh; idelta]) = sign(pk_old([gamma_xh; idelta]))*epsilon;
0178     
0179     % update delx
0180     z_x = -sign(pk_old);
0181     rhs = z_x;
0182     update_mode = 'update';
0183     update_delx;
0184     
0185     
0186     constr_violation = nnz((abs(pk_old(gamma_xc))-epsilon)>1e-10);
0187     sign_violation = nnz((sign(pk_old(gamma_xh))+sign(xk_1(gamma_xh)))>1);
0188     if constr_violation
0189         chk = gamma_xc((abs(pk_old(gamma_xc))-epsilon)>1e-10);
0190         stp = 1;
0191         fprintf('problem... with constraint violation -- %s \n', mfilename);
0192         fprintf('Refactorize the matrix... recompute delx \n');
0193         % some times it comes here due to bad conditioning of AtAgx.
0194         update_mode = 'init0';
0195         update_delx;
0196     end
0197     if sign_violation>=1
0198         chk = gamma_xh(sign(pk_old(gamma_xh))+sign(xk_1(gamma_xh))>1);
0199         stp = 1;
0200         fprintf('problem... sign mismatch -- %s \n',mfilename);
0201         fprintf('Refactorize the matrix... recompute delx \n');
0202         update_mode = 'init0';
0203         update_delx;
0204     end
0205     
0206     if err_record
0207         error_table = [error_table; epsilon norm(xk_1-x_orig)/norm(x_orig) length(gamma_xh)];
0208         % obj = [obj; 1/2*norm(A*xk_1-y)^2+epsilon*norm(xk_1,1)];
0209     end
0210 end
0211 if err_record
0212     error_table = [error_table; epsilon norm(xk_1-x_orig)/norm(x_orig) length(gamma_xh)];
0213     % obj = [obj; 1/2*norm(A*xk_1-y)^2+epsilon*norm(xk_1,1)];
0214 end
0215 total_iter = iter;
0216 total_time = cputime-t0;
0217 
0218 out = [];
0219 out.x_out = xk_1;
0220 out.gamma = gamma_xh;
0221 out.iter = total_iter;
0222 out.time = total_time;
0223 out.error_table = error_table;
0224 % out.obj = obj;

Generated on Mon 10-Jun-2013 23:03:23 by m2html © 2005