How to solve problem of out memory
    조회 수: 3 (최근 30일)
  
       이전 댓글 표시
    
function varargout = sparseapprox(X, D, met, varargin)
% sparseapprox     Returns coefficients in a sparse approximation of X.
%                  Several methods for sparse approximation may be used, 
% some implemented in this m-file and others depend on external parts.
% For the methods (3) and (4) below, the corresponding packages
% should be installed on your computer and be available from Matlab.
%
% The coefficients or weights, W, are usually (but not always) sparse, 
% i.e. number of non-zero coefficients below a limit,
% some methods use the 1-norm but these are not much tested.
% 
% The reconstrucion or approximation of X is (D*W).
% The approximation error is R = X - D*W;
% The Signal to Noise Ratio is snr = 10*log10(var(X(:))/var(R(:)));
%
%   Use of function:
%   ----------------
%   W = SPARSEAPPROX(X, D, met, 'option',value, ...)
%     W is coefficient matrix, size KxL
%     X is data, a matrix of size NxL, (a column vector when L=1)
%     D is the dictionary, size NxK
%     met is a char string for the different methods, see below
%     Additional arguments may be given as pairs: 'option',value, ...
%     (or options may be given in one (or more) struct or cell-array)
%     These options may be used for the different methods.
% 
%   [W, res] = SPARSEAPPROX(X, D, met, 'option',value, ...)
%     res is a struct with additional results 
%   
%   The alternative methods are:
%   ----------------------------
%   (1) Methods that use Matlab standard functions: 'pinv', '\', 'linprog' 
%   The representation is now exact and usually not sparse unless
%   thresholding is done (see below).
% 'MOF', 'MethodOfFrames', or 'pinv'
% 'BackSlash' or '\'
% 'BP' or 'BasisPursuit' or 'linprog' 
%   (2) Methods implemented in this m-file
% 'FOCUSS' a best basis variant. Use options 'nIt' and 'pFOCUSS'.
%   When option 'lambdaFOCUSS' is given Regularized FOCUSS is used.
%   For the four methods ('pinv', 'BackSlash', 'linprog' and 'FOCUSS')
%   thresholding is done when 'tnz', 'tre' or 'tae' is given as option.
%   If 'doOP' the coefficients are set so that D*W(:,i) is an orthogonal  
%   projection onto the space spanned by used columns of D. 
% 'GMP', a Global variant of Matching Pursuit.  NOTE that option 'tnz' 
%   should be given as the total number of non-zeros in W
% 'OMP', Orthogonal Matching Pursuit 
% 'ORMP', Order Recursive Matching Pursuit 
%   (3) Methods implemented in the 'mpv2' java package (by K. Skretting)
%   see page: http://www.ux.uis.no/~karlsk/dle/index.html
%   They are all variants of Matching Pursuit
% 'javaMP', 'javaMatchingPursuit', 'javaBMP', 'javaBasicMatchingPursuit'
% 'javaOMP' or 'javaOrthogonalMatchingPursuit'
% 'javaORMP' or 'javaOrderRecursiveMatchingPursuit'
% 'javaPS' or 'javaPartialSearch'
%   (4) Methods implemented as mex-files in SPAMS (by J. Mairal)
%   These are very fast and can be used also for quite large problems.
%   see page: http://spams-devel.gforge.inria.fr/
% 'mexLasso', 'LARS', or 'LASSO'
% 'mexOMP'  NOTE: this is the same algorithm as ORMP and javaORMP!
%
%   The Options may be:
%   -------------------
%   'tnz' or 'targetNonZeros' with values as 1x1 or 1xL, gives the target
%     number of non-zero coefficients for each column vector in X
%     Default is ceil(N/2)
%   'tre' or 'targetRelativeError' with values as 1x1 or 1xL, gives the 
%     target relative error, i.e. iterations stops when ||r|| < tre*||x||.
%     If both tnz and tre is given, the iterations stops when any criterium
%     is met. Default is 1e-6.
%   'tae' or 'targetAbsoluteError' with values as 1x1 or 1xL, gives an
%     alternative way to set 'tre' on: tre = tae ./ ||x||
%     Iterations stops when ||r|| < tae. If used 'tae' overrides 'tre'.
%   'doOP' do Orthogonal Projection when thresholding, default is true
%   'nIt' or 'nofIt' or 'numberOfIterations' is used in FOCUSS, default 20.
%   'p' or 'pFOCUSS' the p-norm to use in FOCUSS. Default 0.5. 
%   'l' or 'lambdaFOCUSS' is lambda in Regularized FOCUSS, default is 0
%   'nComb' number of combinations in 'javaPS'. Default is 20.
%   'globalReDist', 'tSSE' or 'targetSSE', 'tSNR' or 'targetSNR' are 
%      undocumented options which may be used with method 'javaORMP' only. 
%   'GMPLoopSize', optional parameter used in GMP (default usually ok)
%   'paramSPAMS', optional parameter to use in mexLasso or mexOMP. If not given
%      the following will be used for mexOMP and mexLasso respectively:
%      paramSPAMS = struct( 'eps', tae.^2, 'L', int32(tnz) );
%      paramSPAMS = struct( 'mode',1, 'lambda', tae.^2, 'L', int32(tnz), 'ols',true );
%   'v' or 'verbose' may be 0/false (default), 1/true or 2 (very verbose).
%
%   Examples:
%   ---------
%   L = 400; N = 16; K = 32; D = randn(N,K); X = randn(N,L);  % or
%   % Wi = zeros(K,L); for i=1:L; Wi(:,i) = randperm(K); end;
%   % Wt = zeros(K,L); Wt(Wi <= 5) = randn(5*L,1); X = D*Wt + 0.01*randn(N,L);
%   op = struct('targetNonZeros',5, 'verbose', 2);
%   [Wpinv, ra] = sparseapprox(X, D, 'pinv', op);
%   [Wlp, rc] = sparseapprox(X, D, 'linprog', op); 
%   [Wf, rd] = sparseapprox(X, D, 'FOCUSS', op, 'p', 0.8, 'l', 0.4, 'nIt', 100);
%   [Womp, rf] = sparseapprox(X, D, 'javaOMP', op); 
%   [Wormp, rg] = sparseapprox(X, D, 'javaORMP', op); 
%   [Wps100, rh] = sparseapprox(X, D, 'javaPS', 'nComb',100, op);
%   [Wgmp, ri] = sparseapprox(X, D, 'GMP', 'tnz',5*L, 'v',2); 
%   [Wps, rih] = sparseapprox(X, D, 'javaPS', 'tnz',sum(Wgmp~=0), 'nComb',100);
%   fs = ' %5.2f  %5.2f  %5.2f  %5.2f  %5.2f  %5.2f  %5.2f  %5.2f \n';
%   fprintf('\n       pinv  linprog FOCUSS  OMP   ORMP   PS     GMP   GMP+PS \n'); 
%   fprintf(['SNR  ',fs], ra.snr,rc.snr,rd.snr,rf.snr,rg.snr,rh.snr,ri.snr,rih.snr);  
%   fprintf(['time ',fs], ra.time,rc.time,rd.time,rf.time,rg.time,rh.time,ri.time,rih.time);  
%   [Wmomp, rm] = sparseapprox(X, D, 'mexOMP', op);      % like ORMP
%   [Wlasso, rl] = sparseapprox(X, D, 'mexLasso', op);  
%   % to show the coefficients for a selected vector
%   % i = 11; [Wt(:,i), Womp(:,i), Wormp(:,i), Wmomp(:,i), Wlasso(:,i), Wps100(:,i)]
%----------------------------------------------------------------------
% Copyright (c) 2009.  Karl Skretting.  All rights reserved.
% University of Stavanger, Signal Processing Group
% Mail:  karl.skretting@uis.no   Homepage:  http://www.ux.uis.no/~karlsk/
% 
% HISTORY:  dd.mm.yyyy
% Ver. 1.0  10.10.2009  Made function
% Ver. 1.1  04.01.2010  Add GMP method, and globalReDist in javaORMP
% Ver. 1.2  05.01.2010  added targetTotalSumSquaredError and targetSNR 
%           06.01.2010  and now it works well. 
% Ver. 1.3  26.03.2010  Add LARS and LASSO methods
% Ver. 1.4  07.04.2010  Added smoothed L_0 norm (SL0) method
% Ver. 2.0  06.04.2011  Removed some methods and tried to 'clean' this file
%                       SLO, LARS/LASSO matlab implementations, and
%                       globalReDist after javaORMP were removed.
% Ver. 2.1  31.05.2011  globalReDist included again
% Ver. 2.2  08.08.2012  Added affine ORMP method, 
% Ver. 2.3  15.04.2013  Removed affine ORMP method (It was not as I hoped it would be)
% Ver. 2.4  09.10.2014  Minor changes to make mexOMP work (SPAMS ver. 2.5)
%----------------------------------------------------------------------
%
% additional documentation:
%  - Dictionary Learning Tools: http://www.ux.uis.no/~karlsk/dle/index.html
% alternative functions:
%  - GreedLab (sparsify), Thomas Blumensath et al. (Edinburgh)
%  - SparseLab, David Donoho et al. (Stanford)
%  - SPAMS (Mairal):  http://spams-devel.gforge.inria.fr/
%  - OMPBox (Ron Rubinstein): http://www.cs.technion.ac.il/~ronrubin/software.html
%%Check if input arguments are given
mfile = 'sparseapprox';
L = 400; 
N = 16; 
K = 32; 
D = randn(N,K); 
X = randn(N,L);  
Wi = zeros(K,L); 
for i=1:L; Wi(:,i) = randperm(K); end
Wt = zeros(K,L); 
Wt(Wi <= 5) = randn(5*L,1); 
%X = D*Wt + 0.01*randn(N,L);
op = struct('targetNonZeros',5, 'verbose', 2);
[Wpinv, ra] = sparse(X);
%[Wpinv, ra] = sparseapprox(X, D, 'pinv',op);
[Wlp, rc] = sparseapprox(X, D, 'linprog', op); 
[Wf, rd] = sparseapprox(X, D, 'FOCUSS', op, 'p', 0.8, 'l', 0.4, 'nIt', 100);
[Womp, rf] = sparseapprox(X, D, 'javaOMP', op); 
[Wormp, rg] = sparseapprox(X, D, 'javaORMP', op); 
[Wps100, rh] = sparseapprox(X, D, 'javaPS', 'nComb',100, op);
[Wgmp, ri] = sparseapprox(X, D, 'GMP', 'tnz',5*L, 'v',2); 
[Wps, rih] = sparseapprox(X, D, 'javaPS', 'tnz',sum(Wgmp~=0), 'nComb',100);
fs = ' %5.2f  %5.2f  %5.2f  %5.2f  %5.2f  %5.2f  %5.2f  %5.2f \n';
fprintf('\n       pinv  linprog FOCUSS  OMP   ORMP   PS     GMP   GMP+PS \n'); 
fprintf(['SNR  ',fs], ra.snr,rc.snr,rd.snr,rf.snr,rg.snr,rh.snr,ri.snr,rih.snr);  
fprintf(['time ',fs], ra.time,rc.time,rd.time,rf.time,rg.time,rh.time,ri.time,rih.time);  
[Wmomp, rm] = sparseapprox(X, D, 'mexOMP', op);      % like ORMP
[Wlasso, rl] = sparseapprox(X, D, 'mexLasso', op);  
%   % to show the coefficients for a selected vector
i = 11; [Wt(:,i), Womp(:,i), Wormp(:,i), Wmomp(:,i), Wlasso(:,i), Wps100(:,i)]
if (nargin < 3)  % just check number of input arguments 
    t = [mfile,': arguments must be given, see help.'];
    disp(t);
    if nargout >= 1
        varargout{1} = -1;
    end
    if nargout >= 2
        varargout{2} = struct('Error',t);
    end
    return
