line source
+ − % VCFIT Fits continuous models to frequency responses
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % DESCRIPTION:
+ − %
+ − % Fits a continuous model to a frequency response using relaxed
+ − % s-domain vector fitting algorithm [1, 2]. The function is able to fit more
+ − % than one frequency response per time. In case that more than one
+ − % frequency response is passed as input, they are fitted with a set of
+ − % common poles. Model functions are expanded in partial fractions:
+ − %
+ − % r1 rN
+ − % f(s) = ------- + ... + ------- + d
+ − % s - p1 s - pN
+ − %
+ − % CALL:
+ − %
+ − % [res,poles,dterm,mresp,rdl] = vcfit(y,f,poles,weight,fitin)
+ − %
+ − % INPUTS:
+ − %
+ − % - y: Is a vector wuth the frequency response data.
+ − % - f: Is the frequency vector in Hz.
+ − % - poles: are a set of starting poles.
+ − % - weight: are a set of weights used in the fitting procedure.
+ − % - fitin: is a struct containing fitting options and parameters. fitin
+ − % fields are:
+ − % - fitin.stable = 0; fit without forcing poles to be stable.
+ − % - fitin.stable = 1; force poles to be stable flipping unstable
+ − % poles in the left side of the complex plane. s -> s - 2*conj(s).
+ − % - fitin.dterm = 0; fit with d = 0.
+ − % - fitin.dterm = 1; fit with d different from 0.
+ − % - fitin.polt = 0; fit without plotting results.
+ − % - fitin.plot = 1; plot fit results in loglog scale.
+ − % - fitin.plot = 2; plot fit results in semilogx scale.
+ − % - fitin.plot = 3; plot fit results in semilogy scale.
+ − % - fitin.plot = 4; plot fit results in linear xy scale.
+ − % - fitin.ploth = #; a plot handle to define the figure target for
+ − % plotting. Default: [1]
+ − %
+ − % OUTPUT:
+ − %
+ − % - res: vector or residues.
+ − % - poles: vector of poles.
+ − % - dterm: direct term d.
+ − % - mresp: frequency response of the fitted model
+ − % - rdl: residuals y - mresp
+ − % - mse: normalized mean squared error
+ − %
+ − % EXAMPLES:
+ − %
+ − % - Fit on a single transfer function:
+ − %
+ − % INPUT
+ − % y is a (Nx1) or (1xN) vector
+ − % f is a (Nx1) or (1xN) vector
+ − % poles is a (Npx1) or (1xNp) vector
+ − % weight is a (Nx1) or (1xN) vector
+ − %
+ − % OUTPUT
+ − % res is a (Npx1) vector
+ − % poles is a (Npx1) vector
+ − % dterm is a constant
+ − % mresp is a (Nx1) vector
+ − % rdl is a (Nx1) vector
+ − % mse is a constant
+ − %
+ − % - Fit Nt transfer function at the same time:
+ − %
+ − % INPUT
+ − % y is a (NxNt) or (NtxN) vector
+ − % f is a (Nx1) or (1xN) vector
+ − % poles is a (Npx1) or (1xNp) vector
+ − % weight is a (NxNt) or (NtxN) vector
+ − %
+ − % OUTPUT
+ − % res is a (NpxNt) vector
+ − % poles is a (Npx1) vector
+ − % dterm is a (1xNt) vector
+ − % mresp is a (NxNt) vector
+ − % rdl is a (NxNt) vector
+ − % mse is a (1xNt) vector
+ − %
+ − % REFERENCES:
+ − %
+ − % [1] B. Gustavsen and A. Semlyen, "Rational approximation of frequency
+ − % domain responses by Vector Fitting", IEEE Trans. Power Delivery
+ − % vol. 14, no. 3, pp. 1052-1061, July 1999.
+ − % [2] B. Gustavsen, "Improving the Pole Relocating Properties of Vector
+ − % Fitting", IEEE Trans. Power Delivery vol. 21, no. 3, pp.
+ − % 1587-1592, July 2006.
+ − %
+ − % NOTE:
+ − %
+ − %
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % HISTORY: 12-09-2008 L Ferraioli
+ − % Creation
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % VERSION: '$Id: vcfit.m,v 1.11 2010/02/08 19:05:59 luigi Exp $';
+ − %
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − function [res,poles,dterm,mresp,rdl,mse] = vcfit(y,f,poles,weight,fitin)
+ −
+ − warning off all
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % Collecting inputs
+ −
+ − % Default input struct
+ − defaultparams = struct('stable',0, 'dterm',0, 'plot',0, 'ploth', 1);
+ −
+ − names = {'stable','dterm','plot','ploth'};
+ −
+ − % collecting input and default params
+ − if ~isempty(fitin)
+ − for jj=1:length(names)
+ − if isfield(fitin, names(jj)) && ~isempty(fitin.(names{1,jj}))
+ − defaultparams.(names{1,jj}) = fitin.(names{1,jj});
+ − end
+ − end
+ − end
+ −
+ − stab = defaultparams.stable; % Enforce pole stability is is 1
+ − dt = defaultparams.dterm; % 1 to fit with direct term
+ − plotting = defaultparams.plot; % set to 1 if plotting is required
+ − plth = defaultparams.ploth; % set the figure target
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % Inputs in row vectors
+ −
+ − [a,b] = size(y);
+ − if a > b % shifting to row
+ − y = y.';
+ − end
+ −
+ − [a,b] = size(f);
+ − if a > b % shifting to row
+ − f = f.';
+ − end
+ −
+ − [a,b] = size(poles);
+ − if a > b % shifting to row
+ − poles = poles.';
+ − end
+ −
+ − clear w
+ − w = weight;
+ − [a,b] = size(w);
+ − if a > b % shifting to row
+ − w = w.';
+ − end
+ −
+ − N = length(poles); % Model order
+ −
+ − if dt
+ − dl = 1; % Fit with direct term
+ − else
+ − dl = 0; % Fit without direct term
+ − end
+ −
+ − % definition of s
+ − s = 1i.*2.*pi.*f;
+ −
+ − Nz = length(s);
+ − [Nc,Ny] = size(y);
+ − if Ny ~= Nz
+ − error(' Number of data points different from number of frequency points! ')
+ − end
+ −
+ − %Tolerances used by relaxed version of vector fitting
+ − TOLlow=1e-8;
+ − TOLhigh=1e8;
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % Marking complex and real poles
+ −
+ − % cindex = 1; pole is complex, next conjugate pole is marked with cindex
+ − % = 2. cindex = 0; pole is real
+ − cindex=zeros(1,N);
+ − for m=1:N
+ − if imag(poles(m))~=0
+ − if m==1
+ − cindex(m)=1;
+ − else
+ − if cindex(m-1)==0 || cindex(m-1)==2
+ − cindex(m)=1; cindex(m+1)=2;
+ − else
+ − cindex(m)=2;
+ − end
+ − end
+ − end
+ − end
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % Augmented problem
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ −
+ − % Matrix initialinzation
+ − BA = zeros(Nc*Nz+1,1);
+ − Ak=zeros(Nz,N+1);
+ − AA=zeros(Nz*Nc+1,(N+dl)*Nc+N+1);
+ − nf = zeros(1,Nc*(N+dl)+N+1); % Normalization factor
+ −
+ − % Defining Ak
+ − for jj = 1:N
+ − if cindex(jj) == 1 % conjugate complex couple of poles
+ − Ak(:,jj) = 1./(s-poles(jj)) + 1./(s-conj(poles(jj)));
+ − Ak(:,jj+1) = 1i./(s-poles(jj)) - 1i./(s-conj(poles(jj)));
+ − elseif cindex(jj) == 0 % real pole
+ − Ak(:,jj) = 1./(s-poles(jj));
+ − end
+ − end
+ −
+ − Ak(1:Nz,N+1) = 1;
+ −
+ − % Scaling factor
+ − sc = 0;
+ − for mm = 1:Nc
+ − sc = sc + (norm(w(mm,:).*y(mm,:)))^2;
+ − end
+ − sc=sqrt(sc)/Nz;
+ −
+ − for nn = 1:Nc
+ −
+ − wg = w(nn,:).'; % Weights
+ −
+ − ida=(nn-1)*Nz+1;
+ − idb=nn*Nz;
+ − idc=(nn-1)*(N+dl)+1;
+ −
+ − for mm =1:N+dl % Diagonal blocks
+ − AA(ida:idb,idc-1+mm) = wg.*Ak(1:Nz,mm);
+ − end
+ − for mm =1:N+1 % Last right blocks
+ − AA(ida:idb,Nc*(N+dl)+mm) = -wg.*(Ak(1:Nz,mm).*y(nn,1:Nz).');
+ − end
+ −
+ − end
+ −
+ − % setting the last row of AA and BA for the relaxion condition
+ − for qq = 1:N+1
+ − AA(Nc*Nz+1,Nc*(N+dl)+qq) = real(sc*sum(Ak(:,qq)));
+ − end
+ −
+ − AA = [real(AA);imag(AA)];
+ −
+ − % Last element of the solution vector
+ − BA(Nc*Nz+1) = Nz*sc;
+ −
+ − xBA = real(BA);
+ − xxBA = imag(BA);
+ −
+ − Nrow = Nz*Nc+1;
+ −
+ − BA = zeros(2*Nrow,1);
+ −
+ − BA(1:Nrow,1) = xBA;
+ − BA(Nrow+1:2*Nrow,1) = xxBA;
+ −
+ − % Normalization factor
+ − % nf = zeros(2*N+dl+1,1);
+ − for pp = 1:length(AA(1,:))
+ − nf(pp) = norm(AA(:,pp),2); % Euclidean norm
+ − AA(:,pp) = AA(:,pp)./nf(pp); % Normalization
+ − end
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % Solving augmented problem
+ −
+ − % XA = pinv(AA)*BA;
+ − % XA = inv((AA.')*AA)*(AA.')*BA;
+ −
+ − % XA = AA.'*AA\AA.'*BA;
+ −
+ − XA = AA\BA;
+ −
+ − XA = XA./nf.'; % renormalization
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % Checking the tolerance
+ −
+ − if abs(XA(end))<TOLlow || abs(XA(end))>TOLhigh
+ −
+ − if XA(end)==0
+ − Dnew=1;
+ − elseif abs(XA(end))<TOLlow
+ − Dnew=sign(XA(end))*TOLlow;
+ − elseif abs(XA(end))>TOLhigh
+ − Dnew=sign(XA(end))*TOLhigh;
+ − end
+ −
+ − for pp = 1:length(AA(1,:))
+ − AA(:,pp) = AA(:,pp).*nf(pp); %removing previous scaling
+ − end
+ −
+ − ind=length(AA(:,1))/2; %index to additional row related to relaxation
+ −
+ − AA(ind,:)=[]; % removing relaxation term
+ −
+ − BA=-Dnew*AA(:,end); %new right side
+ −
+ − AA(:,end)=[];
+ −
+ − nf(end)=[];
+ −
+ − for pp = 1:length(AA(1,:))
+ − nf(pp) = norm(AA(:,pp),2); % Euclidean norm
+ − AA(:,pp) = AA(:,pp)./nf(pp); % Normalization
+ − end
+ −
+ − % XA=(AA.'*AA)\(AA.'*BA); % using normal equation
+ −
+ − XA=AA\BA;
+ −
+ − XA = XA./nf.'; % renormalization
+ −
+ − XA=[XA;Dnew];
+ −
+ − end
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % Finding zeros of sigma
+ −
+ − lsr = XA((N+dl)*Nc+1:(N+dl)*Nc+N,1); % collect the least square results
+ −
+ − D = XA(end); % direct term of sigma
+ −
+ − CPOLES = diag(poles);
+ − B = ones(N,1);
+ − C = lsr.';
+ −
+ − for kk = 1:N
+ − if cindex(kk) == 1
+ − CPOLES(kk,kk)=real(poles(kk));
+ − CPOLES(kk,kk+1)=imag(poles(kk));
+ − CPOLES(kk+1,kk)=-1*imag(poles(kk));
+ − CPOLES(kk+1,kk+1)=real(poles(kk));
+ − B(kk,1) = 2;
+ − B(kk+1,1) = 0;
+ − end
+ − end
+ −
+ − H = CPOLES-B*C/D;
+ −
+ − szeros=eig(H);
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % Ruling out unstable poles
+ −
+ − % This option force the poles of f to stay inside the left side of the
+ − % complex plane
+ −
+ − if stab
+ − unst = real(szeros)>0;
+ − szeros(unst) = szeros(unst)-2*real(szeros(unst)); % Mirroring respect to the complex axes
+ − end
+ − szeros = sort(szeros);
+ − N = length(szeros);
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % Separating complex poles from real poles and ordering
+ −
+ − rnpoles = [];
+ − inpoles = [];
+ − for tt = 1:N
+ − if imag(szeros(tt)) == 0
+ − % collecting real poles
+ − rnpoles = [rnpoles; szeros(tt)];
+ − else
+ − % collecting complex poles
+ − inpoles = [inpoles; szeros(tt)];
+ − end
+ − end
+ −
+ − % Sorting complex poles in order to have them in the expected order a+jb
+ − % and a-jb a>0 b>0
+ − inpoles = sort(inpoles);
+ − npoles = [rnpoles;inpoles];
+ − npoles = npoles - 2.*1i.*imag(npoles);
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % Marking complex and real poles
+ −
+ − cindex=zeros(N,1);
+ − for m=1:N
+ − if imag(npoles(m))~=0
+ − if m==1
+ − cindex(m)=1;
+ − else
+ − if cindex(m-1)==0 || cindex(m-1)==2
+ − cindex(m)=1; cindex(m+1)=2;
+ − else
+ − cindex(m)=2;
+ − end
+ − end
+ − end
+ − end
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % Direct problem
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ −
+ − % Matrix initialinzation
+ − nB(1:Nz,1:Nc) = real(w.*y).';
+ − nB(Nz+1:2*Nz,1:Nc) = imag(w.*y).';
+ −
+ − B = zeros(2*Nz,1);
+ − nAD = zeros(Nz,N+dl);
+ − AD = zeros(2*Nz,N+dl);
+ − Ak = zeros(Nz,N+dl);
+ −
+ − % Defining Ak
+ − for jj = 1:N
+ − if cindex(jj) == 1 % conjugate complex couple of poles
+ − Ak(:,jj) = 1./(s-npoles(jj)) + 1./(s-npoles(jj+1));
+ − Ak(:,jj+1) = 1i./(s-npoles(jj)) - 1i./(s-npoles(jj+1));
+ − elseif cindex(jj) == 0 % real pole
+ − Ak(:,jj) = 1./(s-npoles(jj));
+ − end
+ − end
+ −
+ − if dt
+ − Ak(1:Nz,N+dl) = ones(Nz,1); % considering the direct term
+ − end
+ −
+ − XX = zeros(Nc,N+dl);
+ − for nn = 1:Nc
+ −
+ − % Defining AD
+ − for m=1:N+dl
+ − nAD(1:Nz,m) = w(nn,:).'.*Ak(1:Nz,m);
+ − end
+ −
+ − B(1:2*Nz,1) = nB(1:2*Nz,nn);
+ −
+ − AD(1:Nz,:) = real(nAD);
+ − AD(Nz+1:2*Nz,:) = imag(nAD);
+ −
+ − % Normalization factor
+ − nf = zeros(N+dl,1);
+ − for pp = 1:N+dl
+ − nf(pp,1) = norm(AD(:,pp),2); % Euclidean norm
+ − AD(:,pp) = AD(:,pp)./nf(pp,1); % Normalization
+ − end
+ −
+ − % Solving direct problem
+ −
+ − % XD = inv((AD.')*AD)*(AD.')*B;
+ − % XD = AD.'*AD\AD.'*B;
+ − % XD = pinv(AD)*B;
+ − XD = AD\B;
+ −
+ − XD = XD./nf; % Renormalization
+ −
+ − XX(nn,1:N) = XD(1:N).';
+ −
+ − end
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % Final residues and poles of f
+ −
+ − lsr = XX(:,1:N);
+ −
+ − res = zeros(N,Nc);
+ − % Real poles have real residues, complex poles have comples residues
+ − for nn = 1:Nc
+ − for tt = 1:N
+ − if cindex(tt) == 1 % conjugate complex couple of poles
+ − res(tt,nn) = lsr(nn,tt)+1i*lsr(nn,tt+1);
+ − res(tt+1,nn) = lsr(nn,tt)-1i*lsr(nn,tt+1);
+ − elseif cindex(tt) == 0 % real pole
+ − res(tt,nn) = lsr(nn,tt);
+ − end
+ − end
+ − end
+ −
+ − poles = npoles;
+ −
+ − if dt
+ − dterm = XX(:,N+dl).';
+ − else
+ − dterm = zeros(1,Nc);
+ − end
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % Calculating responses and residuals
+ −
+ − mresp = zeros(Nz,Nc);
+ − rdl = zeros(Nz,Nc);
+ − mse = zeros(1,Nc);
+ −
+ − for nn = 1:Nc
+ − % freq resp of the fit model
+ − r = res(:,nn);
+ − p = poles;
+ − d = dterm(:,nn);
+ −
+ − Nf = length(f);
+ − N = length(p);
+ −
+ − rsp = zeros(Nf,1);
+ − indx = (0:length(d)-1).';
+ − for ii = 1:Nf
+ − for jj = 1:N
+ − rsptemp = r(jj)/(1i*2*pi*f(ii)-p(jj));
+ − rsp(ii) = rsp(ii) + rsptemp;
+ − end
+ − % Direct terms response
+ − rsp(ii) = rsp(ii) + sum((((1i*2*pi*f(ii))*ones(length(d),1)).^indx).*d);
+ − end
+ −
+ − % Model response
+ − mresp(:,nn) = rsp;
+ −
+ − % Residual
+ − rdl(:,nn) = y(nn,:).' - rsp;
+ −
+ − % RMS error
+ − % mse(:,nn) = sqrt(sum((abs(rdl(:,nn)./(y(nn,:).')).^2))/(Nf-N));
+ − % Chi Square or mean squared error
+ − % Note that this error is normalized to the input data in order to
+ − % comparable between different sets of data
+ − mse(:,nn) = sum((rdl(:,nn)./y(nn,:).').*conj((rdl(:,nn)./y(nn,:).')))/(Nf-N);
+ −
+ − end
+ −
+ − %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+ − % Plotting response
+ −
+ − switch plotting
+ −
+ − case 0
+ − % No plot
+ −
+ − case 1
+ − % LogLog plot for absolute value
+ − figure(plth)
+ − subplot(2,1,1);
+ − p1 = loglog(f,abs(y.'),'k');
+ − hold on
+ − p2 = loglog(f,abs(mresp),'r');
+ − p3 = loglog(f,abs(rdl),'b');
+ − xlabel('Frequency [Hz]')
+ − ylabel('Amplitude')
+ − legend([p1(1) p2(1) p3(1)],'Original', 'VCFIT','Residual')
+ − hold off
+ −
+ − subplot(2,1,2);
+ − p4 = semilogx(f,(180/pi).*unwrap(angle(y.')),'k');
+ − hold on
+ − p5 = semilogx(f,(180/pi).*unwrap(angle(mresp)),'r');
+ − xlabel('Frequency [Hz]')
+ − ylabel('Phase [Deg]')
+ − legend([p4(1) p5(1)],'Original', 'VCFIT')
+ − hold off
+ −
+ − case 2
+ − % Semilogx plot for absolute value
+ − figure(plth)
+ − subplot(2,1,1);
+ − p1 = semilogx(f,abs(y.'),'k');
+ − hold on
+ − p2 = semilogx(f,abs(mresp),'r');
+ − p3 = semilogx(f,abs(rdl),'b');
+ − xlabel('Frequency [Hz]')
+ − ylabel('Amplitude')
+ − legend([p1(1) p2(1) p3(1)],'Original', 'VCFIT','Residual')
+ − hold off
+ −
+ − subplot(2,1,2);
+ − p4 = semilogx(f,(180/pi).*unwrap(angle(y.')),'k');
+ − hold on
+ − p5 = semilogx(f,(180/pi).*unwrap(angle(mresp)),'r');
+ − xlabel('Frequency [Hz]')
+ − ylabel('Phase [Deg]')
+ − legend([p4(1) p5(1)],'Original', 'VCFIT')
+ − hold off
+ −
+ − case 3
+ − % Semilogy plot for absolute value
+ − figure(plth)
+ − subplot(2,1,1);
+ − p1 = semilogy(f,abs(y.'),'k');
+ − hold on
+ − p2 = semilogy(f,abs(mresp),'r');
+ − p3 = semilogy(f,abs(rdl),'b');
+ − xlabel('Frequency [Hz]')
+ − ylabel('Amplitude')
+ − legend([p1(1) p2(1) p3(1)],'Original', 'VCFIT','Residual')
+ − hold off
+ −
+ − subplot(2,1,2);
+ − p4 = semilogy(f,(180/pi).*unwrap(angle(y.')),'k');
+ − hold on
+ − p5 = semilogy(f,(180/pi).*unwrap(angle(mresp)),'r');
+ − xlabel('Frequency [Hz]')
+ − ylabel('Phase [Deg]')
+ − legend([p4(1) p5(1)],'Original', 'VCFIT')
+ − hold off
+ −
+ − case 4
+ − % Linear plot for absolute value
+ − figure(plth)
+ − subplot(2,1,1);
+ − p1 = plot(f,abs(y.'),'k');
+ − hold on
+ − p2 = plot(f,abs(mresp),'r');
+ − p3 = plot(f,abs(rdl),'b');
+ − xlabel('Frequency [Hz]')
+ − ylabel('Amplitude')
+ − legend([p1(1) p2(1) p3(1)],'Original', 'VCFIT','Residual')
+ − hold off
+ −
+ − subplot(2,1,2);
+ − p4 = plot(f,(180/pi).*unwrap(angle(y.')),'k');
+ − hold on
+ − p5 = plot(f,(180/pi).*unwrap(angle(mresp)),'r');
+ − xlabel('Frequency [Hz]')
+ − ylabel('Phase [Deg]')
+ − legend([p4(1) p5(1)],'Original', 'VCFIT')
+ − hold off
+ −
+ − end