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

📄 hard_l0_mterm.m

📁 Sparse Estimation Algorithms by Blumensath and Davies min ||x||_0 subject to ||y - Ax||_2<e
💻 M
字号:
function [s, err_mse, iter_time]=hard_l0_Mterm(x,A,m,M,varargin)% hard_l0_Mterm: Hard thresholding algorithm that keeps exactly M elements % in each iteration. %% This algorithm has certain performance guarantees as described in [1],% [2] and [3].%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Usage%%   [s, err_mse, iter_time]=hard_l0_Mterm(x,P,m,M,'option_name','option_value')%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Input%%   Mandatory:%               x   Observation vector to be decomposed%               P   Either:%                       1) An nxm matrix (n must be dimension of x)%                       2) A function handle (type "help function_format" %                          for more information)%                          Also requires specification of P_trans option.%                       3) An object handle (type "help object_format" for %                          more information)%               m   length of s %               M   non-zero elements to keep in each iteration%%   Possible additional options:%   (specify as many as you want using 'option_name','option_value' pairs)%   See below for explanation of options:%__________________________________________________________________________%   option_name    |     available option_values                | default%--------------------------------------------------------------------------%   stopTol        | number (see below)                         | 1e-16%   P_trans        | function_handle (see below)                | %   maxIter        | positive integer (see below)               | n^2%   verbose        | true, false                                | false%   start_val      | vector of length m                         | zeros%   step_size      | number                                     | 0 (auto)%%   stopping criteria used : (OldRMS-NewRMS)/RMS(x) < stopTol%%   stopTol: Value for stopping criterion.%%   P_trans: If P is a function handle, then P_trans has to be specified and %            must be a function handle. %%   maxIter: Maximum number of allowed iterations.%%   verbose: Logical value to allow algorithm progress to be displayed.%%   start_val: Allows algorithms to start from partial solution.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Outputs%%    s              Solution vector %    err_mse        Vector containing mse of approximation error for each %                   iteration%    iter_time      Vector containing computation times for each iteration%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Description%%   Implements the M-sparse algorithm described in [1], [2] and [3].%   This algorithm takes a gradient step and then thresholds to only retain%   M non-zero elements. It allows the step-size to be calculated%   automatically as described in [3] and is therefore now independent from %   a rescaling of P.%   %   % References%   [1]  T. Blumensath and M.E. Davies, "Iterative Thresholding for Sparse %        Approximations", submitted, 2007%   [2]  T. Blumensath and M. Davies; "Iterative Hard Thresholding for %        Compressed Sensing" to appear Applied and Computational Harmonic %        Analysis %   [3] T. Blumensath and M. Davies; "A modified Iterative Hard %        Thresholding algorithm with guaranteed performance and stability" %        in preparation (title may change) % See Also%   hard_l0_reg%% Copyright (c) 2007 Thomas Blumensath%% The University of Edinburgh% Email: thomas.blumensath@ed.ac.uk% Comments and bug reports welcome%% This file is part of sparsity Version 0.4% Created: April 2007% Modified January 2009%% Part of this toolbox was developed with the support of EPSRC Grant% D000246/1%% Please read COPYRIGHT.m for terms and conditions.%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                    Default values and initialisation%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%[n1 n2]=size(x);if n2 == 1    n=n1;elseif n1 == 1    x=x';    n=n2;else   error('x must be a vector.');end    sigsize     = x'*x/n;oldERR      = sigsize;err_mse     = [];iter_time   = [];STOPTOL     = 1e-16;MAXITER     = n^2;verbose     = false;initial_given=0;s_initial   = zeros(m,1);MU          = 0;if verbose   display('Initialising...') end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                           Output variables%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%switch nargout     case 3        comp_err=true;        comp_time=true;    case 2         comp_err=true;        comp_time=false;    case 1        comp_err=false;        comp_time=false;    case 0        error('Please assign output variable.')            otherwise        error('Too many output arguments specified')end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                       Look through options%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Put option into nice formatOptions={};OS=nargin-4;c=1;for i=1:OS    if isa(varargin{i},'cell')        CellSize=length(varargin{i});        ThisCell=varargin{i};        for j=1:CellSize            Options{c}=ThisCell{j};            c=c+1;        end    else        Options{c}=varargin{i};        c=c+1;    endendOS=length(Options);if rem(OS,2)   error('Something is wrong with argument name and argument value pairs.') endfor i=1:2:OS   switch Options{i}        case {'stopTol'}            if isa(Options{i+1},'numeric') ; STOPTOL     = Options{i+1};               else error('stopTol must be number. Exiting.'); end        case {'P_trans'}             if isa(Options{i+1},'function_handle'); Pt = Options{i+1};               else error('P_trans must be function _handle. Exiting.'); end        case {'maxIter'}            if isa(Options{i+1},'numeric'); MAXITER     = Options{i+1};                         else error('maxIter must be a number. Exiting.'); end        case {'verbose'}            if isa(Options{i+1},'logical'); verbose     = Options{i+1};               else error('verbose must be a logical. Exiting.'); end         case {'start_val'}            if isa(Options{i+1},'numeric') && length(Options{i+1}) == m ;                s_initial     = Options{i+1};                  initial_given=1;            else error('start_val must be a vector of length m. Exiting.'); end        case {'step_size'}            if isa(Options{i+1},'numeric') && (Options{i+1}) > 0 ;                MU     = Options{i+1};               else error('Stepsize must be between a positive number. Exiting.'); end        otherwise            error('Unrecognised option. Exiting.')    endendif nargout >=2    err_mse = zeros(MAXITER,1);endif nargout ==3    iter_time = zeros(MAXITER,1);end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                        Make P and Pt functions%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%if          isa(A,'float')      P =@(z) A*z;  Pt =@(z) A'*z;elseif      isobject(A)         P =@(z) A*z;  Pt =@(z) A'*z;elseif      isa(A,'function_handle')     try        if          isa(Pt,'function_handle'); P=A;        else        error('If P is a function handle, Pt also needs to be a function handle. Exiting.'); end    catch error('If P is a function handle, Pt needs to be specified. Exiting.'); endelse        error('P is of unsupported type. Use matrix, function_handle or object. Exiting.'); end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                        Do we start from zero or not?%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%if initial_given ==1;        if length(find(s_initial)) > M        display('Initial vector has more than M non-zero elements. Keeping only M largest.')        end    s                   =   s_initial;    [ssort sortind]     =   sort(abs(s),'descend');    s(sortind(M+1:end)) =   0;    Ps                  =   P(s);    Residual            =   x-Ps;    oldERR      = Residual'*Residual/n;else    s_initial   = zeros(m,1);    Residual    = x;    s           = s_initial;    Ps          = zeros(n,1);    oldERR      = sigsize;end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                 Random Check to see if dictionary norm is below 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                x_test=randn(m,1);        x_test=x_test/norm(x_test);        nP=norm(P(x_test));        if abs(MU*nP)>1;            display('WARNING! Algorithm likely to become unstable.')            display('Use smaller step-size or || P ||_2 < 1.')        end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                        Main algorithm%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%if verbose   display('Main iterations...') endtict=0;done = 0;iter=1;while ~done        if MU == 0        %Calculate optimal step size and do line search        olds                =   s;        oldPs               =   Ps;        IND                 =   s~=0;        d                   =   Pt(Residual);        % If the current vector is zero, we take the largest elements in d        if sum(IND)==0            [dsort sortdind]    =   sort(abs(d),'descend');            IND(sortdind(1:M))  =   1;             end          id                  =   (IND.*d);        Pd                  =   P(id);        mu                  =   id'*id/(Pd'*Pd);        s                   =   olds + mu * d;        [ssort sortind]     =   sort(abs(s),'descend');        s(sortind(M+1:end)) =   0;        Ps                  =   P(s);                % Calculate step-size requirement         omega               =   (norm(s-olds)/norm(Ps-oldPs))^2;        % As long as the support changes and mu > omega, we decrease mu        while mu > (0.99)*omega && sum(xor(IND,s~=0))~=0 && sum(IND)~=0%             display(['decreasing mu'])                                        % We use a simple line search, halving mu in each step                    mu                  =   mu/2;                    s                   =   olds + mu * d;                    [ssort sortind]     =   sort(abs(s),'descend');                    s(sortind(M+1:end)) =   0;                    Ps                  =   P(s);                    % Calculate step-size requirement                     omega               =   (norm(s-olds)/norm(Ps-oldPs))^2;        end            else        % Use fixed step size        s                   =   s + MU * Pt(Residual);        [ssort sortind]     =   sort(abs(s),'descend');        s(sortind(M+1:end)) =   0;        Ps                  =   P(s);            end        Residual            =   x-Ps;             ERR=Residual'*Residual/n;     if comp_err         err_mse(iter)=ERR;     end          if comp_time         iter_time(iter)=toc;     end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                        Are we done yet?%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%              if comp_err && iter >=2             if ((err_mse(iter-1)-err_mse(iter))/sigsize<STOPTOL);                 if verbose                    display(['Stopping. Approximation error changed less than ' num2str(STOPTOL)])                 end                done = 1;              elseif verbose && toc-t>10                display(sprintf('Iteration %i. --- %i mse change',iter ,(err_mse(iter-1)-err_mse(iter))/sigsize))                 t=toc;             end         else             if ((oldERR - ERR)/sigsize < STOPTOL) && iter >=2;                 if verbose                    display(['Stopping. Approximation error changed less than ' num2str(STOPTOL)])                 end                done = 1;              elseif verbose && toc-t>10                display(sprintf('Iteration %i. --- %i mse change',iter ,(oldERR - ERR)/sigsize))                 t=toc;             end         end             % Also stop if residual gets too small or maxIter reached     if comp_err         if err_mse(iter)<1e-16             display('Stopping. Exact signal representation found!')             done=1;         end     elseif iter>1          if ERR<1e-16             display('Stopping. Exact signal representation found!')             done=1;         end     end     if iter >= MAXITER         display('Stopping. Maximum number of iterations reached!')         done = 1;      end %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                    If not done, take another round%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%        if ~done        iter=iter+1;         oldERR=ERR;             endend%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%                  Only return as many elements as iterations%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%if nargout >=2    err_mse = err_mse(1:iter);endif nargout ==3    iter_time = iter_time(1:iter);endif verbose   display('Done') end

⌨️ 快捷键说明

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