function [f,relres,iter]=ifilterbankiter(c,g,a,varargin)
%IFILTERBANKITER Filter bank iterative inversion
% Usage: f=ifilterbankiter(c,g,a);
%
% IFILTERBANKITER(c,g,a) iteratively synthesizes a signal f from the
% coefficients c which were obtained using the filters stored in g for
% a channel subsampling rate of a (the hop-size).
%
% The filter bank g and the subsampling rate a must be the same
% as used in FILTERBANK or UFILTERBANK.
%
% This function is useful if there is no way how to explicitly compute
% a dual system using FILTERBANKDUAL or FILTERBANKREALDUAL.
%
% Additional parameters
% ---------------------
%
% The function calls FRSYNITER and passes all the optional arguments to it.
% Please refer to help of FRSYNITER for further details.
%
% Please note that by default, the function expects filterbank g*
% to be created for real signals i.e. g cover only the positive frequencies.
% Additional flag 'complex' is required if the filterbank is defined for
% positive and negative frequencies.
%
% Examples:
% ---------
%
% The following example compares convergence rates of CG and PCG for a
% filterbank which forms a frame, but it is neither uniform or painless:
%
% [f,fs] = greasy; L = size(f,1);
% [g,a,fc]=erbfilters(fs,L,'fractional','bwmul',0.6,'redmul',4/5,'complex');
% filterbankfreqz(g,a,L,'plot','linabs');
% % Filterbankdual does not work
% try
% gd=filterbankdual(g,a,L);
% catch
% disp('FILTERBANKDUAL exited with error.');
% end
%
% c = filterbank(f,g,a);
% [fpcg,~,iterpcg] = ifilterbankiter(c,g,a,'complex','pcg');
% [fcg,~,itercg] = ifilterbankiter(c,g,a,'complex','cg');
%
% fprintf('CG achieved error %e in %d iterations.n',norm(f-fcg), itercg);
% fprintf('PCG achieved error %e in %d iterations.n',norm(f-fpcg), iterpcg);
%
% Similar example with real filterbank:
%
% [f,fs] = greasy; L = size(f,1);
% [g,a,fc]=erbfilters(fs,L,'fractional','bwmul',0.6,'redmul',4/5);
% filterbankfreqz(g,a,L,'plot','linabs');
% % Filterbankrealdual does not work
% try
% gd=filterbankrealdual(g,a,L);
% catch
% disp('FILTERBANKREALDUAL exited with error.');
% end
%
% c = filterbank(f,g,a);
% [fpcg,~,iterpcg] = ifilterbankiter(c,g,a,'pcg');
% [fcg,~,itercg] = ifilterbankiter(c,g,a,'cg');
%
% fprintf('CG achieved error %e in %d iterations.n',norm(f-fcg), itercg);
% fprintf('PCG achieved error %e in %d iterations.n',norm(f-fpcg), iterpcg);
%
% See also: filterbank, ufilterbank, ifilterbank, filterbankdual
%
% References:
% T. Necciari, P. Balazs, N. Holighaus, and P. L. Søndergaard. The ERBlet
% transform: An auditory-based time-frequency representation with perfect
% reconstruction. In Proceedings of the 38th International Conference on
% Acoustics, Speech, and Signal Processing (ICASSP 2013), pages 498--502,
% Vancouver, Canada, May 2013. IEEE.
%
% T. Necciari, N. Holighaus, P. Balazs, Z. Průša, P. Majdak, and
% O. Derrien. Audlet filter banks: A versatile analysis/synthesis
% framework using auditory frequency scales. Applied Sciences, 8(1),
% 2018. [1]http ]
%
% References
%
% 1. http://www.mdpi.com/2076-3417/8/1/96
%
%
% Url: http://ltfat.github.io/doc/filterbank/ifilterbankiter.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/>.
complainif_notenoughargs(nargin,3,'IFILTERBANKITER');
tolchooser.double=1e-9;
tolchooser.single=1e-5;
definput.keyvals.Ls=[];
definput.keyvals.tol=tolchooser.(classofc(c));
definput.keyvals.maxit=100;
definput.flags.alg={'pcg','cg'};
definput.flags.real={'real','complex'};
[flags,kv,Ls]=ltfatarghelper({'Ls'},definput,varargin);
if isnumeric(c)
if flags.do_real
F = frame('ufilterbankreal',g,a,numel(g));
else
F = frame('ufilterbank',g,a,numel(g));
end
else
if flags.do_real
F = frame('filterbankreal',g,a,numel(g));
else
F = frame('filterbank',g,a,numel(g));
end
end
[f,relres,iter] = frsyniter(F,framenative2coef(F,c),'Ls',Ls,flags.alg,'maxit',kv.maxit,'tol',kv.tol);
function cl = classofc(c)
if iscell(c)
cl = class(c{1});
else
cl = class(c);
end