| daniele@170 | 1 function [dic mus srs] = iterativeprojections(dic,mu,Y,X,params) | 
| daniele@169 | 2 % grassmanian attempts to create an n by m matrix with minimal mutual | 
| daniele@169 | 3 % coherence using an iterative projection method. | 
| daniele@169 | 4 % | 
| daniele@170 | 5 % REFERENCE | 
| daniele@169 | 6 % | 
| daniele@169 | 7 | 
| daniele@169 | 8 %% Parameters and Defaults | 
| daniele@170 | 9 if ~nargin, testiterativeprojections; return; end | 
| daniele@169 | 10 | 
| daniele@170 | 11 if ~exist('params','var') || isempty(param), params = struct; end | 
| daniele@170 | 12 if ~isfield(params,'nIter'), params.nIter = 10; end %number of iterations | 
| daniele@170 | 13 if ~isfield(params,'eps'),	 params.eps = 1e-9;	 end %tolerance level | 
| daniele@170 | 14 [n m] = size(dic); | 
| daniele@169 | 15 | 
| daniele@170 | 16 SNR = @(dic) snr(Y,dic*X);									 %SNR function | 
| daniele@170 | 17 MU  = @(dic) max(max(abs((dic'*dic)-diag(diag(dic'*dic))))); %coherence function | 
| daniele@169 | 18 | 
| daniele@170 | 19 %% Main algorithm | 
| daniele@170 | 20 dic = normc(dic);	%normalise columns | 
| daniele@170 | 21 alpha = m/n;		%ratio between number of atoms and ambient dimension | 
| daniele@170 | 22 | 
| daniele@170 | 23 mus = zeros(params.nIter,1);		%coherence at each iteration | 
| daniele@170 | 24 srs = zeros(params.nIter,1);		%signal to noise ratio at each iteration | 
| daniele@170 | 25 iIter = 1; | 
| daniele@170 | 26 while iIter<=params.nIter && MU(dic)>mu | 
| daniele@170 | 27 	fprintf(1,'Iteration number %u\n', iIter); | 
| daniele@170 | 28 	% calculate snr and coherence | 
| daniele@170 | 29 	mus(iIter) = MU(dic); | 
| daniele@170 | 30 	srs(iIter) = SNR(dic); | 
| daniele@170 | 31 | 
| daniele@170 | 32 	% calculate gram matrix | 
| daniele@170 | 33 	G = dic'*dic; | 
| daniele@170 | 34 | 
| daniele@184 | 35 	% project onto the structural constraint set | 
| daniele@170 | 36 	H = zeros(size(G));				%initialise matrix | 
| daniele@170 | 37 	ind1 = find(abs(G(:))<=mu);		%find elements smaller than mu | 
| daniele@170 | 38 	ind2 = find(abs(G(:))>mu);		%find elements bigger than mu | 
| daniele@170 | 39 	H(ind1) = G(ind1);				%copy elements belonging to ind1 | 
| daniele@170 | 40 	H(ind2) = mu*sign(G(ind2));		%threshold elements belonging to ind2 | 
| daniele@170 | 41 	H(1:m+1:end) = 1;				%set diagonal to one | 
| daniele@170 | 42 | 
| daniele@170 | 43 	% project into spectral constraint set | 
| daniele@170 | 44 	[~ , S, V] = svd(H); | 
| daniele@170 | 45 	%G = alpha*(V(:,1:n)*V(:,1:n)'); | 
| daniele@170 | 46 	G = V(:,1:n)*S(1:n,1:n)*V(:,1:n)'; | 
| daniele@170 | 47 | 
| daniele@170 | 48 	% calculate dictionary | 
| daniele@170 | 49 	[~, S V] = svd(G); | 
| daniele@170 | 50 	dic = sqrt(S(1:n,:))*V'; | 
| daniele@170 | 51 | 
| daniele@170 | 52 	% rotate dictionary | 
| daniele@170 | 53 	options = struct('nIter',100,'step',0.001); | 
| daniele@170 | 54 	[~, ~, W] = rotatematrix(Y,dic*X,'conjgradlie',options); | 
| daniele@170 | 55 	dic = W*dic; | 
| daniele@170 | 56 | 
| daniele@170 | 57 	iIter = iIter+1; | 
| daniele@169 | 58 end | 
| daniele@170 | 59 if iIter<params.nIter | 
| daniele@170 | 60 	mus(iIter:end) = mus(iIter); | 
| daniele@170 | 61 	srs(iIter:end) = srs(iIter); | 
| daniele@170 | 62 end | 
| daniele@170 | 63 % Test function | 
| daniele@170 | 64 function testiterativeprojections | 
| daniele@170 | 65 clc | 
| daniele@170 | 66 %define parameters | 
| daniele@170 | 67 n = 256;							%ambient dimension | 
| daniele@170 | 68 m = 512;							%number of atoms | 
| daniele@170 | 69 N = 1024;							%number of signals | 
| daniele@170 | 70 mu_min = sqrt((m-n)/(n*(m-1)));		%minimum coherence | 
| daniele@169 | 71 | 
| daniele@170 | 72 %initialise data | 
| daniele@170 | 73 X = sprandn(m,N,1);					%matrix of coefficients | 
| daniele@170 | 74 phi = normc(randn(n,m));			%dictionary | 
| daniele@170 | 75 temp = randn(n); | 
| daniele@170 | 76 W = expm(0.5*(temp-temp'));			%rotation matrix | 
| daniele@170 | 77 Y = W*phi*X;						%observed signals | 
| daniele@169 | 78 | 
| daniele@170 | 79 %optimise dictionary | 
| daniele@170 | 80 [~, mus srs] = iterativeprojections(phi,0.2,Y,X); | 
| daniele@169 | 81 | 
| daniele@170 | 82 %plot results | 
| daniele@170 | 83 nIter = length(mus); | 
| daniele@169 | 84 | 
| daniele@170 | 85 figure, | 
| daniele@170 | 86 subplot(2,1,1) | 
| daniele@170 | 87 plot(1:nIter,srs,'kd-'); | 
| daniele@170 | 88 xlabel('nIter'); | 
| daniele@170 | 89 ylabel('snr (dB)'); | 
| daniele@170 | 90 grid on | 
| daniele@169 | 91 | 
| daniele@170 | 92 subplot(2,1,2), hold on | 
| daniele@170 | 93 plot(1:nIter,mus,'ko-'); | 
| daniele@170 | 94 plot([1 nIter],[mu_min mu_min],'k') | 
| daniele@170 | 95 grid on | 
| daniele@170 | 96 legend('\mu','\mu_{min}'); | 
| daniele@169 | 97 |