daniele@160
|
1 function [A G res muMin] = grassmannian(n,m,nIter,dd1,dd2,initA,verb)
|
daniele@160
|
2 % grassmanian attempts to create an n by m matrix with minimal mutual
|
daniele@160
|
3 % coherence using an iterative projection method.
|
daniele@160
|
4 %
|
daniele@160
|
5 % [A G res] = grassmanian(n,m,nIter,dd1,dd2,initA)
|
daniele@160
|
6 %
|
daniele@160
|
7 %
|
daniele@160
|
8 %% Parameters and Defaults
|
daniele@160
|
9 error(nargchk(2,7,nargin));
|
daniele@160
|
10
|
daniele@160
|
11 if ~exist('verb','var') || isempty(verb), verb = false; end %verbose output
|
daniele@160
|
12 if ~exist('initA','var') || isempty(initA), initA = randn(n,m); end %initial matrix
|
daniele@160
|
13 if ~exist('dd2','var') || isempty(dd2), dd2 = 0.95; end %shrinking factor
|
daniele@160
|
14 if ~exist('dd1','var') || isempty(dd1), dd1 = 0.9; end %percentage of coherences to be shrinked
|
daniele@162
|
15 if ~exist('nIter','var') || isempty(nIter), nIter = 10; end %number of iterations
|
daniele@160
|
16
|
daniele@162
|
17 %% Main algo
|
daniele@160
|
18 A = normc(initA); %normalise columns
|
daniele@162
|
19 G = A'*A; %gram matrix
|
daniele@160
|
20
|
daniele@162
|
21 muMin = sqrt((m-n)/(n*(m-1))); %Lower bound on mutual coherence (equiangular tight frame)
|
daniele@160
|
22 res = zeros(nIter,1);
|
daniele@162
|
23 if verb
|
daniele@162
|
24 fprintf(1,'Iter mu_min mu \n');
|
daniele@160
|
25 end
|
daniele@160
|
26
|
daniele@162
|
27 % optimise gram matrix
|
daniele@162
|
28 for iIter = 1:nIter
|
daniele@162
|
29 gg = sort(abs(G(:))); %sort inner products from less to most correlated
|
daniele@162
|
30 pos = find(abs(G(:))>=gg(round(dd1*(m^2-m))) & abs(G(:)-1)>1e-6); %find large elements of gram matrix
|
daniele@162
|
31 G(pos) = G(pos)*dd2; %shrink large elements of gram matrix
|
daniele@162
|
32 [U S V] = svd(G); %compute new SVD of gram matrix
|
daniele@162
|
33 S(n+1:end,1+n:end) = 0; %set small eigenvalues to zero (this ensures rank(G)<=d)
|
daniele@162
|
34 G = U*S*V'; %update gram matrix
|
daniele@162
|
35 G = diag(1./abs(sqrt(diag(G))))*G*diag(1./abs(sqrt(diag(G)))); %normalise gram matrix diagonal
|
daniele@162
|
36 if verb
|
daniele@162
|
37 Geye = G - eye(size(G));
|
daniele@162
|
38 fprintf(1,'%6i %12.8f %12.8f \n',iIter,muMin,max(abs(Geye(:))));
|
daniele@162
|
39 end
|
daniele@162
|
40 end
|
daniele@162
|
41
|
daniele@162
|
42 % [~, Sigma_gram V_gram] = svd(G); %calculate svd decomposition of gramian
|
daniele@162
|
43 % Sigma_new = sqrt(Sigma_gram(1:n,:)).*sign(Sigma); %calculate singular values of dictionary
|
daniele@162
|
44 % A = Uinit*Sigma_new*V_gram'; %update dictionary
|
daniele@162
|
45 % A = normc(A); %normalise dictionary
|
daniele@162
|
46
|
daniele@162
|
47 [U S] = svd(G); %calculate svd decomposition of gramian
|
daniele@162
|
48 A = sqrt(S(1:n,1:n))*U(:,1:n)'; %calculate valid frame, s.t. A'*A=G
|
daniele@162
|
49
|
daniele@162
|
50 % %% Debug visualization function
|
daniele@162
|
51 % function plotcart2d(A)
|
daniele@162
|
52 % compass(A(1,:),A(2,:));
|