No BSD License  

Highlights from
Conic Matching Pursuit

image thumbnail
from Conic Matching Pursuit by Joshua Carmichael
Expands data as sum of conic projections

[varargout]=projOnClusters(x,W,varargin)
function [varargout]=projOnClusters(x,W,varargin)
% projOnClusters: A projection pursuit type algorithm that decomposes a
% signal by projecting the residual at each level onto a convex cone and
% the respective polar cone.
%
% The set giving cone k is described by a vector w = W(:,k) and scalar rho:
%
% C_k = { x :  x'w  >= rho*|| x || };
%
% The polar cone is:
%
% C*_k = { y: y'x <= 0, x element of C_k };
%
% where w is the reference vector for the set C. The projector for this set
% is described in:
% 
% Henry Stark and Youngyi Yang, "Vector Space Projections: A Numerical 
% Approach to Signal and Image Processing, Neural Nets, and Optics", Wiley
% Interscienc Publications, 1998.
%
% On pages 109-113, Section 3.5, in the discusssion on similarity
% constraints.
%
%--------------------------------------------------------------------------
% USAGE
%--------------------------------------------------------------------------
%
% [u]=projOnClusters(x,W);
%
%       ...
%
% [u,e,b,ind]=projOnClusters(x,W,rho,'plot');
%
% INPUT
% x: the signal to be analyzed. Must be a column vector or a matrix.
% W: A matrix whose columns are the cone representers (see [].pdf for a
%    description of these). W must have the same number of rows as x does.
% rho: A row vector of correlation coefficients corresponding to the columns
%      of W.
%
% OUTPUT
% u:    The projection onto the convex cones defined by W and rho.
% e:    The projections onto the polar cones correpsonding to the convex
%       cones
% b:    The norm of each projection onto a convex cone: b(k) = ||u(:,k)||
% ind:  The index of cluster that corresponds to u,e, and b.
%
% If no output is requested, a plot is made.  Alternatively, a plot is
% produced if an input argument 'plot' is given.
%
%% Examples:
%%Example 1: Using 5 signals to obtain a rough estimate of a step function
% t   = [linspace(-2*pi,2*pi,256)]';
% x   = zeros(size(t)); x(128-20:128+20)=4;
% y   = zeros(size(t)); y(128-20:128+20)=tukeywin(41,0.4);
% W   = [sin(2*t), y, sinc(2*t), t.*(t-1).*exp(-abs(t)/2),8*t.*[tukeywin(length(t))]];
% rho = 0.95*ones(1,size(W,2)); rho(2:3) = 0.94; %describes cone geometry
% 
% clf;
% [u,e,b,ind]=projOnClusters(x,W,rho,'plot');
% %Check energy preservation
% disp('Check Energy Preservation....');
% disp('Energy in reconstruction');
% recon_erg = sum(b.^2);
% disp('Energy in signal');
% orig_erg = norm(x).^2
% disp('Error : ')
% recon_erg - orig_erg
%--------------------------------------------------------------------------

%Get level of algorithm and length of vectors
J = size(W,2);
M = size(W,1);

%Initialize Outputs
b    = zeros(J+1,1);
u    = zeros(M,J+1);
e    = zeros(M,J+1);
ind  = zeros(J+1,1);
plotopt     = 'none';
rho         = 0.9*ones(1,J);

%% Default variable inputs
if(norm(W)<eps)
    error('W effectively zero');
end;

if( max(rho)>1||min(rho)<0 )
    error('rho must be between 0 and 1');
end;

if(nargin>2)
    for k=1:length(varargin)

        if(ischar(varargin{k}))
            plotopt = varargin{k};
        end;

        if(isnumeric(varargin{k}))
            rho     = varargin{k};
        end;
    end;
end;

%% Normalize Cluster Waveforms (without loops)
temp = W.^2;
temp = (sum(temp)).^(1/2);
s    = diag(temp.^(-1));
W    = W*s;

%make a copy of input W;
C   = W;

%Initialize the first error vector to be the signal
e(:,1)=x;

%% The Convex Set Projection Pursuit Algorithm
for k = 2:J+1

    %--------------------------------------------------------------------------
    %% Edit 21.Feb.2009: Optional to keep xcor-portion of code
%     temp    = [e(:,k-1),W];
%     [temp]  = xcorAlign(temp);
%     W       = temp(:,2:end);
    %--------------------------------------------------------------------------

    %Find the maximum projection of e_k-1 onto a cluster
    [m,i]   = max(rho.*(e(:,k-1)'*W));

    %Record the cluster index
    ind(k)  = i;

    %Extract the waveform for C_k, which is W(:,i)
    w       = W(:,i);

    %Find it's orthongonal complement
    wp      = e(:,k-1) - (e(:,k-1)'*w)*w;

    %Normalize it's orthongonal complement
    wp      = wp/norm(wp);

    %Test to see if e_k-1 is in the convex set defined by W(:,i)
    inSet   = (e(:,k-1)'*w >= rho(i)*norm(e(:,k-1)));

    %if e_k-1 is in C_k then u_k is e_k-1, and the algorithm stops.
    if(inSet)

        u(:,k)   = e(:,k-1);
        b(k)     = norm(u(:,k));
        continue;

    else
        %if e_k-1 is not in C_k then in may be in the C*_k, or have
        %a nonzero projection into both C_k and C*_k
        beta     = [e(:,k-1)'*[w,wp]]';
        r        = [rho(i);sqrt(1-rho(i)^2)];
        inPol    = (r'*beta <= 0);

        %if e_k-1 is in C*_k then it is equal to e_k
        if(inPol)
            e(:,k) = e(:,k-1);
        end;

        %if it is neither in C_k nor in C*_k then it has a projection onto
        %the boundary of C_k, and the boundary of C*_k
        if(~inPol)
            u(:,k) = [w,wp]*r*r'*beta;
            e(:,k) = [w,wp]*(eye(2,2)-r*r')*beta;
            b(k)   = norm(u(:,k));
        end;

    end;

    %Remove the i_th cluster so that it will not be tested again
    W(:,i)=NaN(M,1);

end;

u           = u(:,2:end);
e           = e(:,2:end);
ind         = ind(ind>0);
temp        = zeros(size(ind));
temp(ind)   = b(2:end);
b           = temp;

if(nargout>0)

    for k = 1:nargout

        if(nargout>=1), varargout{1}=u;     end;
        if(nargout>=2), varargout{2}=e;     end;
        if(nargout>=3), varargout{3}=b;     end;
        if(nargout>=4), varargout{4}=ind;   end;

    end;

end;


%% Plot Synthesis and Energy Distribution

if(nargout<1)
    plotopt='plot';
end;

ind = ind(ind>0);

if(strcmp(plotopt,'plot'))

    subplot(2,2,[1,2]);
    plot(x,'k','linewidth',2); hold on;
    %plot(sum(u,2)+e(:,end),'--r','linewidth',2);
    plot(sum(u,2),'--r','linewidth',2);
    title('Signal With Cluster Reconstruction','fontsize',16,'fontweight','bold');
    set(gca,'fontsize',16,'fontweight','bold');
    s=legend('Signal','Reconstruction');
    set(s,'fontsize',16);
    legend('boxoff');
    set(gca,'ytick',[]);
    set(gca,'Color', [0.85,0.9,1]);
    axis tight;

    for k=1:size(ind>0);

        if(b(k)>0.05*max(b))
            color='r';
        else
            color='k';
        end;

        subplot(2,2,3); hold on;

        plot(C(:,k)+k,char(color),'linewidth',1);

        subplot(2,2,4); hold on;

        bar(k,b(k)^2,char(color));

    end;

    subplot(2,2,3);

    set(gca,'xtick',[]);
    xlabel('Cluster Waveforms','fontsize',18,'fontweight','bold');
    set(gca,'fontsize',18,'fontweight','bold');
    axis tight;
    set(gca,'Color', [0.85,0.9,1]);

    subplot(2,2,4);

    %set(gca,'xtick',[]);
    xlabel('Energy in Cluster','fontsize',18,'fontweight','bold');
    set(gca,'fontsize',18,'fontweight','bold');
    axis tight;
    set(gca,'Color', [0.85,0.9,1]);

    set(gcf,'color','w');
end;

Contact us at files@mathworks.com