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@170
|
35 % project into 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
|