end
%%defaults, initial values
tstart = tic;
[N,L] = size(X);
K = size(D,2);
norm2X = sqrt(sum(X.*X)); % ||x(i)||_2     1xL
W = zeros(K,L);      % the weights (coefficients)
tnz = ceil(N/2)*ones(1,L); % target number of non-zeros
thrActive = false;    % is set to true if tnz, tre or tae is given
                      % and used for methods: pinv, backslash, linprog and
                      % FOCUSS
doOP = true;          % do Orthogonal Projection when thresholding                 
relLim = 1e-6;
tre = relLim*ones(1,L);   % target relative error: ||r|| <= tre*||x||
nComb = 20;           % used only in javaPS
nIt = 20;             % used only in FOCUSS 
pFOCUSS = 0.5;        % used only in FOCUSS 
lambdaFOCUSS = 0;     % used only in FOCUSS
deltaWlimit = 1e-8;   % used only in FOCUSS
GMPLoopSize = 0;      % used only in GMP
globalReDist = 0;     % may be used with javaORMP 
targetSSE = 0;        % may be used with javaORMP 
verbose = 0;
done = false;
javaClass = 'mpv2.MatchingPursuit';   % the important java class
spams_mex_file = 'mexLasso'; % one of the used SPAMS files
%%get the options
nofOptions = nargin-3;
optionNumber = 1;
fieldNumber = 1;
while (optionNumber <= nofOptions)
    if isstruct(varargin{optionNumber})
        sOptions = varargin{optionNumber}; 
        sNames = fieldnames(sOptions);
        opName = sNames{fieldNumber};
        opVal = sOptions.(opName);
        % next option is next field or next (pair of) arguments
        fieldNumber = fieldNumber + 1;  % next field
        if (fieldNumber > numel(sNames)) 
            fieldNumber = 1;
            optionNumber = optionNumber + 1;  % next pair of options
        end
    elseif iscell(varargin{optionNumber})
        sOptions = varargin{optionNumber}; 
        opName = sOptions{fieldNumber};
        opVal = sOptions{fieldNumber+1};
        % next option is next pair in cell or next (pair of) arguments
        fieldNumber = fieldNumber + 2;  % next pair in cell
        if (fieldNumber > numel(sOptions)) 
            fieldNumber = 1;
            optionNumber = optionNumber + 1;  % next pair of options
        end
    else
        opName = varargin{optionNumber};
        opVal = varargin{optionNumber+1};
        optionNumber = optionNumber + 2;  % next pair of options
    end
    % interpret opName and opVal
    if strcmpi(opName,'targetNonZeros') || strcmpi(opName,'tnz')
        if strcmpi(met,'GMP') 
            tnz = opVal;   % GMP will distribute the non-zeros
        else
            if numel(opVal)==1
                tnz = opVal*ones(1,L);
            elseif numel(opVal)==L
                tnz = reshape(opVal,1,L);
            else
                error([mfile,': illegal size of value for option ',opName]);
            end
        end
        thrActive = true;
    end
    if strcmpi(opName,'targetRelativeError') || strcmpi(opName,'tre')
        if numel(opVal)==1
           tre = opVal*ones(1,L);
        elseif numel(opVal)==L
           tre = reshape(opVal,1,L);
        else
            error([mfile,': illegal size of value for option ',opName]);
        end
        thrActive = true;
    end
    if strcmpi(opName,'targetAbsoluteError') || strcmpi(opName,'tae')
        if numel(opVal)==1
           tae = opVal*ones(1,L);
        elseif numel(opVal)==L
           tae = reshape(opVal,1,L);
        else
            error([mfile,': illegal size of value for option ',opName]);
        end
        thrActive = true;
    end
    if ( strcmpi(opName,'nIt') || strcmpi(opName,'nofIt') || ...
         strcmpi(opName,'numberOfIterations') )
        if (isnumeric(opVal) && numel(opVal)==1)
            nIt = max(floor(opVal), 1);
        else
            error([mfile,': illegal size of value for option ',opName]);
        end
    end
    if strcmpi(opName,'p') || strcmpi(opName,'pFOCUSS')
        if (isnumeric(opVal) && numel(opVal)==1)
            pFOCUSS = min(opVal, 1);
        else
            error([mfile,': illegal size of value for option ',opName]);
        end
    end
    if strcmpi(opName,'l') || strcmpi(opName,'lambdaFOCUSS')
        if (isnumeric(opVal) && numel(opVal)==1)
            lambdaFOCUSS = abs(opVal);
        else
            error([mfile,': illegal size of value for option ',opName]);
        end
    end
    if strcmpi(opName,'nComb')
        if (isnumeric(opVal) && numel(opVal)==1)
            nComb = max(floor(opVal), 2);
        else
            error([mfile,': illegal size of value for option ',opName]);
        end
    end
    if strcmpi(opName,'paramSPAMS')
        if (isstruct(opVal))
            paramSPAMS = opVal;
        else
            error([mfile,': option paramSPAMS is not a struct as it should be, see SPAMS help.']);
        end
    end
    if strcmpi(opName,'globalReDist')
        if (isnumeric(opVal) && numel(opVal)==1)
            globalReDist = min(max(floor(opVal), 0), 2);  % 0, 1 or 2
        else
            error([mfile,': illegal size of value for option ',opName]);
        end
    end
    if strcmpi(opName,'doOP') 
        if (islogical(opVal)); doOP = opVal; end;
        if isnumeric(opVal); doOP = (opVal ~= 0); end;
    end
    if strcmpi(opName,'GMPLoopSize')
        if (isnumeric(opVal) && numel(opVal)==1)
            GMPLoopSize = max(floor(opVal), 2);
        else
            error([mfile,': illegal size of value for option ',opName]);
        end
    end
    if strcmpi(opName,'tSSE') || strcmpi(opName,'targetSSE')
        if (isnumeric(opVal) && numel(opVal)==1)
            targetSSE = min(max(opVal, 0), sum(sum(X.*X)));
        else
            error([mfile,': illegal size of value for option ',opName]);
        end
    end
    if strcmpi(opName,'tSNR') || strcmpi(opName,'targetSNR')
        if (isnumeric(opVal) && numel(opVal)==1)
            targetSSE = 10^(-abs(opVal)/10) * sum(sum(X.*X));
        else
            error([mfile,': illegal size of value for option ',opName]);
        end
    end
    if strcmpi(opName,'verbose') || strcmpi(opName,'v')
        if (islogical(opVal) && opVal); verbose = 1; end;
        if isnumeric(opVal); verbose = opVal(1); end;
    end
