⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gpsr_basic.m

📁 这是一个压缩传感方面的Gradient Projection for Sparse Reconstruction 工具包。
💻 M
📖 第 1 页 / 共 2 页
字号:
if continuation&(cont_steps > 1)   % If tau is scalar, first check top see if the first factor is    % too large (i.e., large enough to make the first    % solution all zeros). If so, make it a little smaller than that.   % Also set to that value as default   if prod(size(tau)) == 1      if (firstTauFactorGiven == 0)|(firstTauFactor*tau >= max_tau)         firstTauFactor = 0.8*max_tau / tau;         fprintf(1,'parameter FirstTauFactor too large; changing')      end   end   cont_factors = 10.^[log10(firstTauFactor):...                    log10(1/firstTauFactor)/(cont_steps-1):0];else  cont_factors = 1;  cont_steps = 1;end  iter = 1;if compute_mse   mses(iter) = sum((x(:)-true(:)).^2);end% loop for continuationfor cont_loop = 1:cont_steps    tau = final_tau * cont_factors(cont_loop);        if verbose        fprintf(1,'\nSetting tau = %8.4f\n',tau)    end        if cont_loop == cont_steps       stopCriterion = final_stopCriterion;       tolA = final_tolA;    else        stopCriterion = 3;       tolA = 1e-3;    end        % Compute and store initial value of the objective function    resid =  y - A(x);    f = 0.5*(resid(:)'*resid(:)) + ...             sum(tau(:).*u(:)) + sum(tau(:).*v(:));    objective(iter) = f;    times(iter) = cputime - t0;        % Compute the useful quantity resid_base    resid_base = y - resid;    % control variable for the outer loop and iteration counter    % cont_outer = (norm(projected_gradient) > 1.e-5) ;    keep_going = 1;    if verbose       fprintf(1,'\nInitial obj=%10.6e, nonzeros=%7d\n', f,num_nz_x);    end    while keep_going      x_previous = x;      % compute gradient      temp = AT(resid_base);      term  =  temp - Aty;      gradu =  term + tau;      gradv = -term + tau;      % set search direction      %du = -gradu; dv = -gradv; dx = du-dv;       dx = gradv-gradu;      old_u = u; old_v = v;      % calculate useful matrix-vector product involving dx      auv = A(dx);      dGd = auv(:)'*auv(:);      % calculate unconstrained minimizer along this direction, use this      % as the first guess of steplength parameter lambda      %  lambda0 = - (gradu(:)'*du(:) + gradv(:)'*dv(:)) / dGd;      % use instead a first guess based on the "conditional" direction      condgradu = ((old_u>0) | (gradu<0)) .* gradu;      condgradv = ((old_v>0) | (gradv<0)) .* gradv;      auv_cond = A(condgradu-condgradv);      dGd_cond = auv_cond(:)'*auv_cond(:);      lambda0 = (gradu(:)'*condgradu(:) + gradv(:)'*condgradv(:)) /...                (dGd_cond + realmin);      % loop to determine steplength, starting wit the initial guess above.      lambda = lambda0;       while 1        % calculate step for this lambda and candidate point        du = max(u-lambda*gradu,0.0) - u;         u_new = u + du;        dv = max(v-lambda*gradv,0.0) - v;         v_new = v + dv;        dx = du-dv;         x_new = x + dx;        % evaluate function at the candidate point        resid_base = A(x_new);        resid = y - resid_base;        f_new = 0.5*(resid(:)'*resid(:)) +  ...        sum(tau(:).*u_new(:)) + sum(tau(:).*v_new(:));            % test sufficient decrease condition        if f_new <= f + mu * (gradu'*du + gradv'*dv)          %disp('OK')            break        end        lambda = lambda * lambda_backtrack;        fprintf(1,'    reducing lambda to %6.2e\n', lambda)      end      u = u_new;       v = v_new;       prev_f = f;       f = f_new;      uvmin = min(u,v);       u = u - uvmin;       v = v - uvmin;       x = u-v;      % calculate nonzero pattern and number of nonzeros (do this *always*)      nz_x_prev = nz_x;      nz_x = (x~=0.0);      num_nz_x = sum(nz_x(:));            iter = iter + 1;      objective(iter) = f;      times(iter) = cputime-t0;      lambdas(iter) = lambda;      if compute_mse        err = true - x;        mses(iter) = (err(:)'*err(:));      end            % print out stuff      if verbose	fprintf(1,'It =%4d, obj=%9.5e, lambda=%6.2e, nz=%8d   ',...	    iter, f, lambda, num_nz_x);      end          switch stopCriterion	case 0,      % compute the stopping criterion based on the change       % of the number of non-zero components of the estimate      num_changes_active = (sum(nz_x(:)~=nz_x_prev(:)));      if num_nz_x >= 1         criterionActiveSet = num_changes_active;      else         criterionActiveSet = tolA / 2;      end      keep_going = (criterionActiveSet > tolA);      if verbose         fprintf(1,'Delta n-zeros = %d (target = %e)\n',...                criterionActiveSet , tolA)       end	case 1,      % compute the stopping criterion based on the relative      % variation of the objective function.	  criterionObjective = abs(f-prev_f)/(prev_f);      keep_going =  (criterionObjective > tolA);      if verbose         fprintf(1,'Delta obj. = %e (target = %e)\n',...                criterionObjective , tolA)       end	case 2,       % stopping criterion based on relative norm of step taken      delta_x_criterion = norm(dx(:))/norm(x(:));      keep_going = (delta_x_criterion > tolA);      if verbose         fprintf(1,'Norm(delta x)/norm(x) = %e (target = %e)\n',...             delta_x_criterion,tolA)       end	case 3,       % compute the "LCP" stopping criterion - again based on the previous       % iterate. Make it "relative" to the norm of x.        w = [ min(gradu(:), old_u(:)); min(gradv(:), old_v(:)) ];        criterionLCP = norm(w(:), inf);        criterionLCP = criterionLCP / ...                 max([1.0e-6, norm(old_u(:),inf), norm(old_v(:),inf)]);       keep_going = (criterionLCP > tolA);       if verbose         fprintf(1,'LCP = %e (target = %e)\n',criterionLCP,tolA)        end    case 4,      % continue if not yeat reached target value tolA      keep_going = (f > tolA);      if verbose         fprintf(1,'Objective = %e (target = %e)\n',f,tolA)       end	otherwise,	  error(['Unknwon stopping criterion']);    end % end of the stopping criteria switch        % take no less than miniter...     if iter<=miniter       keep_going = 1;    else %and no more than maxiter iterations          if iter > maxiter            keep_going = 0;        end    end    end % end of the main loop of the GP algorithmend % end of the continuation loop% Print resultsif verbose  fprintf(1,'\nFinished the main algorithm!\nResults:\n')  fprintf(1,'||A x - y ||_2^2 = %10.3e\n',resid(:)'*resid(:))  fprintf(1,'||x||_1 = %10.3e\n',sum(abs(x(:))))  fprintf(1,'Objective function = %10.3e\n',f);  nz_x = (x~=0.0); num_nz_x = sum(nz_x(:));  fprintf(1,'Number of non-zero components = %d\n',num_nz_x);  fprintf(1,'CPU time so far = %10.3e\n', times(iter));  fprintf(1,'\n');end% If the 'Debias' option is set to 1, we try to remove the bias from the l1% penalty, by applying CG to the least-squares problem obtained by omitting% the l1 term and fixing the zero coefficients at zero.% do this only if the reduced linear least-squares problem is% overdetermined, otherwise we are certainly applying CG to a problem with a% singular Hessianif debias    if (num_nz_x > length(y(:)))    if verbose      fprintf(1,'\n')      fprintf(1,'Debiasing requested, but not performed\n');      fprintf(1,'There are too many nonzeros in x\n\n');      fprintf(1,'nonzeros in x: %8d, length of y: %8d\n',...	  num_nz_x, length(y(:)));    end  elseif (num_nz_x==0)    if verbose      fprintf(1,'\n')      fprintf(1,'Debiasing requested, but not performed\n');      fprintf(1,'x has no nonzeros\n\n');    end  else    if verbose      fprintf(1,'\n')      fprintf(1,'Starting the debiasing phase...\n\n')    end        x_debias = x;    zeroind = (x_debias~=0);     cont_debias_cg = 1;    debias_start = iter;        % calculate initial residual    resid = A(x_debias);    resid = resid-y;    resid_prev = eps*ones(size(resid));        rvec = AT(resid);        % mask out the zeros    rvec = rvec .* zeroind;    rTr_cg = rvec(:)'*rvec(:);        % set convergence threshold for the residual || RW x_debias - y ||_2    tol_debias = tolD * (rvec(:)'*rvec(:));        % initialize pvec    pvec = -rvec;        % main loop    while cont_debias_cg            % calculate A*p = Wt * Rt * R * W * pvec      RWpvec = A(pvec);            Apvec = AT(RWpvec);            % mask out the zero terms      Apvec = Apvec .* zeroind;            % calculate alpha for CG      alpha_cg = rTr_cg / (pvec(:)'* Apvec(:));            % take the step      x_debias = x_debias + alpha_cg * pvec;      resid = resid + alpha_cg * RWpvec;      rvec  = rvec  + alpha_cg * Apvec;            rTr_cg_plus = rvec(:)'*rvec(:);      beta_cg = rTr_cg_plus / rTr_cg;      pvec = -rvec + beta_cg * pvec;            rTr_cg = rTr_cg_plus;            iter = iter+1;            objective(iter) = 0.5*(resid(:)'*resid(:)) + ...	  sum(tau(:).*abs(x_debias(:)));      times(iter) = cputime - t0;            if compute_mse	err = true - x_debias;	mses(iter) = (err(:)'*err(:));      end            if verbose	% in the debiasing CG phase, always use convergence criterion	% based on the residual (this is standard for CG)	fprintf(1,' Iter = %5d, debias resid = %13.8e, convergence = %8.3e\n', ...	    iter, resid(:)'*resid(:), rTr_cg / tol_debias);      end            cont_debias_cg = (iter-debias_start <= miniter_debias )|...	  ((rTr_cg > tol_debias) & ...	  (iter-debias_start <= maxiter_debias));          end        if verbose      fprintf(1,'\nFinished the debiasing phase!\nResults:\n')      fprintf(1,'||A x - y ||^2_2 = %10.3e\n',resid(:)'*resid(:))      fprintf(1,'||x||_1 = %10.3e\n',sum(abs(x(:))))      fprintf(1,'Objective function = %10.3e\n',f);      nz = (x_debias~=0.0);      fprintf(1,'Number of non-zero components = %d\n',sum(nz(:)));      fprintf(1,'CPU time so far = %10.3e\n', times(iter));      fprintf(1,'\n');    end  end    if compute_mse    mses = mses/length(true(:));  end  end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -