function [ re, resid, fv, Vnew, Di, beta, C, U, Q ] = OBOMPKSwaps( f, V, WC, err, opt, No, ind, swi, sws, tols ) 
% OBOMPKSwaps Oblique Optimized Matching Pursuit with k swaps
%
% Constructs an atomic decomposition which gives the oblique projection of a signal onto a
% subspace of the span of V, along span of WC, using OOMPKSwaps. 
%
% It first takes the orthogonal projection onto the orthogonal complement of the span of
% WC, then finds the atomic decomposition of the projected signal by the OOMP method and
% corrects with KSwapping to obtain the sought projection. 
%
% for an example on how to use OBOMPKSwaps to separate signal components run the code 
% exa_OBOMPKSwaps
%
% Usage:    [ re, resid, fv, Vnew, Di, beta, C, U, Q ] = OBOMPKSwaps( f, V, WC, err,...
%               opt, No, ind, swi, sws, tols );
%           [ re, resid, fv, Vnew, Di ] = OBOMPKSwaps( f, V, W );
%
% Inputs:
%   f       signal to be projected
%   V       dictionary for the space to project onto
%   WC      dictionary spanning the space to project along
%   err     (optional) error of each point of f, or tolerance for the error's norm, before
%           starting the corrections (default err=0.0001*norm(f)) 
%   opt     (optional) chose the method for computing the orthogonal projector with
%           OrthProj (default opt=2 with tolerance for linear Independence 1e-7) 
%   No      (optional) maximal number of atoms to choose,(default No=size(D,2)) 
%   ind     (optional) indices determining the initial subspace
%   swi     (optional) minimum number of atoms to be swapped, (default swi=1) 
%   sws     (optional) maximum number of atoms to be swapped, (default sws=size(beta,2)) 
%   tols    (optional) tolerance for the  final approximation (default 0.0000001*norm(f)) 
%
% Outputs:
%   re      convergence indicator: re=1 if the method converges within the given tols and
%           re=0 otherwise 
%   resid   vector of length sws to store the residuals at each swapping. The first
%           component of resid is the residual when swi atoms are swapped, the second
%           component  when (swi+1) atoms are swapped and so on.
%   fv      oblique projection of f onto  new  V(:,1:k) along WC, i.e. fv=Vnew(:,1:K)*C' 
%   Vnew    the dictionary V rearranged according to the selection process Vnew(:,1:k)
%           contains the atoms chosen to construct the atomic decomposition 
%   Di      indices of atoms in Vnew written w.r.t the original V 
%   beta    'k' biorthogonal vectors to new  V(:,1:k) and U(:,1:k)(spanning the same space
%           as U(:,1:k)  
%   C       'k' coefficients of the atomic decomposition for the oblique projection 
%   U       Dictionary for the orthogonal complement of WC (U(:,1:k)) is a basis
%           bi-orthogonal to beta)  
%   Q       the first k columns Q(:,1:k) gives an orthonormal basis for span of U(:,1:k)
%           and beta.   
%
% References: 
%   [1] L. Rebollo-Neira, "Oblique Matching Pursuit", IEEE Signal Processing Letters,
%   14,10, 703-707 (2007) 
%   [2] L. Rebollo-Neira, "Measurements design and phenomena discrimination", J. Phys. A:
%   Math. Theor. 42 (2009)

% See   http://www.ncrg.aston.ac.uk/Projects/HNLApprox/
%       http://www.nonlinear-approx.info/

%initializing defaults
%
name='OBOMP_KSWAPS';  %name of the routine
%get inputs and setup parameters
[L,N]=size(V);
%
if (nargin<10) tols=0.0000001*norm(f);end
if ((nargin<9) | (isempty(sws)==1)) ;sws=[];end
if ((nargin<8) | (isempty(swi)==1)) ;swi=1;end
if ((nargin<7) | (isempty(ind)==1)) ;ind=[];end
if ((nargin<6) | (isempty(No)==1))  ;No=N;end
if ((nargin<5) | (isempty(opt)==1)) ;opt=2;end
if ((nargin<4) | (isempty(err)==1)) ;err=0.0001*norm(f);end
%
if max(size(err))==1 tol=err;
   else tol=norm(err);
end
%
%============================================
%construct the orthogonal projector onto WC
%============================================
[O,PWC]=OrthProj(WC,opt);
%============================================
%projects the signal f and the subspaces V
%============================================
U=V-PWC*V;
fw=f'-PWC*f';
%errw=(err'-PWC*err');
if max(size(err))==1 tol=err
  else tol=norm(err);
end
%========================================================================   
%find the sparse representation of fw with dictionary U using OOMP method 
%and
%corrects by swapping up to sws atoms or tols is reached
%========================================================================
[re,resid,SU,Di,beta,C,Q]=OOMPKSwaps(fw',U,err,No,ind,swi,sws,tols);
di=size(beta,2);
U=SU;
Vnew=V(:,Di);
fv=Vnew(:,1:di)*C';

%Laura Rebollo-Neira 2008 (Last midification June 2009)