end
if exist('tae','var')   % if both exist 'tae' overrules 'tre'
    tre = tae./norm2X;
elseif exist('tre','var')  % 'tre' was given a default value
    tae = tre.*norm2X;
else                       % so this case is redundant
    disp(' ??? This is never printed.');
end
%%Display info
if (verbose > 1)  % very verbose
    disp(' ');
    disp([mfile,' with method ',met,' started ',datestr(now)]);
    disp(['Size of X is ',int2str(size(X,1)),'x',int2str(size(X,2)),...
          ', D is ',int2str(size(D,1)),'x',int2str(size(D,2)),...
          ', and W is ',int2str(size(W,1)),'x',int2str(size(W,2))]);
end
Method of Frames
if strcmpi(met,'MOF') || strcmpi(met,'MethodOfFrames') || strcmpi(met,'pinv')
    textMethod = 'Method of Frames with pseudoinverse (pinv).';
    if (verbose >= 1); disp([mfile,': ',textMethod]); end;
    W = pinv(D)*X;
    if thrActive  % then adjust w by setting more to zero
        W = setSmallWeightsToZero(X,D,W,tnz,tae,doOP);
    end
    done = true;
end
Backslash method just find an exact solution with N non-zeros
if strcmpi(met,'BackSlash') || strcmpi(met,'\')
    textMethod = 'Matlab backslash operator.';
    if (verbose >= 1); disp([mfile,': ',textMethod]); end;
    W = D\X;
    if thrActive  % then adjust w by setting more to zero
        W = setSmallWeightsToZero(X,D,W,tnz,tae,doOP);
    end
    done = true;
end
Basis Pursuit
if strcmpi(met,'BP') || strcmpi(met,'BasisPursuit') || strcmpi(met,'linprog')
    textMethod = 'Basis Pursuit with Matlab function linprog.';
    if (verbose >= 1); disp([mfile,': ',textMethod]); end;
    f = ones(2*K,1);
    A = [D,-D];
    LB = zeros(2*K,1);         % lower bound for w
    UB = ones(2*K,1)*inf;      % upper bound for w
    for columnNumber = 1:L
        x = X(:,columnNumber);
        w2 = linprog(f,A,x,A,x,LB,UB);     % minimize 1-norm of w 
        W(:,columnNumber) = w2(1:K)-w2((1+K):(2*K));
    end
    if thrActive  % then adjust w by setting more to zero
        W = setSmallWeightsToZero(X,D,W,tnz,tae,doOP);
    end
    done = true;
end
the original (and possible regularized) FOCUSS algorithm
if strcmpi(met,'FOCUSS')
    W = pinv(D)*X;   % initial values
    if (lambdaFOCUSS > 0)  % Regularized FOCUSS
        textMethod = ['FOCUSS with p=',num2str(pFOCUSS),...
            ', and regularization (lambda = ',....
            num2str(lambdaFOCUSS),')',...
            ' and ',int2str(nIt),' iterations.'];
    else
        textMethod = ['FOCUSS with p=',num2str(pFOCUSS),...
            ' and ',int2str(nIt),' iterations.'];
    end
    if thrActive  
        textMethod = char(textMethod, ...
            ' Thresholding is done in the end.');
    end
    if (nargout >= 2)        % keep track of sparseness
        sparseInW = zeros(5,nIt);
        edges = [0, 0.0001, 0.001, 0.01, 0.1, inf];
        changeInW = zeros(nIt,L);
        numberOfIterations = nIt*ones(1,L);
    end
    if (verbose >= 1); disp(char([mfile,': '],textMethod)); end;
    for columnNumber = 1:L
        w = W(:,columnNumber);
        w0 = w;
        x = X(:,columnNumber);
        for i=1:nIt
            Qdiagonal = abs(w).^(1-pFOCUSS/2);
            F = D.*(ones(N,1)*(Qdiagonal'));  % F^{k+1}  in Engan's PhD
            if (lambdaFOCUSS > 0)  % Regularized FOCUSS
                q = F'*( ((F*F'+lambdaFOCUSS*eye(N)) \ x) );
            else  % original FOCUSS
                q = pinv(F) * x;
            end
            w = Qdiagonal.*q;
            change = norm(w-w0);
            if (nargout >= 2)    % keep track of sparseness and more
                m = max(abs(w));
                I = histc(abs(w)/m, edges);
                sparseInW(:,i) = sparseInW(:,i)+I(1:5);
                changeInW(i,columnNumber) = change;
                if (change < deltaWlimit)
                    sparseInW(:,(i+1):nIt) = sparseInW(:,(i+1):nIt) + I(1:5)*ones(1,nIt-i);
                    changeInW((i+1):nIt,columnNumber) = change;
                    numberOfIterations(columnNumber) = i;
                end
            end
            if (change < deltaWlimit); break; end;
            w0 = w;
        end
        W(:,columnNumber) = w;
    end
    if thrActive  % then adjust w by setting more to zero
        W = setSmallWeightsToZero(X,D,W,tnz,tae,doOP);
    end
    done = true;
