www.gusucode.com > wavelet工具箱matlab源码程序 > wavelet/wavelet/modwptdetails.m
function [W,packetlevels,F] = modwptdetails(x,varargin) %Maximal overlap discrete wavelet packet details % W = MODWPTDETAILS(X) returns the maximal overlap discete wavelet packet % (MODWPT) details for the real-valued 1-D signal, X. The details are % returned for the terminal nodes of the wavelet packet transform at % level 4 or at level floor(log2(numel(X))), whichever is smaller. The % Fejer-Korovkin 18 filter, 'fk18', is used to obtain the MODWPT details. % At level 4, W is a 16-by-numel(X) matrix with each row containing the % sequency-ordered wavelet packet details. The approximate passband for % the n-th row of WPT is [(n-1)/2^5, n/2^5) cycles/sample, n = 1,2,...16. % The MODWPT details are zero-phase filtered projections of the signal % onto the subspaces corresponding to the wavelet packet nodes. The sum % of the MODWPT details over each sample reconstructs the original % signal. % % W = MODWPTDETAILS(X,WNAME) uses the orthogonal wavelet filter specified % by the character vector WNAME. Valid built-in orthogonal wavelet % families begin with 'haar', 'dbN', 'fkN', 'coifN', or 'symN' where N is % the number of vanishing moments for all families except 'fk'. For 'fk', % N is the number of filter coefficients. You can determine valid values % for N by using waveinfo. For example, waveinfo('db'). You can check if % your wavelet is orthogonal by using wavemngr('type',wname) to see if a % 1 is returned. For example, wavemngr('type','db2'). % % W = MODWPTDETAILS(X,Lo,Hi) uses the orthogonal scaling filter, Lo, and % wavelet filter, Hi. Lo and Hi are even-length row or column vectors. % These filters must satisfy the conditions for an orthogonal wavelet. % You can only specify either Lo and Hi or WNAME. % % W = MODWPTDETAILS(...,LEVEL) returns the terminal nodes of the % wavelet packet tree at the positive integer level, LEVEL. The value of % LEVEL cannot exceed floor(log2(numel(X))). At level j, W is a % 2^j-by-numel(x) matrix. The approximate passband for the n-th % row of W at level j is [(n-1)/2^(j+1), n/2^(j+1)) cycles/sample, n = % 1,2,...2^j. % % W = MODWPTDETAILS(...,'FullTree',TREEFLAG) determines the type of % wavelet packet tree MODWPTDETAILS returns. TREEFLAG can be one of the % following options [ true | {false}]. If you set 'FullTree' to true, % MODWPTDETAILS returns the full wavelet packet tree down to the % specified level. If you specify TREEFLAG as false, MODWPTDETAILS only % returns the terminal (final-level) wavelet packet nodes. If % unspecified, TREEFLAG defaults to false. For the full wavelet packet % tree, W is a 2^(level+1)-2-by-N matrix where N is the length of the % data. The rows of W are the sequency-ordered wavelet packet details by % level and index. There are 2^j wavelet packet details at each level j. % You can specify the 'FullTree' name-value pair in the input argument % list anywhere after the input signal, X. % % [W,PACKETLEVELS] = MODWPTDETAILS(...) returns a vector of transform % levels corresponding to the rows of W. If W contains only the terminal % level coefficients, PACKETLEVELS is a vector of constants equal to the % terminal level. If W contains the full wavelet packet tree of details, % PACKETLEVELS is a vector with 2^j elements for each level, j. You % can use PACKETLEVELS with logical indexing to select all the MODWPT % details at a particular level. % % [W,PACKETLEVELS,F] = MODWPTDETAILS(...) returns the center frequencies % in cycles/samples of the approximate passbands corresponding to the % MODWPT details in W. You can multiply F by a sampling frequency to % convert to cycles/unit time. % % %Example 1: % % Obtain the MODWPT details for an ECG signal sampled using the % % default wavelet ('fk18') and level. Demonstrate that summing the % % MODWPT details over each sample reconstructs the signal. % load wecg; % wptdetails = modwptdetails(wecg); % xrec = sum(wptdetails); % max(abs(wecg-xrec')) % % %Example 2 % % Obtain the MODWPT details for a 100-Hz time-localized sine wave in % % noise. The sampling rate is 1000 Hz. Obtain the MODWPT at level 4 % % using the 'fk22' wavelet. Plot the MODWPT details for packet number % % 4. The MODWPT details for the fourth packet at level four represent % % a zero-phase filtering of the input signal with an approximate % % passband of [3Fs/2^5, 4Fs/2^5) where Fs is the sampling frequency. % dt = 0.001; % t = 0:dt:1; % x = cos(2*pi*100*t).*(t>0.3 & t<0.7)+0.25*randn(size(t)); % wptdetails = modwptdetails(x,'fk22'); % p4 = wptdetails(4,:); % plot(t,cos(2*pi*100*t).*(t>0.3 & t<0.7)); % hold on; % plot(t,p4,'r') % legend('Sine Wave','MODWPT Details'); % % See also modwpt, imodwpt %Check number of input arguments is between 1 and 6. narginchk(1,6); %Look to see that the user has specified a fulltree option treematches = find(strncmpi('fulltree',varargin,2)); if any(treematches) fulltreetf = varargin{treematches+1}; %validate the value is logical if ~isequal(fulltreetf,logical(fulltreetf)) error(message('Wavelet:FunctionInput:Logical')); end varargin(treematches:treematches+1) = []; end %Parse and validate input arguments N = numel(x); params = parseinputs(N,varargin{:}); validateinputs(x,params); J = params.J; %If a tree is specified, assign it. if any(treematches) params.fulltree = fulltreetf; end %Ensure input signal is row vector x = x(:)'; Nrep = N; %Obtain the scaling and wavelet filters if specified if isfield(params,'wname') [~,~,LoD,HiD] = wfilters(params.wname); wtype = wavemngr('type',params.wname); if (wtype ~= 1) error(message('Wavelet:modwt:Orth_Filt')); end Lo = LoD/sqrt(2); Hi = HiD/sqrt(2); %if user provides filter pair, check to see if they are orthogonal else filtercheck = CheckFilter(params.Lo,params.Hi); if ~filtercheck error(message('Wavelet:modwt:Orth_Filt')); end Lo = params.Lo./sqrt(2); Hi = params.Hi./sqrt(2); end % Ensure Lo and Hi are row vectors Lo = Lo(:)'; Hi = Hi(:)'; % If the signal length is less than the filter length, need to % periodize the signal in order to use the DFT algorithm if (N <numel(Lo)) x = [x repmat(x,1,ceil(numel(Lo)-N))]; Nrep = numel(x); end % Obtain the DFT of the filters G = fft(Lo,Nrep); H = fft(Hi,Nrep); % Obtain DFT of original data X = fft(x,Nrep); % Create array to hold wavelet packets cfs = zeros(2^(J+1)-2,Nrep); cfs(1,:) = X; packetlevels = repelem(1:J,2.^(1:J)); packetlevels = packetlevels(:); Idx = 1:2; %MODWPT algorithm for kk = 1:J index = 0; jj = 2^kk-1; if (kk>1) Idx = find(packetlevels == kk-1); end for nn = 0:2^kk/2-1 index = index+1; X = cfs(Idx(index),:); [vhat,what] = modwptdecxcorr(X,G,H,kk); if mod(nn,2) cfs(jj+2*nn,:) = what; cfs(jj+2*nn+1,:) = vhat; else cfs(jj+2*nn,:) = vhat; cfs(jj+2*nn+1,:) = what; end end end W = ifft(cfs,[],2); %Ensure that column size of output is the length of the input signal W = W(:,1:N); if nargout > 2 df = 1./2.^(packetlevels+1); idxfirst = 1; if (J>1) idxfirst = cumsum(2.^(0:J-1))'; end df(idxfirst) = df(idxfirst)*(1/2); F = cell2mat(accumarray(packetlevels,df,[],@(x){cumsum(x)})); if ~params.fulltree F = F(end-2^J+1:end); end end %If 'FullTree' is false, reduce details to terminal nodes if ~params.fulltree W = W(end-2^J+1:end,:); packetlevels = packetlevels(end-2^J+1:end); end %------------------------------------------------------------------------- function [Vhat,What] = modwptdecxcorr(X,G,H,J) % [Vhat,What] = modwptdecxcorr(X,G,H,J) N = length(X); upfactor = 2^(J-1); Gup = abs(G(1+mod(upfactor*(0:N-1),N))).^2; Hup = abs(H(1+mod(upfactor*(0:N-1),N))).^2; Vhat = Gup.*X; What = Hup.*X; %------------------------------------------------------------------------- function out = CheckFilter(Lo,Hi) % For a user-supplied scaling and wavelet filter, check that % both correspond to an orthogonal wavelet Lo = Lo(:); Hi = Hi(:); Lscaling = length(Lo); Lwavelet = length(Hi); evenlengthLo = 1-rem(Lscaling,2); evenlengthHi = 1-rem(Lwavelet,2); if all([evenlengthLo evenlengthHi]) evenlength = 1; else evenlength = 0; end if (Lscaling ~= Lwavelet) equallen = 0; else equallen = 1; end normLo = norm(Lo,2); normHi = norm(Hi,2); tol = 1e-7; if (abs(normLo-1) > tol && abs(normHi -1) > tol) unitnorm = 0; else unitnorm = 1; end zeroevenlags = 1; if (Lscaling > 2) L = Lscaling; xcorrHi = conv(Hi,flipud(Hi)); xcorrLo = conv(Lo,flipud(Lo)); xcorrLo = xcorrLo(L+2:2:end); xcorrHi = xcorrHi(L+2:2:end); zeroevenlagsLo = 1-any(abs(xcorrLo>tol)); zeroevenlagsHi = 1-any(abs(xcorrHi>tol)); zeroevenlags = max(zeroevenlagsLo,zeroevenlagsHi); end out = all([evenlength equallen unitnorm zeroevenlags]); %------------------------------------------------------------------------ %------------------------------------------------------------------------- function params = parseinputs(siglen,varargin) % Parse varargin and check for valid inputs % Assign defaults params.J = bsxfun(@min,4,floor(log2(siglen))); params.wname = 'fk18'; params.fulltree = false; if isempty(varargin) return; end % Only remaining char variable must be wavelet name tfchar = cellfun(@ischar,varargin); if (nnz(tfchar) == 1) params.wname = varargin{tfchar>0}; elseif nnz(tfchar)>1 error(message('Wavelet:FunctionInput:InvalidChar')); end % Only scalar input must be the level tfscalar = cellfun(@isscalar,varargin); % Check for numeric inputs tffilters = cellfun(@isnumeric,varargin); % At most 3 numeric inputs are supported if nnz(tffilters)>3 error(message('Wavelet:modwt:Invalid_Numeric')); end % If there are at least two numeric inputs, the first two must be the % scaling and wavelet filters if (nnz(tffilters)>1) idxFilt = find(tffilters,2,'first'); params.Lo = varargin{idxFilt(1)}; params.Hi = varargin{idxFilt(2)}; params = rmfield(params,'wname'); if (length(params.Lo) < 2 || length(params.Hi) < 2) error(message('Wavelet:modwt:Invalid_Filt_Length')); end end % Any scalar input must be the level if any(tfscalar) params.J = varargin{tfscalar>0}; end % If the user specifies a filter, use that instead of default wavelet if (isfield(params,'Lo') && any(tfchar)) error(message('Wavelet:FunctionInput:InvalidWavFilter')); end %------------------------------------------------------------------------ function validateinputs(x,params) %Input must be real-valued, double with no Infs or NaNs validateattributes(x,{'double'},{'real','finite'},'modwptdetails','X'); %Input must be 1-D if (~isrow(x) && ~iscolumn(x)) error(message('Wavelet:modwt:OneD_Input')); end %Input must contain at least two samples if (numel(x)<2) error(message('Wavelet:modwt:LenTwo')); end %J is the transform level J = params.J; validateattributes(J,{'double'},{'integer','positive'},... 'modwptdetails','LEVEL'); %Check the transform level does not exceed the maximum N = numel(x); if (J>floor(log2(N))) error(message('Wavelet:modwt:MRALevel')); end