www.gusucode.com > wavelet工具箱matlab源码程序 > wavelet/wavelet/iwsst.m

    function xrec = iwsst(sst,varargin)
%Inverse Wavelet Synchrosqueezed Transform
% XREC = IWSST(SST) returns the inverse of the wavelet synchrosqueezed
% transform in SST. XREC is a N-by-1 vector where N is the number of
% columns in SST. By default, IWSST assumes the analytic Morlet wavelet was
% used to obtain the SST.
%
% XREC = IWSST(SST,F,FREQRANGE) uses the frequency vector F and the
% two-element vector FREQRANGE to invert the synchrosqueezed transform. F
% is the vector of frequencies corresponding to the rows of SST. FREQRANGE
% is a two-element vector with positive strictly increasing values and must
% lie in the range of F. The synchrosqueezed transform is inverted for all
% frequencies included in FREQRANGE.
%
% XREC = IWSST(SST,IRIDGE) inverts the synchrosqueezed transform along the
% time-frequency ridges specified by the index column vector or matrix,
% IRIDGE. IRIDGE is the output of WSSTRIDGE. If IRIDGE is a matrix, IWSST
% first inverts the synchrosqueezed transform along the first column of
% IRIDGE, then iteratively reconstructs along subsequent columns of IRIDGE.
% XREC is a vector or matrix with the same size as IRIDGE.
%
% XREC = IWSST(...,WAV) uses the wavelet specified by WAV in inverting the
% synchrosqueezed transform. Valid options for WAV are 'amor' and
% 'bump'. You must use the same wavelet in the reconstruction that you used
% in computing the synchrosqueezed transform.
%
% XREC = IWSST(...,IRIDGE,'NumFrequencyBins',NBINS) specifies the number of
% frequency bins +/- the indices in IRIDGE to use in the reconstruction. If
% the index of the time-frequency ridge +/- NBINS exceeds the number of
% frequency bins at any time step, IWSST truncates the reconstruction at
% the first or last frequency bin. If unspecified, NBINS defaults to 16
% bins which is 1/2 the default number of voices per octave. The name-value
% pair 'NumFrequencyBins',NBINS is only valid if you provide the IRIDGE
% input. You can specify the name-value pair anywhere in the input argument
% list after the synchrosqueezed transform, SST.
%
%   %Example 1
%   %   Obtain the wavelet synchrosqueezed transform of a speech sample
%   %   using the bump wavelet. Invert the synchrosqueezed transform, plot
%   %   the result, and look at the L-infinity norm of the difference
%   %   between the original waveform and the reconstruction.
%   load mtlb;
%   dt = 1/Fs;
%   t = 0:dt:numel(mtlb)*dt-dt;
%   Txmtlb = wsst(mtlb,'bump');
%   xrec = iwsst(Txmtlb,'bump');
%   Linf = norm(abs(mtlb-xrec),Inf);
%   plot(t,mtlb); hold on; xlabel('Seconds'); ylabel('Amplitude');
%   plot(t,xrec,'r');
%   title({'Reconstruction of Wavelet Synchrosqueezed Transform'; ...
%   ['Largest Absolute Difference ' num2str(Linf,'%1.2f')]});
%
%   %Example 2
%   %   Obtain the wavelet synchrosqueezed transform of a quadratic chirp
%   %   sampled at 1000 Hz. Extract the maximum energy time-frequency ridge
%   %   and reconstruct the signal mode along the ridge.
%   load quadchirp;
%   sstchirp = wsst(quadchirp);
%   [~,iridge] = wsstridge(sstchirp);
%   xrec = iwsst(sstchirp,iridge);
%   plot(tquad,xrec,'r');
%   hold on;
%   plot(tquad,quadchirp,'b--');
%   xlabel('Time'); ylabel('Amplitude');
%   set(gca,'ylim',[-1.5 1.5]);
%   legend('Reconstruction','Original');
%   grid on;
%   title('Reconstruction of Chirp Along Maximum Time-Frequency Ridge');
%
%   See also wsst, wsstridge

%Check that there are between 1 and 5 inputs
narginchk(1,5);

%Check that input is matrix
validateattributes(sst,{'numeric'},{'finite'},'iwsst','sst');
if (iscolumn(sst) || isrow(sst))
    error(message('Wavelet:synchrosqueezed:InvalidMatrixInput'));
end

%Get size of SST matrix
M = size(sst,1);
N = size(sst,2);

params = parseinputs(M,N,varargin{:});
WAV = params.WAV;
nbins = params.nbins;
Rpsi = waveRpsi(WAV);

if isempty(params.idx)
    xrec = wsstrec(sst,Rpsi,params.f,params.freqrange);
    % Return column vector to be consistent
    xrec = xrec(:);
    return;
end

NumRidges = size(params.idx,2);
curverec = zeros(N,NumRidges);

for ii = 1:NumRidges
    curverec(:,ii) = getcurve(sst,M,N,params.idx(:,ii),nbins,Rpsi);
end

xrec = curverec;



%-------------------------------------------------------------------------
function rpsi = waveRpsi(WAV)