end
mexOMP or mexLasso algorithm from SPAMS
if (strcmpi(met,'mexOMP') || strcmpi(met,'mexORMP') || ...
    strcmpi(met,'mexLasso') || strcmpi(met,'LARS') || strcmpi(met,'LASSO'))
    % check matlab version
    t = version('-release');
    if (eval(t(1:4)) < 2009) || strcmpi(t,'2009a')
        t = [mfile,': mexLasso and mexOMP need Matlab version >= 2009b. (?)'];
        disp(t);
        if nargout >= 1
            varargout{1} = -1;
        end
        if nargout >= 2
            varargout{2} = struct('Error',t);
        end
        return
    end
    %
    % The way access to SPAMS is checked on the computeres I may use
    if ~(exist(spams_mex_file,'file') == 3)  % mex-file not available (yet)
        start_spams;   % a m-file that comes with SPAMS and is located on a common path 
    end
    if ~(exist(spams_mex_file,'file') == 3)  % mex-file still not available
        t = [mfile,': can not access mexLasso and mexOMP on this computer.'];
        disp(t);
        if nargout >= 1
            varargout{1} = -1;
        end
        if nargout >= 2
            varargout{2} = struct('Error',t);
        end
        return
    end
    %
    if (strcmpi(met,'mexOMP') || strcmpi(met,'mexORMP'))
        textMethod = 'mexOMP in SPAMS package (by J. Mairal).';
    else
        textMethod = 'mexLasso (mode=1) in SPAMS package (by J. Mairal).';
    end
    if (verbose >= 1); disp([mfile,': ',textMethod]); end;
    if ~exist('paramSPAMS','var')
        if (strcmpi(met,'mexOMP') || strcmpi(met,'mexORMP'))
            % Example from SPAMS documentation, mexOMP
            % parameter of the optimization procedure are chosen
            % param.L=10; % not more than 10 non-zeros coefficients
            % param.eps=0.1; % squared norm of the residual should be less than 0.1
            % param.numThreads=-1; % number of processors/cores to use; the default choice is -1
            % and uses all the cores of the machine
             paramSPAMS = struct(...
                'eps',        tae.^2, ...
                'L',          int32(tnz), ...
                'numThreads', -1  );
        else
            paramSPAMS = struct(...
                'mode',   1, ...            
                'lambda', tae.^2, ...
                'L',      int32(tnz), ...
                'ols',    true  );
        end
        if (verbose >= 1); disp('  and uses ''default'' param when calling SPAMS function.'); end;
    else
        if (verbose >= 1); disp('  and uses user supplied param when calling SPAMS function.'); end;
    end
    %
    d_norm = sqrt(sum(D.^2));  
    if sum(abs(d_norm - ones(1,K))) > 1e-6
        D = D./repmat(d_norm,[N 1]);
    end
    %
    if (strcmpi(met,'mexOMP') || strcmpi(met,'mexORMP'))
        W = mexOMP(X, D, paramSPAMS);
    else
        % x_norm = sqrt(sum(X.^2));  
        % X = X./repmat(x_norm,[N 1]);
        W = mexLasso(X, D, paramSPAMS);
        % W = W.*repmat(x_norm,[K 1]);
        % X = X.*repmat(x_norm,[N 1]);
    end
    W = full(W);
    if sum(abs(d_norm - ones(1,K))) > 1e-6
        W = W./repmat(d_norm(:),[1 L]);
        D = D.*repmat(d_norm,[N 1]);
    end
    done = true;
