0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
1 % DTFIT fits a discrete model to a frequency response.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
2 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
3 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
4 % DESCRIPTION:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
5 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
6 % Fits a discrete model to a frequency response using relaxed z-domain
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
7 % vector fitting algorithm [1 - 3]. Model function is expanded in
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
8 % partial fractions:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
9 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
10 % r1 rN
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
11 % f(z) = ----------- + ... + ----------- + d
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
12 % 1-p1*z^{-1} 1-pN*z^{-1}
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
13 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
14 % CALL:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
15 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
16 % [res,poles,dterm,mresp,rdl] = dtfit(y,f,poles,weight,fitin)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
17 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
18 % INPUTS:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
19 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
20 % - y: Is a vector wuth the frequency response data.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
21 % - f: Is the frequency vector in Hz.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
22 % - poles: are a set of starting poles.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
23 % - weight: are a set of weights used in the fitting procedure.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
24 % - fitin: is a struct containing fitting options and parameters. fitin
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
25 % fields are:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
26 % - fitin.stable = 0; fit without forcing poles to be stable.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
27 % - fitin.stable = 1; force poles to be stable flipping unstable
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
28 % poles in the unit circle. z -> 1/z*.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
29 % - fitin.dterm = 0; fit with d = 0.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
30 % - fitin.dterm = 1; fit with d different from 0.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
31 % - fitin.fs = fs; input the sampling frequency in Hz (default value
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
32 % is 1 Hz).
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
33 % - fitin.polt = 0; fit without plotting results.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
34 % - fitin.plot = 1; plot fit results.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
35 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
36 % OUTPUT:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
37 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
38 % - res: vector or residues.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
39 % - poles: vector of poles.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
40 % - dterm: direct term d.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
41 % - mresp: frequency response of the fitted model
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
42 % - rdl: residuals y - mresp
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
43 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
44 % REFERENCES:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
45 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
46 % [1] B. Gustavsen and A. Semlyen, "Rational approximation of frequency
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
47 % domain responses by Vector Fitting", IEEE Trans. Power Delivery
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
48 % vol. 14, no. 3, pp. 1052-1061, July 1999.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
49 % [2] B. Gustavsen, "Improving the Pole Relocating Properties of Vector
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
50 % Fitting", IEEE Trans. Power Delivery vol. 21, no. 3, pp.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
51 % 1587-1592, July 2006.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
52 % [3] Y. S. Mekonnen and J. E. Schutt-Aine, "Fast broadband
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
53 % macromodeling technique of sampled time/frequency data using
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
54 % z-domain vector-fitting method", Electronic Components and
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
55 % Technology Conference, 2008. ECTC 2008. 58th 27-30 May 2008 pp.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
56 % 1231 - 1235.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
57 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
58 % NOTE:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
59 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
60 % This function cannot handle more than one frequency response per time
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
61 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
62 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
63 % VERSION: $Id: dtfit.m,v 1.2 2008/10/24 06:19:23 hewitson Exp $
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
64 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
65 % HISTORY: 12-09-2008 L Ferraioli
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
66 % Creation
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
67 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
68
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
69 function [res,poles,dterm,mresp,rdl] = dtfit(y,f,poles,weight,fitin)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
70
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
71
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
72 %% Collecting inputs
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
73
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
74 % Default input struct
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
75 defaultparams = struct('stable',0, 'dterm',0, 'fs',1, 'plot',0);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
76
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
77 names = {'stable','dterm','fs','plot'};
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
78
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
79 % collecting input and default params
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
80 if ~isempty(fitin)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
81 for jj=1:length(names)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
82 if isfield(fitin, names(jj))
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
83 defaultparams.(names{1,jj}) = fitin.(names{1,jj});
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
84 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
85 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
86 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
87
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
88 stab = defaultparams.stable; % Enforce pole stability is is 1
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
89 dt = defaultparams.dterm; % 1 to fit with direct term
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
90 fs = defaultparams.fs; % sampling frequency
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
91 plotting = defaultparams.plot; % set to 1 if plotting is required
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
92
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
93
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
94 %% Inputs in column vectors
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
95
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
96 [a,b] = size(y);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
97 if a < b % shifting to column
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
98 y = y.';
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
99 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
100
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
101 [a,b] = size(f);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
102 if a < b % shifting to column
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
103 f = f.';
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
104 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
105
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
106 [a,b] = size(poles);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
107 if a < b % shifting to column
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
108 poles = poles.';
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
109 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
110
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
111 clear w
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
112 w = weight;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
113 [a,b] = size(w);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
114 if a < b % shifting to column
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
115 w = w.';
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
116 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
117
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
118 N = length(poles); % Model order
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
119
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
120 if dt
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
121 dl = 1; % Fit with direct term
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
122 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
123 dl = 0; % Fit without direct term
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
124 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
125
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
126 % definition of z
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
127 z = cos(2.*pi.*f./fs)+1i.*sin(2.*pi.*f./fs);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
128
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
129 Nz = length(z);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
130
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
131 %% Normalizing y
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
132
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
133 y = y./z;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
134
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
135 %% Marking complex and real poles
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
136
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
137 % cindex = 1; pole is complex, next conjugate pole is marked with cindex
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
138 % = 2. cindex = 0; pole is real
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
139 cindex=zeros(N,1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
140 for m=1:N
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
141 if imag(poles(m))~=0
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
142 if m==1
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
143 cindex(m)=1;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
144 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
145 if cindex(m-1)==0 || cindex(m-1)==2
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
146 cindex(m)=1; cindex(m+1)=2;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
147 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
148 cindex(m)=2;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
149 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
150 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
151 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
152 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
153
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
154 %% Initializing the augmented problem matrices
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
155
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
156
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
157
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
158 % Matrix initialinzation
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
159 BA = zeros(Nz+1,1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
160 AA = zeros(Nz+1,2*N+dl+1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
161 Ak=zeros(Nz,N+1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
162
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
163 % Defining Ak
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
164 % for jj = 1:N
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
165 % if cindex(jj) == 1 % conjugate complex couple of poles
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
166 % Ak(:,jj) = (1./(1-poles(jj)./z))+(1./(1-poles(jj+1)./z));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
167 % Ak(:,jj+1) = (j./(1-poles(jj)./z))-(j./(1-poles(jj+1)./z));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
168 % elseif cindex(jj) == 0 % real pole
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
169 % Ak(:,jj) = 1./(1-poles(jj)./z);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
170 % end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
171 % end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
172
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
173 for jj = 1:N
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
174 if cindex(jj) == 1 % conjugate complex couple of poles
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
175 Ak(:,jj) = (1./(z-poles(jj)))+(1./(z-poles(jj+1)));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
176 Ak(:,jj+1) = (j./(z-poles(jj)))-(j./(z-poles(jj+1)));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
177 elseif cindex(jj) == 0 % real pole
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
178 Ak(:,jj) = 1./(z-poles(jj));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
179 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
180 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
181
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
182
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
183 Ak(1:Nz,N+1) = ones(Nz,1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
184
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
185 for m=1:N+dl % left columns
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
186 AA(1:Nz,m)=w.*Ak(1:Nz,m);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
187 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
188 if dt
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
189 AA(1:Nz,N+dl)=w./z;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
190 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
191 for m=1:N+1 %Rightmost blocks
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
192 AA(1:Nz,N+dt+m)=-w.*(Ak(1:Nz,m).*y);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
193 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
194
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
195 % Scaling factor
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
196 clear sc
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
197 sc = norm(w.*y)/Nz;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
198
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
199 % setting the last row of AA and BA for the relaxion condition
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
200 for qq = 1:N+1
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
201 AA(Nz+1,N+dl+qq) = real(sc*sum(Ak(:,qq)));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
202 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
203
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
204 AA = [real(AA);imag(AA)];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
205
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
206 % AAstr1 = AA; % storing
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
207
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
208 % Last element of the solution vector
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
209 BA(Nz+1) = Nz*sc;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
210
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
211 % solving for real and imaginary part of the solution vector
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
212 nBA = [real(BA);imag(BA)];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
213
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
214 % Normalization factor
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
215 nf = zeros(2*N+dl+1,1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
216 for pp = 1:2*N+dl+1
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
217 nf(pp,1) = norm(AA(:,pp),2); % Euclidean norm
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
218 AA(:,pp) = AA(:,pp)./nf(pp,1); % Normalization
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
219 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
220
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
221
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
222 %% Solving augmented problem
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
223
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
224 % XA = pinv(AA)*nBA;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
225 % XA = inv((AA.')*AA)*(AA.')*nBA;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
226
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
227 % XA = AA.'*AA\AA.'*nBA;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
228
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
229 XA = AA\nBA;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
230
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
231 XA = XA./nf; % renormalization
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
232
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
233 %% Finding zeros of sigma
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
234
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
235 lsr = XA(N+dl+1:2*N+dl,1); % collect the least square results
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
236
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
237 Ds = XA(end); % direct term of sigma
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
238
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
239 % Real poles have real residues, complex poles have comples residues
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
240 rs = zeros(N,1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
241 for tt = 1:N
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
242 if cindex(tt) == 1 % conjugate complex couple of poles
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
243 rs(tt,1) = lsr(tt)+1i*lsr(tt+1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
244 rs(tt+1,1) = lsr(tt)-1i*lsr(tt+1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
245 elseif cindex(tt) == 0 % real pole
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
246 rs(tt,1) = lsr(tt);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
247 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
248 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
249
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
250 % [snum, sden] = residuez(rs,poles,Ds);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
251 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
252 % % ceking for numerical calculation errors
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
253 % for jj = 1:length(snum)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
254 % if ~isequal(imag(snum(jj)),0)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
255 % snum(jj)=real(snum(jj));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
256 % end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
257 % end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
258 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
259 % % Zeros of sigma are poles of F
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
260 % szeros = roots(snum);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
261
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
262 DPOLES = diag(poles);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
263 B = ones(N,1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
264 C = rs.';
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
265 for kk = 1:N
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
266 if cindex(kk) == 1
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
267 DPOLES(kk,kk)=real(DPOLES(kk,kk));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
268 DPOLES(kk,kk+1)=imag(DPOLES(kk,kk));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
269 DPOLES(kk+1,kk)=-1*imag(DPOLES(kk,kk));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
270 DPOLES(kk+1,kk+1)=real(DPOLES(kk,kk));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
271 B(kk,1) = 2;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
272 B(kk+1,1) = 0;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
273 C(1,kk) = real(C(1,kk));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
274 C(1,kk+1) = imag(C(1,kk));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
275 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
276 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
277
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
278 H = DPOLES-B*C/Ds;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
279 szeros = eig(H);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
280
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
281 %% Ruling out unstable poles
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
282
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
283 % This option force the poles of f to stay inside the unit circle
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
284 if stab
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
285 unst = abs(szeros) > 1;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
286 szeros(unst) = 1./conj(szeros(unst));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
287 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
288 N = length(szeros);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
289
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
290 %% Separating complex poles from real poles and ordering
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
291
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
292 rnpoles = [];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
293 inpoles = [];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
294 for tt = 1:N
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
295 if imag(szeros(tt)) == 0
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
296 % collecting real poles
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
297 rnpoles = [rnpoles; szeros(tt)];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
298 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
299 % collecting complex poles
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
300 inpoles = [inpoles; szeros(tt)];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
301 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
302 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
303
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
304 % Sorting complex poles in order to have them in the expected order a+jb
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
305 % and a-jb a>0 b>0
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
306 inpoles = sort(inpoles);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
307 npoles = [rnpoles;inpoles];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
308 npoles = npoles - 2.*1i.*imag(npoles);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
309
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
310 %% Marking complex and real poles
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
311
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
312 cindex=zeros(N,1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
313 for m=1:N
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
314 if imag(npoles(m))~=0
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
315 if m==1
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
316 cindex(m)=1;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
317 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
318 if cindex(m-1)==0 || cindex(m-1)==2
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
319 cindex(m)=1; cindex(m+1)=2;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
320 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
321 cindex(m)=2;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
322 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
323 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
324 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
325 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
326
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
327 %% Initializing direct problem
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
328
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
329 % Matrix initialinzation
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
330 B = w.*y;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
331 AD = zeros(Nz,N+dl);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
332 Ak=zeros(Nz,N+dl);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
333
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
334 % Defining Ak
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
335 % for jj = 1:N
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
336 % if cindex(jj) == 1 % conjugate complex couple of poles
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
337 % Ak(:,jj) = (1./(1-npoles(jj)./z))+(1./(1-npoles(jj+1)./z));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
338 % Ak(:,jj+1) = (j./(1-npoles(jj)./z))-(j./(1-npoles(jj+1)./z));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
339 % elseif cindex(jj) == 0 % real pole
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
340 % Ak(:,jj) = 1./(1-npoles(jj)./z);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
341 % end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
342 % end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
343
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
344 for jj = 1:N
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
345 if cindex(jj) == 1 % conjugate complex couple of poles
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
346 Ak(:,jj) = (1./(z-npoles(jj)))+(1./(z-npoles(jj+1)));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
347 Ak(:,jj+1) = (1i./(z-npoles(jj)))-(1i./(z-npoles(jj+1)));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
348 elseif cindex(jj) == 0 % real pole
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
349 Ak(:,jj) = 1./(z-npoles(jj));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
350 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
351 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
352
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
353 if dt
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
354 % Ak(1:Nz,N+dl) = ones(Nz,1); % considering the direct term
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
355 Ak(1:Nz,N+dl) = 1./z;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
356 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
357
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
358 % Defining AD
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
359 for m=1:N+dl
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
360 AD(1:Nz,m)=w.*Ak(1:Nz,m);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
361 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
362
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
363
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
364 AD = [real(AD);imag(AD)];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
365 nB = [real(B);imag(B)];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
366
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
367 % Normalization factor
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
368 nf = zeros(N+dl,1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
369 for pp = 1:N+dl
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
370 nf(pp,1) = norm(AD(:,pp),2); % Euclidean norm
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
371 AD(:,pp) = AD(:,pp)./nf(pp,1); % Normalization
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
372 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
373
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
374 %% Solving direct problem
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
375
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
376 % XD = inv((AD.')*AD)*(AD.')*nB;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
377 % XD = AD.'*AD\AD.'*nB;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
378 % XD = pinv(AD)*nB;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
379 XD = AD\nB;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
380
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
381 XD = XD./nf; % Renormalization
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
382
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
383 %% Final residues and poles of f
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
384
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
385 if dt
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
386 lsr = XD(1:end-1); % Fitting with direct term
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
387 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
388 lsr = XD(1:end); % Fitting without direct term
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
389 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
390
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
391 res = zeros(N,1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
392 % Real poles have real residues, complex poles have comples residues
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
393 for tt = 1:N
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
394 if cindex(tt) == 1 % conjugate complex couple of poles
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
395 res(tt) = lsr(tt)+1i*lsr(tt+1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
396 res(tt+1) = lsr(tt)-1i*lsr(tt+1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
397 elseif cindex(tt) == 0 % real pole
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
398 res(tt) = lsr(tt);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
399 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
400 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
401
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
402 clear poles
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
403 poles = npoles;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
404
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
405 if dt
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
406 dterm = XD(end);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
407 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
408 dterm = 0;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
409 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
410
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
411 %% Calculating response and residual
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
412
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
413 % freq resp of the fit model
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
414 r = res;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
415 p = poles;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
416 d = dterm;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
417
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
418 Nf = length(f);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
419 N = length(p);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
420
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
421 % Defining normalized frequencies
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
422 fn = f./fs;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
423
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
424 rsp = zeros(Nf,1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
425 indx = 0:length(d)-1;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
426 for ii = 1:Nf
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
427 for jj = 1:N
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
428 rsptemp = exp(1i*2*pi*fn(ii))*r(jj)/(exp(1i*2*pi*fn(ii))-p(jj));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
429 rsp(ii) = rsp(ii) + rsptemp;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
430 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
431 % Direct terms response
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
432 rsp(ii) = rsp(ii) + sum(((exp((1i*2*pi*f(ii))*ones(length(d),1))).^(-1.*indx)).*d);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
433 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
434
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
435 % Model response
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
436 mresp = rsp;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
437
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
438 % Residual
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
439 yr = y.*z;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
440 rdl = yr - mresp;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
441
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
442 %% Plotting response
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
443
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
444 if plotting
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
445 figure(1)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
446 subplot(2,1,1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
447 loglog(fn,abs(yr),'k')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
448 hold on
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
449 loglog(fn,abs(mresp),'r')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
450 loglog(fn,abs(rdl),'b')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
451 xlabel('Normalized Frequency [f/fs]')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
452 ylabel('Amplitude')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
453 legend('Original', 'DTFIT','Residual')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
454 hold off
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
455
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
456 subplot(2,1,2);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
457 semilogx(fn,angle(yr),'k')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
458 hold on
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
459 semilogx(fn,angle(mresp),'r')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
460 xlabel('Normalized Frequency [f/fs]')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
461 ylabel('Phase [Rad]')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
462 legend('Original', 'DTFIT')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
463 hold off
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
464 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
465 end |