0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
1 % POLYNOMFIT is a polynomial fitting tool
|
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: POLYNOMFIT is a polynomial fitting tool based on MATLAB's
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
5 % lscov function. It solves an equation in the form
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
6 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
7 % Y = P(1) * X^N(1) + P(2) * X^N(2) + ...
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
8 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
9 % for the fit parameters P. It handles arbitrary powers of the input vector
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
10 % and uncertainties on the dependent vector Y and input vectors X.
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
11 % The output is a pest object where the fields are containing:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
12 % Quantity % Field
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
13 % Fit coefficients y
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
14 % Uncertainties on the fit parameters
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
15 % (given as standard deviations) dy
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
16 % The reduced CHI2 of the fit chi2
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
17 % The covariance matrix cov
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
18 % The degrees of freedom of the fit dof
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
19 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
20 % CALL: P = polynomfit(X, Y, PL)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
21 % P = polynomfit(A, PL)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
22 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
23 % INPUTS: Y - dependent variable
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
24 % X - input variables
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
25 % A - data ao whose x and y fields are used in the fit
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
26 % PL - parameter list
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
27 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
28 % OUTPUT: P - a pest object with M = numel(N) fitting coefficients
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
29 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
30 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
31 % PARAMETERS:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
32 % 'orders' - polynom orders. Eg [0,1,-2] fits to P0 + P1*x + P2./x.^2
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
33 % 'dy' - uncertainty on the dependent variable
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
34 % 'dx' - uncertainties on the input variable
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
35 % 'p0' - initial guess on the fit parameters used ONLY to propagate
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
36 % uncertainities in the input variable X to the dependent variable Y
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
37 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
38 % <a href="matlab:utils.helper.displayMethodInfo('ao', 'polynomfit')">Parameters Description</a>
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
39 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
40 % VERSION: $Id: polynomfit.m,v 1.20 2011/04/08 08:56:11 hewitson Exp $
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
41 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
42 % EXAMPLES:
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
43 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
44 % % 1) Fit with one object input
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
45 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
46 % nsecs = 5;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
47 % fs = 10;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
48 % n = [0 1 -2];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
49 % u1 = unit('mV');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
50 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
51 % pl1 = plist('nsecs', nsecs, 'fs', fs, ...
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
52 % 'tsfcn', sprintf('t.^%d + t.^%d + t.^%d + randn(size(t))', n), ...
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
53 % 'xunits', 's', 'yunits', u1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
54 % a1 = ao(pl1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
55 % out1 = polynomfit(a1, plist('orders', n, 'dx', 0.1, 'dy', 0.1, 'P0', zeros(size(n))));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
56 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
57 % % 2) Fit with two objects input
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
58 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
59 % fs = 1;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
60 % nsecs = 10;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
61 % n = [0 1 -2];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
62 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
63 % X = ao(plist('tsfcn', 'randn(size(t))', 'fs', fs, 'nsecs', nsecs, 'yunits', 'm', 'name', 'base'));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
64 % N = ao(plist('tsfcn', 'randn(size(t))', 'fs', fs, 'nsecs', nsecs, 'yunits', 'm', 'name', 'noise'));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
65 % C = [ao(1, plist('yunits', 'm', 'name', 'C1')) ...
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
66 % ao(4, plist('yunits', 'm/m', 'name', 'C2')) ...
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
67 % ao(2, plist('yunits', 'm/m^(-2)', 'name', 'C3'))];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
68 % Y = C(1) * X.^0 + C(2) * X.^1 + C(3) * X.^(-2) + N;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
69 % Y.simplifyYunits;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
70 % out2 = polynomfit(X, Y, plist('orders', n))
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
71 %
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
72 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
73
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
74 function varargout = polynomfit(varargin)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
75
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
76 % check if this is a call for parameters
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
77 if utils.helper.isinfocall(varargin{:})
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
78 varargout{1} = getInfo(varargin{3});
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
79 return
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
80 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
81
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
82 % tell the system we are runing
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
83 import utils.const.*
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
84 utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
85
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
86 % collect input variable names
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
87 in_names = cell(size(varargin));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
88 for ii = 1:nargin,in_names{ii} = inputname(ii);end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
89
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
90 % collect all AOs and plists
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
91 [aos, ao_invars] = utils.helper.collect_objects(varargin(:), 'ao', in_names);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
92 pli = utils.helper.collect_objects(varargin(:), 'plist', in_names);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
93
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
94 if nargout == 0
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
95 error('### polynomfit can not be used as a modifier method. Please give at least one output');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
96 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
97
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
98 % combine plists, making sure the user input is not empty
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
99 pli = combine(pli, plist());
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
100 pl = parse(pli, getDefaultPlist());
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
101
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
102 % extract arguments
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
103 if (length(aos) == 1)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
104 % we are using x and y fields of the single ao we have
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
105 x = aos(1).x;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
106 dx = aos(1).dx;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
107 y = aos(1).y;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
108 dy = aos(1).dy;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
109 xunits = aos(1).xunits;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
110 yunits = aos(1).yunits;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
111 argsname = aos(1).name;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
112 elseif (length(aos) == 2)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
113 % we are using y fields of the two aos we have
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
114 x = aos(1).y;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
115 dx = aos(1).dy;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
116 y = aos(2).y;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
117 dy = aos(2).dy;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
118 xunits = aos(1).yunits;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
119 yunits = aos(2).yunits;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
120 argsname = [aos(1).name ',' aos(2).name];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
121 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
122 error('### polynomfit needs one or two input AOs');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
123 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
124
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
125 % extract plist parameters. For dx and dy we check the user input plist before
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
126 dy = find(pli, 'dy', dy);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
127 dx = find(pli, 'dx', dx);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
128 n = find(pl, 'orders');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
129 p0 = find(pl, 'p0');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
130
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
131 % vectors length
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
132 N = length(y);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
133
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
134 % number of parameters
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
135 num_params = length(n);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
136
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
137 % uncertainty on Y
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
138 if isempty(dy)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
139 dy = 1;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
140 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
141 if isa(dy, 'ao')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
142 % check units
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
143 if yunits ~= dy.data.yunits
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
144 error('### Y and DY units are not compatible - %s %s', char(yunits), char(dy.data.yunits));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
145 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
146 % extract values from AO
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
147 dy = dy.y;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
148 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
149 if isscalar(dy)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
150 % given a single value construct a vector
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
151 dy = ones(N, 1) * dy;
|
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 % weights
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
155 sigma2 = dy.^2;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
156
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
157 % extract values for initial guess
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
158 if (isa(p0, 'ao') || isa(p0, 'pest'))
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
159 p0 = p0.y;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
160 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
161
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
162 % uncertainty on X
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
163 if ~isempty(dx)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
164
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
165 if length(p0) ~= num_params
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
166 error('### initial parameters guess p0 is mandatory for proper handling of X uncertainties');
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
167 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
168
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
169 if isa(dx, 'ao')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
170 % check units
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
171 if xunits ~= dx.data.yunits
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
172 error('### X and DX units are not compatible - %s %s', char(xunits), char(dx.data.yunits));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
173 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
174 % extract values from AO
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
175 dx = dx.y;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
176 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
177 if isscalar(dx)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
178 % given a single value construct a vector
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
179 dx = ones(N, 1) * dx;
|
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 % propagate X uncertainty on Y
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
183 dy_dx_mod = zeros(N, 1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
184 for k = 1:num_params
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
185 dy_dx_mod = dy_dx_mod + n(k) * p0(k) * x.^(n(k)-1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
186 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
187 sigma2x = dy_dx_mod.^2 .* dx.^2;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
188
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
189 % add contribution to weights
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
190 sigma2 = sigma2 + sigma2x;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
191
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
192 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
193
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
194 % construct matrix with desired powers of X
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
195 m = zeros(length(x), num_params);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
196 for k = 1:num_params
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
197 m(:,k) = x .^ n(k);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
198 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
199
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
200 % check for the presence of 1/0 terms
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
201 M = [];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
202 X = [];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
203 Y = [];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
204 S = [];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
205 kk = 0;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
206
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
207 idx = isfinite(m);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
208 for jj = 1:size(m,1)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
209 if all(idx(jj,:))
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
210 kk = kk + 1;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
211 M(kk,:) = m(jj,:);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
212 X(kk) = x(jj);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
213 Y(kk) = y(jj);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
214 S(kk,:) = sigma2(jj,:);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
215 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
216 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
217 m = M; clear M;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
218 x = X'; clear X;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
219 y = Y'; clear Y;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
220 sigma2 = S; clear S;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
221 N = kk;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
222
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
223 % solve
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
224 [p, stdp, mse, s] = lscov(m, y, 1./sigma2);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
225
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
226 % scale errors
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
227 stdp = stdp ./ sqrt(mse);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
228 s = s ./ (mse);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
229
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
230 % compute chi2
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
231 dof = N - length(p);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
232 chi2 = sum((y - polynomeval(x, n, p)).^2 ./ sigma2) / dof;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
233
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
234 % prepare model, units, names
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
235 model = [];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
236 for kk = 1:length(p)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
237 if kk == 1
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
238 model = [model 'P' num2str(kk) '*X.^(' num2str(n(kk)) ')'];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
239 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
240 model = [model ' + P' num2str(kk) '*X.^(' num2str(n(kk)) ')'];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
241 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
242 units(kk) = simplify(yunits/xunits.^(n(kk)));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
243 names{kk} = ['P' num2str(kk)];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
244 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
245 model = smodel(plist('expression', model, ...
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
246 'params', names, ...
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
247 'values', p, ...
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
248 'xvar', 'X', ...
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
249 'xunits', xunits, ...
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
250 'yunits', yunits ...
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
251 ));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
252
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
253
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
254 % Build the output pest object
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
255 out = pest;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
256 out.setY(p);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
257 out.setDy(stdp);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
258 out.setCov(s);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
259 out.setChi2(chi2);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
260 out.setDof(dof);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
261 out.setNames(names{:});
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
262 out.setYunits(units);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
263 out.setModels(model);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
264 out.name = sprintf('polynomfit(%s)', argsname);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
265 out.addHistory(getInfo('None'), pl, ao_invars, [aos(:).hist]);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
266 % Set procinfo object
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
267 out.procinfo = plist('MSE', mse);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
268
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
269 % set outputs
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
270 varargout{1} = out;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
271
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
272 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
273
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
274 % computes polynomial combination
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
275 function out = polynomeval(x, n, p)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
276 assert(length(p) == length(n));
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
277 out = zeros(size(x, 1), 1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
278 for k = 1:length(n)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
279 out = out + p(k) * x.^n(k);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
280 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
281 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
282
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
283 % get info object
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
284 function ii = getInfo(varargin)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
285 if nargin == 1 && strcmpi(varargin{1}, 'None')
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
286 sets = {};
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
287 pl = [];
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
288 else
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
289 sets = {'Default'};
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
290 pl = getDefaultPlist();
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
291 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
292 % build info object
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
293 ii = minfo(mfilename, 'ao', 'ltpda', utils.const.categories.op, '$Id: polynomfit.m,v 1.20 2011/04/08 08:56:11 hewitson Exp $', sets, pl);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
294 ii.setModifier(false);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
295 ii.setArgsmin(1);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
296 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
297
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
298 % get default plist
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
299 function plout = getDefaultPlist()
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
300 persistent pl;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
301 if ~exist('pl', 'var') || isempty(pl)
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
302 pl = buildplist();
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
303 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
304 plout = pl;
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
305 end
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
306
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
307 function pl = buildplist()
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
308 pl = plist();
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
309
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
310 % orders
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
311 p = param({'orders', 'Polynom orders.'}, [0]);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
312 pl.append(p);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
313
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
314 % default plist for linear fitting
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
315 pl.append(plist.LINEAR_FIT_PLIST);
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
316
|
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
|
317 end
|