function [ re, resid, D, Di, beta, C, Q ] = OOMPKSwaps( f, D, err, No, ind, swi, sws, tols )
% OOMPKSwaps Optimized Orthogonal Matching Pursuit with k swaps
%
% Constructs an approximation of f using OOMP and improves the approximation with
% KSwapping interchanging swi-pairs of atoms (swi from the approximation and swi from the
% dictionary)  then (swi+1)-atoms and (swi+1)-atoms  and so on up to sws-atoms, if tols is
% not reached. If the stopping criterion based on the precision tols  is not reached re=0
% is returned. (See KSwapping)
%
% For an example on how to use OOMPKSwaps to represent a signal run de code exa_OOMPKSwaps
% 
%
% Usage:    [ re, resid, D, Di, beta, C, Q ] = OOMPKSwaps( f, D );
%           [ re, resid, D, Di, beta, C, Q ] = OOMPKSwaps( f, D, err, No, ind, swi,...
%               sws, tols );
%
% Inputs:
%   f       signal to be represenated
%   D       dictionary for the space to project onto
%   err     (optional) error of each point of f, or tolerance for the error's norm, before
%           starting the swappings (default err=0.0001*norm(f))  
%   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.
%   D       updated (re-arranged) dictionary, D(:,1:k) is the selected basis
%   Di      indices of atoms in D with respect to the original dictionary
%   beta    biorthogonal vectors to D(:,1:k)
%   C       coefficients in the expansion
%   Q       Q(:,1:k) orthonormal basis spanning the same space as D(:,1:k), Q(:,k+1:end)
%           unselected atoms subtracted by their component in D(:,1:k) 
%
% References:
%  [1] M. Andrle and L. Rebollo-Neira, "Improvement of Orthogonal Matching Pursuit
%  strategies by Backward and Forward movements," in Proc. of the 31st International
%  Conference on Acoustics, Speech, and Signal Processing (ICASSP'06)
%  [2] M. Andrle and L. Rebollo-Neira, "A swapping-based refinement of orthogonal matching
%  pursuit strategies", Signal Processing, Vol (86,3), 480-495 (2006)
%  [3] 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/
name='OOMP_KSWAPS';  %name of the routine
%get inputs and setup parameters
[L,N]=size(D);
if (nargin<8)     tols=0.0000001*norm(f);end
if ((nargin<7) | (isempty(sws)==1)) ;sws=[];end
if ((nargin<6) | (isempty(swi)==1)) ;swi=1;end
if ((nargin<5) | (isempty(ind)==1)) ;ind=[];end
if ((nargin<4) | (isempty(No)==1))  ;No=N;end
if ((nargin<3) | (isempty(err)==1)) ;err=0.0001*norm(f);end
%
if max(size(err))==1 tol=err;
  else tol=norm(err);
end
%========================================================================
%find the sparse representation of f with dictionary D using OOMP method
%======================================================================== 
[D,Di,beta,C,Q]=OOMP(f,D,tol,No,ind);
di=size(beta,2);
if isempty(sws)==1;sws=di;end
%========================================================================
%improves by swapping up to sws atoms or tols is reached 
%========================================================================
[re,resid,D,Di,beta,C,Q]=KSwapping(f,D,Di,beta,C,Q,swi,sws,tols);
%
%Laura Rebollo-Neira 2008 (Last midification June 2009)
%
