177 int ii = correspdim[0];
178 matrix[ii][ii] = 1. / matrix[ii][ii];
180 }
else if (dim == 2) {
181 int ii = correspdim[0];
182 int jj = correspdim[1];
183 double determinant = -matrix[jj][ii] * matrix[ii][jj] + matrix[ii][ii] * matrix[jj][jj];
186 double i00 = matrix[ii][ii];
187 matrix[ii][ii] = matrix[jj][jj] / determinant;
188 matrix[jj][jj] = i00 / determinant;
189 matrix[ii][jj] = -matrix[ii][jj] / determinant;
190 matrix[jj][ii] = matrix[ii][jj];
192 }
else if (dim == 3) {
193 double sm12 = matrix[0][1] * matrix[0][1];
194 double sm13 = matrix[0][2] * matrix[0][2];
195 double sm23 = matrix[1][2] * matrix[1][2];
196 double determinant = matrix[0][0] * matrix[1][1] * matrix[2][2] - matrix[0][0] * sm23 - sm12 * matrix[2][2] +
197 2. * matrix[0][1] * matrix[0][2] * matrix[1][2] - matrix[1][1] * sm13;
201 double i00 = matrix[1][1] * matrix[2][2] - sm23;
202 double i11 = matrix[0][0] * matrix[2][2] - sm13;
203 double i22 = matrix[0][0] * matrix[1][1] - sm12;
205 matrix[1][0] = (matrix[0][2] * matrix[1][2] - matrix[2][2] * matrix[0][1]) / determinant;
206 matrix[2][0] = (matrix[0][1] * matrix[1][2] - matrix[0][2] * matrix[1][1]) / determinant;
207 matrix[2][1] = (matrix[0][1] * matrix[0][2] - matrix[0][0] * matrix[1][2]) / determinant;
208 matrix[0][1] = matrix[1][0];
209 matrix[0][2] = matrix[2][0];
210 matrix[1][2] = matrix[2][1];
211 matrix[0][0] = i00 / determinant;
212 matrix[1][1] = i11 / determinant;
213 matrix[2][2] = i22 / determinant;
218 printf(
"this is not a 1x1 or 2x2 or 3x3 matrix\n");
224 W[0][3] * W[0][3] * W[1][2] * W[1][2] - 2. * W[0][2] * W[0][3] * W[1][2] * W[1][3] + W[0][2] * W[0][2] * W[1][3] * W[1][3] -
225 W[0][3] * W[0][3] * W[1][1] * W[2][2] + 2. * W[0][1] * W[0][3] * W[1][3] * W[2][2] - W[0][0] * W[1][3] * W[1][3] * W[2][2] +
226 2. * W[0][2] * W[0][3] * W[1][1] * W[2][3] - 2. * W[0][1] * W[0][3] * W[1][2] * W[2][3] -
227 2. * W[0][1] * W[0][2] * W[1][3] * W[2][3] + 2. * W[0][0] * W[1][2] * W[1][3] * W[2][3] + W[0][1] * W[0][1] * W[2][3] * W[2][3] -
228 W[0][0] * W[1][1] * W[2][3] * W[2][3] - W[0][2] * W[0][2] * W[1][1] * W[3][3] + 2. * W[0][1] * W[0][2] * W[1][2] * W[3][3] -
229 W[0][0] * W[1][2] * W[1][2] * W[3][3] - W[0][1] * W[0][1] * W[2][2] * W[3][3] + W[0][0] * W[1][1] * W[2][2] * W[3][3];
231 W[0][1] = W[3][0] * W[3][1] * W[2][2] - W[3][0] * W[2][1] * W[3][2] - W[2][0] * W[3][1] * W[3][2] + W[1][0] * W[3][2] * W[3][2] +
232 W[2][0] * W[2][1] * W[3][3] - W[1][0] * W[2][2] * W[3][3];
233 W[0][2] = -W[3][0] * W[2][1] * W[3][1] + W[2][0] * W[3][1] * W[3][1] + W[3][0] * W[1][1] * W[3][2] - W[1][0] * W[3][1] * W[3][2] -
234 W[2][0] * W[1][1] * W[3][3] + W[1][0] * W[2][1] * W[3][3];
235 W[0][3] = W[3][0] * W[2][1] * W[2][1] - W[2][0] * W[2][1] * W[3][1] - W[3][0] * W[1][1] * W[2][2] + W[1][0] * W[3][1] * W[2][2] +
236 W[2][0] * W[1][1] * W[3][2] - W[1][0] * W[2][1] * W[3][2];
237 W[1][2] = W[3][0] * W[3][0] * W[2][1] - W[2][0] * W[3][0] * W[3][1] - W[1][0] * W[3][0] * W[3][2] + W[0][0] * W[3][1] * W[3][2] +
238 W[1][0] * W[2][0] * W[3][3] - W[0][0] * W[2][1] * W[3][3];
240 W[1][3] = -W[2][0] * W[3][0] * W[2][1] + W[2][0] * W[2][0] * W[3][1] + W[1][0] * W[3][0] * W[2][2] - W[0][0] * W[3][1] * W[2][2] -
241 W[1][0] * W[2][0] * W[3][2] + W[0][0] * W[2][1] * W[3][2];
242 W[2][3] = W[2][0] * W[3][0] * W[1][1] - W[1][0] * W[3][0] * W[2][1] - W[1][0] * W[2][0] * W[3][1] + W[0][0] * W[2][1] * W[3][1] +
243 W[1][0] * W[1][0] * W[3][2] - W[0][0] * W[1][1] * W[3][2];
245 double W00 = -W[3][1] * W[3][1] * W[2][2] + 2. * W[2][1] * W[3][1] * W[3][2] - W[1][1] * W[3][2] * W[3][2] -
246 W[2][1] * W[2][1] * W[3][3] + W[1][1] * W[2][2] * W[3][3];
247 double W11 = -W[3][0] * W[3][0] * W[2][2] + 2. * W[2][0] * W[3][0] * W[3][2] - W[0][0] * W[3][2] * W[3][2] -
248 W[2][0] * W[2][0] * W[3][3] + W[0][0] * W[2][2] * W[3][3];
249 double W22 = -W[3][0] * W[3][0] * W[1][1] + 2. * W[1][0] * W[3][0] * W[3][1] - W[0][0] * W[3][1] * W[3][1] -
250 W[1][0] * W[1][0] * W[3][3] + W[0][0] * W[1][1] * W[3][3];
251 double W33 = -W[2][0] * W[2][0] * W[1][1] + 2. * W[1][0] * W[2][0] * W[2][1] - W[0][0] * W[2][1] * W[2][1] -
252 W[1][0] * W[1][0] * W[2][2] + W[0][0] * W[1][1] * W[2][2];
254 for (
int i = 0; i < 3; i++) {
255 for (
int j = 1; j < 4; j++) {
256 if (i >= j)
continue;
257 W[i][j] = W[i][j] / Determinant;
261 W[0][0] = W00 / Determinant;
262 W[1][1] = W11 / Determinant;
263 W[2][2] = W22 / Determinant;
264 W[3][3] = W33 / Determinant;
294 double *result)
const {
296 const int maxIter = 7;
298 double fitTolerance0 = 0.1;
299 double fitTolerance1 = 0.01;
302 for (
int j = 0; j < 3; j++) p0[j][0] = initValues[j];
308 for (
int i = 0; i < 4; i++) {
313 W[0][1] = 0.03 * ex * ex;
314 W[0][2] = -0.411 * ex * ex;
315 W[0][3] = -0.188 * ex * ex;
316 W[1][2] = 0.0275 * ex * ex;
317 W[1][3] = -0.4303 * ex * ex;
318 W[2][3] = 0. * ex * ex;
335 for (
int i = 0; i < 4; ++i) {
337 for (
int j = 0; j < 3; ++j) {
A[i][j] = 0.; }
344 bool converged =
false;
345 double amplitudeChangeOld = 0.;
346 bool diverganceCandidate =
false;
354 double residFactor[3][4];
356 for (
int i = 0; i < 3; ++i) {
357 for (
int j = 0; j < 4; ++j) {
358 if (j < 3) { weight[i][j] = 0.; }
359 residFactor[i][j] = 0.;
366 while (!converged && counter < maxIter)
373 double helpmatrix[4][3];
374 for (
int i = 0; i < 4; ++i) {
375 for (
int j = 0; j < 3; ++j) { helpmatrix[i][j] = 0.; }
378 for (
int i = 0; i < imeas; i++) {
380 for (
int j = 0; j < ipar; j++) {
382 for (
int k = 0; k < imeas; k++) {
384 helpmatrix[ii][jj] += W[ii][kk] *
A[kk][jj];
388 for (
int i = 0; i < ipar; i++) {
390 for (
int j = i; j < ipar; j++) {
393 for (
int k = 0; k < imeas; k++) {
395 weight[ii][jj] +=
A[kk][ii] * helpmatrix[kk][jj];
398 weight[jj][ii] = weight[ii][jj];
407 double helpmatrix2[3][4];
408 for (
int i = 0; i < 3; ++i) {
409 for (
int j = 0; j < 4; ++j) { helpmatrix2[i][j] = 0.; }
412 for (
int i = 0; i < ipar; i++) {
414 for (
int j = 0; j < imeas; j++) {
416 for (
int k = 0; k < imeas; k++) {
418 helpmatrix2[ii][jj] +=
A[kk][ii] * W[kk][jj];
423 for (
int i = 0; i < ipar; i++) {
425 for (
int j = 0; j < imeas; j++) {
427 residFactor[ii][jj] = 0.;
428 for (
int k = 0; k < ipar; k++) {
430 residFactor[ii][jj] += weight[ii][kk] * helpmatrix2[kk][jj];
437 for (
int i = 0; i < 3; ++i) { paramDiff[i] = 0.; }
439 for (
int i = 0; i < ipar; i++) {
443 for (
int j = 0; j < imeas; j++) {
445 paramDiff[ii] += residFactor[ii][jj] * (m[jj][0] - fp[jj][0]);
447 p0[ii][0] += paramDiff[ii];
449 std::cout <<
"##### " << p0[0][0] <<
" " << p0[1][0] <<
" " << p0[2][0] << std::endl;
453 if (peakingTime < -0.5 || peakingTime > 3.) p0[1][0] = initValues[1];
455 if (p0[0][0] < 0.) p0[0][0] = initValues[0];
456 double amplitudeChangeNew = std::abs(paramDiff[0]);
457 if (std::abs(paramDiff[0]) < fitTolerance0 && std::abs(paramDiff[1]) < fitTolerance1) {
462 for (
int i = 0; i < 4; ++i) { residual[i] = 0.; }
464 for (
int i = 0; i < imeas; i++) {
466 residual[i] = m[ii][0] - fp[ii][0];
470 double helpmatrixchi2[4][1];
471 for (
int i = 0; i < 4; ++i) { helpmatrixchi2[i][0] = 0.; }
472 for (
int i = 0; i < imeas; i++) {
474 for (
int k = 0; k < imeas; k++) {
476 helpmatrixchi2[ii][0] += W[ii][kk] * residual[kk];
479 for (
int k = 0; k < imeas; k++) {
481 tmpChi2 += residual[kk] * helpmatrixchi2[kk][0];
486 }
else if (counter > 4 && (amplitudeChangeNew > 4. * amplitudeChangeOld)) {
487 if (diverganceCandidate) {
490 printf(
"%3.2f %3.2f %3.2f %3.2f\n ",
x[0],
x[1],
x[2],
x[3]);
491 printf(
"Diverging fit\n");
494 diverganceCandidate =
true;
505 if (p0[0][0] < 20.) {
507 fitTolerance1 = 0.05;
509 amplitudeChangeOld = amplitudeChangeNew;
522 result[0] = p0[0][0];
524 result[2] = p0[2][0];
526 if (counter == maxIter)
return 3;
int TheFitter(double *x, const double ex, const double *initValues, int imeas, int *meas, int ipar, int *par, double *chi2, double *result) const