ivan@152: function dico = dico_decorr(dico, mu, amp) ivan@152: %DICO_DECORR decorrelate a dictionary ivan@152: % Parameters: ivan@152: % dico: the dictionary ivan@152: % mu: the coherence threshold ivan@152: % amp: the amplitude coefficients, only used to decide which atom to ivan@152: % project ivan@152: % ivan@152: % Result: ivan@152: % dico: a dictionary close to the input one with coherence mu. ivan@152: ivan@152: % compute atom weights ivan@152: if nargin > 2 ivan@152: rank = sum(amp.*amp, 2); ivan@152: else ivan@152: rank = randperm(length(dico)); ivan@152: end ivan@152: ivan@152: % several decorrelation iterations might be needed to reach global ivan@152: % coherence mu. niter can be adjusted to needs. ivan@152: niter = 1; ivan@152: while niter < 5 && ... ivan@152: max(max(abs(dico'*dico -eye(length(dico))))) > mu + 10^-6 ivan@152: % find pairs of high correlation atoms ivan@152: colors = dico_color(dico, mu); ivan@152: ivan@152: % iterate on all pairs ivan@152: nbColors = max(colors); ivan@152: for c = 1:nbColors ivan@152: index = find(colors==c); ivan@152: if numel(index) == 2 ivan@152: % decide which atom to change (the one with lowest weight) ivan@152: if rank(index(1)) < rank(index(2)) ivan@152: index = fliplr(index); ivan@152: end ivan@152: ivan@152: % update the atom ivan@152: corr = dico(:,index(1))'*dico(:,index(2)); ivan@152: alpha = sqrt((1-mu*mu)/(1-corr*corr)); ivan@152: beta = corr*alpha-mu*sign(corr); ivan@152: dico(:,index(2)) = alpha*dico(:,index(2))... ivan@152: -beta*dico(:,index(1)); ivan@152: end ivan@152: end ivan@152: niter = niter+1; ivan@152: end ivan@152: end ivan@152: