real do_lmfit(int ndata, real c1[], real sig[], real dt, real x0[], real begintimefit, real endtimefit, const output_env_t oenv, gmx_bool bVerbose, int eFitFn, real fitparms[], int fix) { FILE *fp; char buf[32]; int i, j, nparm, nfitpnts; real integral, ttt; real *parm, *dparm; real *x, *y, *dy; real ftol = 1e-4; nparm = nfp_ffn[eFitFn]; if (debug) { fprintf(debug, "There are %d points to fit %d vars!\n", ndata, nparm); fprintf(debug, "Fit to function %d from %g through %g, dt=%g\n", eFitFn, begintimefit, endtimefit, dt); } snew(x, ndata); snew(y, ndata); snew(dy, ndata); j = 0; for (i = 0; i < ndata; i++) { ttt = x0 ? x0[i] : dt*i; if (ttt >= begintimefit && ttt <= endtimefit) { x[j] = ttt; y[j] = c1[i]; /* mrqmin does not like sig to be zero */ if (sig[i] < 1.0e-7) { dy[j] = 1.0e-7; } else { dy[j] = sig[i]; } if (debug) { fprintf(debug, "j= %d, i= %d, x= %g, y= %g, dy= %g\n", j, i, x[j], y[j], dy[j]); } j++; } } nfitpnts = j; integral = 0; if (nfitpnts < nparm) { fprintf(stderr, "Not enough data points for fitting!\n"); } else { snew(parm, nparm); snew(dparm, nparm); if (fitparms) { for (i = 0; (i < nparm); i++) { parm[i] = fitparms[i]; } } if (!lmfit_exp(nfitpnts, x, y, dy, ftol, parm, dparm, bVerbose, eFitFn, fix)) { fprintf(stderr, "Fit failed!\n"); } else if (nparm <= 3) { /* Compute the integral from begintimefit */ if (nparm == 3) { integral = (parm[0]*myexp(begintimefit, parm[1], parm[0]) + parm[2]*myexp(begintimefit, 1-parm[1], parm[2])); } else if (nparm == 2) { integral = parm[0]*myexp(begintimefit, parm[1], parm[0]); } else if (nparm == 1) { integral = parm[0]*myexp(begintimefit, 1, parm[0]); } else { gmx_fatal(FARGS, "nparm = %d in file %s, line %d", nparm, __FILE__, __LINE__); } /* Generate THE output */ if (bVerbose) { fprintf(stderr, "FIT: # points used in fit is: %d\n", nfitpnts); fprintf(stderr, "FIT: %21s%21s%21s\n", "parm0 ", "parm1 (ps) ", "parm2 (ps) "); fprintf(stderr, "FIT: ------------------------------------------------------------\n"); fprintf(stderr, "FIT: %8.3g +/- %8.3g%9.4g +/- %8.3g%8.3g +/- %8.3g\n", parm[0], dparm[0], parm[1], dparm[1], parm[2], dparm[2]); fprintf(stderr, "FIT: Integral (calc with fitted function) from %g ps to inf. is: %g\n", begintimefit, integral); sprintf(buf, "test%d.xvg", nfitpnts); fp = xvgropen(buf, "C(t) + Fit to C(t)", "Time (ps)", "C(t)", oenv); fprintf(fp, "# parm0 = %g, parm1 = %g, parm2 = %g\n", parm[0], parm[1], parm[2]); for (j = 0; (j < nfitpnts); j++) { ttt = x0 ? x0[j] : dt*j; fprintf(fp, "%10.5e %10.5e %10.5e\n", ttt, c1[j], fit_function(eFitFn, parm, ttt)); } xvgrclose(fp); } } if (fitparms) { for (i = 0; (i < nparm); i++) { fitparms[i] = parm[i]; } } sfree(parm); sfree(dparm); } sfree(x); sfree(y); sfree(dy); return integral; }
real do_lmfit(int ndata, real c1[], real sig[], real dt, real *x0, real begintimefit, real endtimefit, const gmx_output_env_t *oenv, gmx_bool bVerbose, int eFitFn, double fitparms[], int fix, const char *fn_fitted) { FILE *fp; int i, j, nfitpnts; double integral, ttt; double *x, *y, *dy; if (0 != fix) { fprintf(stderr, "Using fixed parameters in curve fitting is temporarily not working.\n"); } if (debug) { fprintf(debug, "There are %d points to fit %d vars!\n", ndata, effnNparams(eFitFn)); fprintf(debug, "Fit to function %d from %g through %g, dt=%g\n", eFitFn, begintimefit, endtimefit, dt); } snew(x, ndata); snew(y, ndata); snew(dy, ndata); j = 0; for (i = 0; i < ndata; i++) { ttt = x0 ? x0[i] : dt*i; if (ttt >= begintimefit && ttt <= endtimefit) { x[j] = ttt; y[j] = c1[i]; if (NULL == sig) { // No weighting if all values are divided by 1. dy[j] = 1; } else { dy[j] = std::max(1.0e-7, (double)sig[i]); } if (debug) { fprintf(debug, "j= %d, i= %d, x= %g, y= %g, dy=%g, ttt=%g\n", j, i, x[j], y[j], dy[j], ttt); } j++; } } nfitpnts = j; integral = 0; if (nfitpnts < effnNparams(eFitFn)) { fprintf(stderr, "Not enough (%d) data points for fitting, dt = %g!\n", nfitpnts, dt); } else { gmx_bool bSuccess; if (bVerbose) { print_chi2_params(stdout, eFitFn, fitparms, "initial", nfitpnts, x, y); } initiate_fit_params(eFitFn, fitparms); bSuccess = lmfit_exp(nfitpnts, x, y, dy, fitparms, bVerbose, eFitFn, fix); extract_fit_params(eFitFn, fitparms); if (!bSuccess) { fprintf(stderr, "Fit failed!\n"); } else { if (bVerbose) { print_chi2_params(stdout, eFitFn, fitparms, "final", nfitpnts, x, y); } switch (eFitFn) { case effnEXP1: integral = fitparms[0]*myexp(begintimefit, 1, fitparms[0]); break; case effnEXP2: integral = fitparms[0]*myexp(begintimefit, fitparms[1], fitparms[0]); break; case effnEXPEXP: integral = (fitparms[0]*myexp(begintimefit, fitparms[1], fitparms[0]) + fitparms[2]*myexp(begintimefit, 1-fitparms[1], fitparms[2])); break; case effnEXP5: case effnEXP7: case effnEXP9: integral = 0; for (i = 0; (i < (effnNparams(eFitFn)-1)/2); i++) { integral += fitparms[2*i]*myexp(begintimefit, fitparms[2*i+1], fitparms[2*i]); } break; default: /* Do numerical integration */ integral = 0; for (i = 0; (i < nfitpnts-1); i++) { double y0 = lmcurves[eFitFn](x[i], fitparms); double y1 = lmcurves[eFitFn](x[i+1], fitparms); integral += (x[i+1]-x[i])*(y1+y0)*0.5; } break; } if (bVerbose) { printf("FIT: Integral of fitted function: %g\n", integral); if ((effnEXP5 == eFitFn) || (effnEXP7 == eFitFn) || (effnEXP9 == eFitFn)) { printf("FIT: Note that the constant term is not taken into account when computing integral.\n"); } } /* Generate debug output */ if (NULL != fn_fitted) { fp = xvgropen(fn_fitted, "Data + Fit", "Time (ps)", "Data (t)", oenv); for (i = 0; (i < effnNparams(eFitFn)); i++) { fprintf(fp, "# fitparms[%d] = %g\n", i, fitparms[i]); } for (j = 0; (j < nfitpnts); j++) { real ttt = x0 ? x0[j] : dt*j; fprintf(fp, "%10.5e %10.5e %10.5e\n", x[j], y[j], (lmcurves[eFitFn])(ttt, fitparms)); } xvgrclose(fp); } } } sfree(x); sfree(y); sfree(dy); return integral; }