end
%%Algorithms implemented in Java
if strcmpi(met(1:min(numel(met),3)),'aff') 
    disp('Affine approximation is essentiallaly that sum of coefficients should be 1.');
    disp('This is achieved by adding a row of constants to both D and X and ');
    disp('then doing ordinary aparse approximation. Do this outside this function ');
    disp('to have better control. Set a to an approriate value, 5 perhaps.');
    disp('Ex:  D = [a*ones(1,K); D]; X = [a*ones(1,L); X];');
    % met = ['java',met(4:end)];   % use java method
    % D = [5*ones(1,K); D];    
    % X = [5*ones(1,L); X];    
    done = false;
end
if strcmpi(met(1:min(numel(met),4)),'java') 
    if (not(exist(javaClass,'class')) && exist('java_access.m','file'))
        java_access;
    end
    if (not(exist(javaClass,'class')) && exist('javaAccess.m','file'))
        javaAccess;  % an older version of java_access (may work if it exist)
    end
    if not(exist(javaClass,'class'))   
        javaErrorMessage = ['No access to ',javaClass,' in static or dynamic Java path.'];
        disp(javaErrorMessage);
        met = met(5:end);
        disp(['Use method ',met,' instead.']);
    else
        jD = mpv2.SimpleMatrix( D );
        if (L == 1)
            jMP = mpv2.MatchingPursuit(jD);
        else
            jDD = mpv2.SymmetricMatrix(K,K);
            jDD.eqInnerProductMatrix(jD);
            jMP = mpv2.MatchingPursuit(jD,jDD);
        end
    end
end
if ( strcmpi(met,'javaMP') || strcmpi(met,'javaMatchingPursuit') || ...
     strcmpi(met,'javaBMP') || strcmpi(met,'javaBasicMatchingPursuit') )   
    textMethod = 'Basic Matching Pursuit, Java implementation.';
    if (verbose >= 1); disp([mfile,': ',textMethod]); end;
    % note the 'tre' is not used for BMP
    for j=1:L
        if (tnz(j) > 0)
            W(:,j) = jMP.vsBMP(X(:,j), int32(tnz(j)));
        end
    end
    done = true;
end
if strcmpi(met,'javaOMP') || strcmpi(met,'javaOrthogonalMatchingPursuit')
    textMethod = 'Orthogonal Matching Pursuit, Java implementation.';
    if (verbose >= 1); disp([mfile,': ',textMethod]); end;
    for j=1:L
        if (tnz(j) > 0) && (tre(j) < 1)
            W(:,j) = jMP.vsOMP(X(:,j), int32(tnz(j)), tre(j));
        end
    end
    done = true;