%Admissibility constant for reconstruction


switch WAV
    case 'bump'
        mu = 5;
        sigma = 1;
        bumpwav = @(w)conj(exp(1)*exp(-1./(1-((w-mu)/sigma).^2)))./w;
        rpsi = integral(bumpwav,mu-sigma,mu+sigma);
        rpsi = rpsi/log(2);
        
    case 'amor'
        cf = 6;
        morlwav = @(w)exp(-1/2*(w-cf).^2)./w;
        rpsi = integral(morlwav,0+sqrt(eps),Inf);
        rpsi = rpsi/log(2);
        
end
%-------------------------------------------------------
function curverec = getcurve(sst,M,N,c,nbins,Rpsi)
freqrange = []; %#ok<NASGU>
sstidx = 1:(M*N);
colstart = ones(size(c));
colend = M*ones(size(c));
mincolidx = (0:N-1)'*M+colstart;
maxcolidx = (0:N-1)'*M+colend;
idx = (0:N-1)'*M+c;
idxlower = idx-nbins;
idxupper = idx+nbins;
idxlower = [mincolidx idxlower];
idxlower = max(idxlower,[],2);
idxupper = [maxcolidx idxupper];
idxupper = min(idxupper,[],2);

idxtmp = [];
for ii = 1:numel(idxlower)
    idxtmp = [idxtmp idxlower(ii):idxupper(ii)]; %#ok<AGROW>
end
sst(setdiff(sstidx,idxtmp)) = 0;

curverec = wsstrec(sst,Rpsi,[],[]);

%--------------------------------------------------------------------------
function sigrec = wsstrec(sst,Rpsi,varargin)

if isempty(varargin{1})
    sigrec = 2/Rpsi*real(sum(sst,1));
    return;
else
    f = varargin{1};
    freqrange = varargin{2};
    lfidx = find(f>=freqrange(1),1,'first');
    hfidx = find(f<=freqrange(2),1,'last');
    Txrec = zeros(size(sst));
    Txrec(lfidx:hfidx,:) = sst(lfidx:hfidx,:);
    sigrec = 2/Rpsi*real(sum(Txrec,1));
    
end

%-------------------------------------------------------------------------
function params = parseinputs(nrow,ncol,varargin)
% Set up defaults
params.WAV = 'amor';
params.freqrange = [];
params.f = [];
% Default number of frequency bins is 1/2 the number of voices
params.nbins = 16;
params.idx = [];

tfnumbins = find(strncmpi(varargin,'numfrequencybins',1));

% Find if 'NumFrequencyBins' P-V pair is passed
if any(tfnumbins)
    params.nbins = varargin{tfnumbins+1};
    validateattributes(params.nbins,{'numeric'},...
        {'positive','integer','even','>=',2},'iwsst','NumFrequencyBins');
    varargin(tfnumbins:tfnumbins+1)  = [];
end

% How many numeric inputs
tfvectors = cellfun(@isnumeric,varargin);

% There must be at most two numeric inputs in varargin
if (any(tfvectors) && nnz(tfvectors) >2)
    error(message('Wavelet:modwt:Invalid_Numeric'));
elseif (any(tfvectors) && nnz(tfvectors) == 1)
    % If there is one numeric input, it must be IRIDGE
    params.idx = varargin{tfvectors>0};
    validateattributes(params.idx,{'numeric'},...
        {'positive','integer','>=',1,'<=',nrow,'ndims',2},...
        'iwsst','IRIDGE');
    if (size(params.idx,1) ~= ncol)
        error(message('Wavelet:FunctionInput:DimensionMismatch',...
            size(params.idx,1),ncol));
    end
    
    if any(size(params.idx)==0)
        error(message('Wavelet:FunctionInput:NonzeroColumSize'));
    end
    
elseif (any(tfvectors) && nnz(tfvectors) == 2)
    idxvectors = find(tfvectors,2,'first');
    % If there are two numeric inputs, the first must be F and
    % the second must be FREQRANGE
    params.f = varargin{idxvectors(1)};
    params.freqrange = varargin{idxvectors(2)};
    validateattributes(params.f,{'numeric'},{'positive','increasing'},...
        'iwsst','F');
    % Find the limits of F to test against FREQRANGE
    f1 = params.f(1);
    fend = params.f(end);
    validateattributes(params.freqrange,{'numeric'},...
        {'numel',2,'>=',f1,'<=',fend},'iwsst','FREQRANGE');
end

% You cannot specify the number of bins without specifying the indices
if (isempty(params.idx) && any(tfnumbins))
    error(message('Wavelet:FunctionInput:InvalidSSTReconstruct'));
end

%Only char variable left must be wavelet
tfwav = cellfun(@ischar,varargin);

if (nnz(tfwav) == 1)
    params.WAV = varargin{tfwav>0};
    params.WAV = validatestring(params.WAV,{'bump','amor'},'iwsst','WAV');
elseif nnz(tfwav)>1
    error(message('Wavelet:FunctionInput:InvalidChar'));
    
end