/** 1D Support plane analysis with instrument response. See GCI_SPA_1D_marquardt. */ int GCI_SPA_1D_marquardt_instr( float xincr, float y[], int ndata, int fit_start, int fit_end, float instr[], int ninstr, noise_type noise, float sig[], float param[], int paramfree[], int nparam, restrain_type restrain, float chisq_delta, void (*fitfunc)(float, float [], float *, float [], int), int spa_param, int spa_nvalues, float spa_low, float spa_high, float chisq[], float chisq_target, void (*progressfunc)(float)) { int i, j, ret; float *fitted, *residuals, **covar, **alpha; float param_copy[MAXFIT]; int paramfree_copy[MAXFIT]; if (spa_param < 0 || spa_param >= nparam) /* and so nparam > 0, too */ return -1; if (spa_nvalues < 2) return -2; if ((fitted = (float *) malloc((size_t)ndata * sizeof(float))) == NULL) return -3; if ((residuals = (float *) malloc((size_t)ndata * sizeof(float))) == NULL) { free(fitted); return -3; } if ((covar = GCI_ecf_matrix(nparam, nparam)) == NULL) { free(fitted); free(residuals); return -3; } if ((alpha = GCI_ecf_matrix(nparam, nparam)) == NULL) { free(fitted); free(residuals); GCI_ecf_free_matrix(covar); return -3; } for (j=0; j<nparam; j++) paramfree_copy[j] = paramfree[j]; paramfree_copy[spa_param] = 0; /* we fix the parameter we are analysing */ for (i=0; i<spa_nvalues; i++) { /* Initialise parameter array each time */ for (j=0; j<nparam; j++) param_copy[j] = param[j]; /* Set the parameter we are analysing */ param_copy[spa_param] = spa_low + (spa_high - spa_low) * (float)i / (float)(spa_nvalues - 1); ret = GCI_marquardt_fitting_engine(xincr, y, ndata, fit_start, fit_end, instr, ninstr, noise, NULL, param_copy, paramfree_copy, nparam, restrain, fitfunc, fitted, residuals, &chisq[i], covar, alpha, NULL, chisq_target, chisq_delta, 0); if (progressfunc) progressfunc ((float)i/(float)(spa_nvalues-1)); if (ret < 0) chisq[i] = -1; } free(fitted); free(residuals); GCI_ecf_free_matrix(covar); GCI_ecf_free_matrix(alpha); GCI_marquardt_cleanup(); return 0; }
/** 2D Support plane analysis with instrument response. See GCI_SPA_2D_marquardt. */ int GCI_SPA_2D_marquardt_instr( float xincr, float y[], int ndata, int fit_start, int fit_end, float instr[], int ninstr, noise_type noise, float sig[], float param[], int paramfree[], int nparam, restrain_type restrain, float chisq_delta, void (*fitfunc)(float, float [], float *, float [], int), int spa_param1, int spa_nvalues1, float spa_low1, float spa_high1, int spa_param2, int spa_nvalues2, float spa_low2, float spa_high2, float **chisq, float chisq_target, void (*progressfunc)(float)) { int i1, i2, j, ret, progress, total; float *fitted, *residuals, **covar, **alpha; float param_copy[MAXFIT]; int paramfree_copy[MAXFIT]; if (spa_param1 < 0 || spa_param1 >= nparam) /* and so nparam > 0, too */ return -1; if (spa_param2 < 0 || spa_param2 >= nparam) return -1; if (spa_param1 == spa_param2) return -1; if (spa_nvalues1 < 2 || spa_nvalues2 < 2) return -2; if ((fitted = (float *) malloc((size_t)ndata * sizeof(float))) == NULL) return -3; if ((residuals = (float *) malloc((size_t)ndata * sizeof(float))) == NULL) { free(fitted); return -3; } if ((covar = GCI_ecf_matrix(nparam, nparam)) == NULL) { free(fitted); free(residuals); return -3; } if ((alpha = GCI_ecf_matrix(nparam, nparam)) == NULL) { free(fitted); free(residuals); GCI_ecf_free_matrix(covar); return -3; } for (j=0; j<nparam; j++) paramfree_copy[j] = paramfree[j]; paramfree_copy[spa_param1] = 0; paramfree_copy[spa_param2] = 0; /* we fix the parameters we are analysing */ progress = 0; total = spa_nvalues1*spa_nvalues2; for (i1=0; i1<spa_nvalues1; i1++) { for (i2=0; i2<spa_nvalues2; i2++) { /* Initialise parameter array each time */ for (j=0; j<nparam; j++) param_copy[j] = param[j]; /* Set the parameters we are analysing */ param_copy[spa_param1] = spa_low1 + (spa_high1 - spa_low1) * (float)i1 / (float)(spa_nvalues1 - 1); param_copy[spa_param2] = spa_low2 + (spa_high2 - spa_low2) * (float)i2 / (float)(spa_nvalues2 - 1); ret = GCI_marquardt_fitting_engine(xincr, y, ndata, fit_start, fit_end, instr, ninstr, noise, NULL, param_copy, paramfree_copy, nparam, restrain, fitfunc, fitted, residuals, &chisq[i1][i2], covar, alpha, NULL, chisq_target, chisq_delta, 0); progress++; if (progressfunc) progressfunc ((float)progress/((float)(total-1))); if (ret < 0) chisq[i1][i2] = -1; } } free(fitted); free(residuals); GCI_ecf_free_matrix(covar); GCI_ecf_free_matrix(alpha); GCI_marquardt_cleanup(); return 0; }
// the next fn uses GCI_marquardt_instr() to fit repeatedly until chisq_target is met int nr_GCI_marquardt_fitting_engine(float xincr, float *trans, int ndata, int fit_start, int fit_end, float prompt[], int nprompt, //TODO ARG is this actually instr[] & ninstr? noise_type noise, float sig[], float param[], int paramfree[], int nparam, restrain_type restrain, fit_type fit, //TODO ARG void (*fitfunc)(float, float [], float *, float [], int), float *fitted, float *residuals, float *chisq) { //, //float **covar, float **alpha, float **erraxes, //float chisq_target, int chisq_percent) { void (*fitfunc)(float, float [], float *, float[], int) = NULL; //printf("Incoming params:\n"); //int i; //for (i = 0; i < nparam; ++i) { //printf(" %g ", param[i]); //} //printf("\n"); switch (fit) { case FIT_GLOBAL_MULTIEXP: //printf("GCI_multiexp_lambda\n"); fitfunc = GCI_multiexp_lambda; //TODO lambda VS tau break; case FIT_GLOBAL_STRETCHEDEXP: //printf("GCI_stretchedexp\n"); fitfunc = GCI_stretchedexp; break; } //printf("before LMA\n"); float **covarX = GCI_ecf_matrix(ndata,ndata); float **alphaX = GCI_ecf_matrix(ndata,ndata); float **erraxesX = GCI_ecf_matrix(ndata,ndata); float chisq_target = 100.0; int chisq_percent = 50; //printf("about to LMA\n"); // if (0) int returnValue = GCI_marquardt_fitting_engine(xincr, trans, ndata, fit_start, fit_end, prompt, nprompt, noise, sig, param, paramfree, nparam, restrain, fitfunc, fitted, residuals, chisq, covarX, alphaX, erraxesX, chisq_target, chisq_percent); //printf("back from LMA %d\n", returnValue); //printf("Fitted params:\n"); //for (i = 0; i < nparam; ++i) { //printf(" %g ", param[i]); //} //printf("\n"); int n; float x, y; x = 0.0; float dy_dparam[MAXFIT]; for (n = 0; n < ndata; ++n) { if (n < fit_start || n > fit_end) { fitted[n] = residuals[n] = 0.0; } else { printf("fitted %d\n", n); (*fitfunc)(x, param, &y, dy_dparam, nparam); fitted[n] = y; residuals[n] = trans[n] - y; } x += xincr; } return returnValue; }