end
if strcmpi(met,'javaORMP') || strcmpi(met,'javaOrderRecursiveMatchingPursuit')
    %
    % This could be as simple as javaOMP, but since globalReDist was
    % reintroduced it is now quite complicated here.
    if (targetSSE > 0)   
        % This is initialization of tre (and tnz ?) for the special case of
        % global distribution of non-zeros where a target sum og squared
        % errors is given as an input argument.
        % Perhaps tnz also should be set to an appropriate value
        % tnz = 2*ones(1,L); 
        tre = sqrt(targetSSE/L)./norm2X;
        globalReDist = 2;
        textMethod = ['javaORMP with global distribution of non-zeros ',...
            'given target SSE (or SNR).'];
    elseif (globalReDist == 1)
        textMethod = ['javaORMP with global distribution of non-zeros ',...
            'keeping the total number of non-zeros fixed.'];
    elseif (globalReDist == 2)
        textMethod = ['javaORMP with global distribution of non-zeros ',...
            'keeping the total SSE fixed.'];
    else
        textMethod = 'Order Recursive Matching Pursuit, Java implementation.';
    end
    %
    % below is the javaORMP lines
    if (verbose >= 1); disp([mfile,': ',textMethod]); end;
    for j=1:L
        if (tnz(j) > 0) && (tre(j) < 1)
            W(:,j) = jMP.vsORMP(X(:,j), int32(tnz(j)), tre(j));
        end
    end
    % 
    % below is the globalReDist lines
    % ******* START Global distribution of non-zeros.***** 
    % The structure is:  
    %    1. Initializing:  Sm1 <= S <= Sp1  and  SEm1 >= SE >= SEp1
    %    2. Add atoms until SSE is small enough
    %    3. or remove atoms until SSE is large enough
    %    4. Add one atom as long as one (or more) may be removed and the
    %       SSE is reduced
    if (globalReDist > 0)
        % part 1
        R = X - D * W;    % representation error
        S = sum(W ~= 0);  % selected number of non-zeros for each column
        SE = sum(R.*R);   % squared error for each (when S is selected)
        sumSinit = sum(S);
        SSE = sum(SE);
        SSEinit = SSE;      % store initial SSE
        Sp1 = S + 1;        % selected number of non-zeros plus one
        Sp1(Sp1 > N) = N;
        Sm1 = S - 1;        % selected number of non-zeros minus one
        Sm1(Sm1 < 0) = 0;
        SEp1 = zeros(1,L);  % initializing corresponding squared error
        SEm1 = zeros(1,L);  
        for j=1:L
            x = X(:,j);
            if Sp1(j) == S(j)   % == N
                w = W(:,j);
            else
                w = jMP.vsORMP(x, Sp1(j), relLim);
            end
            r = x-D*w;
            SEp1(j) = r'*r;
            if Sm1(j) == 0
                w = zeros(K,1);
            else
                w = jMP.vsORMP(x, Sm1(j), relLim);
            end
            r = x-D*w;
            SEm1(j) = r'*r;
        end
        SEdec = SE-SEp1;   % the decrease in error by selectiong one more
        SEinc = SEm1-SE;   % the increase in error by selectiong one less
        SEinc(S == 0) = inf;  % not possible to select fewer than zero
        addedS = 0;
        removedS = 0;
        addedSE = 0;
        removedSE = 0;
        [valinc, jinc] = min(SEinc); % min increase in SE by removing one atom
        [valdec, jdec] = max(SEdec); % max reduction in SE by adding one atom
          if (targetSSE > 0)
              if (SSEinit > targetSSE)  % part 2
                  if (verbose > 2)
                      disp(['(part 2 add atoms, target SSE = ',num2str(targetSSE),...
                          ' and initial SSE = ',num2str(SSEinit),')']);
                  end
                  while (SSE > targetSSE)
                      j = jdec;    % an atom is added to vector j
                      addedS = addedS+1;
                      removedSE = removedSE + valdec;
                      SSE = SSE - valdec;
                      % shift in  Sm1,S,Sp1  and  SEm1,SE,SEp1
                      [Sm1(j), S(j), Sp1(j)] = assign3(S(j), Sp1(j), min(Sp1(j)+1, N));
                      [SEm1(j), SE(j)] = assign2(SE(j), SEp1(j));  % and SEp1(j)=SEp1(j)
                      if (Sp1(j) > S(j))   % the normal case, find new SEp1(j)
                          w = jMP.vsORMP(X(:,j), Sp1(j), relLim);
                          r = X(:,j) - D*w;
                          SEp1(j) = r'*r;
                      end
                      SEinc(j) = SEdec(j);      % SE cost by removing this again
                      SEdec(j) = SE(j)-SEp1(j); % SE gain by adding one more atom
                      %
                      W(:,j) = jMP.vsORMP(X(:,j), S(j), relLim);
                      [valdec, jdec] = max(SEdec);
                  end
                  [valinc, jinc] = min(SEinc); 
              elseif ((SSEinit+valinc) < targetSSE)  % part 3
                  if (verbose > 2)
                      disp(['(part 3 remove atoms, target SSE = ',num2str(targetSSE),...
                          ' and initial SSE = ',num2str(SSEinit),')']);
                  end
                  while ((SSE+valinc) < targetSSE)
                      j = jinc;   % an atom is removed from vector j
                      removedS = removedS+1;
                      addedSE = addedSE + valinc;
                      SSE = SSE + valinc;
                      % shift in  Sm1,S,Sp1  and  SEm1,SE,SEp1
                      [Sm1(j), S(j), Sp1(j)] = assign3(max(Sm1(j)-1, 0), Sm1(j), S(j));
                      [SE(j), SEp1(j)] = assign2(SEm1(j), SE(j)); % and SEm1(j)=SEm1(j)
                      if (Sm1(j) > 0)
                          w = jMP.vsORMP(X(:,j), Sm1(j), relLim);
                          r = X(:,j) - D*w;
                      else
                          r = X(:,j);
                      end
                      SEm1(j) = r'*r;
                      %
                      SEdec(j) = SEinc(j);  % SE gain by adding this atom again
                      if (S(j) > 0) % SE cost by removing another atom 
                          W(:,j) = jMP.vsORMP(X(:,j), S(j), relLim);
                          SEinc(j) = SEm1(j)-SE(j);    
                      else
                          W(:,j) = zeros(K,1);
                          SEinc(j) = inf;  % can not select fewer and increase error
                      end
                      [valinc, jinc] = min(SEinc); 
                  end
                  [valdec, jdec] = max(SEdec);
              else  %
                  if (verbose > 2)
                      disp(['(target SSE = ',num2str(targetSSE),...
                          ' is close to initial SSE = ',num2str(SSEinit),')']);
                  end
              end
          else  
              targetSSE = SSEinit;
          end 
          %
          % part 4
          while ((valinc < valdec) && (jinc ~= jdec))  
              j = jdec;
              addedS = addedS+1;
              removedSE = removedSE + valdec;
              SSE = SSE - valdec;
              % shift in  Sm1,S,Sp1  and  SEm1,SE,SEp1
              [Sm1(j), S(j), Sp1(j)] = assign3(S(j), Sp1(j), min(Sp1(j)+1, N));
              [SEm1(j), SE(j)] = assign2(SE(j), SEp1(j));  % and SEp1(j)=SEp1(j)
              if (Sp1(j) > S(j))   % the normal case, find new SEp1(j)
                  w = jMP.vsORMP(X(:,j), Sp1(j), relLim);
                  r = X(:,j) - D*w;
                  SEp1(j) = r'*r;
              end
              SEinc(j) = SEdec(j);      % SE cost by removing this again
              SEdec(j) = SE(j)-SEp1(j); % SE gain by adding one more atom
              W(:,j) = jMP.vsORMP(X(:,j), S(j), relLim);
              [valinc, jinc] = min(SEinc);
              %
              while ((SSE+valinc) < targetSSE) 
                  j = jinc;
                  removedS = removedS+1;
                  addedSE = addedSE + valinc;
                  SSE = SSE + valinc;
                  % shift in  Sm1,S,Sp1  and  SEm1,SE,SEp1
                  [Sm1(j), S(j), Sp1(j)] = assign3(max(Sm1(j)-1, 0), Sm1(j), S(j));
                  [SE(j), SEp1(j)] = assign2(SEm1(j), SE(j)); % and SEm1(j)=SEm1(j)
                  if (Sm1(j) > 0)
                      w = jMP.vsORMP(X(:,j), Sm1(j), relLim);
                      r = X(:,j) - D*w;
                  else
                      r = X(:,j);
                  end
                  SEm1(j) = r'*r;
                  %
                  SEdec(j) = SEinc(j);  % SE gain by adding this atom again
                  if (S(j) > 0) % SE cost by removing another atom 
                      W(:,j) = jMP.vsORMP(X(:,j), S(j), relLim);
                      SEinc(j) = SEm1(j)-SE(j);    
                  else
                      W(:,j) = zeros(K,1);
                      SEinc(j) = inf;  % can not select fewer and increase error
                  end
                  [valinc, jinc] = min(SEinc); 
                  if (globalReDist == 1); break; end;
              end
              [valdec, jdec] = max(SEdec);    % next now
          end
          %
          if (verbose > 2)
              disp(['Using globalReDist=',int2str(globalReDist),': ',...
                  'non-zeros in W changed as ',int2str(sumSinit),...
                  ' + ',int2str(addedS),' - ',int2str(removedS),...
                  ' = ',int2str(sum(sum(W ~= 0)))]); 
              disp(['SSE changed as ',num2str(SSEinit),...
                  ' + ',num2str(addedSE),' - ',num2str(removedSE),...
                  ' = ',num2str(SSE),' = ',num2str(SSEinit+addedSE-removedSE)]); 
              disp(['(target SSE = ',num2str(targetSSE),...
                  ' and actual SSE = ',num2str(sum(sum((X - D * W).^2))),')']); 
          end
      end
      %
      % ******* END Global distribution of non-zeros.***** 
      %
      %
      done = true;
  end
if strcmpi(met,'javaPS') || strcmpi(met,'javaPartialSearch')
    textMethod = ['Partial Search with ',...
            int2str(nComb),' number of combinations.'];
    if (verbose >= 1); disp([mfile,': ',textMethod]); end;
    for j=1:L
        if (tnz(j) > 0) && (tre(j) < 1)
            if (tnz(j) < 2)
                W(:,j) = jMP.vsORMP(X(:,j), int32(tnz(j)), tre(j));
            else
                W(:,j) = jMP.vsPS(X(:,j), int32(tnz(j)), tre(j), int32(nComb));
            end
        end
    end
    done = true;
