comparison m-toolbox/classes/+utils/@math/pfallpz.m @ 0:f0afece42f48

Import.
author Daniele Nicolodi <nicolodi@science.unitn.it>
date Wed, 23 Nov 2011 19:22:13 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:f0afece42f48
1 % PFALLPZ all pass filtering to stabilize TF poles and zeros.
2 %
3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
4 % DESCRIPTION:
5 %
6 % All pass filtering in order to stabilize transfer function poles and
7 % zeros. It inputs a partial fraction expanded discrete model and
8 % outputs a pole-zero minimum phase system
9 %
10 % CALL:
11 %
12 % [resp,np] = pfallpz(ir,ip,id,mresp,f,fs)
13 % [resp,np] = pfallpz(ir,ip,id,mresp,f,fs,minphase)
14 % [resp,np,nz] = pfallpz(ir,ip,id,mresp,f,fs,minphase)
15 %
16 % INPUTS:
17 %
18 % ir: are residues
19 % ip: are poles
20 % id: is direct term
21 % f: is the frequancies vector in (Hz)
22 % fs: is the sampling frequency in (Hz)
23 % minphase: is a flag assuming true (output a minimum phase system) or
24 % false (output a stable non minimum phase system) values. Default,
25 % false
26 %
27 % OUTPUTS:
28 %
29 % resp: is the functions phase frequency response
30 % np: are the new stable poles
31 %
32 % NOTE:
33 %
34 % This function make use of signal analysis toolbox functions
35 %
36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
37 % VERSION: $Id: pfallpz.m,v 1.6 2009/06/10 15:47:00 luigi Exp $
38 %
39 % HISTORY: 12-09-2008 L Ferraioli
40 % Creation
41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 function varargout = pfallpz(ir,ip,id,mresp,f,fs,varargin)
43
44 % Reshaping
45 [a,b] = size(ir);
46 if a<b
47 ir = ir.'; % reshape as a column vector
48 end
49
50 [a,b] = size(ip);
51 if a<b
52 ip = ip.'; % reshape as a column vector
53 end
54
55 [a,b] = size(f);
56 if a<b
57 f = f.'; % reshape as a column vector
58 end
59
60 [a,b] = size(id);
61 if a > b
62 id = id.'; % reshape as a row
63 id = id(1,:); % taking the first row (the function can handle only simple constant direct terms)
64 end
65
66 if isempty(fs)
67 fs = 1;
68 end
69 [a,b] = size(fs);
70 if a ~= b
71 disp(' Fs has to be a number. Only first term will be considered! ')
72 fs = fs(1);
73 end
74
75 if nargin == 7
76 minphase = varargin{1};
77 else
78 minphase = false;
79 end
80
81 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
82 [Na,Nb] = size(ir);
83 np = zeros(Na,Nb);
84 nz = zeros(Na,Nb);
85 for nn = 1:Nb
86
87 r = ir(:,nn);
88 d = id(1,nn);
89 p = ip;
90 % iresp = mresp(:,nn);
91
92 % k = sum(r)+d;
93
94 % stabilizing poles
95 sp = p;
96 unst = abs(p) > 1;
97 sp(unst) = 1./conj(sp(unst));
98
99 s = cos((2*pi/fs).*f) + 1i.*sin((2*pi/fs).*f);
100
101 pp = p(unst);
102 psp = sp(unst);
103 for ii = 1:length(s)
104 nterm = 1;
105 for jj = 1:length(sp(unst))
106 nterm = nterm.*(s(ii)-pp(jj))./(s(ii)-psp(jj));
107 end
108 phs(ii,1) = angle(nterm);
109 end
110
111 resp(:,nn) = mresp(:,nn).*(cos(phs)+1i.*sin(phs));
112
113 % output stable poles
114 np(:,nn) = sp;
115
116 if minphase
117 if d~=0
118 error('!!!Minimum phase filers can be obtained only when direct term is zero')
119 end
120 % finding zeros
121 % N = Na+1;
122 % [mults, idx] = mpoles(p,1e-15,0); % checking for poles multiplicity
123 % p = p(idx); % re-arrange poles & residues
124 % r = r(idx);
125 % den = poly(p);
126 % num = conv(den,d);
127 % for i=1:Na
128 % temp = poly( p([1:(i-mults(i)), (i+1):Na]) );
129 % num = num + [r(i)*temp zeros(1,N-length(temp))];
130 % end
131 % zrs = roots(num);
132 D = 0; % direct term of sigma
133
134 A = diag(p);
135 B = ones(Na,1);
136 C = zeros(1,Na);
137 % Real poles have real residues, complex poles have comples residues
138
139 cindex=zeros(1,Na);
140 for m=1:Na
141 if imag(p(m))~=0
142 if m==1
143 cindex(m)=1;
144 else
145 if cindex(m-1)==0 || cindex(m-1)==2
146 cindex(m)=1; cindex(m+1)=2;
147 else
148 cindex(m)=2;
149 end
150 end
151 end
152 end
153
154
155 for kk = 1:Na
156 if cindex(kk) == 1
157 A(kk,kk)=real(p(kk));
158 A(kk,kk+1)=imag(p(kk));
159 A(kk+1,kk)=-1*imag(p(kk));
160 A(kk+1,kk+1)=real(p(kk));
161 B(kk,1) = 2;
162 B(kk+1,1) = 0;
163 C(1,kk) = real(r(kk,1));
164 C(1,kk+1) = imag(r(kk,1));
165 elseif cindex(kk) == 0 % real pole
166 C(1,kk) = r(kk,1);
167 end
168 end
169
170 [zrs,p2,k] = ss2zp(A,B,C,D,1);
171
172 % stabilizing zeros
173 szrs = zrs;
174 % willing to work with columns
175 [a,b] = size(szrs);
176 if a<b
177 szrs = szrs.'; % reshape as a column vector
178 zrs = zrs.';
179 end
180 % adding the zero at the origin
181 zrs = [0;zrs];
182 szrs = [0;szrs];
183 % do stabilization
184 zunst = abs(zrs) > 1;
185 szrs(zunst) = 1./conj(zrs(zunst));
186
187 zzrs = zrs(zunst);
188 zszrs = szrs(zunst);
189 for ii = 1:length(s)
190 nterm = 1;
191 for jj = 1:length(szrs(zunst))
192 nterm = nterm.*(s(ii)-zszrs(jj))./(s(ii)-zzrs(jj));
193 end
194 zphs(ii,1) = angle(nterm);
195 end
196
197 resp(:,nn) = resp(:,nn).*(cos(zphs)+1i.*sin(zphs));
198
199 % output stable zeros
200 nz(:,nn) = szrs;
201 end
202
203 end
204
205
206 % output
207 if nargout == 1
208 varargout{1} = resp;
209 elseif nargout == 2
210 varargout{1} = resp;
211 varargout{2} = np;
212 elseif (nargout == 3) && minphase
213 varargout{1} = resp;
214 varargout{2} = np;
215 varargout{3} = nz;
216 else
217 error('Too many output arguments!')
218 end
219 end
220
221