function [y,Zf,Zmax]=resfiltq(wm,rm,zm,x,Zi,Q,runmod)
global ovf_global
ovf_global_save=ovf_global; ovf_global=[];
global resfiltq_sign_of_life
error(nargchk(4,7,nargin))
N=length(wm);
if isempty(rm), rm=1/N*ones(N,1); end
if length(wm)==length(rm)+1, b0=wm(end); wm(end)=[]; N=length(wm); else b0=[]; end
if isempty(b0), b0=0; end
if length(rm)~=length(wm), error('lengths of rm and wm differ'), end
if isempty(zm), zm=exp(j*[0:N-1]'/N*2*pi); end
if length(zm)~=length(wm), error('lengths of zm and wm differ'), end
if nargin<5, Zi=[]; end, if isempty(Zi), Zi=zeros(size(wm)); end
if nargin<6, Q=[]; end
if nargin<7
if (nargin>=6)&isstruct(Q)&isfield(Q,'implementation'), runmod=Q; Q=[];
else runmod=[];
end
end
if ~isfield(runmod,'implementation'), runmod.implementation='real'; end
if ~isfield(runmod,'Qmul'), runmod.Qmul=[]; end
Qmul=runmod.Qmul; if isempty(Qmul), Qmul=Q; end
if ~isfield(runmod,'Qadd'), runmod.Qadd=[]; end
Qadd=runmod.Qadd; if isempty(Qadd), Qadd=Q; end
if ~isfield(runmod,'Qcoeff'), runmod.Qcoeff=[]; end
Qcoeff=runmod.Qcoeff; if isempty(Qcoeff), Qcoeff=Q; end
if ~qstructcmp(Qcoeff,'double')
ind=find(~ismember([0:N-1],N/4*[0:4]));
zm(ind)=roundq(zm(ind),Qcoeff,'complex');
end
if any(ovf_global), warning('Overflow at initializing'), end
if nargout>=3, Zmax=[inf,-inf]; end
y=zeros(size(x));
if rem(N,2)==0
zm(N/2+1)=real(zm(N/2+1)); wm(N/2+1)=real(wm(N/2+1));
rm(N/2+1)=real(rm(N/2+1));
end
if strcmpi(runmod.implementation,'real')|strncmpi(runmod.implementation,'direct II',3)|isempty(runmod.implementation)
phirm=angle(rm); rm=abs(rm);
if ~qstructcmp(Qcoeff,'double')
rm=roundq(rm,Qcoeff);
end
for n=1:length(y)
fb=0;
for m=0:N/2
if (m==0)|(m==N/2)
fb=roundq(fb+Zi(m+1),Qadd);
y(n)=roundq(y(n)+roundq(wm(m+1)*Zi(m+1),Qmul),Qadd);
else
m2=N-m; cosphim=real(zm(m+1)); sinphim=imag(zm(m+1));
if all(phirm==0)
fb=roundq(fb+roundq(2*roundq(roundq(cosphim*Zi(m+1),Qmul)...
-Zi(m2+1),Qadd),Qmul),Qadd);
y(n)=roundq(y(n)+roundq(2*...
roundq(...
roundq(roundq(roundq(cosphim*Zi(m+1),Qmul)...
-Zi(m2+1),Qadd)*real(wm(m+1)),Qmul)...
-roundq(roundq(sinphim*Zi(m2+1),Qmul)*imag(wm(m+1)),Qmul),...
Qadd),Qmul),Qadd);
else
Rex=roundq(roundq(cosphim*Zi(m+1),Qmul)-Zi(m2+1),Qadd);
Imx=roundq(sinphim*Zi(m+1),Qmul);
fb=roundq(fb+roundq(2*real(cmulq(exp(j*phirm(m+1)),Rex+j*Imx,Qadd)),Qmul),Qadd);
y(n)=roundq(y(n)+roundq(2*...
real(cmulq(cmulq(exp(j*phirm(m+1)),Rex+j*Imx,Qadd),wm(m+1),Qadd)),...
Qmul),Qadd);
end
end
end
fin=roundq(x(n)-fb,Qadd);
y(n)=roundq(y(n)+roundq(b0*x(n),Qmul),Qadd);
if ~isequal(Qadd,Q)&~qstructcmp(Qadd,Q), y(n)=roundq(y(n),Q); end
for m=0:N/2
if (m==0)|(m==N/2)
Zi(m+1)=roundq(roundq(rm(m+1)*zm(m+1)*fin,Qmul)+...
roundq(zm(m+1)*Zi(m+1),Qmul),Qadd);
else
m2=N-m; cosphim=real(zm(m+1)); sinphim=imag(zm(m+1));
Zim1=roundq(roundq(roundq(2*roundq(Zi(m+1)*cosphim,Qmul),Qmul)-Zi(m2+1))...
+roundq(rm(m+1)*fin,Qmul),Qadd);
Zi(m2+1)=Zi(m+1);
if ~isequal(Qadd,Q)&~qstructcmp(Qadd,Q), Zim1=roundq(Zim1,Q); end
Zi(m+1)=Zim1;
end
end
if ~isequal(Qadd,Q)&~qstructcmp(Qadd,Q), Zi=roundq(Zi,Q); end
if nargout>=3
Zmax(2)=max(Zmax(2),max(Zi));
Zmax(1)=min(Zmax(1),min(Zi));
end
sig='.'; if any(ovf_global), sig='!'; end
if any(resfiltq_sign_of_life)&(rem(n,20)==0), fprintf(sig), end
end
elseif strcmpi(runmod.implementation,'coupled')
phirm=angle(rm); rm=abs(rm);
if ~qstructcmp(Qcoeff,'double')
rm=roundq(rm,Qcoeff);
end
for n=1:length(y)
fb=0;
for m=0:N/2
if (m==0)|(m==N/2)
fb=roundq(fb+Zi(m+1),Qadd);
y(n)=roundq(y(n)+roundq(wm(m+1)*Zi(m+1),Qmul),Qadd);
else
m2=N-m; cosphim=real(zm(m+1)); sinphim=imag(zm(m+1));
if phirm(m+1)==0
fb=roundq(fb+roundq(2*roundq(roundq(cosphim*Zi(m+1),Qmul)...
+roundq(sinphim*Zi(m2+1),Qmul),Qadd),Qmul),Qadd);
y(n)=roundq(y(n)+roundq(2*roundq(...
roundq(roundq(roundq(cosphim*Zi(m+1),Qmul)...
+roundq(sinphim*Zi(m2+1),Qmul),Qadd)*real(wm(m+1)),Qmul)...
+roundq(roundq(roundq(-sinphim*Zi(m+1),Qmul)...
+roundq(cosphim*Zi(m2+1),Qmul),Qadd)*imag(wm(m+1)),Qmul),...
Qadd),Qmul),Qadd);
else
Rex=roundq(roundq(cosphim*Zi(m+1),Qmul)...
+roundq(sinphim*Zi(m2+1),Qmul),Qadd);
Imx=-roundq(roundq(-sinphim*Zi(m+1),Qmul)...
+roundq(cosphim*Zi(m2+1),Qmul),Qadd);
fb=roundq(fb+roundq(2*real(cmulq(exp(j*phirm(m+1)),Rex+j*Imx,Qadd)),...
Qmul),Qadd);
y(n)=roundq(y(n)+roundq(2*real(cmulq(cmulq(exp(j*phirm(m+1)),Rex+j*Imx,Qadd),...
wm(m+1),Qadd)),Qmul),Qadd);
end
end
end
fin=roundq(x(n)-fb,Qadd);
y(n)=roundq(y(n)+roundq(b0*x(n),Qmul),Qadd);
if ~isequal(Qadd,Q)&~qstructcmp(Qadd,Q), y(n)=roundq(y(n),Q); end
for m=0:N/2
if (m==0)|(m==N/2)
Zi(m+1)=roundq(roundq(rm(m+1)*zm(m+1)*fin,Qmul)+...
roundq(zm(m+1)*Zi(m+1),Qmul),Qadd);
else
m2=N-m; cosphim=real(zm(m+1)); sinphim=imag(zm(m+1));
Zim1=roundq(roundq(roundq(Zi(m+1)*cosphim,Qmul)...
+roundq(Zi(m2+1)*sinphim,Qmul),Qadd)...
+roundq(rm(m+1)*fin,Qmul),Qadd);
Zim2=roundq(roundq(roundq(Zi(m2+1)*cosphim,Qmul)...
+roundq(Zi(m+1)*(-sinphim),Qmul),Qadd),Qadd);
if ~isequal(Qadd,Q)&~qstructcmp(Qadd,Q), Zim1=roundq(Zim1,Q); end
Zi(m+1)=Zim1;
if ~isequal(Qadd,Q)&~qstructcmp(Qadd,Q), Zim2=roundq(Zim2,Q); end
Zi(m2+1)=Zim2;
end
end
if ~isequal(Qadd,Q)&~qstructcmp(Qadd,Q), Zi=roundq(Zi,Q); end
if nargout>=3
Zmax(2)=max(Zmax(2),max(Zi));
Zmax(1)=min(Zmax(1),min(Zi));
end
sig='.'; if any(ovf_global), sig='!'; end
if any(resfiltq_sign_of_life)&(rem(n,20)==0), fprintf(sig), end
end
elseif strcmpi(runmod.implementation,'complex')
if ~qstructcmp(Qcoeff,'double')
rm=roundq(rm,Qcoeff);
end
for n=1:length(y)
fb=0;
for m=0:N/2
if (m==0)|(m==N/2)
fb=roundq(fb+Zi(m+1),Qadd);
if isfield(Qmul,'Type')&strncmpi(Qmul.Type,'fixed',2)
mx=Qmul.Maximum;
if abs(real(wm(m+1)))<=mx
y(n)=roundq(y(n)+roundq(wm(m+1)*Zi(m+1),Qmul),Qadd);
elseif abs(real(wm(m+1)))<=2*mx
term=roundq(wm(m+1)/2*Zi(m+1),Qmul);
y(n)=roundq(roundq(y(n)+term,Qadd)+term,Qadd);
else error('wm overflow')
end
else
y(n)=roundq(y(n)+roundq(wm(m+1)*Zi(m+1),Qmul),Qadd);
end
else
fb=roundq(fb+roundq(2*real(Zi(m+1)),Qmul,'complex'),Qadd,'complex');
y(n)=roundq(y(n)+roundq(2*real(roundq(wm(m+1)*Zi(m+1),...
Qmul,'complex')),Qmul,'complex'),Qadd);
end
end
fin=roundq(x(n)-fb,Qadd);
y(n)=roundq(y(n)+roundq(b0*x(n),Qmul),Qadd);
for m=0:N/2
if ismember(m,[0,N/2])
Zi(m+1)=roundq(roundq(rm(m+1)*zm(m+1)*fin,Qmul,'complex')+...
roundq(zm(m+1)*Zi(m+1),Qmul,'complex'),Qadd,'complex');
else
Zi(m+1)=roundq(roundq(roundq(rm(m+1)*zm(m+1),Qmul,'complex')*fin,Qmul,'complex')...
+roundq(zm(m+1)*Zi(m+1),Qmul,'complex'),Qadd,'complex');
end
end
Zi(N:-1:ceil(N/2)+2)=conj(Zi(2:floor(N/2)));
if ~isequal(Qadd,Q)&~qstructcmp(Qadd,Q)
Zi=roundq(Zi,Q,'complex');
y(n)=roundq(y(n),Q);
end
if nargout>=3
Zmax(2)=max([Zmax(2),max(real(Zi)),max(imag(Zi))]);
Zmax(1)=min([Zmax(1),min(real(Zi)),min(imag(Zi))]);
end
sig='.'; if any(ovf_global), sig='!'; end
if any(resfiltq_sign_of_life)&(rem(n,20)==0), fprintf(sig), end
end
else
error('runmod.implementation is not allowed')
end
if any(resfiltq_sign_of_life), fprintf('\n'), end
if nargout>=2, Zf=Zi; end
if any(ovf_global), warning('Overflow happened in resfiltq'), end
if any(ovf_global_save), ovf_global=ovf_global_save; end
Error using ==> resfiltq at 32
Not enough input arguments.