1 function [wt,info] = wfbtinit(wtdef,varargin) 2%-*- texinfo -*- 3%@deftypefn {Function} wfbtinit 4%@verbatim 5%WFBTINIT Initialize Filterbank Tree 6% Usage: wt = wfbtinit(wtdef); 7% 8% Input parameters: 9% wtdef : Filterbank tree definition. 10% 11% Output parameters: 12% wt : Structure describing the filter tree. 13% 14% WFBTINIT({w,J,flag}) creates a filterbank tree of depth J. The 15% parameter w defines a basic wavelet filterbank. For all possible 16% formats see FWT. The following optional flags (still inside of the 17% cell-array) are recognized: 18% 19% 'dwt','full','doubleband','quadband','octaband' 20% Type of the tree to be created. 21% 22% WFBTINIT({w,J,flag,'mod',mod}) creates a filterbank tree as before, 23% but modified according to the value of mod. 24% Recognized options: 25% 26% 'powshiftable' 27% Changes subsampling factors of the root to 1. This results in redundant 28% near-shift invariant representation. 29% 30% The returned structure wt has the following fields: 31% 32% .nodes 33% Cell-array of structures obtained from FWTINIT. Each element 34% define a basic wavelet filterbank. 35% 36% .children 37% Indexes of children nodes 38% 39% .parents 40% Indexes of a parent node 41% 42% .forder 43% Frequency ordering of the resultant frequency bands. 44% 45% The structure together with functions from the wfbtmanip 46% subdirectory acts as an abstract data structure tree. 47% 48% Regular WFBTINIT flags: 49% 50% 'freq','nat' 51% Frequency or natural ordering of the coefficient subbands. The direct 52% usage of the wavelet tree ('nat' option) does not produce coefficient 53% subbans ordered according to the frequency. To achieve that, some 54% filter shuffling has to be done ('freq' option). 55% 56%@end verbatim 57%@strong{Url}: @url{http://ltfat.github.io/doc/wavelets/wfbtinit.html} 58%@seealso{wfbtput, wfbtremove} 59%@end deftypefn 60 61% Copyright (C) 2005-2016 Peter L. Soendergaard <peter@sonderport.dk>. 62% This file is part of LTFAT version 2.3.1 63% 64% This program is free software: you can redistribute it and/or modify 65% it under the terms of the GNU General Public License as published by 66% the Free Software Foundation, either version 3 of the License, or 67% (at your option) any later version. 68% 69% This program is distributed in the hope that it will be useful, 70% but WITHOUT ANY WARRANTY; without even the implied warranty of 71% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 72% GNU General Public License for more details. 73% 74% You should have received a copy of the GNU General Public License 75% along with this program. If not, see <http://www.gnu.org/licenses/>. 76 77% AUTHOR: Zdenek Prusa 78 79% TO DO: Do some caching 80 81% Output structure definition. 82% Effectively, it describes a ADT tree. 83% .nodes, .children, .parents ale all arrays of the same length and the j-th 84% node in the tree is desribed by wt.nodes{j}, wt.children{j} and 85% wt.parents(j). wt.nodes{j} is the actual data stored in the tree node 86% (a structure returned form fwtinit) and wt.parents(j) and wt.children{j} 87% define relationship to other nodes. wt.parents(j) is an index of the 88% parent in the arrays. wt.children{j} is an array of indexes of the 89% children nodes. 90%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 91wt.nodes = {}; 92wt.children = {}; 93wt.parents = []; 94wt.freqOrder = 0; 95%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 96info.istight = 0; 97 98% return empty struct if no argument was passed 99if(nargin<1) 100 return; 101end 102 103 104do_strict = 0; 105do_dual = 0; 106 107% Check 'strict' 108if iscell(wtdef) && ischar(wtdef{1}) && strcmpi(wtdef{1},'strict') 109 do_strict = 1; 110 wtdef = wtdef{2:end}; 111end 112% Check 'dual' 113if iscell(wtdef) && ischar(wtdef{1}) && strcmpi(wtdef{1},'dual') 114 do_dual = 1; 115 wtdef = wtdef{2:end}; 116end 117 118definput.import = {'wfbtcommon'}; 119[flags,kv]=ltfatarghelper({},definput,varargin); 120 121% If wtdef is already a structure 122if (isstruct(wtdef)&&isfield(wtdef,'nodes')) 123 if isempty(wtdef.nodes) 124 error('%s: The tree struct is empty.',upper(mfilename)); 125 end 126 127 wt = wtdef; 128 129 if do_dual || do_strict 130 nodesArg = wt.nodes; 131 if do_dual 132 nodesArg = cellfun(@(nEl) {'dual',nEl},nodesArg,'UniformOutput',0); 133 end 134 if do_strict 135 nodesArg = cellfun(@(nEl) {'strict',nEl},nodesArg,'UniformOutput',0); 136 end 137 info.istight = 1; 138 wt.nodes = {}; 139 for ii=1:numel(nodesArg) 140 % wt.nodes = cellfun(@(nEl) fwtinit(nEl),nodesArg,'UniformOutput',0); 141 [wt.nodes{ii},infotmp] = fwtinit(nodesArg{ii}); 142 if info.istight 143 info.istight = infotmp.istight; 144 end 145 end 146 % Do the filter frequency shuffling again, since the filters were 147 % overwritten in fwtinit. 148 if wt.freqOrder 149 wt = nat2freqOrder(wt); 150 end 151 end 152 153 % Do filter shuffling if flags.do_freq differs from the wt.freqOrder. 154 % Frequency and natural oreding coincide for DWT. 155 if wt.freqOrder ~= flags.do_freq 156 wt = nat2freqOrder(wt); 157 wt.freqOrder = ~wt.freqOrder; 158 end 159 return; 160end 161 162% break if the input parameter is not in the correct format 163if ~(iscell(wtdef)) || isempty(wtdef) 164 error('%s: Unsupported filterbank tree definition.',upper(mfilename)); 165end 166 167% Creating new tree 168% Now wtdef is this {w,J,flag} 169wdef = wtdef{1}; 170definput = []; 171definput.flags.treetype = {'full','dwt','doubleband','quadband',... 172 'octaband','root'}; 173definput.keyvals.mod = []; 174definput.keyvals.overcomplete = []; 175definput.keyvals.J = []; 176[flags2,kv2,J]=ltfatarghelper({'J'},definput,wtdef(2:end)); 177 178complainif_notposint(J,'J'); 179 180if do_dual 181 wdef = {'dual',wdef}; 182end 183 184if do_strict 185 wdef = {'strict',wdef}; 186end 187 188do_powshiftable = 0; 189% Is the first level filterbank different? 190if ~isempty(kv2.mod) 191 if ischar(kv2.mod) 192 if strcmpi(kv2.mod,'powshiftable') 193 if ~flags2.do_dwt 194 error('%s: powshiftable is only valid with the dwt flag.',... 195 upper(mfilename)); 196 end 197 do_powshiftable = 1; 198 else 199 error('%s: Not recognized value for the mod key.',upper(mfilename)); 200 end 201 else 202 error('%s: Not recognized value for the first key.',upper(mfilename)); 203 end 204end 205 206if ~isempty(kv2.overcomplete) 207 error('%s: TO DO: overcomplete.',upper(mfilename)); 208end 209 210 211[w, info] = fwtinit(wdef); 212 213% Doing one-node tree 214if flags2.do_root 215 J = 1; 216end 217 218if flags2.do_dwt 219 % fill the structure to represent a DWT tree 220 for jj=0:J-1 221 wt = wfbtput(jj,0,w,wt); 222 end 223elseif flags2.do_full 224 % fill the structure to represent a full wavelet tree 225 for jj=0:J-1 226 % for ii=0:numel(w.g)^(jj)-1 227 wt = wfbtput(jj,0:numel(w.g)^(jj)-1,w,wt); 228 % end 229 end 230elseif flags2.do_doubleband 231 % fill the structure to represent a double band tree 232 for jj=0:J-1 233 % for ii=0:numel(w.g)^(jj)-1 234 wt = wfbtput(2*jj,0,w,wt); 235 wt = wfbtput(2*jj+1,0:1,w,wt); 236 % end 237 end 238 239elseif flags2.do_quadband 240 % fill the structure to represent a quad band tree 241 for jj=0:J-1 242 % for ii=0:numel(w.g)^(jj)-1 243 wt = wfbtput(3*jj,0,w,wt); 244 wt = wfbtput(3*jj+1,0:1,w,wt); 245 wt = wfbtput(3*jj+2,0:3,w,wt); 246 % end 247 end 248elseif flags2.do_octaband 249 % fill the structure to represent a octa band tree 250 for jj=0:J-1 251 % for ii=0:numel(w.g)^(jj)-1 252 wt = wfbtput(4*jj,0,w,wt); 253 wt = wfbtput(4*jj+1,0:1,w,wt); 254 wt = wfbtput(4*jj+2,0:3,w,wt); 255 wt = wfbtput(4*jj+3,0:7,w,wt); 256 % end 257 end 258end 259 260% Do filter shuffling if frequency ordering is required, 261wt.freqOrder = flags.do_freq; 262if flags.do_freq 263 wt = nat2freqOrder(wt); 264end 265 266if do_powshiftable 267 % Change subsampling factors of the root to 1 268 wt.nodes{wt.parents==0}.a(:) = 1; 269end 270 271 272 273 274 275