Mercurial > hg > ltpda
comparison m-toolbox/classes/+utils/@math/linfitsvd.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 % Linear fit with singular value decomposition | |
2 % | |
3 % INPUT: | |
4 % - exps: is a N dimensional struct whose fields are fitdata | |
5 % (experimental data), fitbasis (basis for the fit) and params (cell | |
6 % array with the names of the parameters used in the experiment). | |
7 % - groundexps: a M dim struct containing results from on ground experiments. | |
8 % Fuields are: pos (parameter position number), value (on ground measurement | |
9 % result) and err (experimental error on the on ground measurement). | |
10 % - sThreshold it's a threshold for singular values. It is a | |
11 % number, typically 1. It will remove singular values larger | |
12 % than sThreshold which corresponds to removing svd parameters estimated | |
13 % with an error larger than sThreshold. | |
14 % | |
15 % OUTPUT: | |
16 % a: params values | |
17 % Ca: fit covariance matrix for A | |
18 % Corra: fit correlation matrix for A | |
19 % Vu: is the complete conversion matrix | |
20 % Cbu: is the new variables covariance matrix | |
21 % Fbu: is the information matrix for the new variable | |
22 % mse: is the fit Mean Square Error | |
23 % dof: degrees of freedom for the global estimation | |
24 % ppm: number of svd parameters per measurements, provides also the | |
25 % number of independent combinations of parameters per each singular | |
26 % measurement. The coefficients of the combinations are then stored in Vu | |
27 % | |
28 % 21-07-2009 L Ferraioli | |
29 % CREATION | |
30 % | |
31 % | |
32 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
33 % $Id: linfitsvd.m,v 1.8 2010/10/29 12:40:47 ingo Exp $ | |
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
35 function [a,Ca,Corra,Vu,bu,Cbu,Fbu,mse,dof,ppm] = linfitsvd(varargin) | |
36 | |
37 % get inputs | |
38 if nargin == 1 % no ground experiment | |
39 exps = varargin{1}; | |
40 groundexps = []; | |
41 remerr = false; | |
42 elseif nargin == 2 | |
43 exps = varargin{1}; | |
44 if isnumeric(varargin{2}) | |
45 sThreshold = varargin{2}; | |
46 remerr = true; | |
47 groundexps = []; | |
48 else | |
49 groundexps = varargin{2}; | |
50 remerr = false; | |
51 end | |
52 elseif nargin == 3 | |
53 exps = varargin{1}; | |
54 groundexps = varargin{2}; | |
55 sThreshold = varargin{3}; % admitted threshold for singular values | |
56 remerr = true; | |
57 if ~isnumeric(sThreshold) | |
58 sThreshold = inf; | |
59 end | |
60 end | |
61 | |
62 % init collect results struct | |
63 | |
64 % init union matrices | |
65 Vu = []; | |
66 Fbu = []; | |
67 wFbu = []; | |
68 bu = []; | |
69 % eCbu = []; | |
70 Cbu = []; | |
71 ppm = []; % number of svd parameters per measurements | |
72 | |
73 N = numel(exps); | |
74 % run over input experiments | |
75 for ii=1:N | |
76 % get data of the experiments out of the input struct | |
77 y = exps(ii).fitdata; | |
78 X = exps(ii).fitbasis; | |
79 | |
80 % willing to work with columns | |
81 if size(y,1)<size(y,2) | |
82 y = y.'; | |
83 end | |
84 if size(X,1)<size(X,2) | |
85 X = X.'; | |
86 end | |
87 | |
88 % get svd of X | |
89 [U,W,V] = svd(X,0); | |
90 | |
91 % removing zero singular values | |
92 svals = diag(W); | |
93 idx = svals==0; | |
94 svals(idx) = []; | |
95 | |
96 % removing columns of U and V corresponding to zero svalues | |
97 U(:,idx) = []; | |
98 V(:,idx) = []; | |
99 | |
100 if remerr | |
101 % Find params combinations with error larger than 1 | |
102 idx = svals<sThreshold; | |
103 svals(idx) = []; | |
104 | |
105 % removing columns of U and V corresponding to params combinations with | |
106 % error larger than 1 | |
107 U(:,idx) = []; | |
108 V(:,idx) = []; | |
109 end | |
110 | |
111 % Sanity check | |
112 % if svals is empty you are going to gain no information from the | |
113 % current data series | |
114 if ~isempty(svals) % go with the fit | |
115 % rebuild W | |
116 W = diag(svals); | |
117 | |
118 % update ppm with the number of parameters for the given experiment | |
119 ppm = [ppm; numel(svals)]; | |
120 | |
121 % get new basis for the fit | |
122 K = U*W; | |
123 | |
124 % get expected covariance matrix for b, assuming white noise | |
125 Fb = W*W; % information matrix for parameters b | |
126 | |
127 % get b params with errors, mse is the mean square error, Cb is the | |
128 % covariance matrix of fitted b. It should be equal to eCb.*mse | |
129 [b,stdxb,mseb,Cb] = lscov(K,y); | |
130 | |
131 % information matrix weighted for fit results Cb = inv(wFb) | |
132 wFb = Fb./mseb; | |
133 | |
134 % add params from present experiment | |
135 % get union matrices | |
136 Vu = [Vu;V.']; | |
137 Fbu = blkdiag(Fbu,Fb); | |
138 wFbu = blkdiag(wFbu,wFb); | |
139 Cbu = blkdiag(Cbu,Cb); | |
140 bu = [bu;b]; | |
141 | |
142 else % no information, no fit | |
143 % update ppm with the number of parameters for the given experiment | |
144 ppm = [ppm; 0]; | |
145 end | |
146 | |
147 | |
148 | |
149 end | |
150 | |
151 % insert values from on-ground measured parameters if applicable | |
152 if nargin == 2 | |
153 | |
154 for jj = 1:numel(groundexps) | |
155 | |
156 % get values | |
157 pos = groundexps(jj).pos; | |
158 val = groundexps(jj).value; | |
159 err = groundexps(jj).err; | |
160 | |
161 tV = zeros(1,size(Vu,2)); | |
162 tV(1,pos) = 1; | |
163 Vu = [Vu;tV]; | |
164 bu = [bu;val]; | |
165 Cbu = blkdiag(Cbu,err^2); | |
166 Fbu = blkdiag(Fbu,1/(err^2)); | |
167 wFbu = blkdiag(wFbu,1/(err^2)); | |
168 ppm = [ppm; 1]; | |
169 | |
170 end | |
171 | |
172 end | |
173 | |
174 % get results on physical parameters, solve the system with proper weights | |
175 a = lscov(Vu,bu,1./diag(Cbu)); | |
176 | |
177 % get params covariance | |
178 Ca = inv(Vu'*wFbu*Vu); | |
179 | |
180 % get params correlation matrix | |
181 Corra = Ca; | |
182 for tt=1:size(Corra,1) | |
183 for hh=1:size(Corra,2) | |
184 Corra(tt,hh) = Ca(tt,hh)/(sqrt(Ca(tt,tt))*sqrt(Ca(hh,hh))); | |
185 end | |
186 end | |
187 | |
188 % get chi square assuming unitary variance white noise | |
189 N = numel(exps); | |
190 mse = 0; | |
191 tL = 0; | |
192 % run over input experiments | |
193 for ii=1:N | |
194 % get data of the experiments out of the input struct | |
195 y = exps(ii).fitdata; | |
196 X = exps(ii).fitbasis; | |
197 | |
198 mse = mse + sum((y - X*a).^2); | |
199 tL = tL + numel(y); | |
200 end | |
201 dof = tL-numel(a); | |
202 mse = mse./dof; | |
203 | |
204 end | |
205 | |
206 | |
207 | |
208 | |
209 | |
210 | |
211 | |
212 | |
213 |