178 int ii = correspdim[0];
179 matrix[ii][ii] = 1. / matrix[ii][ii];
181 }
else if (dim == 2) {
182 int ii = correspdim[0];
183 int jj = correspdim[1];
184 double determinant = -matrix[jj][ii] * matrix[ii][jj] + matrix[ii][ii] * matrix[jj][jj];
187 double i00 = matrix[ii][ii];
188 matrix[ii][ii] = matrix[jj][jj] / determinant;
189 matrix[jj][jj] = i00 / determinant;
190 matrix[ii][jj] = -matrix[ii][jj] / determinant;
191 matrix[jj][ii] = matrix[ii][jj];
193 }
else if (dim == 3) {
194 double sm12 = matrix[0][1] * matrix[0][1];
195 double sm13 = matrix[0][2] * matrix[0][2];
196 double sm23 = matrix[1][2] * matrix[1][2];
197 double determinant = matrix[0][0] * matrix[1][1] * matrix[2][2] - matrix[0][0] * sm23 - sm12 * matrix[2][2] +
198 2. * matrix[0][1] * matrix[0][2] * matrix[1][2] - matrix[1][1] * sm13;
202 double i00 = matrix[1][1] * matrix[2][2] - sm23;
203 double i11 = matrix[0][0] * matrix[2][2] - sm13;
204 double i22 = matrix[0][0] * matrix[1][1] - sm12;
206 matrix[1][0] = (matrix[0][2] * matrix[1][2] - matrix[2][2] * matrix[0][1]) / determinant;
207 matrix[2][0] = (matrix[0][1] * matrix[1][2] - matrix[0][2] * matrix[1][1]) / determinant;
208 matrix[2][1] = (matrix[0][1] * matrix[0][2] - matrix[0][0] * matrix[1][2]) / determinant;
209 matrix[0][1] = matrix[1][0];
210 matrix[0][2] = matrix[2][0];
211 matrix[1][2] = matrix[2][1];
212 matrix[0][0] = i00 / determinant;
213 matrix[1][1] = i11 / determinant;
214 matrix[2][2] = i22 / determinant;
219 printf(
"this is not a 1x1 or 2x2 or 3x3 matrix\n");
225 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] -
226 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] +
227 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] -
228 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] -
229 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] -
230 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];
232 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] +
233 W[2][0] * W[2][1] * W[3][3] - W[1][0] * W[2][2] * W[3][3];
234 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] -
235 W[2][0] * W[1][1] * W[3][3] + W[1][0] * W[2][1] * W[3][3];
236 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] +
237 W[2][0] * W[1][1] * W[3][2] - W[1][0] * W[2][1] * W[3][2];
238 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] +
239 W[1][0] * W[2][0] * W[3][3] - W[0][0] * W[2][1] * W[3][3];
241 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] -
242 W[1][0] * W[2][0] * W[3][2] + W[0][0] * W[2][1] * W[3][2];
243 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] +
244 W[1][0] * W[1][0] * W[3][2] - W[0][0] * W[1][1] * W[3][2];
246 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] -
247 W[2][1] * W[2][1] * W[3][3] + W[1][1] * W[2][2] * W[3][3];
248 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] -
249 W[2][0] * W[2][0] * W[3][3] + W[0][0] * W[2][2] * W[3][3];
250 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] -
251 W[1][0] * W[1][0] * W[3][3] + W[0][0] * W[1][1] * W[3][3];
252 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] -
253 W[1][0] * W[1][0] * W[2][2] + W[0][0] * W[1][1] * W[2][2];
255 for (
int i = 0; i < 3; i++) {
256 for (
int j = 1; j < 4; j++) {
257 if (i >= j)
continue;
258 W[i][j] = W[i][j] / Determinant;
262 W[0][0] = W00 / Determinant;
263 W[1][1] = W11 / Determinant;
264 W[2][2] = W22 / Determinant;
265 W[3][3] = W33 / Determinant;
297 const int maxIter = 7;
299 double fitTolerance0 = 0.1;
300 double fitTolerance1 = 0.01;
303 for (
int j = 0; j < 3; j++) p0[j][0] = initValues[j];
309 for (
int i = 0; i < 4; i++) {
314 W[0][1] = 0.03 * ex * ex;
315 W[0][2] = -0.411 * ex * ex;
316 W[0][3] = -0.188 * ex * ex;
317 W[1][2] = 0.0275 * ex * ex;
318 W[1][3] = -0.4303 * ex * ex;
319 W[2][3] = 0. * ex * ex;
336 for (
int i = 0; i < 4; ++i) {
338 for (
int j = 0; j < 3; ++j) {
A[i][j] = 0.; }
345 bool converged =
false;
346 double amplitudeChangeOld = 0.;
347 bool diverganceCandidate =
false;
355 double residFactor[3][4];
357 for (
int i = 0; i < 3; ++i) {
358 for (
int j = 0; j < 4; ++j) {
359 if (j < 3) { weight[i][j] = 0.; }
360 residFactor[i][j] = 0.;
367 while (!converged && counter < maxIter)
374 double helpmatrix[4][3];
375 for (
int i = 0; i < 4; ++i) {
376 for (
int j = 0; j < 3; ++j) { helpmatrix[i][j] = 0.; }
379 for (
int i = 0; i < imeas; i++) {
381 for (
int j = 0; j < ipar; j++) {
383 for (
int k = 0; k < imeas; k++) {
385 helpmatrix[ii][jj] += W[ii][kk] *
A[kk][jj];
389 for (
int i = 0; i < ipar; i++) {
391 for (
int j = i; j < ipar; j++) {
394 for (
int k = 0; k < imeas; k++) {
396 weight[ii][jj] +=
A[kk][ii] * helpmatrix[kk][jj];
399 weight[jj][ii] = weight[ii][jj];
408 double helpmatrix2[3][4];
409 for (
int i = 0; i < 3; ++i) {
410 for (
int j = 0; j < 4; ++j) { helpmatrix2[i][j] = 0.; }
413 for (
int i = 0; i < ipar; i++) {
415 for (
int j = 0; j < imeas; j++) {
417 for (
int k = 0; k < imeas; k++) {
419 helpmatrix2[ii][jj] +=
A[kk][ii] * W[kk][jj];
424 for (
int i = 0; i < ipar; i++) {
426 for (
int j = 0; j < imeas; j++) {
428 residFactor[ii][jj] = 0.;
429 for (
int k = 0; k < ipar; k++) {
431 residFactor[ii][jj] += weight[ii][kk] * helpmatrix2[kk][jj];
438 for (
int i = 0; i < 3; ++i) { paramDiff[i] = 0.; }
440 for (
int i = 0; i < ipar; i++) {
444 for (
int j = 0; j < imeas; j++) {
446 paramDiff[ii] += residFactor[ii][jj] * (m[jj][0] - fp[jj][0]);
448 p0[ii][0] += paramDiff[ii];
450 std::cout <<
"##### " << p0[0][0] <<
" " << p0[1][0] <<
" " << p0[2][0] << std::endl;
454 if (peakingTime < -0.5 || peakingTime > 3.) p0[1][0] = initValues[1];
456 if (p0[0][0] < 0.) p0[0][0] = initValues[0];
457 double amplitudeChangeNew = std::abs(paramDiff[0]);
458 if (std::abs(paramDiff[0]) < fitTolerance0 && std::abs(paramDiff[1]) < fitTolerance1) {
463 for (
int i = 0; i < 4; ++i) { residual[i] = 0.; }
465 for (
int i = 0; i < imeas; i++) {
467 residual[i] = m[ii][0] - fp[ii][0];
471 double helpmatrixchi2[4][1];
472 for (
int i = 0; i < 4; ++i) { helpmatrixchi2[i][0] = 0.; }
473 for (
int i = 0; i < imeas; i++) {
475 for (
int k = 0; k < imeas; k++) {
477 helpmatrixchi2[ii][0] += W[ii][kk] * residual[kk];
480 for (
int k = 0; k < imeas; k++) {
482 tmpChi2 += residual[kk] * helpmatrixchi2[kk][0];
487 }
else if (counter > 4 && (amplitudeChangeNew > 4. * amplitudeChangeOld)) {
488 if (diverganceCandidate) {
491 printf(
"%3.2f %3.2f %3.2f %3.2f\n ",
x[0],
x[1],
x[2],
x[3]);
492 printf(
"Diverging fit\n");
495 diverganceCandidate =
true;
506 if (p0[0][0] < 20.) {
508 fitTolerance1 = 0.05;
510 amplitudeChangeOld = amplitudeChangeNew;
527 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