end
%%GMP is Global Matching Pursuit
if strcmpi(met,'GMP')
    if (GMPLoopSize <= 0)
        GMPLoopSize = floor(tnz/N);
    end
    if (GMPLoopSize > 0.9*L)
        GMPLoopSize = floor(0.9*L);
    end
    textMethod = ['Global Matching Pursuit with ',...
            int2str(tnz),' non-zeros, (N=',int2str(N),...
            ', L=',int2str(L),' GMPLoopSize=',int2str(GMPLoopSize),').'];
    if verbose    
        disp(textMethod);    
    end
    Gd = (1./sqrt(sum(D.*D)));        %                G = diag(Gd)
    F = D.*(ones(size(D,1),1)*Gd);    % normalize D,   F = D*G
    %
    nzW = 0;
    R = X;
    while (nzW < tnz)
        if (verbose > 2)
            disp(['GMP: nzW = ',int2str(nzW),' and ||R||^2 = ',...
                num2str(sum(sum((R.*R))))]);
        end
        U = F'*R;    % inner products = G*D'*R
        [um,iK] = max(abs(U));
        [temp,iL] = sort(um,2,'descend'); %#ok<ASGLU>
        for i=1:min(tnz-nzW, GMPLoopSize)
            il = iL(i);
            ik = iK(il);
            W(ik,il) = W(ik,il) + U(ik,il)*Gd(ik);
        end
        nzW = sum(W(:) ~= 0);
        R = X - D*W;
    end
    if (verbose > 1)
        disp(['GMP: nzW = ',int2str(nzW),' and ||R||^2 = ',...
            num2str(sum(sum((R.*R))))]);
    end
    done = true;
