function [c,info]=dtwfb(f,dualwt,varargin)
%DTWFB Dual-Tree Wavelet Filter Bank
% Usage: c=dtwfb(f,dualwt);
% c=dtwfb(f,{dualw,J});
% [c,info]=dtwfb(...);
%
% Input parameters:
% f : Input data.
% dualwt : Dual-tree Wavelet Filter bank definition.
%
% Output parameters:
% c : Coefficients stored in a cell-array.
% info : Additional transform parameters struct.
%
% c=DTWFBt(f,dualwt) computes dual-tree complex wavelet coefficients
% of the signal f. The representation is approximately
% time-invariant and provides analytic behaviour. Due to these facts,
% the resulting subbands are nearly aliasing free making them suitable
% for severe coefficient modifications. The representation is two times
% redundant, provided critical subsampling of all involved filter banks.
%
% The shape of the filterbank tree and filters used is controlled by
% dualwt (for possible formats see below). The output c is a
% cell-array with each element containing a single subband. The subbands
% are ordered with the increasing subband centre frequency.
%
% In addition, the function returns struct. info containing transform
% parameters. It can be conveniently used for the inverse transform
% IDTWFB e.g. fhat = iDTWFB(c,info). It is also required by
% the PLOTWAVELETS function.
%
% If f is a matrix, the transform is applied to each column.
%
% Two formats of dualwt are accepted:
%
% 1) Cell array of parameters. First two elements of the array are
% mandatory {dualw,J}.
%
% dualw
% Basic dual-tree filters
% J*
% Number of levels of the filter bank tree
%
% Possible formats of dualw are the same as in FWTINIT except the
% wfiltdt_ prefix is used when searching for function specifying
% the actual impulse responses. These filters were designed specially
% for the dual-tree filter bank to achieve the half-sample shift
% ultimately resulting in analytic (complex) behaviour of the
% transform.
%
% The default shape of the filter bank tree is DWT i.e. only low-pass
% output is decomposed further (*J times in total).
%
% Different filter bank tree shapes can be obtained by passing
% additional flag in the cell array. Supported flags (mutually
% exclusive) are:
%
% 'dwt'
% Plain DWT tree (default). This gives one band per octave freq.
% resolution when using 2 channel basic wavelet filter bank.
%
% 'full'
% Full filter bank tree. Both (all) basic filter bank outputs are
% decomposed further up to depth J achieving linear frequency band
% division.
%
% 'doubleband','quadband','octaband'
% The filter bank is designed such that it mimics 4-band, 8-band or
% 16-band complex wavelet transform provided the basic filter bank
% is 2 channel. In this case, J is treated such that it defines
% number of levels of 4-band, 8-band or 16-band transform.
%
% The dual-tree wavelet filter bank can use any basic wavelet
% filter bank in the first stage of both trees, provided they are
% shifted by 1 sample (done internally). A custom first stage
% filter bank can be defined by passing the following
% key-value pair in the cell array:
%
% 'first',w
% w defines a regular basic filter bank. Accepted formats are the
% same as in FWTINIT assuming the wfilt_ prefix.
%
% Similarly, when working with a filter bank tree containing
% decomposition of high-pass outputs, some filters in both trees must
% be replaced by a regular basic filter bank in order to achieve the
% approximately analytic behaviour. A custom filter bank can be
% specified by passing another key-value pair in the cell array:
%
% 'leaf',w
% w defines a regular basic filter bank. Accepted formats are the
% same as in FWTINIT assuming the wfilt_ prefix.
%
% 2) Another possibility is to pass directly a struct. returned by
% DTWFBINIT and possibly modified by WFBTREMOVE.
%
% Optional args.:
% ---------------
%
% In addition, the following flag groups are supported:
%
% 'freq','nat'
% Frequency or natural (Paley) ordering of coefficient subbands.
% By default, subbands are ordered according to frequency. The natural
% ordering is how the subbands are obtained from the filter bank tree
% without modifications. The ordering differs only in non-plain DWT
% case.
%
% Boundary handling:
% ------------------
%
% In contrast with FWT, WFBT and WPFBT, this function supports
% periodic boundary handling only.
%
% Examples:
% ---------
%
% A simple example of calling the DTWFB function using the regular
% DWT iterated filter bank. The second figure shows a magnitude frequency
% response of an identical filter bank.:
%
% [f,fs] = greasy;
% J = 6;
% [c,info] = dtwfb(f,{'qshift3',J});
% figure(1);
% plotwavelets(c,info,fs,'dynrange',90);
% figure(2);
% [g,a] = dtwfb2filterbank({'qshift3',J});
% filterbankfreqz(g,a,1024,'plot','linabs');
%
% The second example shows a decomposition using a full filter bank tree
% of depth J*:
%
% [f,fs] = greasy;
% J = 5;
% [c,info] = dtwfb(f,{'qshift4',J,'full'});
% figure(1);
% plotwavelets(c,info,fs,'dynrange',90);
% figure(2);
% [g,a] = dtwfb2filterbank({'qshift4',J,'full'});
% filterbankfreqz(g,a,1024,'plot','linabs');
%
% See also: dtwfbreal idtwfb plotwavelets dtwfb2filterbank
%
% References:
% I. Selesnick, R. Baraniuk, and N. Kingsbury. The dual-tree complex
% wavelet transform. Signal Processing Magazine, IEEE, 22(6):123 -- 151,
% nov. 2005.
%
% N. Kingsbury. Complex wavelets for shift invariant analysis and
% filtering of signals. Applied and Computational Harmonic Analysis,
% 10(3):234 -- 253, 2001.
%
% I. Bayram and I. Selesnick. On the dual-tree complex wavelet packet and
% m-band transforms. Signal Processing, IEEE Transactions on,
% 56(6):2298--2310, June 2008.
%
%
% Url: http://ltfat.github.io/doc/wavelets/dtwfb.html
% Copyright (C) 2005-2023 Peter L. Soendergaard <peter@sonderport.dk> and others.
% This file is part of LTFAT version 2.6.0
%
% This program is free software: you can redistribute it and/or modify
% it under the terms of the GNU General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU General Public License
% along with this program. If not, see <http://www.gnu.org/licenses/>.
% Author: Zdenek Prusa
% Date: 30.6.2014
complainif_notenoughargs(nargin,2,'DTWFB');
definput.import = {'wfbtcommon'};
flags =ltfatarghelper({},definput,varargin);
% Initialize the wavelet tree structure
dtw = dtwfbinit(dualwt,flags.forder);
%% ----- step 1 : Verify f and determine its length -------
[f,Ls]=comp_sigreshape_pre(f,upper(mfilename),0);
% Determine next legal input data length.
L = wfbtlength(Ls,dtw,'per');
% Pad with zeros if the safe length L differs from the Ls.
if(Ls~=L)
f=postpad(f,L);
end
%% ----- step 3 : Run computation
[nodesBF, rangeLoc, rangeOut] = treeBFranges(dtw);
c = comp_dtwfb(f,dtw.nodes(nodesBF),dtw.dualnodes(nodesBF),rangeLoc,...
rangeOut,'per',1);
%% ----- Optionally : Fill info struct ----
if nargout>1
% Transform name
info.fname = 'dtwfb';
% Dual-Tree struct.
info.wt = dtw;
% Periodic boundary handling
info.ext = 'per';
% Lengths of subbands
info.Lc = cellfun(@(cEl) size(cEl,1),c);
% Signal length
info.Ls = Ls;
% Ordering of the subbands
info.fOrder = flags.forder;
% Cell format
info.isPacked = 0;
end