0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
1 % MULTICHANNELNOISE
|
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 % FUNCTION: MultiChannelNoise
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
5 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
6 % DESCRIPTION:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
7 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
8 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
9 % CALL: a = MultiChannelNoise(a, pl)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
10 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
11 % PARAMETER:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
12 % pl: plist containing Nsecs, fs
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
13 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
14 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
15 function a = MultiChannelNoise(a, pli)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
16
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
17 VERSION = '$Id: MultiChannelNoise.m,v 1.10 2010/10/29 16:09:13 ingo Exp $';
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
18
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
19 % get AO info
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
20 iobj = matrix.getInfo('matrix', 'Multichannel Noise');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
21
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
22 % Set the method version string in the minfo object
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
23 iobj.setMversion([VERSION '-->' iobj.mversion]);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
24
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
25 % Add default values
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
26 pl = parse(pli, iobj.plists);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
27
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
28 % Get parameters and set params for fit
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
29 Nsecs = find(pl, 'nsecs');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
30 fs = find(pl, 'fs');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
31 filter = find(pl, 'model');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
32 yunit = find(pl, 'yunits');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
33
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
34 % total number of data in the series
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
35 Ntot = round(Nsecs*fs);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
36
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
37 % chose case for input filter
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
38 if isa(filter,'matrix') && isa(filter.objs(1),'filterbank')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
39 % discrete system
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
40 sys = 'z';
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
41 mfil = filter.objs;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
42 [nn,mm] = size(mfil);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
43 if nn~=mm
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
44 error('!!! Filter matrix must be square')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
45 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
46 elseif isa(filter,'matrix') && isa(filter.objs(1),'parfrac')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
47 % continuous system
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
48 sys = 's';
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
49 mfil = filter.objs;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
50 [nn,mm] = size(mfil);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
51 if nn~=mm
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
52 error('!!! Filter matrix must be square')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
53 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
54 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
55 error('!!! Input filter must be a ''matrix'' of ''filterbank'' or ''parfrac'' objects.')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
56 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
57
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
58 % init output
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
59 out(nn,1) = ao;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
60
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
61 % switch between input filter type
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
62 switch sys
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
63 case 'z' % discrete input filters
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
64
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
65 o = zeros(nn,Ntot);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
66
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
67 for zz=1:nn % moving along system dimension
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
68
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
69 % extract residues and poles from input objects
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
70 % run over matrix dimensions
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
71 res = [];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
72 pls = [];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
73 filtsz = [];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
74 for jj=1:nn % collect filters coefficients along the columns zz
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
75 bfil = mfil(jj,zz).filters;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
76 filtsz = [filtsz; numel(bfil)];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
77 for kk=1:numel(bfil)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
78 num = bfil(kk).a;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
79 den = bfil(kk).b;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
80 res = [res; num(1)];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
81 pls = [pls; -1*den(2)];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
82 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
83 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
84
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
85 % rescaling residues to get the correct result for univariate psd
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
86 res = res.*sqrt(fs/2);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
87
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
88 Nrs = numel(res);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
89 % get covariance matrix
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
90 R = zeros(Nrs);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
91 for aa=1:Nrs
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
92 for bb=1:Nrs
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
93 R(aa,bb) = (res(aa)*conj(res(bb)))/(1-pls(aa)*conj(pls(bb)));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
94 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
95 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
96
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
97 % avoiding problems caused by roundoff errors
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
98 HH = triu(R,0); % get upper triangular part of R
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
99 HH1 = triu(R,1); % get upper triangular part of R above principal diagonal
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
100 HH2 = HH1'; % do transpose conjugate
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
101 R = HH + HH2; % reconstruct R in order to be really hermitian
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
102
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
103 % get singular value decomposition of R
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
104 [U,S,V] = svd(R,0);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
105
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
106 % conversion matrix
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
107 A = V*sqrt(S);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
108
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
109 % generate unitary variance gaussian random noise
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
110 %ns = randn(Nrs,Ntot);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
111 ns = randn(Nrs,1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
112
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
113 % get correlated starting data points
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
114 cns = A*ns;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
115
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
116 % need to correct for roundoff errors
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
117 % cleaning up results for numerical approximations
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
118 idx = imag(pls(:,1))==0;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
119 cns(idx) = real(cns(idx));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
120
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
121 % cleaning up results for numerical roundoff errors
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
122 % states associated to complex conjugate poles must be complex
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
123 % conjugate
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
124 idxi = imag(pls(:,1))~=0;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
125 icns = cns(idxi);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
126 for jj = 1:2:numel(icns)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
127 icns(jj+1,1) = conj(icns(jj,1));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
128 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
129 cns(idxi) = icns;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
130
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
131 y = zeros(sum(filtsz),2);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
132 rnoise = zeros(sum(filtsz),1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
133 rns = randn(1,Ntot);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
134 %rns = utils.math.blwhitenoise(Ntot,fs,1/Nsecs,fs/2);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
135 %rns = rns.'; % willing to work with raw
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
136
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
137 y(:,1) = cns;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
138
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
139 % start recurrence
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
140 for xx = 2:Ntot+1
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
141 rnoise(:,1) = rns(xx-1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
142 y(:,2) = pls.*y(:,1) + res.*rnoise;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
143 idxr = 0;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
144 for kk=1:nn
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
145 o(kk,xx-1) = o(kk,xx-1) + sum(y(idxr+1:idxr+filtsz(kk),2));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
146 idxr = idxr+filtsz(kk);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
147 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
148 y(:,1) = y(:,2);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
149 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
150
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
151 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
152
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
153 clear rns
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
154
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
155 % build output ao
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
156 for dd=1:nn
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
157 out(dd,1) = ao(tsdata(o(dd,:),fs));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
158 out(dd,1).setYunits(unit(yunit));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
159 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
160
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
161 a = matrix(out);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
162
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
163 case 's' % continuous input filters
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
164
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
165 o = zeros(nn,Ntot);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
166
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
167 T = 1/fs; % sampling period
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
168
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
169 for zz=1:nn % moving along system dimension
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
170
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
171 % extract residues and poles from input objects
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
172 % run over matrix dimensions
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
173 res = [];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
174 pls = [];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
175 filtsz = [];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
176 for jj=1:nn % collect filters coefficients along the columns zz
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
177 bfil = mfil(jj,zz);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
178 filtsz = [filtsz; numel(bfil.res)];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
179 res = [res; bfil.res];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
180 pls = [pls; bfil.poles];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
181 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
182
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
183 % rescaling residues to get the correct result for univariate psd
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
184 res = res.*sqrt(fs/2);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
185
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
186 Nrs = numel(res);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
187
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
188 % get covariance matrix for innovation
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
189 Ri = zeros(Nrs);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
190 for aa=1:Nrs
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
191 for bb=1:Nrs
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
192 Ri(aa,bb) = (res(aa)*conj(res(bb)))*(exp((pls(aa) + conj(pls(bb)))*T)-1)/(pls(aa) + conj(pls(bb)));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
193 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
194 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
195
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
196 % avoiding problems caused by roundoff errors
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
197 HH = triu(Ri,0); % get upper triangular part of R
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
198 HH1 = triu(Ri,1); % get upper triangular part of R above principal diagonal
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
199 HH2 = HH1'; % do transpose conjugate
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
200 Ri = HH + HH2; % reconstruct R in order to be really hermitian
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
201
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
202 % get singular value decomposition of R
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
203 [Ui,Si,Vi] = svd(Ri,0);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
204
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
205 % conversion matrix for innovation
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
206 Ai = Vi*sqrt(Si);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
207
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
208 % get covariance matrix for initial state
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
209 Rx = zeros(Nrs);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
210 for aa=1:Nrs
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
211 for bb=1:Nrs
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
212 Rx(aa,bb) = -1*(res(aa)*conj(res(bb)))/(pls(aa) + conj(pls(bb)));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
213 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
214 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
215
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
216 % avoiding problems caused by roundoff errors
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
217 HH = triu(Rx,0); % get upper triangular part of R
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
218 HH1 = triu(Rx,1); % get upper triangular part of R above principal diagonal
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
219 HH2 = HH1'; % do transpose conjugate
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
220 Rx = HH + HH2; % reconstruct R in order to be really hermitian
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
221
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
222 % get singular value decomposition of R
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
223 [Ux,Sx,Vx] = svd(Rx,0);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
224
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
225 % conversion matrix for initial state
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
226 Ax = Vx*sqrt(Sx);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
227
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
228 % generate unitary variance gaussian random noise
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
229 %ns = randn(Nrs,Ntot);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
230 ns = randn(Nrs,1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
231
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
232 % get correlated starting data points
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
233 cns = Ax*ns;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
234
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
235 % need to correct for roundoff errors
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
236 % cleaning up results for numerical approximations
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
237 idx = imag(pls(:,1))==0;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
238 cns(idx) = real(cns(idx));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
239
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
240 % cleaning up results for numerical roundoff errors
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
241 % states associated to complex conjugate poles must be complex
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
242 % conjugate
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
243 idxi = imag(pls(:,1))~=0;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
244 icns = cns(idxi);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
245 for jj = 1:2:numel(icns)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
246 icns(jj+1,1) = conj(icns(jj,1));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
247 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
248 cns(idxi) = icns;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
249
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
250 y = zeros(sum(filtsz),2);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
251 rnoise = zeros(sum(filtsz),1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
252 rns = randn(1,Ntot);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
253 %rns = utils.math.blwhitenoise(Ntot,fs,1/Nsecs,fs/2);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
254 %rns = rns.'; % willing to work with raw
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
255
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
256 y(:,1) = cns;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
257
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
258 % start recurrence
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
259 for xx = 2:Ntot+1
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
260 % innov = Ai*randn(sum(filtsz),1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
261 rnoise(:,1) = rns(xx-1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
262 innov = Ai*rnoise;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
263 % need to correct for roundoff errors
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
264 % cleaning up results for numerical approximations
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
265 innov(idx) = real(innov(idx));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
266
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
267 % cleaning up results for numerical roundoff errors
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
268 % states associated to complex conjugate poles must be complex
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
269 % conjugate
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
270 iinnov = innov(idxi);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
271 for jj = 1:2:numel(iinnov)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
272 iinnov(jj+1,1) = conj(iinnov(jj,1));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
273 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
274 innov(idxi) = iinnov;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
275
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
276 y(:,2) = diag(exp(pls.*T))*y(:,1) + innov;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
277
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
278 idxr = 0;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
279 for kk=1:nn
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
280 o(kk,xx-1) = o(kk,xx-1) + sum(y(idxr+1:idxr+filtsz(kk),2));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
281 idxr = idxr+filtsz(kk);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
282 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
283 y(:,1) = y(:,2);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
284 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
285
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
286 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
287
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
288 % clear rns
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
289
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
290 % build output ao
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
291 for dd=1:nn
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
292 out(dd,1) = ao(tsdata(o(dd,:),fs));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
293 out(dd,1).setYunits(unit(yunit));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
294 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
295
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
296 a = matrix(out);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
297
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
298 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
299
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
300
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
301 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
302
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
303
|