Mercurial > hg > smallbox
diff util/classes/dictionaryMatrices/grassmannian.m @ 160:e3035d45d014 danieleb
Added support classes
author | Daniele Barchiesi <daniele.barchiesi@eecs.qmul.ac.uk> |
---|---|
date | Wed, 31 Aug 2011 10:53:10 +0100 |
parents | |
children | 88578ec2f94a |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/util/classes/dictionaryMatrices/grassmannian.m Wed Aug 31 10:53:10 2011 +0100 @@ -0,0 +1,44 @@ +function [A G res muMin] = grassmannian(n,m,nIter,dd1,dd2,initA,verb) +% grassmanian attempts to create an n by m matrix with minimal mutual +% coherence using an iterative projection method. +% +% [A G res] = grassmanian(n,m,nIter,dd1,dd2,initA) +% +% +%% Parameters and Defaults +error(nargchk(2,7,nargin)); + +if ~exist('verb','var') || isempty(verb), verb = false; end %verbose output +if ~exist('initA','var') || isempty(initA), initA = randn(n,m); end %initial matrix +if ~exist('dd2','var') || isempty(dd2), dd2 = 0.95; end %shrinking factor +if ~exist('dd1','var') || isempty(dd1), dd1 = 0.9; end %percentage of coherences to be shrinked +if ~exist('nIter','var') || isempty(nIter), nIter = 5; end %number of iterations + +%% Compute svd and gramian +A = normc(initA); %normalise columns +[Uinit Sigma] = svd(A); %calculate svd of the matrix +G = A'*A; %gramian matrix + +muMin = sqrt((m-n)/(n*(m-1))); %Lower bound on mutual coherence +res = zeros(nIter,1); +for iIter = 1:nIter + gg = sort(abs(G(:))); %sort inner products from less to ost correlated + pos = find(abs(G(:))>gg(round(dd1*(m^2-m))) & abs(G(:)-1)>1e-6); + G(pos) = G(pos)*dd2; + [U S V] = svd(G); + S(n+1:end,1+n:end) = 0; + G = U*S*V'; + G = diag(1./abs(sqrt(diag(G))))*G*diag(1./abs(sqrt(diag(G)))); + gg = sort(abs(G(:))); + pos = find(abs(G(:))>gg(round(dd1*(m^2-m))) & abs(G(:)-1)>1e-6); + res(iIter) = max(abs(G(pos))); + if verb + fprintf(1,'%6i %12.8f %12.8f %12.8f \n',... + [iIter,muMin,mean(abs(G(pos))),max(abs(G(pos)))]); + end +end + +[~, Sigma_gram V_gram] = svd(G); %calculate svd decomposition of gramian +Sigma_new = sqrt(Sigma_gram(1:n,:)).*sign(Sigma); +A = Uinit*Sigma_new*V_gram'; +A = normc(A);