end
%%OMP and ORMP are almost equal.
% function is from FrameTools\VSormp.m (ver 12.06.2003 with some few
% modifications). Variables have short names so there is a risk for
% variable mixup when using the algoritm within a larger context.
if strcmpi(met,'OMP') || strcmpi(met,'ORMP')
    if strcmpi(met,'OMP')
        textMethod = 'Orthogonal Matching Pursuit.';
    end
    if strcmpi(met,'ORMP')
        textMethod = 'Order Recursive Matching Pursuit.';
    end
    if (verbose >= 1); disp([mfile,': ',textMethod]); end;
    F = D.*(ones(size(D,1),1)*(1./sqrt(sum(D.*D))));  % normalize D
    FF = F'*F;
    for columnNumber = 1:L        % i.e. for each data vector
        % **********************  INITIALIZE  **********************
        x = X(:,columnNumber);
        S = tnz(columnNumber);
        r = zeros(S,K);
        w = zeros(K,1);
        T = 1:K;
        e = ones(K,1);
        u = ones(K,1);
        c = x'*F;
        n2x = x'*x;
        n2xLim = n2x*tre(columnNumber);
        % select the first frame vector
        [cm,km] = max(abs(c));
        s = 1;
        J = km;
        T(km) = -1;
        r(1,km) = u(km);
        n2x = n2x-cm*cm;
        % **********************  THE MAIN LOOP  **********************
        while ((s<S) && (n2x>n2xLim))
            for k=1:K
                if (T(k)>=0)
                    r(s,k) = FF(km,k);
                    for n=1:(s-1)
                        r(s,k) = r(s,k)-r(n,km)*r(n,k);
                    end
                    if (u(km)~=0); r(s,k) = r(s,k)/u(km); end;
                    c(k) = c(k)*u(k)-c(km)*r(s,k);
                    if strcmpi(met,'OMP')  % use next line for OMP
                        w(k) = abs(c(k));  % use w here (instead of a new variable d)
                    end
                    e(k) = e(k)-r(s,k)*r(s,k);
                    u(k) = sqrt(abs(e(k)));  % abs kun i matlab!
                    if (u(k)~=0); c(k) = c(k)/u(k); end;
                    if strcmpi(met,'ORMP')  % use next line for ORMP
                        w(k) = abs(c(k));     % use w here (instead of a new variable d)
                    end
                end
            end
            w(km) = 0;   % w(J) = 0;
            % select the next frame vector
            [temp,km] = max(abs(w)); %#ok<ASGLU>
            s = s+1;
            J(s) = km;
            T(km) = -1;
            r(s,km) = u(km);
            cm = c(km);
            n2x = n2x-cm*cm;
        end  % ******** END OF MAIN LOOP **********************************
          % ************ BACK-SUBSTITUTION *************
          w = zeros(K,1);
          for k=s:(-1):1
              Jk=J(k);
              for n=s:(-1):(k+1)
                  c(Jk) = c(Jk)-c(J(n))*r(k,J(n));
              end
              if (r(k,Jk)~=0); c(Jk) = c(Jk)/r(k,Jk); end;
              w(Jk) = c(Jk);
          end
          %
          W(:,columnNumber) = w;
      end
      W = W .* ((1./sqrt(sum(D.*D)))'*ones(1,L));  % rescale W
      done = true;
  end
%%Now we are finished, 'done' should be true
%  but test this before finding (and/or) displaying results
W = full(W);   
% W = sparse(W);     % is a good alternative
%%may display info before returning
if done && ((verbose > 1) || (nargout >= 2))  % need some results
    R = X - D*W;
    varX = var(X(:));     
    varR = var(R(:));     
    if (varR > 0)
        snr = 10*log10(varX/varR);
    else
        snr = inf;
    end
    norm0X = sum(X ~= 0);
    norm1X = sum(abs(X));
    normiX = max(abs(X));  
    norm0R = sum(R ~= 0);
    norm1R = sum(abs(R));
    norm2R = sqrt(sum(R.*R));  
    normiR = max(abs(R));  
    norm0W = sum(W ~= 0);
    norm1W = sum(abs(W));
    norm2W = sqrt(sum(W.*W));  
    normiW = max(abs(W));  
end
if done && (verbose >= 2)  % very verbose
    if (snr < 100)
        disp([mfile,': SNR for the reconstruction is ',...
              num2str(snr,'%7.4f')]);
    elseif (snr < 500)
        disp([mfile,': Almost perfect reconstruction, SNR > 100.']);
    else
        disp([mfile,': Perfect reconstruction, X = D*W.']);
    end
    disp(['Number of non-zeros in W is ',int2str(sum(norm0W)),...
        ' (sparseness factor is ',num2str(sum(norm0W)/(N*L)),')']);
    if exist('numberOfIterations','var');        
        disp(['Average number of iterations for each column : ',...
            num2str(mean(numberOfIterations),'%5.1f')]);
    end
    %
    disp(['X: ',num2str(min(norm0X)),' <= ||x||_0 <= ',...
        num2str(max(norm0X)),'  and mean is ',num2str(mean(norm0X))]);
    disp(['   ',num2str(min(norm1X)),' <= ||x||_1 <= ',...
        num2str(max(norm1X)),'  and mean is ',num2str(mean(norm1X))]);
    disp(['   ',num2str(min(norm2X)),' <= ||x||_2 <= ',...
        num2str(max(norm2X)),'  and mean is ',num2str(mean(norm2X))]);
    disp(['   ',num2str(min(normiX)),' <= ||x||_inf <= ',...
        num2str(max(normiX)),'  and mean is ',num2str(mean(normiX))]);
    disp(['R: ',num2str(min(norm0R)),' <= ||r||_0 <= ',...
        num2str(max(norm0R)),'  and mean is ',num2str(mean(norm0R))]);
    disp(['   ',num2str(min(norm1R)),' <= ||r||_1 <= ',...
        num2str(max(norm1R)),'  and mean is ',num2str(mean(norm1R))]);
    disp(['   ',num2str(min(norm2R)),' <= ||r||_2 <= ',...
        num2str(max(norm2R)),'  and mean is ',num2str(mean(norm2R))]);
    disp(['   ',num2str(min(normiR)),' <= ||r||_inf <= ',...
        num2str(max(normiR)),'  and mean is ',num2str(mean(normiR))]);
    disp(['W: ',num2str(min(norm0W)),' <= ||w||_0 <= ',...
        num2str(max(norm0W)),'  and mean is ',num2str(mean(norm0W))]);
    disp(['   ',num2str(min(norm1W)),' <= ||w||_1 <= ',...
        num2str(max(norm1W)),'  and mean is ',num2str(mean(norm1W))]);
    disp(['   ',num2str(min(norm2W)),' <= ||w||_2 <= ',...
        num2str(max(norm2W)),'  and mean is ',num2str(mean(norm2W))]);
    disp(['   ',num2str(min(normiW)),' <= ||w||_inf <= ',...
        num2str(max(normiW)),'  and mean is ',num2str(mean(normiW))]);
    disp(' ');
    disp([mfile,' with ',met,' done. Used time is ',num2str(toc(tstart))]);
    disp(' ');
end
%%Return Outputs
if done
    if (nargout >= 1)
        varargout{1} = W;
    end
    if (nargout >= 2)
        varargout{2} = struct( 'time', toc(tstart), 'snr', snr, ...
            'textMethod', textMethod, ...
            'norm0X', norm0X, 'norm1X', norm1X, ...
            'norm2X', norm2X, 'normiX', normiX, ...
            'norm0R', norm0R, 'norm1R', norm1R, ...
            'norm2R', norm2R, 'normiR', normiR, ...
            'norm0W', norm0W, 'norm1W', norm1W, ...
            'norm2W', norm2W, 'normiW', normiW );
        % extra output arguments for standard and regularized FOUCUSS 
        if exist('sparseInW','var');        
            varargout{2}.sparseInW = sparseInW;
            varargout{2}.edges = edges;
        end
        if exist('changeInW','var');        
            varargout{2}.changeInW = changeInW;
        end
        if exist('numberOfIterations','var');        
            varargout{2}.numberOfIterations = numberOfIterations;
        end
        if exist('sol','var');        
            varargout{2}.sol = sol;
        end
        if exist('paramSPAMS','var');        
            varargout{2}.paramSPAMS = paramSPAMS;
        end
    end
else  %  ~done      did not find W
    textMethod = ['Unknown method ',met,'. Coefficients W not found.'];
    disp([mfile,': ',textMethod]);
    if (nargout >= 1)
        varargout{1} = [];
    end
    if (nargout >= 2)
        varargout{2} = struct( 'time', toc(tstart), ...
            'textMethod', textMethod );
    end
end
if exist('javaErrorMessage','var');        
    varargout{2}.Error = javaErrorMessage;
end
return
function W = setSmallWeightsToZero(X,D,W,tnz,tae,doOP)
[K,L] = size(W);  % K=size(D,2), L=size(X,2)
for i = 1:L
    [absw,I] = sort(abs(W(:,i)),'descend');
    w = zeros(K,1);
    for s = 1:tnz(i)
        if (absw(s) < 1e-10); break; end;
        if doOP % do orthogonal projection onto the selected columns of D
            Di = D(:,I(1:s));
            w(I(1:s)) = (Di'*Di)\(Di'*X(:,i));
        else  % simple thresholding keeps the largest coefficients unaltered
            w(I(s)) = W(I(s),i);
        end
        r = X(:,i) - D*w;
        if (sqrt(r'*r) < tae(i)); break; end;
    end
    W(:,i) = w;
end
return
function [a, b] = assign2(c, d)
a = c;
b = d;
return
function [a, b, c] = assign3(d, e, f)
a = d;
b = e;
c = f;
return
댓글 수: 0
답변 (1개)
  OCDER
      
 2018년 8월 22일
        
      편집: OCDER
      
 2018년 8월 22일
  
      The code is very weird. It immediately summons itself with no switch to break the recursion it seems. Also, inputs D and X are just overridden immediately with randn(N, k) and randn(N, L).
Essentially, it does this as shown below. Not sure how to fix it to give the "correct" results.
function varargout = sparseapprox(X, D, met, varargin)
L = 400;
N = 16;
K = 32;
D = randn(N,K);
X = randn(N,L);
Wi = zeros(K,L);
for i=1:L; Wi(:,i) = randperm(K); end
op = struct('targetNonZeros',5, 'verbose', 2);
[Wlp, rc] = sparseapprox(X, D, 'linprog', op); 
if (nargout >= 1)
    varargout{1} = Wlb;
end
if (nargout >= 2)
    varargout{2} = struct('error', 'failed');
end
Try contacting the author of this work for help, as this is too complex to fix "correctly", as in we could stop the infinite recursion, but don't know when it was suppose to do stop the recursion.
Copyright (c) 2009.  Karl Skretting.  All rights reserved.
University of Stavanger, Signal Processing Group
Mail:  karl.skretting@uis.no   Homepage:  http://www.ux.uis.no/~karlsk/
-----------------------------------------------------
It is unlikely that we'll read every code you've uploaded in your post. The best answer is probably just the link below:
See this link to begin your debugging journey.
If this is not the answer you seek, read this before editing your question:
댓글 수: 0
참고 항목
카테고리
				Help Center 및 File Exchange에서 Model Order Reduction에 대해 자세히 알아보기
			
	Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

