Mercurial > hg > ltpda
comparison m-toolbox/classes/+utils/@math/vcfit.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 % VCFIT Fits continuous models to frequency responses | |
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
3 % DESCRIPTION: | |
4 % | |
5 % Fits a continuous model to a frequency response using relaxed | |
6 % s-domain vector fitting algorithm [1, 2]. The function is able to fit more | |
7 % than one frequency response per time. In case that more than one | |
8 % frequency response is passed as input, they are fitted with a set of | |
9 % common poles. Model functions are expanded in partial fractions: | |
10 % | |
11 % r1 rN | |
12 % f(s) = ------- + ... + ------- + d | |
13 % s - p1 s - pN | |
14 % | |
15 % CALL: | |
16 % | |
17 % [res,poles,dterm,mresp,rdl] = vcfit(y,f,poles,weight,fitin) | |
18 % | |
19 % INPUTS: | |
20 % | |
21 % - y: Is a vector wuth the frequency response data. | |
22 % - f: Is the frequency vector in Hz. | |
23 % - poles: are a set of starting poles. | |
24 % - weight: are a set of weights used in the fitting procedure. | |
25 % - fitin: is a struct containing fitting options and parameters. fitin | |
26 % fields are: | |
27 % - fitin.stable = 0; fit without forcing poles to be stable. | |
28 % - fitin.stable = 1; force poles to be stable flipping unstable | |
29 % poles in the left side of the complex plane. s -> s - 2*conj(s). | |
30 % - fitin.dterm = 0; fit with d = 0. | |
31 % - fitin.dterm = 1; fit with d different from 0. | |
32 % - fitin.polt = 0; fit without plotting results. | |
33 % - fitin.plot = 1; plot fit results in loglog scale. | |
34 % - fitin.plot = 2; plot fit results in semilogx scale. | |
35 % - fitin.plot = 3; plot fit results in semilogy scale. | |
36 % - fitin.plot = 4; plot fit results in linear xy scale. | |
37 % - fitin.ploth = #; a plot handle to define the figure target for | |
38 % plotting. Default: [1] | |
39 % | |
40 % OUTPUT: | |
41 % | |
42 % - res: vector or residues. | |
43 % - poles: vector of poles. | |
44 % - dterm: direct term d. | |
45 % - mresp: frequency response of the fitted model | |
46 % - rdl: residuals y - mresp | |
47 % - mse: normalized mean squared error | |
48 % | |
49 % EXAMPLES: | |
50 % | |
51 % - Fit on a single transfer function: | |
52 % | |
53 % INPUT | |
54 % y is a (Nx1) or (1xN) vector | |
55 % f is a (Nx1) or (1xN) vector | |
56 % poles is a (Npx1) or (1xNp) vector | |
57 % weight is a (Nx1) or (1xN) vector | |
58 % | |
59 % OUTPUT | |
60 % res is a (Npx1) vector | |
61 % poles is a (Npx1) vector | |
62 % dterm is a constant | |
63 % mresp is a (Nx1) vector | |
64 % rdl is a (Nx1) vector | |
65 % mse is a constant | |
66 % | |
67 % - Fit Nt transfer function at the same time: | |
68 % | |
69 % INPUT | |
70 % y is a (NxNt) or (NtxN) vector | |
71 % f is a (Nx1) or (1xN) vector | |
72 % poles is a (Npx1) or (1xNp) vector | |
73 % weight is a (NxNt) or (NtxN) vector | |
74 % | |
75 % OUTPUT | |
76 % res is a (NpxNt) vector | |
77 % poles is a (Npx1) vector | |
78 % dterm is a (1xNt) vector | |
79 % mresp is a (NxNt) vector | |
80 % rdl is a (NxNt) vector | |
81 % mse is a (1xNt) vector | |
82 % | |
83 % REFERENCES: | |
84 % | |
85 % [1] B. Gustavsen and A. Semlyen, "Rational approximation of frequency | |
86 % domain responses by Vector Fitting", IEEE Trans. Power Delivery | |
87 % vol. 14, no. 3, pp. 1052-1061, July 1999. | |
88 % [2] B. Gustavsen, "Improving the Pole Relocating Properties of Vector | |
89 % Fitting", IEEE Trans. Power Delivery vol. 21, no. 3, pp. | |
90 % 1587-1592, July 2006. | |
91 % | |
92 % NOTE: | |
93 % | |
94 % | |
95 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
96 % HISTORY: 12-09-2008 L Ferraioli | |
97 % Creation | |
98 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
99 % VERSION: '$Id: vcfit.m,v 1.11 2010/02/08 19:05:59 luigi Exp $'; | |
100 % | |
101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
102 function [res,poles,dterm,mresp,rdl,mse] = vcfit(y,f,poles,weight,fitin) | |
103 | |
104 warning off all | |
105 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
106 % Collecting inputs | |
107 | |
108 % Default input struct | |
109 defaultparams = struct('stable',0, 'dterm',0, 'plot',0, 'ploth', 1); | |
110 | |
111 names = {'stable','dterm','plot','ploth'}; | |
112 | |
113 % collecting input and default params | |
114 if ~isempty(fitin) | |
115 for jj=1:length(names) | |
116 if isfield(fitin, names(jj)) && ~isempty(fitin.(names{1,jj})) | |
117 defaultparams.(names{1,jj}) = fitin.(names{1,jj}); | |
118 end | |
119 end | |
120 end | |
121 | |
122 stab = defaultparams.stable; % Enforce pole stability is is 1 | |
123 dt = defaultparams.dterm; % 1 to fit with direct term | |
124 plotting = defaultparams.plot; % set to 1 if plotting is required | |
125 plth = defaultparams.ploth; % set the figure target | |
126 | |
127 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
128 % Inputs in row vectors | |
129 | |
130 [a,b] = size(y); | |
131 if a > b % shifting to row | |
132 y = y.'; | |
133 end | |
134 | |
135 [a,b] = size(f); | |
136 if a > b % shifting to row | |
137 f = f.'; | |
138 end | |
139 | |
140 [a,b] = size(poles); | |
141 if a > b % shifting to row | |
142 poles = poles.'; | |
143 end | |
144 | |
145 clear w | |
146 w = weight; | |
147 [a,b] = size(w); | |
148 if a > b % shifting to row | |
149 w = w.'; | |
150 end | |
151 | |
152 N = length(poles); % Model order | |
153 | |
154 if dt | |
155 dl = 1; % Fit with direct term | |
156 else | |
157 dl = 0; % Fit without direct term | |
158 end | |
159 | |
160 % definition of s | |
161 s = 1i.*2.*pi.*f; | |
162 | |
163 Nz = length(s); | |
164 [Nc,Ny] = size(y); | |
165 if Ny ~= Nz | |
166 error(' Number of data points different from number of frequency points! ') | |
167 end | |
168 | |
169 %Tolerances used by relaxed version of vector fitting | |
170 TOLlow=1e-8; | |
171 TOLhigh=1e8; | |
172 | |
173 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
174 % Marking complex and real poles | |
175 | |
176 % cindex = 1; pole is complex, next conjugate pole is marked with cindex | |
177 % = 2. cindex = 0; pole is real | |
178 cindex=zeros(1,N); | |
179 for m=1:N | |
180 if imag(poles(m))~=0 | |
181 if m==1 | |
182 cindex(m)=1; | |
183 else | |
184 if cindex(m-1)==0 || cindex(m-1)==2 | |
185 cindex(m)=1; cindex(m+1)=2; | |
186 else | |
187 cindex(m)=2; | |
188 end | |
189 end | |
190 end | |
191 end | |
192 | |
193 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
194 % Augmented problem | |
195 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
196 | |
197 % Matrix initialinzation | |
198 BA = zeros(Nc*Nz+1,1); | |
199 Ak=zeros(Nz,N+1); | |
200 AA=zeros(Nz*Nc+1,(N+dl)*Nc+N+1); | |
201 nf = zeros(1,Nc*(N+dl)+N+1); % Normalization factor | |
202 | |
203 % Defining Ak | |
204 for jj = 1:N | |
205 if cindex(jj) == 1 % conjugate complex couple of poles | |
206 Ak(:,jj) = 1./(s-poles(jj)) + 1./(s-conj(poles(jj))); | |
207 Ak(:,jj+1) = 1i./(s-poles(jj)) - 1i./(s-conj(poles(jj))); | |
208 elseif cindex(jj) == 0 % real pole | |
209 Ak(:,jj) = 1./(s-poles(jj)); | |
210 end | |
211 end | |
212 | |
213 Ak(1:Nz,N+1) = 1; | |
214 | |
215 % Scaling factor | |
216 sc = 0; | |
217 for mm = 1:Nc | |
218 sc = sc + (norm(w(mm,:).*y(mm,:)))^2; | |
219 end | |
220 sc=sqrt(sc)/Nz; | |
221 | |
222 for nn = 1:Nc | |
223 | |
224 wg = w(nn,:).'; % Weights | |
225 | |
226 ida=(nn-1)*Nz+1; | |
227 idb=nn*Nz; | |
228 idc=(nn-1)*(N+dl)+1; | |
229 | |
230 for mm =1:N+dl % Diagonal blocks | |
231 AA(ida:idb,idc-1+mm) = wg.*Ak(1:Nz,mm); | |
232 end | |
233 for mm =1:N+1 % Last right blocks | |
234 AA(ida:idb,Nc*(N+dl)+mm) = -wg.*(Ak(1:Nz,mm).*y(nn,1:Nz).'); | |
235 end | |
236 | |
237 end | |
238 | |
239 % setting the last row of AA and BA for the relaxion condition | |
240 for qq = 1:N+1 | |
241 AA(Nc*Nz+1,Nc*(N+dl)+qq) = real(sc*sum(Ak(:,qq))); | |
242 end | |
243 | |
244 AA = [real(AA);imag(AA)]; | |
245 | |
246 % Last element of the solution vector | |
247 BA(Nc*Nz+1) = Nz*sc; | |
248 | |
249 xBA = real(BA); | |
250 xxBA = imag(BA); | |
251 | |
252 Nrow = Nz*Nc+1; | |
253 | |
254 BA = zeros(2*Nrow,1); | |
255 | |
256 BA(1:Nrow,1) = xBA; | |
257 BA(Nrow+1:2*Nrow,1) = xxBA; | |
258 | |
259 % Normalization factor | |
260 % nf = zeros(2*N+dl+1,1); | |
261 for pp = 1:length(AA(1,:)) | |
262 nf(pp) = norm(AA(:,pp),2); % Euclidean norm | |
263 AA(:,pp) = AA(:,pp)./nf(pp); % Normalization | |
264 end | |
265 | |
266 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
267 % Solving augmented problem | |
268 | |
269 % XA = pinv(AA)*BA; | |
270 % XA = inv((AA.')*AA)*(AA.')*BA; | |
271 | |
272 % XA = AA.'*AA\AA.'*BA; | |
273 | |
274 XA = AA\BA; | |
275 | |
276 XA = XA./nf.'; % renormalization | |
277 | |
278 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
279 % Checking the tolerance | |
280 | |
281 if abs(XA(end))<TOLlow || abs(XA(end))>TOLhigh | |
282 | |
283 if XA(end)==0 | |
284 Dnew=1; | |
285 elseif abs(XA(end))<TOLlow | |
286 Dnew=sign(XA(end))*TOLlow; | |
287 elseif abs(XA(end))>TOLhigh | |
288 Dnew=sign(XA(end))*TOLhigh; | |
289 end | |
290 | |
291 for pp = 1:length(AA(1,:)) | |
292 AA(:,pp) = AA(:,pp).*nf(pp); %removing previous scaling | |
293 end | |
294 | |
295 ind=length(AA(:,1))/2; %index to additional row related to relaxation | |
296 | |
297 AA(ind,:)=[]; % removing relaxation term | |
298 | |
299 BA=-Dnew*AA(:,end); %new right side | |
300 | |
301 AA(:,end)=[]; | |
302 | |
303 nf(end)=[]; | |
304 | |
305 for pp = 1:length(AA(1,:)) | |
306 nf(pp) = norm(AA(:,pp),2); % Euclidean norm | |
307 AA(:,pp) = AA(:,pp)./nf(pp); % Normalization | |
308 end | |
309 | |
310 % XA=(AA.'*AA)\(AA.'*BA); % using normal equation | |
311 | |
312 XA=AA\BA; | |
313 | |
314 XA = XA./nf.'; % renormalization | |
315 | |
316 XA=[XA;Dnew]; | |
317 | |
318 end | |
319 | |
320 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
321 % Finding zeros of sigma | |
322 | |
323 lsr = XA((N+dl)*Nc+1:(N+dl)*Nc+N,1); % collect the least square results | |
324 | |
325 D = XA(end); % direct term of sigma | |
326 | |
327 CPOLES = diag(poles); | |
328 B = ones(N,1); | |
329 C = lsr.'; | |
330 | |
331 for kk = 1:N | |
332 if cindex(kk) == 1 | |
333 CPOLES(kk,kk)=real(poles(kk)); | |
334 CPOLES(kk,kk+1)=imag(poles(kk)); | |
335 CPOLES(kk+1,kk)=-1*imag(poles(kk)); | |
336 CPOLES(kk+1,kk+1)=real(poles(kk)); | |
337 B(kk,1) = 2; | |
338 B(kk+1,1) = 0; | |
339 end | |
340 end | |
341 | |
342 H = CPOLES-B*C/D; | |
343 | |
344 szeros=eig(H); | |
345 | |
346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
347 % Ruling out unstable poles | |
348 | |
349 % This option force the poles of f to stay inside the left side of the | |
350 % complex plane | |
351 | |
352 if stab | |
353 unst = real(szeros)>0; | |
354 szeros(unst) = szeros(unst)-2*real(szeros(unst)); % Mirroring respect to the complex axes | |
355 end | |
356 szeros = sort(szeros); | |
357 N = length(szeros); | |
358 | |
359 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
360 % Separating complex poles from real poles and ordering | |
361 | |
362 rnpoles = []; | |
363 inpoles = []; | |
364 for tt = 1:N | |
365 if imag(szeros(tt)) == 0 | |
366 % collecting real poles | |
367 rnpoles = [rnpoles; szeros(tt)]; | |
368 else | |
369 % collecting complex poles | |
370 inpoles = [inpoles; szeros(tt)]; | |
371 end | |
372 end | |
373 | |
374 % Sorting complex poles in order to have them in the expected order a+jb | |
375 % and a-jb a>0 b>0 | |
376 inpoles = sort(inpoles); | |
377 npoles = [rnpoles;inpoles]; | |
378 npoles = npoles - 2.*1i.*imag(npoles); | |
379 | |
380 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
381 % Marking complex and real poles | |
382 | |
383 cindex=zeros(N,1); | |
384 for m=1:N | |
385 if imag(npoles(m))~=0 | |
386 if m==1 | |
387 cindex(m)=1; | |
388 else | |
389 if cindex(m-1)==0 || cindex(m-1)==2 | |
390 cindex(m)=1; cindex(m+1)=2; | |
391 else | |
392 cindex(m)=2; | |
393 end | |
394 end | |
395 end | |
396 end | |
397 | |
398 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
399 % Direct problem | |
400 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
401 | |
402 % Matrix initialinzation | |
403 nB(1:Nz,1:Nc) = real(w.*y).'; | |
404 nB(Nz+1:2*Nz,1:Nc) = imag(w.*y).'; | |
405 | |
406 B = zeros(2*Nz,1); | |
407 nAD = zeros(Nz,N+dl); | |
408 AD = zeros(2*Nz,N+dl); | |
409 Ak = zeros(Nz,N+dl); | |
410 | |
411 % Defining Ak | |
412 for jj = 1:N | |
413 if cindex(jj) == 1 % conjugate complex couple of poles | |
414 Ak(:,jj) = 1./(s-npoles(jj)) + 1./(s-npoles(jj+1)); | |
415 Ak(:,jj+1) = 1i./(s-npoles(jj)) - 1i./(s-npoles(jj+1)); | |
416 elseif cindex(jj) == 0 % real pole | |
417 Ak(:,jj) = 1./(s-npoles(jj)); | |
418 end | |
419 end | |
420 | |
421 if dt | |
422 Ak(1:Nz,N+dl) = ones(Nz,1); % considering the direct term | |
423 end | |
424 | |
425 XX = zeros(Nc,N+dl); | |
426 for nn = 1:Nc | |
427 | |
428 % Defining AD | |
429 for m=1:N+dl | |
430 nAD(1:Nz,m) = w(nn,:).'.*Ak(1:Nz,m); | |
431 end | |
432 | |
433 B(1:2*Nz,1) = nB(1:2*Nz,nn); | |
434 | |
435 AD(1:Nz,:) = real(nAD); | |
436 AD(Nz+1:2*Nz,:) = imag(nAD); | |
437 | |
438 % Normalization factor | |
439 nf = zeros(N+dl,1); | |
440 for pp = 1:N+dl | |
441 nf(pp,1) = norm(AD(:,pp),2); % Euclidean norm | |
442 AD(:,pp) = AD(:,pp)./nf(pp,1); % Normalization | |
443 end | |
444 | |
445 % Solving direct problem | |
446 | |
447 % XD = inv((AD.')*AD)*(AD.')*B; | |
448 % XD = AD.'*AD\AD.'*B; | |
449 % XD = pinv(AD)*B; | |
450 XD = AD\B; | |
451 | |
452 XD = XD./nf; % Renormalization | |
453 | |
454 XX(nn,1:N) = XD(1:N).'; | |
455 | |
456 end | |
457 | |
458 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
459 % Final residues and poles of f | |
460 | |
461 lsr = XX(:,1:N); | |
462 | |
463 res = zeros(N,Nc); | |
464 % Real poles have real residues, complex poles have comples residues | |
465 for nn = 1:Nc | |
466 for tt = 1:N | |
467 if cindex(tt) == 1 % conjugate complex couple of poles | |
468 res(tt,nn) = lsr(nn,tt)+1i*lsr(nn,tt+1); | |
469 res(tt+1,nn) = lsr(nn,tt)-1i*lsr(nn,tt+1); | |
470 elseif cindex(tt) == 0 % real pole | |
471 res(tt,nn) = lsr(nn,tt); | |
472 end | |
473 end | |
474 end | |
475 | |
476 poles = npoles; | |
477 | |
478 if dt | |
479 dterm = XX(:,N+dl).'; | |
480 else | |
481 dterm = zeros(1,Nc); | |
482 end | |
483 | |
484 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
485 % Calculating responses and residuals | |
486 | |
487 mresp = zeros(Nz,Nc); | |
488 rdl = zeros(Nz,Nc); | |
489 mse = zeros(1,Nc); | |
490 | |
491 for nn = 1:Nc | |
492 % freq resp of the fit model | |
493 r = res(:,nn); | |
494 p = poles; | |
495 d = dterm(:,nn); | |
496 | |
497 Nf = length(f); | |
498 N = length(p); | |
499 | |
500 rsp = zeros(Nf,1); | |
501 indx = (0:length(d)-1).'; | |
502 for ii = 1:Nf | |
503 for jj = 1:N | |
504 rsptemp = r(jj)/(1i*2*pi*f(ii)-p(jj)); | |
505 rsp(ii) = rsp(ii) + rsptemp; | |
506 end | |
507 % Direct terms response | |
508 rsp(ii) = rsp(ii) + sum((((1i*2*pi*f(ii))*ones(length(d),1)).^indx).*d); | |
509 end | |
510 | |
511 % Model response | |
512 mresp(:,nn) = rsp; | |
513 | |
514 % Residual | |
515 rdl(:,nn) = y(nn,:).' - rsp; | |
516 | |
517 % RMS error | |
518 % mse(:,nn) = sqrt(sum((abs(rdl(:,nn)./(y(nn,:).')).^2))/(Nf-N)); | |
519 % Chi Square or mean squared error | |
520 % Note that this error is normalized to the input data in order to | |
521 % comparable between different sets of data | |
522 mse(:,nn) = sum((rdl(:,nn)./y(nn,:).').*conj((rdl(:,nn)./y(nn,:).')))/(Nf-N); | |
523 | |
524 end | |
525 | |
526 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
527 % Plotting response | |
528 | |
529 switch plotting | |
530 | |
531 case 0 | |
532 % No plot | |
533 | |
534 case 1 | |
535 % LogLog plot for absolute value | |
536 figure(plth) | |
537 subplot(2,1,1); | |
538 p1 = loglog(f,abs(y.'),'k'); | |
539 hold on | |
540 p2 = loglog(f,abs(mresp),'r'); | |
541 p3 = loglog(f,abs(rdl),'b'); | |
542 xlabel('Frequency [Hz]') | |
543 ylabel('Amplitude') | |
544 legend([p1(1) p2(1) p3(1)],'Original', 'VCFIT','Residual') | |
545 hold off | |
546 | |
547 subplot(2,1,2); | |
548 p4 = semilogx(f,(180/pi).*unwrap(angle(y.')),'k'); | |
549 hold on | |
550 p5 = semilogx(f,(180/pi).*unwrap(angle(mresp)),'r'); | |
551 xlabel('Frequency [Hz]') | |
552 ylabel('Phase [Deg]') | |
553 legend([p4(1) p5(1)],'Original', 'VCFIT') | |
554 hold off | |
555 | |
556 case 2 | |
557 % Semilogx plot for absolute value | |
558 figure(plth) | |
559 subplot(2,1,1); | |
560 p1 = semilogx(f,abs(y.'),'k'); | |
561 hold on | |
562 p2 = semilogx(f,abs(mresp),'r'); | |
563 p3 = semilogx(f,abs(rdl),'b'); | |
564 xlabel('Frequency [Hz]') | |
565 ylabel('Amplitude') | |
566 legend([p1(1) p2(1) p3(1)],'Original', 'VCFIT','Residual') | |
567 hold off | |
568 | |
569 subplot(2,1,2); | |
570 p4 = semilogx(f,(180/pi).*unwrap(angle(y.')),'k'); | |
571 hold on | |
572 p5 = semilogx(f,(180/pi).*unwrap(angle(mresp)),'r'); | |
573 xlabel('Frequency [Hz]') | |
574 ylabel('Phase [Deg]') | |
575 legend([p4(1) p5(1)],'Original', 'VCFIT') | |
576 hold off | |
577 | |
578 case 3 | |
579 % Semilogy plot for absolute value | |
580 figure(plth) | |
581 subplot(2,1,1); | |
582 p1 = semilogy(f,abs(y.'),'k'); | |
583 hold on | |
584 p2 = semilogy(f,abs(mresp),'r'); | |
585 p3 = semilogy(f,abs(rdl),'b'); | |
586 xlabel('Frequency [Hz]') | |
587 ylabel('Amplitude') | |
588 legend([p1(1) p2(1) p3(1)],'Original', 'VCFIT','Residual') | |
589 hold off | |
590 | |
591 subplot(2,1,2); | |
592 p4 = semilogy(f,(180/pi).*unwrap(angle(y.')),'k'); | |
593 hold on | |
594 p5 = semilogy(f,(180/pi).*unwrap(angle(mresp)),'r'); | |
595 xlabel('Frequency [Hz]') | |
596 ylabel('Phase [Deg]') | |
597 legend([p4(1) p5(1)],'Original', 'VCFIT') | |
598 hold off | |
599 | |
600 case 4 | |
601 % Linear plot for absolute value | |
602 figure(plth) | |
603 subplot(2,1,1); | |
604 p1 = plot(f,abs(y.'),'k'); | |
605 hold on | |
606 p2 = plot(f,abs(mresp),'r'); | |
607 p3 = plot(f,abs(rdl),'b'); | |
608 xlabel('Frequency [Hz]') | |
609 ylabel('Amplitude') | |
610 legend([p1(1) p2(1) p3(1)],'Original', 'VCFIT','Residual') | |
611 hold off | |
612 | |
613 subplot(2,1,2); | |
614 p4 = plot(f,(180/pi).*unwrap(angle(y.')),'k'); | |
615 hold on | |
616 p5 = plot(f,(180/pi).*unwrap(angle(mresp)),'r'); | |
617 xlabel('Frequency [Hz]') | |
618 ylabel('Phase [Deg]') | |
619 legend([p4(1) p5(1)],'Original', 'VCFIT') | |
620 hold off | |
621 | |
622 end |