function varargout = sparseapprox(X, D, met, varargin)
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);
op = struct('targetNonZeros',5, 'verbose', 2);
[Wpinv, ra] = sparse(X);
[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);
[Wlasso, rl] = sparseapprox(X, D, 'mexLasso', op);
i = 11; [Wt(:,i), Womp(:,i), Wormp(:,i), Wmomp(:,i), Wlasso(:,i), Wps100(:,i)]
if (nargin < 3)
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
tstart = tic;
[N,L] = size(X);
K = size(D,2);
norm2X = sqrt(sum(X.*X));
W = zeros(K,L);
tnz = ceil(N/2)*ones(1,L);
thrActive = false;
doOP = true;
relLim = 1e-6;
tre = relLim*ones(1,L);
nComb = 20;
nIt = 20;
pFOCUSS = 0.5;
lambdaFOCUSS = 0;
deltaWlimit = 1e-8;
GMPLoopSize = 0;
globalReDist = 0;
targetSSE = 0;
verbose = 0;
done = false;
javaClass = 'mpv2.MatchingPursuit';
spams_mex_file = 'mexLasso';
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);
fieldNumber = fieldNumber + 1;
if (fieldNumber > numel(sNames))
fieldNumber = 1;
optionNumber = optionNumber + 1;
end
elseif iscell(varargin{optionNumber})
sOptions = varargin{optionNumber};
opName = sOptions{fieldNumber};
opVal = sOptions{fieldNumber+1};
fieldNumber = fieldNumber + 2;
if (fieldNumber > numel(sOptions))
fieldNumber = 1;
optionNumber = optionNumber + 1;
end
else
opName = varargin{optionNumber};
opVal = varargin{optionNumber+1};
optionNumber = optionNumber + 2;
end
if strcmpi(opName,'targetNonZeros') || strcmpi(opName,'tnz')
if strcmpi(met,'GMP')
tnz = opVal;
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);
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')
tre = tae./norm2X;
elseif exist('tre','var')
tae = tre.*norm2X;
else
disp(' ??? This is never printed.');
end
if (verbose > 1)
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
if (strcmpi(met,'mexOMP') || strcmpi(met,'mexORMP') || ...
strcmpi(met,'mexLasso') || strcmpi(met,'LARS') || strcmpi(met,'LASSO'))
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
if ~(exist(spams_mex_file,'file') == 3)
start_spams;
end
if ~(exist(spams_mex_file,'file') == 3)
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'))
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
W = mexLasso(X, D, paramSPAMS);
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
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];');
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;
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;
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')
if (targetSSE > 0)
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
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
if (globalReDist > 0)
R = X - D * W;
S = sum(W ~= 0);
SE = sum(R.*R);
sumSinit = sum(S);
SSE = sum(SE);
SSEinit = SSE;
Sp1 = S + 1;
Sp1(Sp1 > N) = N;
Sm1 = S - 1;
Sm1(Sm1 < 0) = 0;
SEp1 = zeros(1,L);
SEm1 = zeros(1,L);
for j=1:L
x = X(:,j);
if Sp1(j) == S(j)
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;
SEinc = SEm1-SE;
SEinc(S == 0) = inf;
addedS = 0;
removedS = 0;
addedSE = 0;
removedSE = 0;
[valinc, jinc] = min(SEinc);
[valdec, jdec] = max(SEdec);
if (targetSSE > 0)
if (SSEinit > targetSSE)
if (verbose > 2)
disp(['(part 2 add atoms, target SSE = ',num2str(targetSSE),...
' and initial SSE = ',num2str(SSEinit),')']);
end
while (SSE > targetSSE)
j = jdec;
addedS = addedS+1;
removedSE = removedSE + valdec;
SSE = SSE - valdec;
[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));
if (Sp1(j) > S(j))
w = jMP.vsORMP(X(:,j), Sp1(j), relLim);
r = X(:,j) - D*w;
SEp1(j) = r'*r;
end
SEinc(j) = SEdec(j);
SEdec(j) = SE(j)-SEp1(j);
W(:,j) = jMP.vsORMP(X(:,j), S(j), relLim);
[valdec, jdec] = max(SEdec);
end
[valinc, jinc] = min(SEinc);
elseif ((SSEinit+valinc) < targetSSE)
if (verbose > 2)
disp(['(part 3 remove atoms, target SSE = ',num2str(targetSSE),...
' and initial SSE = ',num2str(SSEinit),')']);
end
while ((SSE+valinc) < targetSSE)
j = jinc;
removedS = removedS+1;
addedSE = addedSE + valinc;
SSE = SSE + valinc;
[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));
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);
if (S(j) > 0)
W(:,j) = jMP.vsORMP(X(:,j), S(j), relLim);
SEinc(j) = SEm1(j)-SE(j);
else
W(:,j) = zeros(K,1);
SEinc(j) = inf;
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
while ((valinc < valdec) && (jinc ~= jdec))
j = jdec;
addedS = addedS+1;
removedSE = removedSE + valdec;
SSE = SSE - valdec;
[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));
if (Sp1(j) > S(j))
w = jMP.vsORMP(X(:,j), Sp1(j), relLim);
r = X(:,j) - D*w;
SEp1(j) = r'*r;
end
SEinc(j) = SEdec(j);
SEdec(j) = SE(j)-SEp1(j);
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;
[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));
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);
if (S(j) > 0)
W(:,j) = jMP.vsORMP(X(:,j), S(j), relLim);
SEinc(j) = SEm1(j)-SE(j);
else
W(:,j) = zeros(K,1);
SEinc(j) = inf;
end
[valinc, jinc] = min(SEinc);
if (globalReDist == 1); break; end;
end
[valdec, jdec] = max(SEdec);
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
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
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)));
F = D.*(ones(size(D,1),1)*Gd);
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;
[um,iK] = max(abs(U));
[temp,iL] = sort(um,2,'descend');
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
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))));
FF = F'*F;
for columnNumber = 1:L
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);
[cm,km] = max(abs(c));
s = 1;
J = km;
T(km) = -1;
r(1,km) = u(km);
n2x = n2x-cm*cm;
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')
w(k) = abs(c(k));
end
e(k) = e(k)-r(s,k)*r(s,k);
u(k) = sqrt(abs(e(k)));
if (u(k)~=0); c(k) = c(k)/u(k); end;
if strcmpi(met,'ORMP')
w(k) = abs(c(k));
end
end
end
w(km) = 0;
[temp,km] = max(abs(w));
s = s+1;
J(s) = km;
T(km) = -1;
r(s,km) = u(km);
cm = c(km);
n2x = n2x-cm*cm;
end
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));
done = true;
end
W = full(W);
if done && ((verbose > 1) || (nargout >= 2))
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)
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
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 );
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
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);
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
Di = D(:,I(1:s));
w(I(1:s)) = (Di'*Di)\(Di'*X(:,i));
else
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