0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1 % XFIT fit a function of x to data.
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: XFIT performs a non-linear fit of a function of x to data.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 5 % smodels fitting is also supported.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 6 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 7 % ALGORITHM: XFIT does a chi-squared minimization by means of different
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 8 % algorithms (see details in the default plist). Covariance matrix is also
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 9 % computed from the Fisher's Information Matrix. In case the Information
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 10 % Matrix is not positive-definite, uncertainties will not be stored in the
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 11 % output.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 12 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 13 % CALL: b = xfit(a, pl)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 14 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 15 % INPUTS: a - input AO to fit to
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 16 % pl - parameter list (see below)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 17 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 18 % OUTPUTs: b - a pest object containing the best-fit parameters,
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 19 % goodness-of-fit reduced chi-squared, fit degree-of-freedom
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 20 % covariance matrix and uncertainties. Additional
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 21 % quantities, like the Information Matrix, are contained
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 22 % within the procinfo. The best-fit model can be evaluated
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 23 % from pest\eval.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 24 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 25 % <a href="matlab:utils.helper.displayMethodInfo('ao', 'xfit')">Parameters Description</a>
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 26 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 27 % EXAMPLES:
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 28 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 29 % % 1) Fit to a frequency-series
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 30 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 31 % % Create a frequency-series
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 32 % datapl = plist('fsfcn', '0.01./(0.0001+f) + 5*abs(randn(size(f))) ', 'f1', 1e-5, 'f2', 5, 'nf', 1000, ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 33 % 'xunits', 'Hz', 'yunits', 'N/Hz');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 34 % data = ao(datapl);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 35 % data.setName;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 36 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 37 % % Do fit
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 38 % fitpl = plist('Function', 'P(1)./(P(2) + Xdata) + P(3)', ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 39 % 'P0', [0.1 0.01 1]);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 40 % params = xfit(data, fitpl)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 41 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 42 % % Evaluate model
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 43 % BestModel = eval(params,plist('type','fsdata','xdata',data,'xfield','x'));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 44 % BestModel.setName;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 45 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 46 % % Display results
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 47 % iplot(data,BestModel)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 48 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 49 % % 2) Fit to a noisy sine-wave
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 50 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 51 % % Create a noisy sine-wave
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 52 % fs = 10;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 53 % nsecs = 500;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 54 % datapl = plist('waveform', 'Sine wave', 'f', 0.01, 'A', 0.6, 'fs', fs, 'nsecs', nsecs, ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 55 % 'xunits', 's', 'yunits', 'm');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 56 % sw = ao(datapl);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 57 % noise = ao(plist('tsfcn', '0.01*randn(size(t))', 'fs', fs, 'nsecs', nsecs));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 58 % data = sw+noise;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 59 % data.setName;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 60 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 61 % % Do fit
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 62 % fitpl = plist('Function', 'P(1).*sin(2*pi*P(2).*Xdata + P(3))', ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 63 % 'P0', [1 0.01 0]);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 64 % params = xfit(data, fitpl)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 65 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 66 % % Evaluate model
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 67 % BestModel = eval(params,plist('type','tsdata','xdata',sw,'xfield','x'));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 68 % BestModel.setName;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 69 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 70 % % Display results
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 71 % iplot(data,BestModel)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 72 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 73 % % 3) Fit an smodel of a straight line to some data
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 74 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 75 % % Create a noisy straight-line
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 76 % datapl = plist('xyfcn', '2.33 + 0.1*x + 0.01*randn(size(x))', 'x', 0:0.1:10, ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 77 % 'xunits', 's', 'yunits', 'm');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 78 % data = ao(datapl);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 79 % data.setName;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 80 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 81 % % Model to fit
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 82 % mdl = smodel('a + b*x');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 83 % mdl.setXvar('x');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 84 % mdl.setParams({'a', 'b'}, {1 2});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 85 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 86 % % Fit model
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 87 % fitpl = plist('Function', mdl, 'P0', [1 1]);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 88 % params = xfit(data, fitpl)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 89 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 90 % % Evaluate model
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 91 % BestModel = eval(params,plist('xdata',data,'xfield','x'));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 92 % BestModel.setName;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 93 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 94 % % Display results
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 95 % iplot(data,BestModel)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 96 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 97 % % 4) Fit a chirp-sine firstly starting from an initial guess (quite close
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 98 % % to the true values) (bad convergency) and secondly by a Monte Carlo
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 99 % % search (good convergency)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 100 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 101 % % Create a noisy chirp-sine
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 102 % fs = 10;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 103 % nsecs = 1000;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 104 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 105 % % Model to fit and generate signal
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 106 % mdl = smodel(plist('name', 'chirp', 'expression', 'A.*sin(2*pi*(f + f0.*t).*t + p)', ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 107 % 'params', {'A','f','f0','p'}, 'xvar', 't', 'xunits', 's', 'yunits', 'm'));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 108 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 109 % % signal
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 110 % s = mdl.setValues({10,1e-4,1e-5,0.3});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 111 % s.setXvals(0:1/fs:nsecs-1/fs);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 112 % signal = s.eval;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 113 % signal.setName;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 114 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 115 % % noise
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 116 % noise = ao(plist('tsfcn', '1*randn(size(t))', 'fs', fs, 'nsecs', nsecs));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 117 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 118 % % data
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 119 % data = signal + noise;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 120 % data.setName;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 121 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 122 % % Fit model from the starting guess
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 123 % fitpl_ig = plist('Function', mdl, 'P0',[8,9e-5,9e-6,0]);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 124 % params_ig = xfit(data, fitpl_ig);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 125 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 126 % % Evaluate model
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 127 % BestModel_ig = eval(params_ig,plist('xdata',data,'xfield','x'));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 128 % BestModel_ig.setName;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 129 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 130 % % Display results
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 131 % iplot(data,BestModel_ig)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 132 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 133 % % Fit model by a Monte Carlo search
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 134 % fitpl_mc = plist('Function', mdl, ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 135 % 'MonteCarlo', 'yes', 'Npoints', 1000, 'LB', [8,9e-5,9e-6,0], 'UB', [11,3e-4,2e-5,2*pi]);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 136 % params_mc = xfit(data, fitpl_mc)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 137 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 138 % % Evaluate model
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 139 % BestModel_mc = eval(params_mc,plist('xdata',data,'xfield','x'));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 140 % BestModel_mc.setName;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 141 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 142 % % Display results
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 143 % iplot(data,BestModel_mc)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 144 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 145 % % 5) Multichannel fit of smodels
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 146 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 147 % % Ch.1 data
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 148 % datapl = plist('xyfcn', '0.1*x + 0.01*randn(size(x))', 'x', 0:0.1:10, 'name', 'channel 1', ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 149 % 'xunits', 'K', 'yunits', 'Pa');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 150 % a1 = ao(datapl);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 151 % % Ch.2 data
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 152 % datapl = plist('xyfcn', '2.5*x + 0.1*sin(2*pi*x) + 0.01*randn(size(x))', 'x', 0:0.1:10, 'name', 'channel 2', ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 153 % 'xunits', 'K', 'yunits', 'T');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 154 % a2 = ao(datapl);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 155 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 156 % % Model to fit
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 157 % mdl1 = smodel('a*x');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 158 % mdl1.setXvar('x');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 159 % mdl1.setParams({'a'}, {1});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 160 % mdl1.setXunits('K');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 161 % mdl1.setYunits('Pa');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 162 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 163 % mdl2 = smodel('b*x + a*sin(2*pi*x)');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 164 % mdl2.setXvar('x');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 165 % mdl2.setParams({'a','b'}, {1,2});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 166 % mdl2.setXunits('K');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 167 % mdl2.setYunits('T');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 168 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 169 % % Fit model
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 170 % params = xfit(a1,a2, plist('Function', [mdl1,mdl2]));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 171 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 172 % % evaluate model
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 173 % b = eval(params, plist('index',1,'xdata',a1,'xfield','x'));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 174 % b.setName('fit Ch.1');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 175 % r = a1-b;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 176 % r.setName('residuals');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 177 % iplot(a1,b,r)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 178 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 179 % b = eval(params, plist('index',2,'xdata',a2,'xfield','x'));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 180 % b.setName('fit Ch.2');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 181 % r = a2-b;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 182 % r.setName('residuals');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 183 % iplot(a2,b,r)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 184 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 185 % <a href="matlab:utils.helper.displayMethodInfo('ao', 'xfit')">Parameters Description</a>
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 186 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 187 % VERSION: $Id: xfit.m,v 1.83 2011/05/12 07:46:29 mauro Exp $
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 188 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 189 % HISTORY: 17-09-2009 G. Congedo
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 190 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 191 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 192
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 193 function varargout = xfit(varargin)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 194
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 195 % global variables
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 196 global Pidx Ydata weights modelFuncs dFcns hFcns lb ub Nch Ndata estimator
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 197
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 198
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 199 % Check if this is a call for parameters
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 200 if utils.helper.isinfocall(varargin{:})
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 201 varargout{1} = getInfo(varargin{3});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 202 return
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 203 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 204
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 205 import utils.const.*
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 206 utils.helper.msg(msg.PROC3, 'running %s/%s', mfilename('class'), mfilename);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 207
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 208 % Collect input variable names
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 209 in_names = cell(size(varargin));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 210 for ii = 1:nargin,in_names{ii} = inputname(ii);end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 211
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 212 % Collect all AOs and plists
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 213 [as, ao_invars] = utils.helper.collect_objects(varargin(:), 'ao', in_names);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 214 pl = utils.helper.collect_objects(varargin(:), 'plist', in_names);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 215
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 216 if nargout == 0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 217 error('### xfit cannot be used as a modifier. Please give an output variable.');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 218 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 219
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 220 % combine plists
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 221 pl = parse(pl, getDefaultPlist());
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 222
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 223 % Extract necessary parameters
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 224 targetFcn = pl.find('Function');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 225 P0 = pl.find('P0');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 226 % ADDP = pl.find('ADDP');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 227 userOpts = pl.find('OPTSET');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 228 weights = pl.find('WEIGHTS');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 229 FitUnc = pl.find('FitUnc');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 230 UncMtd = pl.find('UncMtd');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 231 linUnc = pl.find('LinUnc');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 232 FastHess = pl.find('FastHess');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 233 SymDiff = pl.find('SymDiff');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 234 SymGrad = pl.find('SymGrad');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 235 SymHess = pl.find('SymHess');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 236 DiffOrder = pl.find('DiffOrder');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 237 lb = pl.find('LB');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 238 ub = pl.find('UB');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 239 MCsearch = pl.find('MonteCarlo');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 240 Npoints = pl.find('Npoints');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 241 Noptims = pl.find('Noptims');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 242 % SVDsearch = pl.find('SVD');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 243 % nSVD = pl.find('nSVD');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 244 Algorithm = pl.find('Algorithm');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 245 % AdpScale = pl.find('AdpScale');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 246 % only for function handle fitting
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 247 pnames = pl.find('pnames');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 248 % pvalues = pl.find('pvalues');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 249 estimator = pl.find('estimator');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 250
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 251 % Convert yes/no, true/false, etc. to booleans
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 252 FitUnc = utils.prog.yes2true(FitUnc);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 253 linUnc = utils.prog.yes2true(linUnc);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 254 FastHess = utils.prog.yes2true(FastHess);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 255 SymDiff = utils.prog.yes2true(SymDiff);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 256 MCsearch = utils.prog.yes2true(MCsearch);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 257 % SVDsearch = utils.prog.yes2true(SVDsearch);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 258 % AdpScale = utils.prog.yes2true(AdpScale);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 259
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 260 % Check the fitting algorithm
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 261 % AlgoCheck = ~strcmpi(Algorithm,'fminsearch') & ~strcmpi(Algorithm,'fminunc') & ~isempty(Algorithm);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 262
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 263 if isempty(Algorithm)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 264 Algorithm = 'fminsearch';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 265 utils.helper.msg(msg.IMPORTANT, 'using %s as the fitting algorithm', upper(Algorithm));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 266 elseif ischar(Algorithm)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 267 Algorithm = lower(Algorithm);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 268 switch Algorithm
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 269 case 'fminsearch'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 270 utils.helper.msg(msg.IMPORTANT, 'using %s as the fitting algorithm', upper(Algorithm));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 271 Algorithm = 'fminsearch';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 272 case 'fminunc'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 273 if exist('fminunc','file')==2
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 274 utils.helper.msg(msg.IMPORTANT, 'using %s as the fitting algorithm', upper(Algorithm));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 275 Algorithm = 'fminunc';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 276 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 277 error('### you must install Optimization Toolbox in order to use %s', upper(Algorithm))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 278 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 279 case 'fmincon'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 280 if exist('fmincon','file')==2
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 281 utils.helper.msg(msg.IMPORTANT, 'using %s as the fitting algorithm', upper(Algorithm));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 282 Algorithm = 'fmincon';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 283 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 284 error('### you must install Optimization Toolbox in order to use %s', upper(Algorithm))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 285 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 286 case 'patternsearch'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 287 if exist('patternsearch','file')==2
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 288 utils.helper.msg(msg.IMPORTANT, 'using %s as the fitting algorithm', upper(Algorithm));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 289 Algorithm = 'patternsearch';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 290 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 291 error('### you must install Genetic Algorithm and Direct Search Toolbox in order to use %s', upper(Algorithm))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 292 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 293 case 'ga'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 294 if exist('ga','file')==2
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 295 utils.helper.msg(msg.IMPORTANT, 'using %s as the fitting algorithm', upper(Algorithm));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 296 Algorithm = 'ga';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 297 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 298 error('### you must install Genetic Algorithm and Direct Search Toolbox in order to use %s', upper(Algorithm))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 299 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 300 case 'simulannealbnd'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 301 if exist('simulannealbnd','file')==2
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 302 utils.helper.msg(msg.IMPORTANT, 'using %s as the fitting algorithm', upper(Algorithm));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 303 Algorithm = 'simulannealbnd';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 304 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 305 error('### you must install Genetic Algorithm and Direct Search Toolbox in order to use %s', upper(Algorithm))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 306 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 307 otherwise
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 308 error('### unknown fitting algorithm')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 309 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 310 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 311 error('### unknown format for ALGORITHM parameter')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 312 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 313
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 314 % Estimator
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 315 if isempty(estimator)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 316 estimator = 'chi2';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 317 elseif ~strcmp(estimator,{'chi2','abs','log','median'})
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 318 error('### unknown name of the estimator')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 319 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 320
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 321
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 322 % Data we will fit to
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 323 Xdata = as.x;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 324 Ydata = as.y;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 325 % dYdata = as.dy;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 326
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 327 % Number of data point per each channel
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 328 Ndata = numel(as(1).x);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 329
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 330 % Number of channels
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 331 Nch = numel(as);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 332 multiCh = Nch-1;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 333
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 334 % Number of models
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 335 if all(isa(targetFcn, 'smodel'))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 336 Nmdls = numel(targetFcn);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 337 elseif iscell(targetFcn)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 338 Nmdls = numel(targetFcn);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 339 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 340 Nmdls = 1;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 341 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 342
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 343 % consistency check on the data units
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 344 Xunits = as.xunits;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 345 % Xunits = as(1).xunits.strs;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 346 if Nch>1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 347 XunitsCheck = Xunits(1).strs;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 348 for kk=2:Nch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 349 if ~strcmp(Xunits(kk).strs,XunitsCheck)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 350 error('### in multi-channel fitting the xunits of all data objects must be the same')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 351 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 352 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 353 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 354 Xunits = as(1).xunits;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 355 Yunits = as.yunits;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 356
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 357 % consistency check on the inputs
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 358
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 359 if isempty(targetFcn)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 360 error('### please specify at least a model');
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 if Nch~=Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 364 error('### number of data channels and models do not match')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 365 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 366
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 367 for kk=1:Nch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 368 if any(numel(as(kk).x)~=Ndata)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 369 error('### the number of data is not self-consistent: please check that all channels have the same length')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 370 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 371 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 372
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 373 for kk=1:Nch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 374 for kkk=1:Nch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 375 if any(Xdata(:,kk)~=Xdata(:,kkk))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 376 error('### in multi-channel fitting the x-field of all data objects must be the same')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 377 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 378 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 379 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 380
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 381 cellMdl = iscell(targetFcn);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 382
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 383 if multiCh
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 384 if cellMdl
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 385 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 386 if ~isa(targetFcn{kk}, 'function_handle')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 387 error('### please use a cell array of function handles')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 388 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 389 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 390 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 391 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 392 if ~isa(targetFcn(kk), 'smodel')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 393 error('### multi-channel fitting is only possible with smodels')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 394 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 395 if isempty(targetFcn(kk).expr)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 396 error('### please specify a target function for all smodels');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 397 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 398 if ~isempty(targetFcn(kk).values) & size(targetFcn(kk).values)~=size(targetFcn(kk).params)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 399 error('### please give an initial value for each parameter')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 400 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 401 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 402 if ~isempty(P0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 403 error('in multi-channel fitting the initial values for the parameters must be within each smodel')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 404 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 405 checkExistAllParams = 0;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 406 for kk=1:Nch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 407 checkExistAllParams = checkExistAllParams + ~isempty(targetFcn(kk).values);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 408 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 409 if checkExistAllParams==0 && ~MCsearch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 410 error('### please give initial values for all parameters or use Monte Carlo instead')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 411 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 412 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 413 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 414
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 415 % check P0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 416 if isempty(P0) && ~MCsearch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 417 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 418 if isa(targetFcn(kk), 'smodel') && isempty(targetFcn(kk).values)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 419 error('### please give initial values for all parameters or use Monte Carlo instead')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 420 elseif ischar(targetFcn)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 421 error('### please give initial values for all parameters or use Monte Carlo instead')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 422 % elseif cellMdl
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 423 % error('### please give initial values for all parameters or use Monte Carlo instead')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 424 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 425 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 426 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 427
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 428 % Extract anonymous functions
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 429
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 430 if multiCh
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 431
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 432 if ~cellMdl
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 433 % concatenate models and parameters
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 434 [params,mdl_params,Pidx] = cat_mdls(targetFcn);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 435 else%if iscell(P0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 436 [params,mdl_params,Pidx] = cat_mdls_cell(targetFcn, pnames);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 437 % else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 438 % params = pnames;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 439 % Pidx = cell(1,Nch);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 440 % mdl_params = pnames;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 441 % for ii=1:Nch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 442 % Pidx{ii} = ones(1,numel(pnames));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 443 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 444 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 445
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 446 % create the full initial value array
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 447 if ~MCsearch && ~cellMdl
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 448 P0 = zeros(1,numel(params));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 449 for ii=1:numel(params)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 450 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 451 for jj=1:numel(targetFcn(kk).params)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 452 if strcmp(params{ii},targetFcn(kk).params{jj})
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 453 P0(ii) = targetFcn(kk).values{jj};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 454 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 455 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 456 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 457 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 458 elseif cellMdl
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 459 if isempty(P0)% || ~iscell(pvalues)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 460 error('### please give initial values')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 461 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 462 if isempty(pnames) || ~iscell(pnames)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 463 error('### please give parameter names in a cell array')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 464 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 465 if size(P0)~=size(pnames)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 466 error('### the size of pnames and pvalues does not match')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 467 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 468 % P0 = zeros(1,numel(params));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 469 % for ii=1:numel(P0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 470 % P0(ii) = pvalues{ii};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 471 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 472 if iscell(P0) && ~MCsearch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 473 for ii=1:numel(P0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 474 if isempty(P0{ii})
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 475 error('### please give initial values for all parameters or use Monte Carlo instead');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 476 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 477 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 478 for ii=1:numel(params)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 479 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 480 for jj=1:numel(pnames{kk})
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 481 if strcmp(params{ii},pnames{kk}{jj})
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 482 P0new(ii) = P0{kk}(jj);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 483 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 484 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 485 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 486 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 487 P0 = P0new;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 488 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 489 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 490
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 491 if all(isa(targetFcn,'smodel'))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 492 % anonymous fcns
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 493 modelFuncs = cell(1,Nch);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 494 for kk=1:Nch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 495 targetFcn(kk).setXvals(Xdata(:,kk));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 496 modelFuncs{kk} = targetFcn(kk).fitfunc;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 497 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 498 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 499 % if cellMdl
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 500 % for kk=1:Nch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 501 % modelFuncs{kk} = targetFcn{kk};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 502 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 503 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 504
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 505 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 506
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 507 % Check parameters
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 508 if isempty(P0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 509 if isa(targetFcn, 'smodel')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 510 P0 = [targetFcn.values{:}];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 511 elseif isempty(P0) && ~MCsearch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 512 error('### please give initial values for all parameters or use Monte Carlo instead');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 513 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 514 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 515 if size(P0)~=[1 numel(P0)]
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 516 P0 = P0';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 517 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 518
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 519 % convert input regular expression to anonymous function only for
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 520 % single-channel fitting
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 521 % create anonymouse function from user input expression
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 522 if ischar(targetFcn)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 523 checkFcn = regexp(targetFcn, 'Xdata');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 524 if isempty(checkFcn)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 525 error('### when using a string expression for the input model, the independent variable must be named as Xdata')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 526 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 527 % tfunc = eval(['@(P,Xdata,ADDP) (',targetFcn,')']);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 528 tfunc = eval(['@(P,Xdata) (',targetFcn,')']);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 529 % now create another anonymous function that only depends on the
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 530 % parameters
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 531 % modelFunc = @(x)tfunc(x, Xdata, ADDP);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 532 modelFuncs{1} = @(x)tfunc(x, Xdata);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 533 elseif isa(targetFcn,'smodel')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 534 targetFcn.setXvals(Xdata);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 535 modelFuncs{1} = targetFcn.fitfunc;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 536 % elseif isa(targetFcn,'function_handle')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 537 % modelFunc = targetFcn;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 538 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 539
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 540 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 541
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 542 if cellMdl
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 543 for kk=1:Nch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 544 modelFuncs{kk} = targetFcn{kk};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 545 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 546 % if ~multiCh
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 547 % modelFunc = modelFuncs{1};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 548 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 549 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 550
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 551
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 552
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 553 % check lb and ub
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 554
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 555 % constrained search or not
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 556 conSearch = ~isempty(lb) || ~isempty(ub);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 557
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 558 if MCsearch || conSearch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 559 if isempty(lb) || isempty(ub)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 560 error('### please give LB and UB')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 561 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 562 if multiCh && (~iscell(lb) || ~iscell(ub))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 563 error('### in multi-channel fitting upper and lower bounds must be cell array')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 564 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 565 if size(lb)~=size(ub) % | size(lb)~=size(P0) | size(ub)~=size(P0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 566 error('### LB and UB must be of the same size');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 567 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 568 if multiCh && numel(lb)~=Nch && numel(ub)~=Nch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 569 error('### in multi-channel fitting LB and UB must be cell array whose number of elements is equal to the number of models');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 570 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 571 if ~multiCh && ~all(lb<=ub)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 572 error('### UB must me greater equal to LB');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 573 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 574 if multiCh
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 575 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 576 if numel(lb{kk})~=numel(mdl_params{kk})
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 577 error('### please give the proper number of values for LB for each model')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 578 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 579 if numel(ub{kk})~=numel(mdl_params{kk})
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 580 error('### please give the proper number of values for UB for each model')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 581 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 582 if ~all(lb{kk}<=ub{kk})
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 583 error('### UB must me greater equal to LB for all parameters and models');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 584 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 585 if size(lb{kk})~=[1 numel(lb{kk})]
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 586 lb{kk} = lb{kk}';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 587 ub{kk} = ub{kk}';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 588 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 589 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 590 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 591 if ~multiCh
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 592 if size(lb)~=[1 numel(lb)]
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 593 lb = lb';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 594 ub = ub';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 595 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 596 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 597 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 598
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 599
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 600 % create the full bounds array
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 601 if (MCsearch || conSearch) && multiCh && ~cellMdl
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 602 lb_full = zeros(1,numel(params));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 603 ub_full = zeros(1,numel(params));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 604 for ii=1:numel(params)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 605 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 606 for jj=1:numel(targetFcn(kk).params)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 607 if strcmp(params{ii},targetFcn(kk).params{jj})
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 608 lb_full(ii) = lb{kk}(jj);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 609 ub_full(ii) = ub{kk}(jj);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 610 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 611 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 612 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 613 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 614 lb = lb_full;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 615 ub = ub_full;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 616 elseif (MCsearch || conSearch) && multiCh && cellMdl
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 617 lb_full = zeros(1,numel(params));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 618 ub_full = zeros(1,numel(params));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 619 for ii=1:numel(params)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 620 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 621 for jj=1:numel(mdl_params{kk})
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 622 if strcmp(params{ii},mdl_params{kk}(jj))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 623 lb_full(ii) = lb{kk}(jj);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 624 ub_full(ii) = ub{kk}(jj);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 625 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 626 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 627 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 628 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 629 lb = lb_full;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 630 ub = ub_full;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 631 % elseif cellMdl
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 632 % lb = lb;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 633 % ub = ub;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 634 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 635
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 636 % if ~iscell(ADDP)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 637 % ADDP = {ADDP};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 638 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 639
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 640 % Get input options
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 641 switch Algorithm
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 642 case 'fminsearch'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 643 opts = optimset(@fminsearch);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 644 if isstruct(userOpts)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 645 opts = optimset(opts, userOpts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 646 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 647 for j=1:2:numel(userOpts)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 648 opts = optimset(opts, userOpts{j}, userOpts{j+1});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 649 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 650 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 651 case 'fminunc'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 652 opts = optimset(@fminunc);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 653 if isstruct(userOpts)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 654 opts = optimset(opts, userOpts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 655 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 656 for j=1:2:numel(userOpts)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 657 opts = optimset(opts, userOpts{j}, userOpts{j+1});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 658 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 659 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 660 case 'fmincon'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 661 opts = optimset(@fmincon);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 662 if isstruct(userOpts)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 663 opts = optimset(opts, userOpts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 664 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 665 for j=1:2:numel(userOpts)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 666 opts = optimset(opts, userOpts{j}, userOpts{j+1});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 667 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 668 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 669 case 'patternsearch'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 670 opts = psoptimset(@patternsearch);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 671 if isstruct(userOpts)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 672 opts = psoptimset(opts, userOpts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 673 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 674 for j=1:2:numel(userOpts)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 675 opts = psoptimset(opts, userOpts{j}, userOpts{j+1});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 676 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 677 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 678 case 'ga'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 679 opts = gaoptimset(@ga);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 680 if isstruct(userOpts)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 681 opts = gaoptimset(opts, userOpts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 682 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 683 for j=1:2:numel(userOpts)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 684 opts = gaoptimset(opts, userOpts{j}, userOpts{j+1});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 685 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 686 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 687 case 'simulannealbnd'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 688 opts = saoptimset(@simulannealbnd);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 689 if isstruct(userOpts)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 690 opts = saoptimset(opts, userOpts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 691 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 692 for j=1:2:numel(userOpts)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 693 opts = saoptimset(opts, userOpts{j}, userOpts{j+1});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 694 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 695 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 696 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 697
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 698
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 699 % compute the right weights
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 700 [weights,unweighted] = find_weights(as,weights);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 701
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 702
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 703 % define number of free parameters
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 704 if ~MCsearch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 705 Nfreeparams = length(P0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 706 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 707 Nfreeparams = length(lb);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 708 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 709
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 710 if Nch==1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 711 Pidx{1}=1:Nfreeparams;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 712 % modelFuncs{1}=modelFunc;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 713 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 714
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 715 % Check for user-supplied analytical gradient as cell-array of function
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 716 % handles
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 717 if ~isempty(SymGrad)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 718 dFcns = cell(Nmdls,1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 719 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 720 for ii=1:numel(SymGrad{kk})
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 721 dFcns{kk}{ii} = SymGrad{kk}{ii};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 722 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 723 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 724 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 725
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 726 % Check for user-supplied analytical hessian as cell-array of function
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 727 % handles
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 728 if ~isempty(SymGrad) && ~isempty(SymHess)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 729 hFcns = cell(Nmdls,1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 730 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 731 for jj=1:numel(dFcns{kk})
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 732 for ii=1:jj
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 733 hFcns{kk}{ii,jj} = SymHess{kk}{ii,jj};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 734 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 735 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 736 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 737 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 738
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 739 % If requested, compute the analytical gradient
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 740 if SymDiff || linUnc && isempty(SymGrad)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 741 utils.helper.msg(msg.IMPORTANT, 'evaluating symbolic derivatives');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 742 if ~isa(targetFcn,'smodel')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 743 error('### smodel functions must be used in order to do symbolic differentiation')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 744 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 745 % compute symbolic 1st-order differentiation
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 746 dFcnsSmodel = cell(Nmdls,1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 747 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 748 p = targetFcn(kk).params;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 749 for ii=1:numel(p)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 750 dFcnsSmodel{kk}(ii) = diff(targetFcn(kk),p{ii});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 751 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 752 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 753 % extract anonymous function
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 754 dFcns = cell(Nmdls,1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 755 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 756 for ii=1:numel(dFcnsSmodel{kk})
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 757 dFcns{kk}{ii} = dFcnsSmodel{kk}(ii).fitfunc;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 758 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 759 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 760 if DiffOrder==2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 761 % compute symbolic 2nd-order differentiation
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 762 hFcnsSmodel = cell(Nmdls,1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 763 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 764 p = targetFcn(kk).params;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 765 for jj=1:numel(p)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 766 for ii=1:jj
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 767 hFcnsSmodel{kk}(ii,jj) = diff(dFcnsSmodel{kk}(ii),p{jj});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 768 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 769 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 770 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 771 % extract anonymous function
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 772 hFcns = cell(Nmdls,1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 773 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 774 for jj=1:numel(dFcnsSmodel{kk})
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 775 for ii=1:jj
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 776 hFcns{kk}{ii,jj} = hFcnsSmodel{kk}(ii,jj).fitfunc;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 777 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 778 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 779 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 780 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 781 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 782
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 783 % Set optimset in order to take care of eventual symbolic differentiation
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 784 if ~isempty(dFcns) && any(strcmp(Algorithm,{'fminunc','fmincon'}))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 785 opts = optimset(opts, 'GradObj', 'on');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 786 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 787 if ~isempty(hFcns) && any(strcmp(Algorithm,{'fminunc','fmincon'}))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 788 opts = optimset(opts, 'Hessian', 'on');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 789 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 790
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 791 % Start the best-fit search
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 792
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 793 if MCsearch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 794
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 795 utils.helper.msg(msg.IMPORTANT, 'performing a Monte Carlo search');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 796
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 797 % find best-fit by a Monte Carlo search
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 798 [P,chi2,exitflag,output,h,MChistory] = ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 799 find_bestfit_montecarlo(lb, ub, Npoints, Noptims, opts, Algorithm, FastHess);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 800
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 801 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 802
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 803 utils.helper.msg(msg.IMPORTANT, 'looking for a best-fit from the initial guess');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 804
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 805 % find best-fit starting from an initial guess
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 806 [P,chi2,exitflag,output,h,chainHistory] = ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 807 find_bestfit_guess(P0, opts, Algorithm, FastHess);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 808
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 809 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 810
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 811
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 812 % degrees of freedom in the problem
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 813 % dof = Nch * (Ndata - Nfreeparams);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 814 dof = Nch * Ndata - Nfreeparams;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 815
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 816 % redefine MChistory's column to put the reduced chi2s
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 817 if MCsearch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 818 MChistory(:,1) = MChistory(:,1)./dof;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 819 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 820
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 821 % redefine history to put the reduced chi2s
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 822 if ~MCsearch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 823 chainHistory.fval = chainHistory.fval./dof;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 824 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 825
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 826 % Confidence intervals contruction
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 827
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 828 if FitUnc
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 829
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 830 utils.helper.msg(msg.IMPORTANT, 'estimating confidence intervals');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 831
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 832 % find best-fit errors
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 833 [se,Sigma,Corr,I,H,errH,J,errJ] = ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 834 find_errors(modelFuncs, P, chi2, dof, UncMtd, FastHess, h, weights, unweighted, linUnc, dFcns);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 835
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 836
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 837 % report issue on covariance matrix in case of
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 838 % degeneracy/quasi-singularity/ill-conditioning, etc.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 839 posDef = all(diag(Sigma)>=0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 840 if ~posDef
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 841 % analysis of information matrix in order to cancel out un-important
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 842 % parameters
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 843 Inorm=I./norm(I);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 844 pnorms = zeros(1,size(Inorm,2));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 845 for ii=1:size(I,2);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 846 pnorms(ii) = norm(Inorm(:,ii));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 847 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 848 [pnorms_sort,IX] = sort(pnorms,'descend');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 849 if Nmdls>1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 850 pnames_sort = params(IX);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 851 elseif isa(targetFcn,'smodel') && Nmdls==1%&& ~isempty(targetFcn.params)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 852 params = targetFcn.params;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 853 pnames_sort = params(IX);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 854 elseif isa(targetFcn,'function_handle') %&& ~isempty(targetFcn.params)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 855 pnames_sort = pnames(IX);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 856 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 857 utils.helper.msg(msg.IMPORTANT, ['Information matrix is quasi-singular due to degeneracy or ill-conditioning: \n'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 858 'consider eliminating the parameters with low information.']); % ...'In the following, parameters are reported in descending order of information']);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 859 for ii=1:numel(pnorms_sort);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 860 if exist('pnames_sort','var')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 861 utils.helper.msg(msg.IMPORTANT, 'param %s: %g ', pnames_sort{ii}, pnorms_sort(ii));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 862 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 863 utils.helper.msg(msg.IMPORTANT, 'param %d: %g ', IX(ii), pnorms_sort(ii));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 864 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 865 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 866
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 867 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 868
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 869 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 870
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 871 utils.helper.msg(msg.IMPORTANT, 'final best-fit found at reduced chi2, dof: %g %d ', chi2/dof, dof);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 872
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 873 if FitUnc && ~isempty(se)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 874 for kk=1:numel(P)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 875 utils.helper.msg(msg.IMPORTANT, 'best-fit param %d: %g +- %2.1g ', kk, P(kk), se(kk));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 876 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 877 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 878 for kk=1:numel(P)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 879 utils.helper.msg(msg.IMPORTANT, 'best-fit param %d: %g ', kk, P(kk));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 880 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 881 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 882
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 883
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 884 % check the existence of all variables
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 885 if ~exist('se','var'); se = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 886 if ~exist('Sigma','var'); Sigma = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 887 if ~exist('Corr','var'); Corr = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 888 if ~exist('I','var'); I = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 889 if ~exist('H','var'); H = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 890 if ~exist('errH','var'); errH = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 891 if ~exist('J','var'); J = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 892 if ~exist('errJ','var'); errJ = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 893 if ~exist('Sigma','var'); Sigma = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 894 if ~exist('MChistory','var'); MChistory = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 895 % if ~exist('SVDhistory','var'); SVDhistory = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 896 if ~exist('output','var'); output = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 897
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 898
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 899 % Make output pest
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 900 out = pest;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 901 if Nch>1 %exist('params')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 902 out.setNames(params);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 903 elseif Nch==1 && isa(targetFcn, 'smodel')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 904 out.setNames(targetFcn.params);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 905 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 906 out.setY(P');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 907 out.setDy(se');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 908 out.setCov(Sigma);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 909 out.setCorr(Corr);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 910 out.setChi2(chi2/dof);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 911 out.setDof(dof);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 912 if ~MCsearch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 913 out.setChain([chainHistory.fval,chainHistory.x]);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 914 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 915
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 916 % add the output best-fit models
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 917 outFcn = targetFcn;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 918 if isa(targetFcn, 'smodel') && Nmdls>1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 919 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 920 p = P(Pidx{kk});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 921 outFcn(kk).setValues(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 922 % outFcn(kk).setXvals(Xdata(:,1));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 923 outFcn(kk).setXunits(Xunits);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 924 outFcn(kk).setYunits(Yunits(kk));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 925 outFcn(kk).setName(['Best-fit model ' num2str(kk)]);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 926 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 927 out.setModels(outFcn);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 928 elseif isa(targetFcn, 'smodel') && Nmdls==1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 929 outFcn.setValues(P');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 930 % outFcn.setXvals(Xdata(:,1));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 931 outFcn.setXunits(Xunits);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 932 outFcn.setYunits(Yunits);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 933 outFcn.setName('Best-fit model');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 934 out.setModels(outFcn);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 935 elseif ischar(targetFcn)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 936 % convert regular expression into smodel
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 937 targetFcn = regexprep(targetFcn, 'Xdata', 'x');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 938 for ii=1:Nfreeparams
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 939 targetFcn = regexprep(targetFcn, ['P\(' num2str(ii) '\)'], ['P' num2str(ii)]);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 940 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 941 outFcn = smodel((targetFcn));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 942 pnames = cell(1,Nfreeparams);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 943 for ii=1:Nfreeparams
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 944 pnames{ii} = ['P' num2str(ii)];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 945 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 946 outFcn.setParams(pnames, P');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 947 outFcn.setXvar('x');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 948 % outFcn.setXvals(Xdata);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 949 outFcn.setXunits(Xunits);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 950 outFcn.setYunits(Yunits);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 951 outFcn.setName('Best-fit model');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 952 out.setModels(outFcn);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 953 out.setNames(pnames);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 954 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 955
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 956
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 957 % Set Name, History and Procinfo
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 958 if ~cellMdl
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 959 mdlname = char(targetFcn);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 960 if numel(mdlname)>20
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 961 mdlname = mdlname(1:20);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 962 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 963 out.name = sprintf('xfit(%s)', mdlname);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 964 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 965 mdlname = func2str(targetFcn{1});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 966 for kk=2:Nch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 967 mdlname = strcat(mdlname,[',' func2str(targetFcn{kk})]);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 968 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 969 out.name = sprintf('xfit(%s)', mdlname);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 970 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 971 out.addHistory(getInfo('None'), pl, ao_invars(:), [as(:).hist]);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 972 out.procinfo = plist('algorithm', Algorithm, 'exitflag', exitflag, 'output', output, ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 973 'InfoMatrix', I,...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 974 'MChistory', MChistory);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 975 % 'SVDhistory', SVDhistory, 'res', res, 'hess', H, 'errhess', errH, 'jac', J, 'errjac', errJ);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 976
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 977 % Set outputs
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 978 if nargout > 0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 979 varargout{1} = out;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 980 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 981
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 982 clear global Pidx Ydata weights modelFuncs dFcns hFcns lb ub scale Nch Ndata estimator
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 983
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 984 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 985
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 986 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 987 % Included Functions
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 988 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 989
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 990 function [chi2,g,H] = fit_chi2(x)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 991
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 992 global Pidx Ydata weights modelFuncs dFcns hFcns lb ub scale estimator
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 993
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 994 Nfreeparams = numel(x);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 995 Nmdls = numel(modelFuncs);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 996 Ndata = numel(Ydata(:,1));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 997
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 998 mdldata = zeros(Ndata,Nmdls);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 999 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1000 p = x(Pidx{kk}).*scale(Pidx{kk});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1001 mdldata(:,kk) = modelFuncs{kk}(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1002 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1003 res = (mdldata-Ydata).*weights;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1004 if all(x.*scale>=lb & x.*scale<=ub)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1005 % chi2 = res'*res;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1006 % chi2 = sum(diag(chi2));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1007 if strcmp(estimator,'chi2')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1008 chi2 = sum(sum(res.^2));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1009 elseif strcmp(estimator,'abs')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1010 chi2 = sum(sum(abs(res)));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1011 elseif strcmp(estimator,'log')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1012 chi2 = sum(sum(log(1+res.^2/2)));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1013 elseif strcmp(estimator,'median')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1014 dof = Ndata*Nmdls - Nfreeparams;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1015 res = reshape(res,numel(res),1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1016 chi2 = median(abs(res))*dof;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1017 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1018 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1019 chi2 = 10e50;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1020 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1021
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1022 if nargout > 1 % gradient required
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1023 % if all(x.*scale>=lb & x.*scale<=ub)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1024 grad = cell(Nmdls,1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1025 g = zeros(Nmdls,Nfreeparams);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1026 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1027 p = x(Pidx{kk}).*scale(Pidx{kk});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1028 Np = numel(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1029 grad{kk} = zeros(Ndata,Np);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1030 for ii=1:Np
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1031 grad{kk}(:,ii) = dFcns{kk}{ii}(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1032 g(kk,Pidx{kk}(ii)) = 2.*res(:,kk)'*grad{kk}(:,ii);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1033 % dF=dFcns{kk}{ii}(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1034 % g(kk,Pidx{kk}(ii)) = 2.*sum(res(:,kk)'*dF);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1035 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1036 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1037 if Nmdls>1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1038 g = sum(g);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1039 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1040 % elseif any(x.*scale<lb)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1041 % g = repmat(-10e50,[1 Nfreeparams]);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1042 % elseif any(x.*scale>ub)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1043 % g = repmat(10e50,[1 Nfreeparams]);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1044 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1045 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1046
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1047 if nargout > 2 % hessian required
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1048 % hess = cell(Nmdls,1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1049 H = zeros(Nmdls,Nfreeparams,Nfreeparams);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1050 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1051 p = x(Pidx{kk}).*scale(Pidx{kk});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1052 Np = numel(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1053 % hess{kk} = zeros(Ndata,Np);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1054 for jj=1:Np
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1055 for ii=1:jj
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1056 hF = hFcns{kk}{ii,jj}(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1057 H1 = sum(res(:,kk)'*hF);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1058 H2 = sum(weights(:,kk).*grad{kk}(:,ii).*grad{kk}(:,jj));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1059 H(kk,Pidx{kk}(ii),Pidx{kk}(jj)) = 2*(H1+H2);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1060 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1061 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1062 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1063 H = squeeze(sum(H,1));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1064 % if Nmdls>1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1065 % H = sum(H);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1066 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1067 H = H+triu(H,1)';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1068 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1069
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1070 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1071
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1072 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1073
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1074 % function chi2 = fit_chi2(P, ydata, weights, fcn)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1075 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1076 % % evaluate model
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1077 % mdldata = fcn(P);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1078 % % if ~isequal(size(mdldata), size(ydata))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1079 % % ydata = ydata.';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1080 % % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1081 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1082 % chi2 = sum((abs((mdldata-ydata)).^2).*weights);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1083 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1084 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1085
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1086 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1087
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1088 % function chi2 = fit_chi2_bounds(P, ydata, weights, fcn, LB, UB)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1089 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1090 % % evaluate model
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1091 % mdldata = fcn(P);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1092 % % if ~isequal(size(mdldata), size(ydata))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1093 % % ydata = ydata.';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1094 % % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1095 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1096 % if all(P>=LB & P<=UB)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1097 % chi2 = sum((abs((mdldata-ydata)).^2).*weights);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1098 % else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1099 % chi2 = 10e50;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1100 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1101 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1102 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1103
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1104 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1105
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1106 % function g = scaling(f, x, scale)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1107 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1108 % g = f(x.*scale);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1109 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1110 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1111
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1112 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1113
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1114 function scale = find_scale(P0, LB, UB)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1115
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1116 if ~isempty(P0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1117 Nfreeparams = numel(P0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1118 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1119 Nfreeparams = numel(LB);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1120 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1121
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1122 % define parameter scale
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1123 % scale = ones(1,Nfreeparams);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1124
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1125 % if ~isempty(LB) & ~isempty(UB)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1126 % for ii=1:Nfreeparams
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1127 % if ~(LB(ii)==0 & UB(ii)==0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1128 % if LB(ii)==0 | UB(ii)==0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1129 % scale(ii) = max(abs(LB(ii)),abs(UB(ii)));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1130 % elseif abs(LB(ii))==abs(UB(ii))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1131 % scale(ii) = abs(UB);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1132 % elseif LB(ii)~=UB(ii)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1133 % scale(ii) = sqrt(abs(LB(ii)) * abs(UB(ii))); % (abs(lb(ii)) + abs(ub(ii)))/2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1134 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1135 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1136 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1137 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1138 if ~isempty(LB) && ~isempty(UB)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1139 scale = sqrt(abs(LB) .* abs(UB));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1140 for ii=1:Nfreeparams
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1141 if scale(ii)==0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1142 scale(ii) = max(abs(LB(ii)),abs(UB(ii)));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1143 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1144 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1145 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1146 scale = abs(P0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1147 for ii=1:Nfreeparams
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1148 if scale(ii)==0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1149 scale(ii) = 1;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1150 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1151 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1152 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1153
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1154 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1155
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1156 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1157
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1158 function [weightsOut,unweighted] = find_weights(as,weightsIn)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1159
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1160 Ydata = as.y;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1161 dYdata = as.dy;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1162
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1163 noWeights = isempty(weightsIn);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1164 noDY = isempty(dYdata);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1165
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1166 unweighted = noWeights & noDY;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1167
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1168 % check data uncertainties
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1169 if any(dYdata==0) && ~noDY
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1170 error('### some of the data uncertainties are zero: cannot fit')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1171 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1172
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1173 if length(dYdata)~=length(Ydata) && ~noDY
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1174 error('### length of Y fields and dY fields do not match')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1175 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1176
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1177 if noWeights
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1178 % The user did not input weights.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1179 % Looking for the dy field of the input data
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1180 if noDY
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1181 % Really no input from user
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1182 weightsOut = ones(size(Ydata));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1183 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1184 % Uses uncertainties in Ydata to evaluate data weights
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1185 weightsOut = 1./dYdata.^2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1186 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1187 % elseif isnumeric(weightsIn)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1188 % if size(weightsIn)~=size(Ydata)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1189 % weightsOut = weightsIn';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1190 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1191 elseif numel(weightsIn) == 1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1192 if isnumeric(weightsIn)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1193 weightsOut = weightsIn .* ones(size(Ydata));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1194 elseif isa(weightsIn, 'ao')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1195 if weightsIn.yunits == as.yunits
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1196 weightsOut = weightsIn.y;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1197 elseif size(weightsIn.data.getY)~=size(Ydata)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1198 error('### size of data ao and weights ao do not match')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1199 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1200 error('### units for data and uncertainties do not match')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1201 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1202 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1203 error('### unknown format for weights parameter');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1204 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1205 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1206 weightsOut = weightsIn;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1207 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1208
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1209 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1210
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1211 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1212
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1213 function [params,mdl_params,paramidx] = cat_mdls(mdls)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1214
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1215 % This function concatenates the parameter names and values for
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1216 % all the input models to construct the new parameter list.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1217
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1218 Nmdls = numel(mdls);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1219
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1220 % create the full parameter name array
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1221 params_cat = horzcat(mdls(:).params);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1222 params_new = cell(1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1223 for ii=1:numel(params_cat)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1224 if ~strcmp(params_cat{ii},params_new)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1225 params_new = [params_new params_cat{ii}];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1226 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1227 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1228 params = params_new(2:numel(params_new));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1229
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1230 % create the parameter list for each model
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1231 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1232 mdl_params{kk} = mdls(kk).params;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1233 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1234
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1235 % create a cell array of indeces which map the parameter vector of each
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1236 % model to the full one
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1237 paramidx = cell(1,Nmdls);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1238 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1239 for jdx=1:length(mdl_params{kk})
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1240 for idx=1:length(params)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1241 if (strcmp(params{idx}, mdl_params{kk}(jdx)))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1242 paramidx{kk}(jdx) = idx;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1243 break;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1244 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1245 paramidx{kk}(jdx) = 0;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1246 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1247 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1248 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1249 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1250
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1251 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1252
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1253 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1254
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1255 function [params,mdl_params,paramidx] = cat_mdls_cell(mdls, pnames)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1256
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1257 % This function concatenates the parameter names and values for
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1258 % all the input models to construct the new parameter list.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1259
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1260 Nmdls = numel(mdls);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1261
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1262 % create the full parameter name array
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1263 params_cat = horzcat(pnames{:});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1264 params_new = cell(1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1265 for ii=1:numel(params_cat)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1266 if ~strcmp(params_cat{ii},params_new)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1267 params_new = [params_new params_cat{ii}];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1268 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1269 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1270 params = params_new(2:numel(params_new));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1271
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1272 % create the parameter list for each model
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1273 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1274 mdl_params{kk} = pnames{kk};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1275 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1276
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1277 % create a cell array of indeces which map the parameter vector of each
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1278 % model to the full one
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1279 paramidx = cell(1,Nmdls);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1280 for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1281 for jdx=1:length(mdl_params{kk})
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1282 for idx=1:length(params)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1283 if (strcmp(params{idx}, mdl_params{kk}(jdx)))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1284 paramidx{kk}(jdx) = idx;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1285 break;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1286 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1287 paramidx{kk}(jdx) = 0;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1288 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1289 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1290 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1291 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1292
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1293 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1294
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1295 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1296
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1297 % function chi2 = fit_chi2_multich(P, Pidx, ydata, weights, fcns)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1298 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1299 % Nmdls = numel(fcns);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1300 % Ndata = numel(ydata(:,1));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1301 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1302 % mdldata = zeros(Ndata,Nmdls);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1303 % for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1304 % p = P(Pidx{kk});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1305 % mdldata(:,kk) = fcns{kk}(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1306 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1307 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1308 % res = (ydata-mdldata).*weights;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1309 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1310 % chi2 = res'*res;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1311 % chi2 = sum(diag(chi2));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1312 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1313 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1314
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1315 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1316
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1317 % function chi2 = fit_chi2_multich_bounds(P, Pidx, ydata, weights, fcns, LB, UB)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1318 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1319 % if all(P>=LB & P<=UB)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1320 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1321 % Nmdls = numel(fcns);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1322 % Ndata = numel(ydata(:,1));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1323 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1324 % mdldata = zeros(Ndata,Nmdls);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1325 % for kk=1:Nmdls
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1326 % p = P(Pidx{kk});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1327 % mdldata(:,kk) = fcns{kk}(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1328 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1329 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1330 % res = (ydata-mdldata).*weights;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1331 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1332 % chi2 = res'*res;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1333 % chi2 = sum(diag(chi2));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1334 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1335 % else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1336 % chi2 = 10e50;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1337 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1338 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1339 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1340
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1341 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1342
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1343 function chi2_guesses = montecarlo(func, LB, UB, Npoints)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1344
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1345 Nfreeparams = numel(LB);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1346
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1347 % construct the guess matrix: each rows contain the chi2 and the
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1348 % parameter guess
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1349 guesses = zeros(Npoints,Nfreeparams);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1350 for jj=1:Nfreeparams
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1351 guesses(:,jj) = LB(jj)+(UB(jj)-LB(jj))*rand(1,Npoints);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1352 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1353
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1354 % evaluate the chi2 at each guess
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1355 chi2_guesses = zeros(1,Nfreeparams+1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1356 for ii=1:Npoints
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1357 % check = ii-1/Npoints*100;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1358 % if rem(fix(check),10)==0 && check==fix(check)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1359 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1360 % disp(sprintf('%d%% done',check));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1361 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1362 chi2_guess = func(guesses(ii,:));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1363 chi2_guesses = cat(1,chi2_guesses,[chi2_guess,guesses(ii,:)]);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1364 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1365 chi2_guesses(1,:) = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1366
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1367 % sort the guesses for ascending chi2
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1368 chi2_guesses = sortrows(chi2_guesses);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1369
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1370 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1371
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1372 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1373
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1374 function [x,fval,exitflag,output,h,MChistory] = ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1375 find_bestfit_montecarlo(LB, UB, Npoints, Noptims, opts, algorithm, FastHess)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1376
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1377 global scale
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1378
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1379 Nfreeparams = length(LB);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1380
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1381 % check Npoints
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1382 if isempty(Npoints)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1383 Npoints = 100000;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1384 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1385 % check Noptims
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1386 if isempty(Noptims)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1387 Noptims = 10;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1388 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1389
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1390 if Npoints<Noptims
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1391 error('### Npoints must be at least equal to Noptims')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1392 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1393
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1394 % define parameter scale
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1395 scale = find_scale([], LB, UB);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1396
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1397 % scale function to minimize
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1398 % func = @(x)scaling(func, x, scale);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1399
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1400 % scale bounds
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1401 LB = LB./scale;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1402 UB = UB./scale;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1403
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1404 % do a Monte Carlo search
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1405 chi2_guesses = montecarlo(@fit_chi2, LB, UB, Npoints);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1406
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1407 % minimize over the first guesses
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1408 fitresults = zeros(Noptims,Nfreeparams+1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1409 exitflags = {};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1410 outputs = {};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1411 hs = {};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1412 for ii=1:Noptims
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1413 P0 = chi2_guesses(ii,2:Nfreeparams+1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1414 if strcmpi(algorithm,'fminunc')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1415 [x,fval,exitflag,output,dummy,h] = fminunc(@fit_chi2, P0, opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1416 elseif strcmpi(algorithm,'fmincon')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1417 [x,fval,exitflag,output,dummy,dummy,h] = fmincon(@fit_chi2, P0, [], [], [], [], LB, UB, [], opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1418 elseif strcmpi(algorithm,'patternsearch')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1419 [x,fval,exitflag,output] = patternsearch(@fit_chi2, P0, [], [], [], [], LB, UB, [], opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1420 elseif strcmpi(algorithm,'ga')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1421 [x,fval,exitflag,output] = ga(@fit_chi2, numel(P0), [], [], [], [], LB, UB, [], opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1422 elseif strcmpi(algorithm,'simulannealbnd')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1423 [x,fval,exitflag,output] = simulannealbnd(@fit_chi2, P0, LB, UB, opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1424 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1425 [x,fval,exitflag,output] = fminsearch(@fit_chi2, P0, opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1426 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1427 fitresults(ii,1) = fval;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1428 fitresults(ii,2:Nfreeparams+1) = x;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1429 exitflags{ii} = exitflag;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1430 outputs{ii} = output;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1431 if FastHess && ~exist('h','var')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1432 h = fastHessian(@fit_chi2,x,fval);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1433 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1434 if exist('h','var')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1435 hs{ii} = h;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1436 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1437 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1438
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1439 % sort the results
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1440 [dummy, ix] = sort(fitresults(:,1));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1441 fitresults = fitresults(ix,:);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1442
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1443 % % refine fit over the first bestfit
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1444 % P0 = fitresults(1,2:Nfreeparams+1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1445 % if strcmpi(algorithm,'fminunc')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1446 % [x,fval,exitflag,output] = fminunc(func, P0, opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1447 % elseif strcmpi(algorithm,'fmincon')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1448 % [x,fval,exitflag,output] = fmincon(func, P0, [], [], [], [], LB, UB, [], opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1449 % elseif strcmpi(algorithm,'patternsearch')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1450 % [x,fval,exitflag,output] = patternsearch(func, P0, [], [], [], [], LB, UB, [], opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1451 % elseif strcmpi(algorithm,'ga')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1452 % [x,fval,exitflag,output] = ga(func, numel(P0), [], [], [], [], LB, UB, [], opts); % ga does not improve the bestfit
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1453 % elseif strcmpi(algorithm,'simulannealbnd')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1454 % [x,fval,exitflag,output] = simulannealbnd(func, P0, LB, UB, opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1455 % else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1456 % [x,fval,exitflag,output] = fminsearch(func, P0, opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1457 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1458
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1459 % set the best-fit
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1460 fval = fitresults(1,1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1461 x = fitresults(1,2:Nfreeparams+1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1462
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1463 % scale best-fit
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1464 x = x.*scale;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1465
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1466 % scale hessian
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1467 if exist('hs','var')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1468 for kk=1:numel(hs)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1469 for ii=1:numel(x)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1470 for jj=1:numel(x)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1471 hs{kk}(ii,jj) = hs{kk}(ii,jj)/scale(ii)/scale(jj);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1472 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1473 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1474 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1475 % else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1476 % h = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1477 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1478
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1479 % scale fit results
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1480 MChistory = fitresults;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1481 for ii=1:size(MChistory,1)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1482 MChistory(ii,2:Nfreeparams+1) = MChistory(ii,2:Nfreeparams+1).*scale;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1483 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1484
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1485 % set the proper exitflag & output
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1486 exitflags = exitflags(ix);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1487 outputs = outputs(ix);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1488 if exist('hs','var') && ~(isempty(hs))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1489 hs = hs(ix);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1490 h = hs{1};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1491 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1492 h = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1493 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1494 exitflag = exitflags{1};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1495 output = outputs{1};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1496
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1497 clear global scale
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1498
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1499 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1500
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1501 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1502
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1503 function [x,fval,exitflag,output,h,outHistory] = ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1504 find_bestfit_guess(P0, opts, algorithm, FastHess)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1505
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1506 global lb ub scale chainHistory
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1507
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1508 if isempty(lb)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1509 lb = -Inf;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1510 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1511 if isempty(ub)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1512 ub = Inf;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1513 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1514
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1515 % define parameter scale
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1516 scale = find_scale(P0, [], []);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1517
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1518 % scale initial guess
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1519 P0 = P0./scale;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1520
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1521 % initialize history
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1522 chainHistory.x = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1523 chainHistory.fval = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1524 opts=optimset(opts,'outputfcn',@outfun);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1525
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1526 % minimize over the initial guess
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1527 if strcmpi(algorithm,'fminunc')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1528 [x,fval,exitflag,output,dummy,h] = fminunc(@fit_chi2, P0, opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1529 elseif strcmpi(algorithm,'fmincon')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1530 [x,fval,exitflag,output,dummy,dummy,h] = fmincon(@fit_chi2, P0, [], [], [], [], lb, ub, [], opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1531 elseif strcmpi(algorithm,'patternsearch')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1532 [x,fval,exitflag,output] = patternsearch(@fit_chi2, P0, [], [], [], [], lb, ub, [], opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1533 elseif strcmpi(algorithm,'ga')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1534 [x,fval,exitflag,output] = ga(@fit_chi2, numel(P0), [], [], [], [], lb, ub, [], opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1535 elseif strcmpi(algorithm,'simulannealbnd')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1536 [x,fval,exitflag,output] = simulannealbnd(@fit_chi2, P0, lb, ub, opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1537 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1538 [x,fval,exitflag,output] = fminsearch(@fit_chi2, P0, opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1539 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1540
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1541 if FastHess && ~exist('h','var')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1542 h = fastHessian(@fit_chi2,x,fval);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1543 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1544
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1545 % scale best-fit
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1546 x = x.*scale;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1547
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1548 % scale hessian
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1549 if exist('h','var')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1550 for ii=1:numel(x)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1551 for jj=1:numel(x)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1552 h(ii,jj) = h(ii,jj)/scale(ii)/scale(jj);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1553 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1554 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1555 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1556 h = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1557 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1558
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1559 outHistory = chainHistory;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1560 outHistory.x = chainHistory.x.*repmat(scale,size(chainHistory.x,1),1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1561
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1562 clear global lb ub scale chainHistory
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1563
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1564 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1565
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1566 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1567
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1568 function stop = outfun(x,optimvalues,state)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1569
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1570 global chainHistory
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1571
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1572 stop = false;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1573 if strcmp(state,'iter')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1574 chainHistory.fval = [chainHistory.fval; optimvalues.fval];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1575 chainHistory.x = [chainHistory.x; x];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1576 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1577
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1578 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1579
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1580 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1581
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1582 function hess = fastHessian(fun,x0,fx0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1583 % fastHessian calculates the numerical Hessian of fun evaluated at x
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1584 % using finite differences.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1585
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1586 nVars = numel(x0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1587
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1588 hess = zeros(nVars);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1589
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1590 % Define stepsize
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1591 stepSize = eps^(1/4)*sign(x0).*max(abs(x0),1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1592
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1593 % Min e Max change
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1594 DiffMinChange = 1e-008;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1595 DiffMaxChange = 0.1;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1596
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1597 % Make sure step size lies within DiffMinChange and DiffMaxChange
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1598 stepSize = sign(stepSize+eps).*min(max(abs(stepSize),DiffMinChange),DiffMaxChange);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1599 % Calculate the upper triangle of the finite difference Hessian element
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1600 % by element, using only function values. The forward difference formula
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1601 % we use is
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1602 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1603 % Hessian(i,j) = 1/(h(i)*h(j)) * [f(x+h(i)*ei+h(j)*ej) - f(x+h(i)*ei)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1604 % - f(x+h(j)*ej) + f(x)] (2)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1605 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1606 % The 3rd term in (2) is common within each column of Hessian and thus
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1607 % can be reused. We first calculate that term for each column and store
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1608 % it in the row vector fplus_array.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1609 fplus_array = zeros(1,nVars);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1610 for j = 1:nVars
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1611 xplus = x0;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1612 xplus(j) = x0(j) + stepSize(j);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1613 % evaluate
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1614 fplus = fun(xplus);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1615 fplus_array(j) = fplus;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1616 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1617
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1618 for i = 1:nVars
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1619 % For each row, calculate the 2nd term in (4). This term is common to
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1620 % the whole row and thus it can be reused within the current row: we
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1621 % store it in fplus_i.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1622 xplus = x0;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1623 xplus(i) = x0(i) + stepSize(i);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1624 % evaluate
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1625 fplus_i = fun(xplus);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1626
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1627 for j = i:nVars % start from i: only upper triangle
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1628 % Calculate the 1st term in (2); this term is unique for each element
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1629 % of Hessian and thus it cannot be reused.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1630 xplus = x0;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1631 xplus(i) = x0(i) + stepSize(i);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1632 xplus(j) = xplus(j) + stepSize(j);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1633 % evaluate
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1634 fplus = fun(xplus);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1635
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1636 hess(i,j) = (fplus - fplus_i - fplus_array(j) + fx0)/(stepSize(i)*stepSize(j));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1637 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1638 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1639
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1640 % Fill in the lower triangle of the Hessian
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1641 hess = hess + triu(hess,1)';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1642
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1643 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1644
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1645 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1646
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1647 % function [x,fval,exitflag,output,h,SVDhistory] = ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1648 % find_bestfit_guess_SVD(P0, lb, ub, opts, algorithm, FastHess, nSVD)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1649 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1650 % if isempty(lb)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1651 % lb = -Inf;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1652 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1653 % if isempty(ub)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1654 % ub = Inf;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1655 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1656 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1657 % % define parameter scale
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1658 % scale = find_scale(P0, [], []);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1659 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1660 % % % scale function to minimize
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1661 % % func = @(x)scaling(func, x, scale);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1662 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1663 % % scale initial guess
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1664 % P0 = P0./scale;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1665 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1666 % % scale bounds
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1667 % if ~isempty(lb)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1668 % lb = lb./scale;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1669 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1670 % if ~isempty(ub)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1671 % ub = ub./scale;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1672 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1673 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1674 % % set the guess for 0-iteration
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1675 % x = P0;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1676 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1677 % Nfreeparams = numel(P0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1678 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1679 % fitresults = zeros(nSVD,Nfreeparams+1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1680 % exitflags = {};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1681 % outputs = {};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1682 % hs = {};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1683 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1684 % % start SVD loop
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1685 % for ii=1:nSVD
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1686 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1687 % % minimize over the old parameter space
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1688 % if strcmpi(algorithm,'fminunc')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1689 % [x,fval,exitflag,output,grad,h] = fminunc(@fit_chi2, x, opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1690 % elseif strcmpi(algorithm,'fmincon')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1691 % [x,fval,exitflag,output,lambda,grad,h] = fmincon(@fit_chi2, x, [], [], [], [], lb, ub, [], opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1692 % elseif strcmpi(algorithm,'patternsearch')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1693 % [x,fval,exitflag,output] = patternsearch(@fit_chi2, P0, [], [], [], [], lb, ub, [], opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1694 % elseif strcmpi(algorithm,'ga')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1695 % [x,fval,exitflag,output] = ga(@fit_chi2, numel(P0), [], [], [], [], lb, ub, [], opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1696 % elseif strcmpi(algorithm,'simulannealbnd')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1697 % [x,fval,exitflag,output] = simulannealbnd(@fit_chi2, P0, lb, ub, opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1698 % else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1699 % [x,fval,exitflag,output] = fminsearch(@fit_chi2, P0, opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1700 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1701 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1702 % if FastHess && ~exist('h','var')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1703 % h = fastHessian(func,x,fval);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1704 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1705 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1706 % % compute Jacobian
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1707 % J = zeros(Nch*Ndata,Np);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1708 % for kk=1:Nch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1709 % for ll=1:Np
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1710 % J(((ii-1)*Ndata+1):ii*Ndata,ll) = dFcns{kk}{ll}(x.*scale);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1711 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1712 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1713 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1714 % % take SVD decomposition of hessian
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1715 % [U,S,V] = svd(J);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1716 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1717 % % cancel out column with very low information
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1718 % thresh = 100*eps;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1719 % idx = (diag(S)./norm(diag(S)))<=thresh;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1720 % pos = find(idx~=0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1721 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1722 % % reduced matrix
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1723 % Sred = S;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1724 % Ured = U;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1725 % Vred = V;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1726 % Sred(:,pos) = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1727 % Sred(pos,:) = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1728 % Ured(:,pos) = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1729 % Ured(pos,:) = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1730 % Vred(:,pos) = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1731 % Vred(pos,:) = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1732 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1733 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1734 % % start from here inserting norm-rescaling... also in funcSVD!
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1735 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1736 % % guess in the new parameter space
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1737 % % pay attention because here x is row-vector and xSVD ic column-vector
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1738 % xSVD = U'*x';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1739 % xSVD(pos) = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1740 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1741 % % % bounds in the new parameter space
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1742 % % if ~isempty(lb) && ~isempty(ub)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1743 % % lbSVD = U'*lb';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1744 % % ubSVD = U'*ub';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1745 % % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1746 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1747 % % do the change in the variables
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1748 % funcSVD = @(xSVD)func_SVD(func,xSVD,U,pos);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1749 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1750 % % minimize over the new parameter space
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1751 % if strcmpi(algorithm,'fminunc')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1752 % [xSVD,fvalSVD,exitflag,output,grad,hSVD] = fminunc(funcSVD, xSVD, opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1753 % elseif strcmpi(algorithm,'fmincon')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1754 % [xSVD,fvalSVD,exitflag,output,lambda,grad,hSVD] = fmincon(funcSVD, xSVD, [], [], [], [], [], [], [], opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1755 % elseif strcmpi(algorithm,'patternsearch')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1756 % [xSVD,fvalSVD,exitflag,output] = patternsearch(funcSVD, xSVD, [], [], [], [], [], [], [], opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1757 % elseif strcmpi(algorithm,'ga')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1758 % [xSVD,fvalSVD,exitflag,output] = ga(funcSVD, numel(xSVD), [], [], [], [], [], [], [], opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1759 % elseif strcmpi(algorithm,'simulannealbnd')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1760 % [xSVD,fvalSVD,exitflag,output] = simulannealbnd(funcSVD, xSVD, [], [], opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1761 % else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1762 % [xSVD,fvalSVD,exitflag,output] = fminsearch(funcSVD, xSVD, opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1763 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1764 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1765 % if FastHess && ~exist('hSVD','var')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1766 % hSVD = fastHessian(funcSVD,xSVD,fvalSVD);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1767 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1768 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1769 % % if fvalSVD<fval
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1770 % % % take the new
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1771 % % x = (U'*xSVD)';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1772 % % fval = fvalSVD;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1773 % % % trasformare la nuova h nella vecchia
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1774 % % h = U'*hSVD;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1775 % % else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1776 % % % take the old
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1777 % % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1778 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1779 % % return to the full parameter vector
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1780 % xSVDfull = zeros(numel(xSVD)+numel(pos),1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1781 % setVals = setdiff(1:numel(xSVDfull),pos);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1782 % xSVDfull(setVals) = xSVD;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1783 % % x = xb;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1784 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1785 % % back to the old parameter space
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1786 % x = (U*xSVDfull)';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1787 % fval = fvalSVD;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1788 % hRed = Ured*hSVD*Vred';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1789 % h = hRed;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1790 % for kk=1:numel(pos)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1791 % h(pos(kk),:) = zeros(1,size(h,2));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1792 % h(:,pos(kk)) = zeros(size(h,1),1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1793 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1794 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1795 % fitresults(ii,1) = fval;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1796 % fitresults(ii,2:Nfreeparams+1) = x;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1797 % exitflags{ii} = exitflag;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1798 % outputs{ii} = output;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1799 % hs{ii} = h;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1800 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1801 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1802 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1803 % % sort the results
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1804 % [chi2s, ix] = sort(fitresults(:,1));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1805 % fitresults = fitresults(ix,:);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1806 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1807 % % set the best-fit
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1808 % fval = fitresults(1,1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1809 % x = fitresults(1,2:Nfreeparams+1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1810 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1811 % % scale best-fit
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1812 % x = x.*scale;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1813 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1814 % % scale hessian
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1815 % for ii=1:numel(x)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1816 % for jj=1:numel(x)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1817 % h(ii,jj) = h(ii,jj)/scale(ii)/scale(jj);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1818 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1819 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1820 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1821 % % scale fit results
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1822 % SVDhistory = fitresults;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1823 % for ii=1:size(SVDhistory,1)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1824 % SVDhistory(ii,2:Nfreeparams+1) = SVDhistory(ii,2:Nfreeparams+1).*scale;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1825 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1826 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1827 % % set the proper exitflag & output
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1828 % exitflags = exitflags(ix);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1829 % outputs = outputs(ix);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1830 % hs = hs(ix);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1831 % exitflag = exitflags{1};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1832 % output = outputs{1};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1833 % h = hs{1};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1834 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1835 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1836
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1837 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1838
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1839 % function z = func_SVD(func,y,U,pos)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1840 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1841 % yFull = zeros(numel(y)+numel(pos),1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1842 % setVals = setdiff(1:numel(yFull),pos);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1843 % yFull(setVals) = y;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1844 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1845 % x = (U*yFull)';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1846 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1847 % z = func(x);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1848 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1849 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1850
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1851 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1852
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1853 % function adaptive_scaling(P0, scaleIn, func, Niter, opts, algorithm)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1854 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1855 % Nfreeparams = numel(P0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1856 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1857 % for ii=1:Niter
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1858 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1859 % % new guess
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1860 % P0_new = P0;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1861 % % new scale
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1862 % scale = find_scale(P0, [], []);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1863 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1864 % % scale bounds
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1865 % LB = LB./scale;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1866 % UB = UB./scale;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1867 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1868 % % if ~multiCh
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1869 % % rescale model
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1870 % modelFunc = @(x)scaling(modelFunc, x, scale_new./scale);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1871 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1872 % % define function to minimize
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1873 % if isempty(lb) & isempty(ub)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1874 % func = @(x)fit_chi2(x, Ydata, weights, modelFunc);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1875 % else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1876 % lb = lb.*scale./scale_new;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1877 % ub = ub.*scale./scale_new;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1878 % func = @(x)fit_chi2_bounds(x, Ydata, weights, modelFunc, lb, ub);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1879 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1880 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1881 % % else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1882 % % % func = @(x)fit_chi2_multich(params, x, Ydata, mdl_params, modelFuncs);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1883 % % func = @(x)scaling(func, x, scale_new/scale);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1884 % % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1885 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1886 % % Make new fit
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1887 % [x,fval_new,exitflag,output] = fminsearch(func, P0_new./scale_new, opts);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1888 % % stopping criterion
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1889 % if abs(fval_new-fval) <= 3*eps(fval_new-fval)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1890 % fval = fval_new;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1891 % scale = scale_new;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1892 % break
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1893 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1894 % fval = fval_new;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1895 % scale = scale_new;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1896 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1897 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1898 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1899 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1900
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1901 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1902
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1903 function [se,Sigma,Corr,I,H,errH,J,errJ] = find_errors(modelFcn, x, fval, dof, UncMtd, FastHess, h, weights, unweighted, linUnc, dFcns)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1904
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1905 global scale Nch Ndata lb ub
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1906
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1907 % set infinite bounds
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1908 lb = repmat(-Inf,size(x));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1909 ub = repmat(Inf,size(x));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1910
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1911 % check on UncMtd and FastHess
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1912 if strcmpi(UncMtd,'jacobian')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1913 FastHess = 0;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1914 elseif FastHess==1 && isempty(h)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1915 FastHess = 0;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1916 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1917
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1918 Nfreeparams = numel(x);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1919
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1920 if ~FastHess
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1921
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1922 % find new scale based on the best-fit found
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1923 scale = find_scale(x, [], []);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1924
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1925 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1926
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1927 scale = ones(1,Nfreeparams);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1928
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1929 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1930
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1931 % scale best-fit
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1932 x = x./scale;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1933
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1934
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1935 % standard deviation of the residuals
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1936 sdr = sqrt(fval/dof);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1937
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1938 % compute information matrix from linear approximation: error propagation
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1939 % from symbolical gradient
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1940 if linUnc
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1941 % compute Jacobian
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1942 J = zeros(Nch*Ndata,Nfreeparams);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1943 for ii=1:Nch
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1944 for ll=1:Nfreeparams
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1945 J(((ii-1)*Ndata+1):ii*Ndata,ll) = dFcns{ii}{ll}(x.*scale);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1946 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1947 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1948 elseif ~strcmpi(UncMtd,'jacobian') || numel(modelFcn)~=1 && ~linUnc
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1949
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1950 % Hessian method.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1951 % Brief description.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1952 % Here I use the most general method: Hessian of chi2 function. For further readings see
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1953 % Numerical Recipes. Note that for inv, H should be non-singular.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1954 % Badly-scaled matrices may take to singularities: use Cholesky
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1955 % factorization instead.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1956 % In practice, a singular Hessian matrix may go out for the following main reasons:
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1957 % 1 - you have reached a false minimum (H should be strictly
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1958 % positive-definite for a well-behaved minimum);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1959 % 2 - strong correlation between some parameters;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1960 % 3 - independency of the model on some parameters.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1961 % In the last two cases you should reduce the dimensionality of the
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1962 % problem.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1963 % One last point discussed here in Trento is that the Hessian method reduces
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1964 % to the Jacobian, when considering linear models.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1965 % Feedbacks are welcome.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1966 % Trento, Giuseppe Congedo
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1967
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1968 if ~FastHess
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1969 % scale function to find the hessian
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1970 % func = @(x)scaling(func, x, scale);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1971
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1972 [H,errH] = hessian(@fit_chi2,x);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1973
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1974 elseif ~isempty(h) && FastHess % here the hessian is not scaled
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1975 H = h;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1976 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1977
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1978 if unweighted
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1979 % information matrix based on sdr
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1980 I = H / sdr^2 / 2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1981 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1982 % information matrix based on canonical form
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1983 I = H./2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1984 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1985
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1986 elseif ~linUnc
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1987
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1988 % % scale function to find the jacobian
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1989 % modelFcn = @(x)scaling(modelFcn, x, scale);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1990
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1991 % Jacobian method
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1992 [J,errJ] = jacobianest(modelFcn{1},x);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1993 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1994
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1995 if exist('J','var')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1996 if unweighted
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1997 % information matrix based on sdr
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1998 I = J'*J ./ sdr^2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 1999 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2000 % redefine the jacobian to take care of the weights
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2001 if size(weights)~=size(J(:,1))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2002 weights = weights';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2003 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2004 for ii=1:size(J,2)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2005 J(:,ii) = sqrt(weights).*J(:,ii);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2006 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2007 % information matrix based on jacobian
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2008 I = J'*J;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2009 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2010
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2011 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2012
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2013 % check positive-definiteness
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2014 % [R,p] = chol(I);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2015 % posDef = p==0;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2016
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2017 % Covariance matrix from inverse
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2018 Sigma = inv(I);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2019
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2020 % % Covariance matrix from pseudo-inverse
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2021 % if issparse(I)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2022 % % [U,S,V] = svds(I,Nfreeparams);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2023 % % I = full(I);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2024 % I = full(I);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2025 % [U,S,V] = svd(I);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2026 % else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2027 % [U,S,V] = svd(I);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2028 % end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2029 % Sigma = V/S*U';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2030
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2031 % Does the covariance give proper positive-definite variances?
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2032 posDef = all(diag(Sigma)>=0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2033
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2034 if posDef
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2035
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2036 % Compute correlation matrix
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2037 Corr = zeros(size(Sigma));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2038 for ii=1:size(Sigma,1)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2039 for jj=1:size(Sigma,2)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2040 Corr(ii,jj) = Sigma(ii,jj) / sqrt(Sigma(ii,ii)) / sqrt(Sigma(jj,jj));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2041 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2042 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2043
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2044 % Parameter standard errors
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2045 se = sqrt(diag(Sigma))';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2046
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2047 % rescale errors and covariance matrix
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2048 if ~FastHess && ~linUnc % otherwise H is already scaled in find_bestfit function
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2049 se = se.*scale;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2050 for ii=1:Nfreeparams
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2051 for jj=1:Nfreeparams
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2052 Sigma(ii,jj) = Sigma(ii,jj)*scale(ii)*scale(jj);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2053 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2054 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2055 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2056 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2057
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2058 % rescale information matrix
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2059 if ~FastHess && ~linUnc % otherwise H is already scaled in find_bestfit function
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2060 for ii=1:Nfreeparams
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2061 for jj=1:Nfreeparams
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2062 I(ii,jj) = I(ii,jj)/scale(ii)/scale(jj);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2063 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2064 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2065 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2066
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2067 if ~exist('se','var'); se = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2068 if ~exist('Sigma','var'); Sigma = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2069 if ~exist('Corr','var'); Corr = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2070 if ~exist('I','var'); I = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2071 if ~exist('H','var'); H = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2072 if ~exist('errH','var'); errH = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2073 if ~exist('J','var'); J = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2074 if ~exist('errJ','var'); errJ = []; end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2075
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2076 clear global scale
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2077
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2078 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2079
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2080 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2081 % Get Info Object
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2082 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2083 function ii = getInfo(varargin)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2084 if nargin == 1 && strcmpi(varargin{1}, 'None')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2085 sets = {};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2086 pl = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2087 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2088 sets = {'Default'};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2089 pl = getDefaultPlist;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2090 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2091 % Build info object
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2092 ii = minfo(mfilename, 'ao', 'ltpda', utils.const.categories.sigproc, '$Id: xfit.m,v 1.83 2011/05/12 07:46:29 mauro Exp $', sets, pl);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2093 ii.setModifier(false);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2094 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2095
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2096 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2097 % Get Default Plist
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2098 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2099 function plout = getDefaultPlist()
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2100 persistent pl;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2101 if exist('pl', 'var')==0 || isempty(pl)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2102 pl = buildplist();
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2103 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2104 plout = pl;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2105 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2106
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2107 function pl = buildplist()
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2108
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2109 pl = plist();
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2110
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2111 % Function
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2112 p = param({'Function', 'The function (or symbolic model <tt>smodel</tt>) of Xdata that you want to fit. For example: ''P(1)*Xdata''.'}, paramValue.EMPTY_STRING);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2113 pl.append(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2114
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2115 % Weights
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2116 p = param({'Weights', ['An array of weights, one value per X sample.<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2117 'By default, <tt>xfit</tt> takes data uncertainties from the dy field of the input object.'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2118 'If provided, <tt>weights</tt> make <tt>xfit</tt> ignore these.'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2119 'Otherwise <tt>weights</tt> will be considered as ones.']}, paramValue.EMPTY_STRING);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2120 pl.append(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2121
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2122 % P0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2123 p = param({'P0', ['An array of starting guesses for the parameters.<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2124 'This is not necessary if you fit with <tt>smodel</tt>s; in that case the parameter'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2125 'values from the <tt>smodel</tt> are taken as the initial guess.']}, paramValue.EMPTY_DOUBLE);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2126 pl.append(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2127
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2128 % % ADDP
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2129 % p = param({'ADDP', 'A cell-array of additional parameters to pass to the function. These will not be fit.'}, {1, {'{}'}, paramValue.OPTIONAL});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2130 % pl.append(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2131
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2132 % LB
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2133 p = param({'LB', ['Lower bounds for the parameters.<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2134 'This improves the convergency. Mandatory for Monte Carlo.<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2135 'For multichannel fitting it has to be a cell-array.']}, paramValue.EMPTY_DOUBLE);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2136 pl.append(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2137
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2138 % UB
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2139 p = param({'UB', ['Upper bounds for the parameters.<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2140 'This improves the convergency. Mandatory for Monte Carlo.<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2141 'For multichannel fitting it has to be a cell-array.']}, paramValue.EMPTY_DOUBLE);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2142 pl.append(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2143
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2144 % Algorithm
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2145 p = param({'ALGORITHM', ['A string defining the fitting algorithm.<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2146 '<tt>fminunc</tt>, <tt>fmincon</tt> require ''Optimization Toolbox'' to be installed.<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2147 '<tt>patternsearch</tt>, <tt>ga</tt>, <tt>simulannealbnd</tt> require ''Genetic Algorithm and Direct Search'' to be installed.<br>']}, ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2148 {1, {'fminsearch', 'fminunc', 'fmincon', 'patternsearch', 'ga', 'simulannealbnd'}, paramValue.SINGLE});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2149 pl.append(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2150
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2151 % OPTSET
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2152 p = param({'OPTSET', ['An optimisation structure to pass to the fitting algorithm.<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2153 'See <tt>fminsearch</tt>, <tt>fminunc</tt>, <tt>fmincon</tt>, <tt>optimset</tt>, for details.<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2154 'See <tt>patternsearch</tt>, <tt>psoptimset</tt>, for details.<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2155 'See <tt>ga</tt>, <tt>gaoptimset</tt>, for details.<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2156 'See <tt>simulannealbnd</tt>, <tt>saoptimset</tt>, for details.']}, paramValue.EMPTY_STRING);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2157 pl.append(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2158
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2159 % FitUnc
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2160 p = param({'FitUnc', 'Fit parameter uncertainties or not.'}, paramValue.YES_NO);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2161 pl.append(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2162
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2163 % UncMtd
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2164 p = param({'UncMtd', ['Choose the uncertainties estimation method.<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2165 'For multi-channel fitting <tt>hessian</tt> is mandatory.']}, {1, {'hessian', 'jacobian'}, paramValue.SINGLE});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2166 pl.append(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2167
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2168 % FastHess
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2169 p = param({'FastHess', ['Choose whether or not the hessian should be estimated from a fast-forward finite differences algorithm; '...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2170 'use this method to achieve better performance in CPU-time, but accuracy is not ensured; '...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2171 'otherwise, the default (computer expensive, but more accurate) method will be used.']}, paramValue.NO_YES);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2172 pl.append(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2173
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2174 % MonteCarlo
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2175 p = param({'MonteCarlo', ['Do a Monte Carlo search in the parameter space.<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2176 'Useful when dealing with high multiplicity of local minima. May be computer-expensive.<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2177 'Note that, if used, P0 will be ignored. It also requires to define LB and UB.']}, paramValue.NO_YES);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2178 pl.append(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2179
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2180 % Npoints
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2181 p = param({'Npoints', 'Set the number of points in the parameter space to be extracted.'}, 100000);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2182 pl.append(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2183
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2184 % Noptims
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2185 p = param({'Noptims', 'Set the number of optimizations to be performed after the Monte Carlo.'}, 10);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2186 pl.append(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2187
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2188 % estimator
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2189 p = param({'estimator', ['Choose the robust local M-estimate as the statistical estimator of the fit:<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2190 ' ''chi2'' (least square) for data with normal distribution;<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2191 ' ''abs'' (mean absolute deviation) for data with double exponential distribution;<br>'...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2192 ' ''log'' (log least square) for data with Lorentzian distribution.']}, ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2193 {1, {'chi2', 'abs', 'log'}, paramValue.SINGLE});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2194 pl.append(p);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2195
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2196
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2197 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2198 % END
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2199
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2200 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2201
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2202 % Author: John D'Errico
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2203 % e-mail: woodchips@rochester.rr.com
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2204
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2205 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2206 % DERIVEST SUITE
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2207 %--------------------------------------------------------------------------
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2208
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2209 function [der,errest,finaldelta] = derivest(fun,x0,varargin)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2210 % DERIVEST: estimate the n'th derivative of fun at x0, provide an error estimate
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2211 % usage: [der,errest] = DERIVEST(fun,x0) % first derivative
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2212 % usage: [der,errest] = DERIVEST(fun,x0,prop1,val1,prop2,val2,...)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2213 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2214 % Derivest will perform numerical differentiation of an
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2215 % analytical function provided in fun. It will not
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2216 % differentiate a function provided as data. Use gradient
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2217 % for that purpose, or differentiate a spline model.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2218 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2219 % The methods used by DERIVEST are finite difference
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2220 % approximations of various orders, coupled with a generalized
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2221 % (multiple term) Romberg extrapolation. This also yields
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2222 % the error estimate provided. DERIVEST uses a semi-adaptive
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2223 % scheme to provide the best estimate that it can by its
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2224 % automatic choice of a differencing interval.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2225 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2226 % Finally, While I have not written this function for the
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2227 % absolute maximum speed, speed was a major consideration
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2228 % in the algorithmic design. Maximum accuracy was my main goal.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2229 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2230 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2231 % Arguments (input)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2232 % fun - function to differentiate. May be an inline function,
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2233 % anonymous, or an m-file. fun will be sampled at a set
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2234 % of distinct points for each element of x0. If there are
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2235 % additional parameters to be passed into fun, then use of
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2236 % an anonymous function is recommended.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2237 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2238 % fun should be vectorized to allow evaluation at multiple
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2239 % locations at once. This will provide the best possible
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2240 % speed. IF fun is not so vectorized, then you MUST set
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2241 % 'vectorized' property to 'no', so that derivest will
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2242 % then call your function sequentially instead.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2243 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2244 % Fun is assumed to return a result of the same
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2245 % shape as its input x0.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2246 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2247 % x0 - scalar, vector, or array of points at which to
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2248 % differentiate fun.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2249 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2250 % Additional inputs must be in the form of property/value pairs.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2251 % Properties are character strings. They may be shortened
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2252 % to the extent that they are unambiguous. Properties are
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2253 % not case sensitive. Valid property names are:
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2254 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2255 % 'DerivativeOrder', 'MethodOrder', 'Style', 'RombergTerms'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2256 % 'FixedStep', 'MaxStep'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2257 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2258 % All properties have default values, chosen as intelligently
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2259 % as I could manage. Values that are character strings may
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2260 % also be unambiguously shortened. The legal values for each
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2261 % property are:
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2262 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2263 % 'DerivativeOrder' - specifies the derivative order estimated.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2264 % Must be a positive integer from the set [1,2,3,4].
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2265 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2266 % DEFAULT: 1 (first derivative of fun)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2267 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2268 % 'MethodOrder' - specifies the order of the basic method
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2269 % used for the estimation.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2270 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2271 % For 'central' methods, must be a positive integer
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2272 % from the set [2,4].
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2273 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2274 % For 'forward' or 'backward' difference methods,
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2275 % must be a positive integer from the set [1,2,3,4].
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2276 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2277 % DEFAULT: 4 (a second order method)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2278 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2279 % Note: higher order methods will generally be more
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2280 % accurate, but may also suffere more from numerical
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2281 % problems.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2282 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2283 % Note: First order methods would usually not be
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2284 % recommended.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2285 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2286 % 'Style' - specifies the style of the basic method
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2287 % used for the estimation. 'central', 'forward',
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2288 % or 'backwards' difference methods are used.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2289 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2290 % Must be one of 'Central', 'forward', 'backward'.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2291 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2292 % DEFAULT: 'Central'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2293 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2294 % Note: Central difference methods are usually the
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2295 % most accurate, but sometiems one must not allow
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2296 % evaluation in one direction or the other.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2297 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2298 % 'RombergTerms' - Allows the user to specify the generalized
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2299 % Romberg extrapolation method used, or turn it off
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2300 % completely.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2301 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2302 % Must be a positive integer from the set [0,1,2,3].
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2303 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2304 % DEFAULT: 2 (Two Romberg terms)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2305 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2306 % Note: 0 disables the Romberg step completely.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2307 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2308 % 'FixedStep' - Allows the specification of a fixed step
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2309 % size, preventing the adaptive logic from working.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2310 % This will be considerably faster, but not necessarily
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2311 % as accurate as allowing the adaptive logic to run.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2312 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2313 % DEFAULT: []
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2314 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2315 % Note: If specified, 'FixedStep' will define the
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2316 % maximum excursion from x0 that will be used.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2317 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2318 % 'Vectorized' - Derivest will normally assume that your
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2319 % function can be safely evaluated at multiple locations
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2320 % in a single call. This would minimize the overhead of
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2321 % a loop and additional function call overhead. Some
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2322 % functions are not easily vectorizable, but you may
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2323 % (if your matlab release is new enough) be able to use
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2324 % arrayfun to accomplish the vectorization.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2325 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2326 % When all else fails, set the 'vectorized' property
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2327 % to 'no'. This will cause derivest to loop over the
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2328 % successive function calls.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2329 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2330 % DEFAULT: 'yes'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2331 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2332 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2333 % 'MaxStep' - Specifies the maximum excursion from x0 that
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2334 % will be allowed, as a multiple of x0.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2335 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2336 % DEFAULT: 100
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2337 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2338 % 'StepRatio' - Derivest uses a proportionally cascaded
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2339 % series of function evaluations, moving away from your
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2340 % point of evaluation. The StepRatio is the ratio used
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2341 % between sequential steps.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2342 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2343 % DEFAULT: 2
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2344 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2345 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2346 % See the document DERIVEST.pdf for more explanation of the
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2347 % algorithms behind the parameters of DERIVEST. In most cases,
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2348 % I have chosen good values for these parameters, so the user
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2349 % should never need to specify anything other than possibly
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2350 % the DerivativeOrder. I've also tried to make my code robust
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2351 % enough that it will not need much. But complete flexibility
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2352 % is in there for your use.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2353 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2354 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2355 % Arguments: (output)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2356 % der - derivative estimate for each element of x0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2357 % der will have the same shape as x0.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2358 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2359 % errest - 95% uncertainty estimate of the derivative, such that
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2360 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2361 % abs(der(j) - f'(x0(j))) < erest(j)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2362 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2363 % finaldelta - The final overall stepsize chosen by DERIVEST
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2364 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2365 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2366 % Example usage:
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2367 % First derivative of exp(x), at x == 1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2368 % [d,e]=derivest(@(x) exp(x),1)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2369 % d =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2370 % 2.71828182845904
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2371 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2372 % e =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2373 % 1.02015503167879e-14
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2374 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2375 % True derivative
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2376 % exp(1)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2377 % ans =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2378 % 2.71828182845905
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2379 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2380 % Example usage:
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2381 % Third derivative of x.^3+x.^4, at x = [0,1]
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2382 % derivest(@(x) x.^3 + x.^4,[0 1],'deriv',3)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2383 % ans =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2384 % 6 30
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2385 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2386 % True derivatives: [6,30]
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2387 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2388 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2389 % See also: gradient
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2390 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2391 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2392 % Author: John D'Errico
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2393 % e-mail: woodchips@rochester.rr.com
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2394 % Release: 1.0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2395 % Release date: 12/27/2006
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2396
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2397 par.DerivativeOrder = 1;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2398 par.MethodOrder = 4;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2399 par.Style = 'central';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2400 par.RombergTerms = 2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2401 par.FixedStep = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2402 par.MaxStep = 100;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2403 par.StepRatio = 2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2404 par.NominalStep = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2405 par.Vectorized = 'yes';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2406
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2407 na = length(varargin);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2408 if (rem(na,2)==1)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2409 error 'Property/value pairs must come as PAIRS of arguments.'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2410 elseif na>0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2411 par = parse_pv_pairs(par,varargin);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2412 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2413 par = check_params(par);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2414
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2415 % Was fun a string, or an inline/anonymous function?
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2416 if (nargin<1)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2417 help derivest
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2418 return
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2419 elseif isempty(fun)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2420 error 'fun was not supplied.'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2421 elseif ischar(fun)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2422 % a character function name
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2423 fun = str2func(fun);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2424 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2425
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2426 % no default for x0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2427 if (nargin<2) || isempty(x0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2428 error 'x0 was not supplied'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2429 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2430 par.NominalStep = max(x0,0.02);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2431
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2432 % was a single point supplied?
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2433 nx0 = size(x0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2434 n = prod(nx0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2435
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2436 % Set the steps to use.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2437 if isempty(par.FixedStep)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2438 % Basic sequence of steps, relative to a stepsize of 1.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2439 delta = par.MaxStep*par.StepRatio .^(0:-1:-25)';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2440 ndel = length(delta);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2441 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2442 % Fixed, user supplied absolute sequence of steps.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2443 ndel = 3 + ceil(par.DerivativeOrder/2) + ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2444 par.MethodOrder + par.RombergTerms;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2445 if par.Style(1) == 'c'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2446 ndel = ndel - 2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2447 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2448 delta = par.FixedStep*par.StepRatio .^(-(0:(ndel-1)))';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2449 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2450
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2451 % generate finite differencing rule in advance.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2452 % The rule is for a nominal unit step size, and will
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2453 % be scaled later to reflect the local step size.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2454 fdarule = 1;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2455 switch par.Style
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2456 case 'central'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2457 % for central rules, we will reduce the load by an
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2458 % even or odd transformation as appropriate.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2459 if par.MethodOrder==2
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2460 switch par.DerivativeOrder
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2461 case 1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2462 % the odd transformation did all the work
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2463 fdarule = 1;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2464 case 2
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2465 % the even transformation did all the work
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2466 fdarule = 2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2467 case 3
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2468 % the odd transformation did most of the work, but
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2469 % we need to kill off the linear term
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2470 fdarule = [0 1]/fdamat(par.StepRatio,1,2);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2471 case 4
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2472 % the even transformation did most of the work, but
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2473 % we need to kill off the quadratic term
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2474 fdarule = [0 1]/fdamat(par.StepRatio,2,2);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2475 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2476 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2477 % a 4th order method. We've already ruled out the 1st
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2478 % order methods since these are central rules.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2479 switch par.DerivativeOrder
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2480 case 1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2481 % the odd transformation did most of the work, but
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2482 % we need to kill off the cubic term
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2483 fdarule = [1 0]/fdamat(par.StepRatio,1,2);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2484 case 2
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2485 % the even transformation did most of the work, but
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2486 % we need to kill off the quartic term
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2487 fdarule = [1 0]/fdamat(par.StepRatio,2,2);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2488 case 3
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2489 % the odd transformation did much of the work, but
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2490 % we need to kill off the linear & quintic terms
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2491 fdarule = [0 1 0]/fdamat(par.StepRatio,1,3);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2492 case 4
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2493 % the even transformation did much of the work, but
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2494 % we need to kill off the quadratic and 6th order terms
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2495 fdarule = [0 1 0]/fdamat(par.StepRatio,2,3);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2496 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2497 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2498 case {'forward' 'backward'}
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2499 % These two cases are identical, except at the very end,
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2500 % where a sign will be introduced.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2501
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2502 % No odd/even trans, but we already dropped
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2503 % off the constant term
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2504 if par.MethodOrder==1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2505 if par.DerivativeOrder==1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2506 % an easy one
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2507 fdarule = 1;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2508 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2509 % 2:4
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2510 v = zeros(1,par.DerivativeOrder);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2511 v(par.DerivativeOrder) = 1;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2512 fdarule = v/fdamat(par.StepRatio,0,par.DerivativeOrder);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2513 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2514 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2515 % par.MethodOrder methods drop off the lower order terms,
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2516 % plus terms directly above DerivativeOrder
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2517 v = zeros(1,par.DerivativeOrder + par.MethodOrder - 1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2518 v(par.DerivativeOrder) = 1;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2519 fdarule = v/fdamat(par.StepRatio,0,par.DerivativeOrder+par.MethodOrder-1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2520 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2521
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2522 % correct sign for the 'backward' rule
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2523 if par.Style(1) == 'b'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2524 fdarule = -fdarule;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2525 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2526
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2527 end % switch on par.style (generating fdarule)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2528 nfda = length(fdarule);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2529
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2530 % will we need fun(x0)?
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2531 if (rem(par.DerivativeOrder,2) == 0) || ~strncmpi(par.Style,'central',7)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2532 if strcmpi(par.Vectorized,'yes')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2533 f_x0 = fun(x0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2534 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2535 % not vectorized, so loop
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2536 f_x0 = zeros(size(x0));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2537 for j = 1:numel(x0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2538 f_x0(j) = fun(x0(j));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2539 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2540 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2541 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2542 f_x0 = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2543 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2544
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2545 % Loop over the elements of x0, reducing it to
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2546 % a scalar problem. Sorry, vectorization is not
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2547 % complete here, but this IS only a single loop.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2548 der = zeros(nx0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2549 errest = der;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2550 finaldelta = der;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2551 for i = 1:n
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2552 x0i = x0(i);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2553 h = par.NominalStep(i);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2554
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2555 % a central, forward or backwards differencing rule?
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2556 % f_del is the set of all the function evaluations we
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2557 % will generate. For a central rule, it will have the
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2558 % even or odd transformation built in.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2559 if par.Style(1) == 'c'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2560 % A central rule, so we will need to evaluate
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2561 % symmetrically around x0i.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2562 if strcmpi(par.Vectorized,'yes')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2563 f_plusdel = fun(x0i+h*delta);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2564 f_minusdel = fun(x0i-h*delta);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2565 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2566 % not vectorized, so loop
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2567 f_minusdel = zeros(size(delta));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2568 f_plusdel = zeros(size(delta));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2569 for j = 1:numel(delta)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2570 f_plusdel(j) = fun(x0i+h*delta(j));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2571 f_minusdel(j) = fun(x0i-h*delta(j));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2572 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2573 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2574
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2575 if ismember(par.DerivativeOrder,[1 3])
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2576 % odd transformation
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2577 f_del = (f_plusdel - f_minusdel)/2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2578 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2579 f_del = (f_plusdel + f_minusdel)/2 - f_x0(i);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2580 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2581 elseif par.Style(1) == 'f'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2582 % forward rule
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2583 % drop off the constant only
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2584 if strcmpi(par.Vectorized,'yes')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2585 f_del = fun(x0i+h*delta) - f_x0(i);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2586 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2587 % not vectorized, so loop
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2588 f_del = zeros(size(delta));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2589 for j = 1:numel(delta)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2590 f_del(j) = fun(x0i+h*delta(j)) - f_x0(i);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2591 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2592 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2593 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2594 % backward rule
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2595 % drop off the constant only
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2596 if strcmpi(par.Vectorized,'yes')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2597 f_del = fun(x0i-h*delta) - f_x0(i);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2598 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2599 % not vectorized, so loop
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2600 f_del = zeros(size(delta));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2601 for j = 1:numel(delta)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2602 f_del(j) = fun(x0i-h*delta(j)) - f_x0(i);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2603 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2604 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2605 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2606
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2607 % check the size of f_del to ensure it was properly vectorized.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2608 f_del = f_del(:);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2609 if length(f_del)~=ndel
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2610 error 'fun did not return the correct size result (fun must be vectorized)'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2611 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2612
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2613 % Apply the finite difference rule at each delta, scaling
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2614 % as appropriate for delta and the requested DerivativeOrder.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2615 % First, decide how many of these estimates we will end up with.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2616 ne = ndel + 1 - nfda - par.RombergTerms;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2617
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2618 % Form the initial derivative estimates from the chosen
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2619 % finite difference method.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2620 der_init = vec2mat(f_del,ne,nfda)*fdarule.';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2621
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2622 % scale to reflect the local delta
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2623 der_init = der_init(:)./(h*delta(1:ne)).^par.DerivativeOrder;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2624
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2625 % Each approximation that results is an approximation
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2626 % of order par.DerivativeOrder to the desired derivative.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2627 % Additional (higher order, even or odd) terms in the
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2628 % Taylor series also remain. Use a generalized (multi-term)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2629 % Romberg extrapolation to improve these estimates.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2630 switch par.Style
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2631 case 'central'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2632 rombexpon = 2*(1:par.RombergTerms) + par.MethodOrder - 2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2633 otherwise
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2634 rombexpon = (1:par.RombergTerms) + par.MethodOrder - 1;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2635 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2636 [der_romb,errors] = rombextrap(par.StepRatio,der_init,rombexpon);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2637
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2638 % Choose which result to return
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2639
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2640 % first, trim off the
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2641 if isempty(par.FixedStep)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2642 % trim off the estimates at each end of the scale
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2643 nest = length(der_romb);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2644 switch par.DerivativeOrder
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2645 case {1 2}
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2646 trim = [1 2 nest-1 nest];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2647 case 3
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2648 trim = [1:4 nest+(-3:0)];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2649 case 4
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2650 trim = [1:6 nest+(-5:0)];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2651 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2652
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2653 [der_romb,tags] = sort(der_romb);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2654
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2655 der_romb(trim) = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2656 tags(trim) = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2657 errors = errors(tags);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2658 trimdelta = delta(tags);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2659
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2660 [errest(i),ind] = min(errors);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2661
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2662 finaldelta(i) = h*trimdelta(ind);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2663 der(i) = der_romb(ind);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2664 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2665 [errest(i),ind] = min(errors);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2666 finaldelta(i) = h*delta(ind);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2667 der(i) = der_romb(ind);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2668 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2669 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2670
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2671 end % mainline end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2672
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2673
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2674 function [jac,err] = jacobianest(fun,x0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2675 % gradest: estimate of the Jacobian matrix of a vector valued function of n variables
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2676 % usage: [jac,err] = jacobianest(fun,x0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2677 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2678 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2679 % arguments: (input)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2680 % fun - (vector valued) analytical function to differentiate.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2681 % fun must be a function of the vector or array x0.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2682 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2683 % x0 - vector location at which to differentiate fun
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2684 % If x0 is an nxm array, then fun is assumed to be
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2685 % a function of n*m variables.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2686 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2687 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2688 % arguments: (output)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2689 % jac - array of first partial derivatives of fun.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2690 % Assuming that x0 is a vector of length p
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2691 % and fun returns a vector of length n, then
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2692 % jac will be an array of size (n,p)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2693 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2694 % err - vector of error estimates corresponding to
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2695 % each partial derivative in jac.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2696 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2697 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2698 % Example: (nonlinear least squares)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2699 % xdata = (0:.1:1)';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2700 % ydata = 1+2*exp(0.75*xdata);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2701 % fun = @(c) ((c(1)+c(2)*exp(c(3)*xdata)) - ydata).^2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2702 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2703 % [jac,err] = jacobianest(fun,[1 1 1])
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2704 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2705 % jac =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2706 % -2 -2 0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2707 % -2.1012 -2.3222 -0.23222
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2708 % -2.2045 -2.6926 -0.53852
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2709 % -2.3096 -3.1176 -0.93528
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2710 % -2.4158 -3.6039 -1.4416
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2711 % -2.5225 -4.1589 -2.0795
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2712 % -2.629 -4.7904 -2.8742
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2713 % -2.7343 -5.5063 -3.8544
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2714 % -2.8374 -6.3147 -5.0518
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2715 % -2.9369 -7.2237 -6.5013
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2716 % -3.0314 -8.2403 -8.2403
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2717 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2718 % err =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2719 % 5.0134e-15 5.0134e-15 0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2720 % 5.0134e-15 0 2.8211e-14
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2721 % 5.0134e-15 8.6834e-15 1.5804e-14
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2722 % 0 7.09e-15 3.8227e-13
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2723 % 5.0134e-15 5.0134e-15 7.5201e-15
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2724 % 5.0134e-15 1.0027e-14 2.9233e-14
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2725 % 5.0134e-15 0 6.0585e-13
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2726 % 5.0134e-15 1.0027e-14 7.2673e-13
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2727 % 5.0134e-15 1.0027e-14 3.0495e-13
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2728 % 5.0134e-15 1.0027e-14 3.1707e-14
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2729 % 5.0134e-15 2.0053e-14 1.4013e-12
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2730 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2731 % (At [1 2 0.75], jac should be numerically zero)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2732 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2733 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2734 % See also: derivest, gradient, gradest
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2735 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2736 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2737 % Author: John D'Errico
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2738 % e-mail: woodchips@rochester.rr.com
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2739 % Release: 1.0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2740 % Release date: 3/6/2007
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2741
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2742 % get the length of x0 for the size of jac
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2743 nx = numel(x0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2744
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2745 MaxStep = 100;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2746 StepRatio = 2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2747
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2748 % was a string supplied?
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2749 if ischar(fun)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2750 fun = str2func(fun);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2751 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2752
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2753 % get fun at the center point
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2754 f0 = fun(x0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2755 f0 = f0(:);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2756 n = length(f0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2757 if n==0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2758 % empty begets empty
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2759 jac = zeros(0,nx);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2760 err = jac;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2761 return
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2762 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2763
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2764 relativedelta = MaxStep*StepRatio .^(0:-1:-25);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2765 nsteps = length(relativedelta);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2766
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2767 % total number of derivatives we will need to take
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2768 jac = zeros(n,nx);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2769 err = jac;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2770 for i = 1:nx
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2771 x0_i = x0(i);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2772 if x0_i ~= 0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2773 delta = x0_i*relativedelta;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2774 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2775 delta = relativedelta;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2776 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2777
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2778 % evaluate at each step, centered around x0_i
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2779 % difference to give a second order estimate
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2780 fdel = zeros(n,nsteps);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2781 for j = 1:nsteps
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2782 fdif = fun(swapelement(x0,i,x0_i + delta(j))) - ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2783 fun(swapelement(x0,i,x0_i - delta(j)));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2784
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2785 fdel(:,j) = fdif(:);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2786 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2787
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2788 % these are pure second order estimates of the
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2789 % first derivative, for each trial delta.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2790 derest = fdel.*repmat(0.5 ./ delta,n,1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2791
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2792 % The error term on these estimates has a second order
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2793 % component, but also some 4th and 6th order terms in it.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2794 % Use Romberg exrapolation to improve the estimates to
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2795 % 6th order, as well as to provide the error estimate.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2796
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2797 % loop here, as rombextrap coupled with the trimming
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2798 % will get complicated otherwise.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2799 for j = 1:n
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2800 [der_romb,errest] = rombextrap(StepRatio,derest(j,:),[2 4]);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2801
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2802 % trim off 3 estimates at each end of the scale
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2803 nest = length(der_romb);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2804 trim = [1:3, nest+(-2:0)];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2805 [der_romb,tags] = sort(der_romb);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2806 der_romb(trim) = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2807 tags(trim) = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2808
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2809 errest = errest(tags);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2810
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2811 % now pick the estimate with the lowest predicted error
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2812 [err(j,i),ind] = min(errest);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2813 jac(j,i) = der_romb(ind);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2814 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2815 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2816
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2817 end % mainline function end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2818
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2819
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2820 function [grad,err,finaldelta] = gradest(fun,x0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2821 % gradest: estimate of the gradient vector of an analytical function of n variables
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2822 % usage: [grad,err,finaldelta] = gradest(fun,x0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2823 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2824 % Uses derivest to provide both derivative estimates
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2825 % and error estimates. fun needs not be vectorized.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2826 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2827 % arguments: (input)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2828 % fun - analytical function to differentiate. fun must
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2829 % be a function of the vector or array x0.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2830 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2831 % x0 - vector location at which to differentiate fun
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2832 % If x0 is an nxm array, then fun is assumed to be
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2833 % a function of n*m variables.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2834 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2835 % arguments: (output)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2836 % grad - vector of first partial derivatives of fun.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2837 % grad will be a row vector of length numel(x0).
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2838 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2839 % err - vector of error estimates corresponding to
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2840 % each partial derivative in grad.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2841 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2842 % finaldelta - vector of final step sizes chosen for
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2843 % each partial derivative.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2844 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2845 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2846 % Example:
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2847 % [grad,err] = gradest(@(x) sum(x.^2),[1 2 3])
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2848 % grad =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2849 % 2 4 6
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2850 % err =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2851 % 5.8899e-15 1.178e-14 0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2852 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2853 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2854 % Example:
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2855 % At [x,y] = [1,1], compute the numerical gradient
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2856 % of the function sin(x-y) + y*exp(x)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2857 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2858 % z = @(xy) sin(diff(xy)) + xy(2)*exp(xy(1))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2859 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2860 % [grad,err ] = gradest(z,[1 1])
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2861 % grad =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2862 % 1.7183 3.7183
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2863 % err =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2864 % 7.537e-14 1.1846e-13
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2865 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2866 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2867 % Example:
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2868 % At the global minimizer (1,1) of the Rosenbrock function,
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2869 % compute the gradient. It should be essentially zero.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2870 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2871 % rosen = @(x) (1-x(1)).^2 + 105*(x(2)-x(1).^2).^2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2872 % [g,err] = gradest(rosen,[1 1])
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2873 % g =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2874 % 1.0843e-20 0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2875 % err =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2876 % 1.9075e-18 0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2877 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2878 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2879 % See also: derivest, gradient
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2880 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2881 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2882 % Author: John D'Errico
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2883 % e-mail: woodchips@rochester.rr.com
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2884 % Release: 1.0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2885 % Release date: 2/9/2007
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2886
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2887 % get the size of x0 so we can reshape
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2888 % later.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2889 sx = size(x0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2890
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2891 % total number of derivatives we will need to take
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2892 nx = numel(x0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2893
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2894 grad = zeros(1,nx);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2895 err = grad;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2896 finaldelta = grad;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2897 for ind = 1:nx
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2898 [grad(ind),err(ind),finaldelta(ind)] = derivest( ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2899 @(xi) fun(swapelement(x0,ind,xi)), ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2900 x0(ind),'deriv',1,'vectorized','no', ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2901 'methodorder',2);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2902 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2903
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2904 end % mainline function end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2905
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2906
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2907 function [HD,err,finaldelta] = hessdiag(fun,x0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2908 % HESSDIAG: diagonal elements of the Hessian matrix (vector of second partials)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2909 % usage: [HD,err,finaldelta] = hessdiag(fun,x0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2910 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2911 % When all that you want are the diagonal elements of the hessian
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2912 % matrix, it will be more efficient to call HESSDIAG than HESSIAN.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2913 % HESSDIAG uses DERIVEST to provide both second derivative estimates
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2914 % and error estimates. fun needs not be vectorized.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2915 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2916 % arguments: (input)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2917 % fun - SCALAR analytical function to differentiate.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2918 % fun must be a function of the vector or array x0.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2919 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2920 % x0 - vector location at which to differentiate fun
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2921 % If x0 is an nxm array, then fun is assumed to be
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2922 % a function of n*m variables.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2923 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2924 % arguments: (output)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2925 % HD - vector of second partial derivatives of fun.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2926 % These are the diagonal elements of the Hessian
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2927 % matrix, evaluated at x0.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2928 % HD will be a row vector of length numel(x0).
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2929 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2930 % err - vector of error estimates corresponding to
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2931 % each second partial derivative in HD.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2932 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2933 % finaldelta - vector of final step sizes chosen for
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2934 % each second partial derivative.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2935 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2936 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2937 % Example usage:
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2938 % [HD,err] = hessdiag(@(x) x(1) + x(2)^2 + x(3)^3,[1 2 3])
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2939 % HD =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2940 % 0 2 18
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2941 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2942 % err =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2943 % 0 0 0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2944 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2945 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2946 % See also: derivest, gradient, gradest
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2947 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2948 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2949 % Author: John D'Errico
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2950 % e-mail: woodchips@rochester.rr.com
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2951 % Release: 1.0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2952 % Release date: 2/9/2007
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2953
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2954 % get the size of x0 so we can reshape
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2955 % later.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2956 sx = size(x0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2957
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2958 % total number of derivatives we will need to take
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2959 nx = numel(x0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2960
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2961 HD = zeros(1,nx);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2962 err = HD;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2963 finaldelta = HD;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2964 for ind = 1:nx
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2965 [HD(ind),err(ind),finaldelta(ind)] = derivest( ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2966 @(xi) fun(swapelement(x0,ind,xi)), ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2967 x0(ind),'deriv',2,'vectorized','no');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2968 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2969
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2970 end % mainline function end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2971
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2972
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2973 function [hess,err] = hessian(fun,x0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2974 % hessian: estimate elements of the Hessian matrix (array of 2nd partials)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2975 % usage: [hess,err] = hessian(fun,x0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2976 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2977 % Hessian is NOT a tool for frequent use on an expensive
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2978 % to evaluate objective function, especially in a large
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2979 % number of dimensions. Its computation will use roughly
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2980 % O(6*n^2) function evaluations for n parameters.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2981 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2982 % arguments: (input)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2983 % fun - SCALAR analytical function to differentiate.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2984 % fun must be a function of the vector or array x0.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2985 % fun does not need to be vectorized.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2986 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2987 % x0 - vector location at which to compute the Hessian.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2988 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2989 % arguments: (output)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2990 % hess - nxn symmetric array of second partial derivatives
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2991 % of fun, evaluated at x0.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2992 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2993 % err - nxn array of error estimates corresponding to
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2994 % each second partial derivative in hess.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2995 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2996 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2997 % Example usage:
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2998 % Rosenbrock function, minimized at [1,1]
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 2999 % rosen = @(x) (1-x(1)).^2 + 105*(x(2)-x(1).^2).^2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3000 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3001 % [h,err] = hessian(rosen,[1 1])
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3002 % h =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3003 % 842 -420
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3004 % -420 210
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3005 % err =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3006 % 1.0662e-12 4.0061e-10
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3007 % 4.0061e-10 2.6654e-13
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3008 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3009 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3010 % Example usage:
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3011 % cos(x-y), at (0,0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3012 % Note: this hessian matrix will be positive semi-definite
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3013 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3014 % hessian(@(xy) cos(xy(1)-xy(2)),[0 0])
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3015 % ans =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3016 % -1 1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3017 % 1 -1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3018 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3019 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3020 % See also: derivest, gradient, gradest, hessdiag
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3021 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3022 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3023 % Author: John D'Errico
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3024 % e-mail: woodchips@rochester.rr.com
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3025 % Release: 1.0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3026 % Release date: 2/10/2007
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3027
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3028 % parameters that we might allow to change
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3029 params.StepRatio = 2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3030 params.RombergTerms = 3;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3031
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3032 % get the size of x0 so we can reshape
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3033 % later.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3034 sx = size(x0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3035
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3036 % was a string supplied?
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3037 if ischar(fun)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3038 fun = str2func(fun);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3039 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3040
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3041 % total number of derivatives we will need to take
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3042 nx = length(x0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3043
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3044 % get the diagonal elements of the hessian (2nd partial
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3045 % derivatives wrt each variable.)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3046 [hess,err] = hessdiag(fun,x0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3047
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3048 % form the eventual hessian matrix, stuffing only
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3049 % the diagonals for now.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3050 hess = diag(hess);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3051 err = diag(err);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3052 if nx<2
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3053 % the hessian matrix is 1x1. all done
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3054 return
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3055 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3056
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3057 % get the gradient vector. This is done only to decide
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3058 % on intelligent step sizes for the mixed partials
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3059 [grad,graderr,stepsize] = gradest(fun,x0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3060
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3061 % Get params.RombergTerms+1 estimates of the upper
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3062 % triangle of the hessian matrix
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3063 dfac = params.StepRatio.^(-(0:params.RombergTerms)');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3064 for i = 2:nx
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3065 for j = 1:(i-1)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3066 dij = zeros(params.RombergTerms+1,1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3067 for k = 1:(params.RombergTerms+1)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3068 dij(k) = fun(x0 + swap2(zeros(sx),i, ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3069 dfac(k)*stepsize(i),j,dfac(k)*stepsize(j))) + ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3070 fun(x0 + swap2(zeros(sx),i, ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3071 -dfac(k)*stepsize(i),j,-dfac(k)*stepsize(j))) - ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3072 fun(x0 + swap2(zeros(sx),i, ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3073 dfac(k)*stepsize(i),j,-dfac(k)*stepsize(j))) - ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3074 fun(x0 + swap2(zeros(sx),i, ...
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3075 -dfac(k)*stepsize(i),j,dfac(k)*stepsize(j)));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3076
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3077 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3078 dij = dij/4/prod(stepsize([i,j]));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3079 dij = dij./(dfac.^2);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3080
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3081 % Romberg extrapolation step
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3082 [hess(i,j),err(i,j)] = rombextrap(params.StepRatio,dij,[2 4]);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3083 hess(j,i) = hess(i,j);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3084 err(j,i) = err(i,j);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3085 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3086 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3087
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3088
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3089 end % mainline function end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3090
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3091
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3092
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3093 % ============================================
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3094 % subfunction - romberg extrapolation
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3095 % ============================================
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3096 function [der_romb,errest] = rombextrap(StepRatio,der_init,rombexpon)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3097 % do romberg extrapolation for each estimate
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3098 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3099 % StepRatio - Ratio decrease in step
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3100 % der_init - initial derivative estimates
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3101 % rombexpon - higher order terms to cancel using the romberg step
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3102 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3103 % der_romb - derivative estimates returned
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3104 % errest - error estimates
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3105 % amp - noise amplification factor due to the romberg step
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3106
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3107 srinv = 1/StepRatio;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3108
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3109 % do nothing if no romberg terms
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3110 nexpon = length(rombexpon);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3111 rmat = ones(nexpon+2,nexpon+1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3112 switch nexpon
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3113 case 0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3114 % rmat is simple: ones(2,1)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3115 case 1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3116 % only one romberg term
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3117 rmat(2,2) = srinv^rombexpon;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3118 rmat(3,2) = srinv^(2*rombexpon);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3119 case 2
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3120 % two romberg terms
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3121 rmat(2,2:3) = srinv.^rombexpon;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3122 rmat(3,2:3) = srinv.^(2*rombexpon);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3123 rmat(4,2:3) = srinv.^(3*rombexpon);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3124 case 3
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3125 % three romberg terms
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3126 rmat(2,2:4) = srinv.^rombexpon;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3127 rmat(3,2:4) = srinv.^(2*rombexpon);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3128 rmat(4,2:4) = srinv.^(3*rombexpon);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3129 rmat(5,2:4) = srinv.^(4*rombexpon);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3130 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3131
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3132 % qr factorization used for the extrapolation as well
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3133 % as the uncertainty estimates
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3134 [qromb,rromb] = qr(rmat,0);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3135
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3136 % the noise amplification is further amplified by the Romberg step.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3137 % amp = cond(rromb);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3138
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3139 % this does the extrapolation to a zero step size.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3140 ne = length(der_init);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3141 rhs = vec2mat(der_init,nexpon+2,max(1,ne - (nexpon+2)));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3142 rombcoefs = rromb\(qromb.'*rhs);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3143 der_romb = rombcoefs(1,:).';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3144
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3145 % uncertainty estimate of derivative prediction
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3146 s = sqrt(sum((rhs - rmat*rombcoefs).^2,1));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3147 rinv = rromb\eye(nexpon+1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3148 cov1 = sum(rinv.^2,2); % 1 spare dof
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3149 errest = s.'*12.7062047361747*sqrt(cov1(1));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3150
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3151 end % rombextrap
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3152
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3153
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3154 % ============================================
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3155 % subfunction - vec2mat
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3156 % ============================================
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3157 function mat = vec2mat(vec,n,m)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3158 % forms the matrix M, such that M(i,j) = vec(i+j-1)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3159 [i,j] = ndgrid(1:n,0:m-1);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3160 ind = i+j;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3161 mat = vec(ind);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3162 if n==1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3163 mat = mat.';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3164 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3165
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3166 end % vec2mat
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3167
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3168
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3169 % ============================================
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3170 % subfunction - fdamat
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3171 % ============================================
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3172 function mat = fdamat(sr,parity,nterms)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3173 % Compute matrix for fda derivation.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3174 % parity can be
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3175 % 0 (one sided, all terms included but zeroth order)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3176 % 1 (only odd terms included)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3177 % 2 (only even terms included)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3178 % nterms - number of terms
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3179
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3180 % sr is the ratio between successive steps
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3181 srinv = 1./sr;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3182
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3183 switch parity
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3184 case 0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3185 % single sided rule
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3186 [i,j] = ndgrid(1:nterms);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3187 c = 1./factorial(1:nterms);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3188 mat = c(j).*srinv.^((i-1).*j);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3189 case 1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3190 % odd order derivative
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3191 [i,j] = ndgrid(1:nterms);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3192 c = 1./factorial(1:2:(2*nterms));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3193 mat = c(j).*srinv.^((i-1).*(2*j-1));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3194 case 2
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3195 % even order derivative
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3196 [i,j] = ndgrid(1:nterms);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3197 c = 1./factorial(2:2:(2*nterms));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3198 mat = c(j).*srinv.^((i-1).*(2*j));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3199 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3200
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3201 end % fdamat
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3202
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3203
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3204 % ============================================
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3205 % subfunction - check_params
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3206 % ============================================
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3207 function par = check_params(par)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3208 % check the parameters for acceptability
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3209 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3210 % Defaults
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3211 % par.DerivativeOrder = 1;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3212 % par.MethodOrder = 2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3213 % par.Style = 'central';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3214 % par.RombergTerms = 2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3215 % par.FixedStep = [];
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3216
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3217 % DerivativeOrder == 1 by default
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3218 if isempty(par.DerivativeOrder)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3219 par.DerivativeOrder = 1;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3220 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3221 if (length(par.DerivativeOrder)>1) || ~ismember(par.DerivativeOrder,1:4)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3222 error 'DerivativeOrder must be scalar, one of [1 2 3 4].'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3223 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3224 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3225
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3226 % MethodOrder == 2 by default
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3227 if isempty(par.MethodOrder)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3228 par.MethodOrder = 2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3229 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3230 if (length(par.MethodOrder)>1) || ~ismember(par.MethodOrder,[1 2 3 4])
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3231 error 'MethodOrder must be scalar, one of [1 2 3 4].'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3232 elseif ismember(par.MethodOrder,[1 3]) && (par.Style(1)=='c')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3233 error 'MethodOrder==1 or 3 is not possible with central difference methods'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3234 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3235 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3236
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3237 % style is char
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3238 valid = {'central', 'forward', 'backward'};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3239 if isempty(par.Style)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3240 par.Style = 'central';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3241 elseif ~ischar(par.Style)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3242 error 'Invalid Style: Must be character'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3243 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3244 ind = find(strncmpi(par.Style,valid,length(par.Style)));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3245 if (length(ind)==1)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3246 par.Style = valid{ind};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3247 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3248 error(['Invalid Style: ',par.Style])
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3249 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3250
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3251 % vectorized is char
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3252 valid = {'yes', 'no'};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3253 if isempty(par.Vectorized)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3254 par.Vectorized = 'yes';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3255 elseif ~ischar(par.Vectorized)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3256 error 'Invalid Vectorized: Must be character'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3257 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3258 ind = find(strncmpi(par.Vectorized,valid,length(par.Vectorized)));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3259 if (length(ind)==1)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3260 par.Vectorized = valid{ind};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3261 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3262 error(['Invalid Vectorized: ',par.Vectorized])
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3263 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3264
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3265 % RombergTerms == 2 by default
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3266 if isempty(par.RombergTerms)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3267 par.RombergTerms = 2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3268 else
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3269 if (length(par.RombergTerms)>1) || ~ismember(par.RombergTerms,0:3)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3270 error 'RombergTerms must be scalar, one of [0 1 2 3].'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3271 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3272 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3273
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3274 % FixedStep == [] by default
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3275 if (length(par.FixedStep)>1) || (~isempty(par.FixedStep) && (par.FixedStep<=0))
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3276 error 'FixedStep must be empty or a scalar, >0.'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3277 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3278
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3279 % MaxStep == 10 by default
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3280 if isempty(par.MaxStep)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3281 par.MaxStep = 10;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3282 elseif (length(par.MaxStep)>1) || (par.MaxStep<=0)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3283 error 'MaxStep must be empty or a scalar, >0.'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3284 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3285
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3286 end % check_params
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3287
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3288
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3289 % ============================================
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3290 % Included subfunction - parse_pv_pairs
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3291 % ============================================
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3292 function params=parse_pv_pairs(params,pv_pairs)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3293 % parse_pv_pairs: parses sets of property value pairs, allows defaults
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3294 % usage: params=parse_pv_pairs(default_params,pv_pairs)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3295 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3296 % arguments: (input)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3297 % default_params - structure, with one field for every potential
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3298 % property/value pair. Each field will contain the default
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3299 % value for that property. If no default is supplied for a
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3300 % given property, then that field must be empty.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3301 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3302 % pv_array - cell array of property/value pairs.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3303 % Case is ignored when comparing properties to the list
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3304 % of field names. Also, any unambiguous shortening of a
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3305 % field/property name is allowed.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3306 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3307 % arguments: (output)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3308 % params - parameter struct that reflects any updated property/value
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3309 % pairs in the pv_array.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3310 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3311 % Example usage:
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3312 % First, set default values for the parameters. Assume we
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3313 % have four parameters that we wish to use optionally in
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3314 % the function examplefun.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3315 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3316 % - 'viscosity', which will have a default value of 1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3317 % - 'volume', which will default to 1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3318 % - 'pie' - which will have default value 3.141592653589793
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3319 % - 'description' - a text field, left empty by default
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3320 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3321 % The first argument to examplefun is one which will always be
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3322 % supplied.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3323 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3324 % function examplefun(dummyarg1,varargin)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3325 % params.Viscosity = 1;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3326 % params.Volume = 1;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3327 % params.Pie = 3.141592653589793
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3328 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3329 % params.Description = '';
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3330 % params=parse_pv_pairs(params,varargin);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3331 % params
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3332 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3333 % Use examplefun, overriding the defaults for 'pie', 'viscosity'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3334 % and 'description'. The 'volume' parameter is left at its default.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3335 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3336 % examplefun(rand(10),'vis',10,'pie',3,'Description','Hello world')
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3337 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3338 % params =
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3339 % Viscosity: 10
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3340 % Volume: 1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3341 % Pie: 3
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3342 % Description: 'Hello world'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3343 %
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3344 % Note that capitalization was ignored, and the property 'viscosity'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3345 % was truncated as supplied. Also note that the order the pairs were
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3346 % supplied was arbitrary.
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3347
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3348 npv = length(pv_pairs);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3349 n = npv/2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3350
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3351 if n~=floor(n)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3352 error 'Property/value pairs must come in PAIRS.'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3353 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3354 if n<=0
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3355 % just return the defaults
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3356 return
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3357 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3358
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3359 if ~isstruct(params)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3360 error 'No structure for defaults was supplied'
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3361 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3362
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3363 % there was at least one pv pair. process any supplied
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3364 propnames = fieldnames(params);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3365 lpropnames = lower(propnames);
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3366 for i=1:n
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3367 p_i = lower(pv_pairs{2*i-1});
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3368 v_i = pv_pairs{2*i};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3369
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3370 ind = strmatch(p_i,lpropnames,'exact');
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3371 if isempty(ind)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3372 ind = find(strncmp(p_i,lpropnames,length(p_i)));
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3373 if isempty(ind)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3374 error(['No matching property found for: ',pv_pairs{2*i-1}])
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3375 elseif length(ind)>1
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3376 error(['Ambiguous property name: ',pv_pairs{2*i-1}])
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3377 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3378 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3379 p_i = propnames{ind};
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3380
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3381 % override the corresponding default in params
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3382 params = setfield(params,p_i,v_i); %#ok
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3383
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3384 end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3385
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3386 end % parse_pv_pairs
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3387
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3388
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3389 % =======================================
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3390 % sub-functions
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3391 % =======================================
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3392 function vec = swapelement(vec,ind,val)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3393 % swaps val as element ind, into the vector vec
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3394 vec(ind) = val;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3395
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3396 end % sub-function end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3397
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3398
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3399 % =======================================
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3400 % sub-functions
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3401 % =======================================
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3402 function vec = swap2(vec,ind1,val1,ind2,val2)
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3403 % swaps val as element ind, into the vector vec
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3404 vec(ind1) = val1;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3405 vec(ind2) = val2;
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3406
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3407 end % sub-function end
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3408
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3409 % End of DERIVEST SUITE
Daniele Nicolodi <nicolodi@science.unitn.it>
parents:
diff
changeset
+ − 3410