double MLFitterGSL::iteration(){ //do one itteration //lock the model so user can not add or remove components during itteration modelptr->setlocked(true); //if the model has changed (a new or removed component eg.) create a new solver if (modelptr->has_changed()){ createmodelinfo(); //this automaticaly calls initfitter() via created_modelinfo() } //do an itteration step try{ const int status=gsl_multifit_fdfsolver_iterate(solver); #ifdef FITTER_DEBUG std::cout <<"solver status: "<<gsl_strerror(status)<<"\n"; std::cout <<"chi square/dof: "<<gsl_blas_dnrm2(solver->f)<<"\n"; #endif this->setstatus(gsl_strerror(status)); //update status info of fitter convertxtoparam(solver->x); } catch(...){ Saysomething mysay(0,"Error","Problem with call to gsl_multifit_fdfsolver_iterate, exit MLFitterGSL",true); delete(this); } //unlock the model so user can add or remove components modelptr->setlocked(false); //put the goodness in the goodnessqueue to check for convergence const double newgoodness= goodness_of_fit(); addgoodness(newgoodness); return newgoodness; }
/** * C++ version of gsl_multifit_fdfsolver_iterate(). * @param s The fdfsolver. * @return Error code on failure. */ inline static int iterate( fdfsolver& s ){ int const result = gsl_multifit_fdfsolver_iterate( s.get() ); s.x_v.wrap_gsl_vector_without_ownership( s.get()->x ); s.f_v.wrap_gsl_vector_without_ownership( s.get()->x ); s.dx_v.wrap_gsl_vector_without_ownership( s.get()->dx ); s.J_m.wrap_gsl_matrix_without_ownership( s.get()->J ); return result; }
/** * C++ version of gsl_multifit_fdfsolver_iterate(). * @return Error code on failure. */ int iterate(){ int const result = gsl_multifit_fdfsolver_iterate( get() ); x_v.wrap_gsl_vector_without_ownership( get()->x ); f_v.wrap_gsl_vector_without_ownership( get()->f ); dx_v.wrap_gsl_vector_without_ownership( get()->dx ); J_m.wrap_gsl_matrix_without_ownership( get()->J ); return result; }
Vector MultiSolver::NLLeastSquareSolver(MultiSolverInput *input) { /**/condition.analyzer->solverSolving.startTimer(); // ---- ---- T5 start const gsl_multifit_fdfsolver_type *T; gsl_multifit_fdfsolver *s; gsl_multifit_function_fdf f; double x_init[3] = {0.0, 0.0, 150.0}; // x_init[0] = input->initLocation.x; // x_init[1] = input->initLocation.y; // x_init[2] = input->initLocation.z; gsl_vector_view x = gsl_vector_view_array(x_init, 3); int n = (int)input->data.size(); // sort restriction.. // n = 3; int p = 3; f.f = &ms_f; f.df = &ms_df; f.fdf = &ms_fdf; f.n = n; f.p = p; f.params = input; T = gsl_multifit_fdfsolver_lmsder; s = gsl_multifit_fdfsolver_alloc(T, n, p); gsl_multifit_fdfsolver_set(s, &f, &x.vector); gsl_vector *gradt = gsl_vector_alloc(p); int iter = 0; int status; do { iter ++; status = gsl_multifit_fdfsolver_iterate(s); if (status) break; /// status = gsl_multifit_test_delta(s->dx, s->x, 1e-4, 1e-4); gsl_multifit_gradient(s->J, s->f, gradt); status = gsl_multifit_test_gradient(gradt, 1e-6); } while (status == GSL_CONTINUE && iter < 500); Vector point = Vector(gsl_vector_get(s->x, 0), gsl_vector_get(s->x, 1), gsl_vector_get(s->x, 2)); gsl_vector_free(gradt); gsl_multifit_fdfsolver_free(s); /**/condition.analyzer->solverSolving.stopTimer(); // ---- ---- T5 end return point; }
gsl_multifit_fdfsolver * Fit::fitGSL(gsl_multifit_function_fdf f, int &iterations, int &status) { const gsl_multifit_fdfsolver_type *T; if (d_solver) T = gsl_multifit_fdfsolver_lmder; else T = gsl_multifit_fdfsolver_lmsder; gsl_set_error_handler_off(); gsl_multifit_fdfsolver *s = gsl_multifit_fdfsolver_alloc (T, d_n, d_p); status = gsl_multifit_fdfsolver_set (s, &f, d_param_init); size_t iter = 0; bool inRange = true; for (int i=0; i<d_p; i++){ double p = gsl_vector_get(d_param_init, i); d_results[i] = p; if (p < d_param_range_left[i] || p > d_param_range_right[i]){ inRange = false; break; } } if (status){ gsl_multifit_covar (s->J, 0.0, covar); iterations = 0; return s; } do{ iter++; status = gsl_multifit_fdfsolver_iterate (s); if (status) break; for (int i=0; i<d_p; i++){ double p = gsl_vector_get(s->x, i); if (p < d_param_range_left[i] || p > d_param_range_right[i]){ inRange = false; break; } } if (!inRange) break; for (int i = 0; i < d_p; i++) d_results[i] = gsl_vector_get(s->x, i); status = gsl_multifit_test_delta (s->dx, s->x, d_tolerance, d_tolerance); } while (inRange && status == GSL_CONTINUE && (int)iter < d_max_iterations); gsl_multifit_covar (s->J, 0.0, covar); iterations = iter; return s; }
void test_lmder (gsl_multifit_function_fdf * f, double x0[], double * X, double F[], double * cov) { const gsl_multifit_fdfsolver_type *T; gsl_multifit_fdfsolver *s; const size_t n = f->n; const size_t p = f->p; int status; size_t iter = 0, i; gsl_vector_view x = gsl_vector_view_array (x0, p); T = gsl_multifit_fdfsolver_lmsder; s = gsl_multifit_fdfsolver_alloc (T, n, p); gsl_multifit_fdfsolver_set (s, f, &x.vector); do { status = gsl_multifit_fdfsolver_iterate (s); for (i = 0 ; i < p; i++) { gsl_test_rel (gsl_vector_get (s->x, i), X[p*iter+i], 1e-5, "lmsder, iter=%u, x%u", iter, i); } gsl_test_rel (gsl_blas_dnrm2 (s->f), F[iter], 1e-5, "lmsder, iter=%u, f", iter); iter++; } while (iter < 20); { size_t i, j; gsl_matrix * covar = gsl_matrix_alloc (4, 4); gsl_multifit_covar (s->J, 0.0, covar); for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { gsl_test_rel (gsl_matrix_get(covar,i,j), cov[i*p + j], 1e-7, "gsl_multifit_covar cov(%d,%d)", i, j) ; } } gsl_matrix_free (covar); } gsl_multifit_fdfsolver_free (s); }
gsl_multifit_fdfsolver *Fit::fitGSL(gsl_multifit_function_fdf f, int &iterations, int &status) { const gsl_multifit_fdfsolver_type *T; if (d_solver) T = gsl_multifit_fdfsolver_lmder; else T = gsl_multifit_fdfsolver_lmsder; gsl_multifit_fdfsolver *s = gsl_multifit_fdfsolver_alloc(T, d_n, d_p); gsl_multifit_fdfsolver_set(s, &f, d_param_init); size_t iter = 0; bool inRange = true; for (int i = 0; i < d_p; i++) { double p = gsl_vector_get(d_param_init, i); d_results[i] = p; if (p < d_param_range_left[i] || p > d_param_range_right[i]) { inRange = false; break; } } do { iter++; status = gsl_multifit_fdfsolver_iterate(s); if (status) break; for (int i = 0; i < d_p; i++) { double p = gsl_vector_get(s->x, i); if (p < d_param_range_left[i] || p > d_param_range_right[i]) { inRange = false; break; } } if (!inRange) break; for (int i = 0; i < d_p; i++) d_results[i] = gsl_vector_get(s->x, i); status = gsl_multifit_test_delta(s->dx, s->x, d_tolerance, d_tolerance); } while (inRange && status == GSL_CONTINUE && (int)iter < d_max_iterations); #if GSL_MAJOR_VERSION < 2 gsl_multifit_covar(s->J, 0.0, covar); #else gsl_matrix *J = gsl_matrix_alloc(d_n, d_p); gsl_multifit_fdfsolver_jac(s, J); gsl_multifit_covar(J, 0.0, covar); gsl_matrix_free(J); #endif iterations = static_cast<int>(iter); return s; }
int gsl_multifit_fdfridge_iterate (gsl_multifit_fdfridge * w) { int status = gsl_multifit_fdfsolver_iterate(w->s); /* update function/Jacobian evaluations */ w->fdf->nevalf = w->fdftik.nevalf; w->fdf->nevaldf = w->fdftik.nevaldf; return status; }
int NonLinearLSQ::curvefit() { size_t n(nSize()); size_t p(nParms()); // Initialize the solver function information _nlsqPointer d = { this }; gsl_multifit_function_fdf mf; mf.f = &f; mf.df = &df; mf.fdf = &fdf; mf.n = n; mf.p = p; mf.params = &d; const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder; gsl_multifit_fdfsolver *s = gsl_multifit_fdfsolver_alloc(T, n, p); _fitParms = guess(); gsl_vector *x = NlsqTogsl(_fitParms); gsl_matrix *covar = gsl_matrix_alloc(p, p); gsl_multifit_fdfsolver_set(s, &mf, x); _nIters = 0; checkIteration(_nIters, gslToNlsq(s->x), NLVector(p,999.0), gsl_blas_dnrm2(s->f), GSL_CONTINUE); do { _nIters++; _status = gsl_multifit_fdfsolver_iterate(s); _fitParms = gslToNlsq(s->x); gsl_multifit_covar(s->J, 0.0, covar); _uncert = getUncertainty(covar); _status = checkIteration(_nIters, _fitParms, _uncert, gsl_blas_dnrm2(s->f), _status); if ( _status ) { break; } if(!doContinue()) { break; } _status = gsl_multifit_test_delta(s->dx, s->x, absErr(), relErr()); } while ((_status == GSL_CONTINUE) && (_nIters < _maxIters)); // Clean up gsl_multifit_fdfsolver_free(s); gsl_matrix_free(covar); return (_status); }
int MultiFitter::MainFDF() { multifit_fdfsolver_type = gsl_multifit_fdfsolver_lmsder; s = gsl_multifit_fdfsolver_alloc (multifit_fdfsolver_type, n, p); gsl_multifit_fdfsolver_set (s, &F, &x.vector); do { iter++; status = gsl_multifit_fdfsolver_iterate (s); status = gsl_multifit_test_delta (s->dx, s->x, epsabs, epsrel); } while (status == GSL_CONTINUE && iter < max_iter); return status; }
static int gauss_fit(dist_t *dist, int ngauss, double *params) { data_t *dat = &dist->dat; dat->ngauss = ngauss; gsl_multifit_function_fdf mfunc; mfunc.f = &func_f; mfunc.df = &func_df; mfunc.fdf = &func_set; mfunc.n = dat->nvals; mfunc.p = ngauss*3; // number of fitting parameters mfunc.params = dat; const gsl_multifit_fdfsolver_type *solver_type; gsl_multifit_fdfsolver *solver; gsl_vector_view vview = gsl_vector_view_array(params, mfunc.p); solver_type = gsl_multifit_fdfsolver_lmsder; solver = gsl_multifit_fdfsolver_alloc(solver_type, dat->nvals, mfunc.p); gsl_multifit_fdfsolver_set(solver, &mfunc, &vview.vector); int i, status; size_t iter = 0; do { status = gsl_multifit_fdfsolver_iterate(solver); if ( status ) break; status = gsl_multifit_test_delta(solver->dx, solver->x, 1e-4, 1e-4); } while (status == GSL_CONTINUE && iter++ < 500); for (i=0; i<mfunc.p; i++) params[i] = gsl_vector_get(solver->x, i); gsl_multifit_fdfsolver_free(solver); return iter>500 ? -1 : 0; }
/* Removes the ballistic term from the beginning of the ACF, * just like in Omer's paper. */ extern void takeAwayBallistic(double *ct, double *t, int len, real tMax, int nexp, gmx_bool bDerivative) { /* Use nonlinear regression with GSL instead. * Fit with 4 exponentials and one constant term, * subtract the fatest exponential. */ int nData,i,status, iter; balData *BD; double *guess, /* Initial guess. */ *A, /* The fitted parameters. (A1, B1, A2, B2,... C) */ a[2], ddt[2]; gmx_bool sorted; size_t n; size_t p; nData = 0; do { nData++; } while (t[nData]<tMax+t[0] && nData<len); p = nexp*2+1; /* Number of parameters. */ #ifdef HAVE_LIBGSL const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder; gsl_multifit_fdfsolver *s; /* The solver itself. */ gsl_multifit_function_fdf fitFunction; /* The function to be fitted. */ gsl_matrix *covar; /* Covariance matrix for the parameters. * We'll not use the result, though. */ gsl_vector_view theParams; nData = 0; do { nData++; } while (t[nData]<tMax+t[0] && nData<len); guess = NULL; n = nData; snew(guess, p); snew(A, p); covar = gsl_matrix_alloc (p, p); /* Set up an initial gess for the parameters. * The solver is somewhat sensitive to the initial guess, * but this worked fine for a TIP3P box with -geminate dd * EDIT: In fact, this seems like a good starting pont for other watermodels too. */ for (i=0; i<nexp; i++) { guess[i*2] = 0.1; guess[i*2+1] = -0.5 + (((double)i)/nexp - 0.5)*0.3; } guess[nexp * 2] = 0.01; theParams = gsl_vector_view_array(guess, p); snew(BD,1); BD->n = n; BD->y = ct; BD->tDelta = t[1]-t[0]; BD->nexp = nexp; fitFunction.f = &balFunc_f; fitFunction.df = &balFunc_df; fitFunction.fdf = &balFunc_fdf; fitFunction.n = nData; fitFunction.p = p; fitFunction.params = BD; s = gsl_multifit_fdfsolver_alloc (T, nData, p); if (s==NULL) gmx_fatal(FARGS, "Could not set up the nonlinear solver."); gsl_multifit_fdfsolver_set(s, &fitFunction, &theParams.vector); /* \=============================================/ */ iter = 0; do { iter++; status = gsl_multifit_fdfsolver_iterate (s); if (status) break; status = gsl_multifit_test_delta (s->dx, s->x, 1e-4, 1e-4); } while (iter < 5000 && status == GSL_CONTINUE); if (iter == 5000) { fprintf(stderr, "The non-linear fitting did not converge in 5000 steps.\n" "Check the quality of the fit!\n"); } else { fprintf(stderr, "Non-linear fitting of ballistic term converged in %d steps.\n\n", (int)iter); } for (i=0; i<nexp; i++) { fprintf(stdout, "%c * exp(%c * t) + ", 'A'+(char)i*2, 'B'+(char)i*2); } fprintf(stdout, "%c\n", 'A'+(char)nexp*2); fprintf(stdout, "Here are the actual numbers for A-%c:\n", 'A'+nexp*2); for (i=0; i<nexp; i++) { A[i*2] = gsl_vector_get(s->x, i*2); A[i*2+1] = gsl_vector_get(s->x, i*2+1); fprintf(stdout, " %g*exp(%g * x) +", A[i*2], A[i*2+1]); } A[i*2] = gsl_vector_get(s->x, i*2); /* The last and constant term */ fprintf(stdout, " %g\n", A[i*2]); fflush(stdout); /* Implement some check for parameter quality */ for (i=0; i<nexp; i++) { if (A[i*2]<0 || A[i*2]>1) { fprintf(stderr, "WARNING: ----------------------------------\n" " | A coefficient does not lie within [0,1].\n" " | This may or may not be a problem.\n" " | Double check the quality of the fit!\n"); } if (A[i*2+1]>0) { fprintf(stderr, "WARNING: ----------------------------------\n" " | One factor in the exponent is positive.\n" " | This could be a problem if the coefficient\n" " | is large. Double check the quality of the fit!\n"); } } if (A[i*2]<0 || A[i*2]>1) { fprintf(stderr, "WARNING: ----------------------------------\n" " | The constant term does not lie within [0,1].\n" " | This may or may not be a problem.\n" " | Double check the quality of the fit!\n"); } /* Sort the terms */ sorted = (nexp > 1) ? FALSE : TRUE; while (!sorted) { sorted = TRUE; for (i=0;i<nexp-1;i++) { ddt[0] = A[i*2] * A[i*2+1]; ddt[1] =A[i*2+2] * A[i*2+3]; if ((bDerivative && (ddt[0]<0 && ddt[1]<0 && ddt[0]>ddt[1])) || /* Compare derivative at t=0... */ (!bDerivative && (A[i*2+1] > A[i*2+3]))) /* Or just the coefficient in the exponent */ { sorted = FALSE; a[0] = A[i*2]; /* coefficient */ a[1] = A[i*2+1]; /* parameter in the exponent */ A[i*2] = A[i*2+2]; A[i*2+1] = A[i*2+3]; A[i*2+2] = a[0]; A[i*2+3] = a[1]; } } } /* Subtract the fastest component */ fprintf(stdout, "Fastest component is %g * exp(%g * t)\n" "Subtracting fastest component from ACF.\n", A[0], A[1]); for (i=0; i<len; i++) { ct[i] = (ct[i] - A[0] * exp(A[1] * i*BD->tDelta)) / (1-A[0]); } sfree(guess); sfree(A); gsl_multifit_fdfsolver_free(s); gsl_matrix_free(covar); fflush(stdout); #else /* We have no gsl. */ fprintf(stderr, "Sorry, can't take away ballistic component without gsl. " "Recompile using --with-gsl.\n"); return; #endif /* HAVE_LIBGSL */ }
int InterpolaVPR_GSL::interpola_VPR(const float* vpr, int hvprmax, int livmin) { LOG_CATEGORY("radar.vpr"); static const unsigned N = 10; const gsl_multifit_fdfsolver_type *T; gsl_multifit_fdfsolver *s; int status; unsigned int i; const size_t n = N; const size_t p = 5; char file_vprint[512]; gsl_matrix *covar = gsl_matrix_alloc (p, p); double a[5]; struct data d(N); gsl_multifit_function_fdf f; double x_init[5] = { 4, 0.2, 3. , 1.4, -0.4 }; gsl_vector_view x = gsl_vector_view_array (x_init, p); ////////////////////////////////////////////////////////////////////////////// int ier_int=0; double xint,yint; /* punti interessanti per inizializzare parametri*/ int in1=(int)((hvprmax-TCK_VPR/2)/TCK_VPR); //indice del massimo int in2=(int)((hvprmax+HALF_BB)/TCK_VPR); //indice del massimo + 500 m int in3=in2+1; int in4=in2+5; //indice del massimo + 1000 m if (in4 > NMAXLAYER-1) { ier_int=1; return ier_int; } B=vpr[in1]-vpr[in2]; E=hvprmax/1000.; G=0.25; C=vpr[in2-1]; F=vpr[in4]<vpr[in3]?(vpr[in4]-vpr[in3])/((in4-in3)*TCK_VPR/1000.):0.; // fprintf(stderr, "const unsigned NMAXLAYER=%d;\n", NMAXLAYER); // fprintf(stderr, "float vpr[] = {"); // for (unsigned i = 0; i < NMAXLAYER; ++i) // fprintf(stderr, "%s%f", i==0?"":",", (double)vpr[i]); // fprintf(stderr, "};\n"); x_init[0]= a[0]=B; x_init[1]= a[1]=E; x_init[2]= a[2]=G; x_init[3]= a[3]=C; x_init[4]= a[4]=F; ///////////////////////////////////////////////////////////////////////////////////////////////////////// f.f = &expb_f; f.df = &expb_df; f.fdf = &expb_fdf; f.n = n; f.p = p; f.params = &d; /* This is the data to be fitted */ for (i = 0; i < n; i++) { d.t[i]= ((hvprmax-1000.)>livmin)? (i*TCK_VPR+(hvprmax-800)-TCK_VPR)/1000. : (livmin+i*TCK_VPR)/1000.; d.y[i]= ((hvprmax-1000.)>livmin)? vpr[i+(int)(((hvprmax-800)-TCK_VPR)/TCK_VPR)] : vpr[i+(int)(livmin/TCK_VPR)]; d.sigma[i] = 0.5; }; T = gsl_multifit_fdfsolver_lmsder; s = gsl_multifit_fdfsolver_alloc (T, n, p); gsl_multifit_fdfsolver_set (s, &f, &x.vector); //print_state (0, s); bool found = false; for (unsigned iter = 0; !found && iter < 500; ++iter) { //fprintf(stderr, "Iter %d\n", iter); //d.print(); int status = gsl_multifit_fdfsolver_iterate (s); if (status != 0) { LOG_ERROR("gsl_multifit_fdfsolver_iterate: %s", gsl_strerror(status)); return 1; } //print_state (iter, s); status = gsl_multifit_test_delta (s->dx, s->x, 1e-4, 1e-4); switch (status) { case GSL_SUCCESS: found = true; break; case GSL_CONTINUE: break; default: LOG_ERROR("gsl_multifit_test_delta: %s", gsl_strerror(status)); return 1; } } #if GSL_MAJOR_VERSION == 2 // Use of GSL 2.0 taken from https://sft.its.cern.ch/jira/browse/ROOT-7776 gsl_matrix* J = gsl_matrix_alloc(s->fdf->n, s->fdf->p); gsl_multifit_fdfsolver_jac(s, J); gsl_multifit_covar(J, 0.0, covar); #else gsl_multifit_covar(s->J, 0.0, covar); #endif #define FIT(i) gsl_vector_get(s->x, i) #define ERR(i) sqrt(gsl_matrix_get(covar,i,i)) { double chi = gsl_blas_dnrm2(s->f); double dof = n - p; double c = GSL_MAX_DBL(1, chi / sqrt(dof)); // printf("chisq/dof = %g\n", pow(chi, 2.0) / dof); // printf ("B = %.5f +/- %.5f\n", FIT(0), c*ERR(0)); // printf ("E = %.5f +/- %.5f\n", FIT(1), c*ERR(1)); // printf ("G = %.5f +/- %.5f\n", FIT(2), c*ERR(2)); // printf ("C = %.5f +/- %.5f\n", FIT(3), c*ERR(3)); // printf ("F = %.5f +/- %.5f\n", FIT(4), c*ERR(4)); } B = a[0] = FIT(0); E = a[1] = FIT(1); G = a[2] = FIT(2); C = a[3] = FIT(3); F = a[4] = FIT(4); gsl_multifit_fdfsolver_free (s); gsl_matrix_free (covar); ///////////////////////////////////////////////////////// if (testfit(a) == 1) return 1; for (i=1; i<=N; i++) { xint=(i*TCK_VPR-TCK_VPR/2)/1000.; yint= lineargauss(xint, a); vpr_int[i-1] = yint; } return 0; }
/* * Gaussian parameters calculation y=A/sqrt(2*pi*sigma^2) exp(-(x-x_0)^2/2/sigma^2), * which approximates the points set pts * Parameters A_, sigma_, x0_ may be NULL (if you don't need any of them) */ void gauss_fit(Points *pts, double *C_, double *A_, double *sigma_, double *x0_){ // VVVV lower parameters may be formed as a structure to change as function argument double epsabs = 1e-8,// absolute error epsrel = 1e-5,// relative error chi_max = 0.01;// max chi value for iterations criteria int max_iter = 300; // limit iterations number of gsl_multifit_fdfsolver size_t N_MIN = 10; // minimum points for approximation double x_init[4]; // AAAA upper parameters may be formed as a structure to change as function argument /* x_init, the best approximations: * x0 - not far from real (the nearest is the better) * sigma - not far from real (the nearest is the better) * A - not large ~10 (it has a weak effect) */ const gsl_multifit_fdfsolver_type *T; gsl_multifit_fdfsolver *s; int status; #ifdef EBUG int appNo = 0; #endif int iter; size_t i, j, n = pts->n, oldn; const size_t p = 4; gsl_matrix *covar = gsl_matrix_alloc (p, p); #ifdef EBUG double t0; #endif double *x, *y, *dy, chi, C, A, sigma, x0; if(n < 1) return; x = malloc(n * sizeof(double)); y = malloc(n * sizeof(double)); dy = malloc(n * sizeof(double)); struct data d = {n, x, y, dy}; gsl_multifit_function_fdf f; gsl_vector_view xx = gsl_vector_view_array(x_init, p); const gsl_rng_type *type; gsl_rng *r; gsl_rng_env_setup(); type = gsl_rng_default; r = gsl_rng_alloc (type); f.f = &gauss_f; f.df = &gauss_df; f.fdf = &gauss_fdf; f.n = n; f.p = p; f.params = &d; // fill data structure. Don't forget Okkam's razor!!! { Point *pt = pts->data; double *px = x, *py = y, *pdy = dy, sum = 0.; for(i = 0; i < n; i++, pt++){ *pdy++ = 1.; // I have no idea what is it, so init by 1 *px++ = pt->x; *py++ = pt->y; sum += pt->y; //DBG("point %d: (%g, %g)", i, pt->x, pt->y); } // fill x_init: x0, sigma, C, A (it can be a funtion parameter) x_init[3] = (*(--px) + *x) / 2.; x_init[2] = fabs((*x - *px) / 4.); x_init[0] = sum/(double)n; x_init[1] = sum; DBG("\nInitial parameters: x0=%.1f, sigma=%.1f, A=%.1f, C=%.1f", x_init[3], x_init[2], x_init[1], x_init[0]); } T = gsl_multifit_fdfsolver_lmder; // or also gsl_multifit_fdfsolver_lmsder s = gsl_multifit_fdfsolver_alloc(T, n, p); #ifdef EBUG t0 = dtime(); #endif do{ double dof, tres, c; DBG("\n************ Approximation %d ******************\n", appNo++); iter = 0; gsl_multifit_fdfsolver_set(s, &f, &xx.vector); do{ iter++; status = gsl_multifit_fdfsolver_iterate(s); if(status) break; status = gsl_multifit_test_delta(s->dx, s->x, epsabs, epsrel); }while(status == GSL_CONTINUE && iter < max_iter); DBG("time=%g\n", dtime()-t0); gsl_multifit_covar(s->J, 0.0, covar); chi = gsl_blas_dnrm2(s->f); dof = n - p; tres = chi; c = chi / sqrt(dof); // GSL_MAX_DBL(1., chi / sqrt(dof)); C = FIT(0), A = FIT(1), sigma = FIT(2), x0 = FIT(3); DBG("Number of iteratons = %d\n", iter); DBG("chi = %g, chi/dof = %g\n", chi, chi / sqrt(dof)); DBG("C = %.5f +/- %.5f\n", C, c*ERR(0)); DBG("A = %.5f +/- %.5f\n", A, c*ERR(1)); DBG("sigma = %.5f +/- %.5f\n", sigma, c*ERR(2)); DBG("x0 = %.5f +/- %.5f\n", x0, c*ERR(3)); j = 0; oldn = n; if(c < chi_max) break; // throw out bad (by chi) data for(i = 0; i < n; i++){ if(fabs(FN(i)) < tres){ if(i != j){ x[j] = x[i]; y[j] = y[i]; dy[j] = dy[i]; } j++; continue; } } if(j != n){ DBG("Chi tresholding %g, %zd points of %zd\n", tres, j, n); n = j; d.n = n; } }while(chi > chi_max && n != oldn && n > N_MIN); if(C_) *C_ = C; if(A_) *A_ = A; if(sigma_) *sigma_ = sigma; if(x0_) *x0_ = x0; //printf ("status = %s\n", gsl_strerror (status)); gsl_multifit_fdfsolver_free(s); gsl_matrix_free(covar); gsl_rng_free(r); free(x); free(y); free(dy); }
//------------------------------------------------------------------------------ // findCorrection () : Uses a GSL Levenberg-Marquardt algorithm to fit the lines // in FittedLines to the wavenumbers in the user-specified calibration standard. // The result is the optimal wavenumber correction factor for the uncalibrated // data, which is stored in the class variable WaveCorrection. Information about // the fit residuals are saved by calling calcDiffStats(). // void ListCal::findCorrection () { // Prepare the GSL Solver and associated objects. A non-linear solver is used, // the precise type of which is determined by SOLVER_TYPE, defined in // MgstFcn.h. const size_t NumParameters = 1; const size_t NumLines = FittedLines.size (); double GuessArr [NumParameters]; for (unsigned int i = 0; i < NumParameters; i ++) { GuessArr[i] = WaveCorrection; } const gsl_multifit_fdfsolver_type *SolverType; gsl_multifit_fdfsolver *Solver; gsl_multifit_function_fdf FitFunction; gsl_matrix *Covariance = gsl_matrix_alloc (NumParameters, NumParameters); gsl_vector_view VectorView = gsl_vector_view_array (GuessArr, NumParameters); FitFunction.f = &fitFn; FitFunction.df = &derivFn; FitFunction.fdf = &fitAndDerivFns; FitFunction.n = NumLines; FitFunction.p = NumParameters; FitFunction.params = &FittedLines; SolverType = SOLVER_TYPE; Solver = gsl_multifit_fdfsolver_alloc(SolverType, NumLines, NumParameters); gsl_multifit_fdfsolver_set (Solver, &FitFunction, &VectorView.vector); // Perform the fitting, one iteration at a time until one of the following // conditions is met: The absolute and relative changes in the fit parameters // become smaller than SOLVER_TOL, or the max number of allowed iterations, // SOLVER_MAX_ITERATIONS, is reached. unsigned int Iteration = 0; int Status; do { Iteration ++; Status = gsl_multifit_fdfsolver_iterate (Solver); if (Status) break; Status = gsl_multifit_test_delta (Solver->dx, Solver->x, SOLVER_TOL, SOLVER_TOL); } while (Status == GSL_CONTINUE && Iteration < SOLVER_MAX_ITERATIONS); // Output all the fit parameters with their associated error. gsl_multifit_covar (Solver -> J, 0.0, Covariance); #define FIT(i) gsl_vector_get (Solver -> x, i) #define ERR(i) sqrt (gsl_matrix_get (Covariance, i, i)) double chi = gsl_blas_dnrm2 (Solver -> f); double dof = NumLines - double(NumParameters); double c = chi / sqrt (dof); cout << "Correction factor: " << FIT(0) << " +/- " << c*ERR(0) << " (" << "reduced chi^2 = " << pow(chi, 2) / dof << ", " << "lines fitted = " << NumLines << ", c = " << c << ")" << endl; // Apply the wavenumber correction to all the lines loaded from the // uncalibrated spectrum WaveCorrection = FIT(0); WaveCorrectionError = c*ERR(0); calcDiffStats (); cout << "dSig/Sig Mean Residual: " << DiffMean / LC_DATA_SCALE << ", StdDev: " << DiffStdDev / LC_DATA_SCALE << ", StdErr: " << DiffStdErr / LC_DATA_SCALE << endl; // Clean up the memory and exit gsl_multifit_fdfsolver_free (Solver); gsl_matrix_free (Covariance); }
static int MLalgo(struct dataStruct *data) { /* declare solvers */ const gsl_multifit_fdfsolver_type *T; gsl_multifit_fdfsolver *s; gsl_vector_view x = gsl_vector_view_array(data->x_init, data->np); const gsl_rng_type *type; gsl_rng_env_setup(); type = gsl_rng_default; gsl_multifit_function_fdf f; f.f = &gaussian_f; f.df = &gaussian_df; f.fdf = &gaussian_fdf; f.n = data->nValid; f.p = data->np; f.params = data; T = gsl_multifit_fdfsolver_lmsder; s = gsl_multifit_fdfsolver_alloc(T, data->nValid, data->np); gsl_multifit_fdfsolver_set(s, &f, &x.vector); int status, status2; int iter = 0; gsl_vector *gradt = gsl_vector_alloc(data->np); do { iter++; status = gsl_multifit_fdfsolver_iterate(s); if (status) break; status = gsl_multifit_test_delta(s->dx, s->x, data->eAbs, data->eRel); gsl_multifit_gradient(s->J, s->f, gradt); status2 = gsl_multifit_test_gradient(gradt, data->eAbs); } while ((status == GSL_CONTINUE || status2 == GSL_CONTINUE) && iter < data->maxIter); gsl_vector_free(gradt); int i; for (i=0; i<data->np; ++i) { data->prmVect[data->estIdx[i]] = gsl_vector_get(s->x, i); } data->prmVect[3] = fabs(data->prmVect[3]); /* copy residuals */ data->residuals = gsl_vector_alloc(data->nValid); gsl_vector_memcpy(data->residuals, s->f); /* copy Jacobian */ data->J = gsl_matrix_alloc(data->nValid, data->np); gsl_matrix_memcpy(data->J, s->J); gsl_multifit_fdfsolver_free(s); return 0; }
/** Executes the algorithm * * @throw runtime_error Thrown if algorithm cannot execute */ void Fit1D::exec() { // Custom initialization prepare(); // check if derivative defined in derived class bool isDerivDefined = true; gsl_matrix *M = NULL; try { const std::vector<double> inTest(m_parameterNames.size(), 1.0); std::vector<double> outTest(m_parameterNames.size()); const double xValuesTest = 0; JacobianImpl J; M = gsl_matrix_alloc(m_parameterNames.size(), 1); J.setJ(M); // note nData set to zero (last argument) hence this should avoid further // memory problems functionDeriv(&(inTest.front()), &J, &xValuesTest, 0); } catch (Exception::NotImplementedError &) { isDerivDefined = false; } gsl_matrix_free(M); // Try to retrieve optional properties int histNumber = getProperty("WorkspaceIndex"); const int maxInterations = getProperty("MaxIterations"); // Get the input workspace MatrixWorkspace_const_sptr localworkspace = getProperty("InputWorkspace"); // number of histogram is equal to the number of spectra const size_t numberOfSpectra = localworkspace->getNumberHistograms(); // Check that the index given is valid if (histNumber >= static_cast<int>(numberOfSpectra)) { g_log.warning("Invalid Workspace index given, using first Workspace"); histNumber = 0; } // Retrieve the spectrum into a vector const MantidVec &XValues = localworkspace->readX(histNumber); const MantidVec &YValues = localworkspace->readY(histNumber); const MantidVec &YErrors = localworkspace->readE(histNumber); // Read in the fitting range data that we were sent double startX = getProperty("StartX"); double endX = getProperty("EndX"); // check if the values had been set, otherwise use defaults if (isEmpty(startX)) { startX = XValues.front(); modifyStartOfRange(startX); // does nothing by default but derived class may // provide a more intelligent value } if (isEmpty(endX)) { endX = XValues.back(); modifyEndOfRange(endX); // does nothing by default but derived class may // previde a more intelligent value } int m_minX; int m_maxX; // Check the validity of startX if (startX < XValues.front()) { g_log.warning("StartX out of range! Set to start of frame."); startX = XValues.front(); } // Get the corresponding bin boundary that comes before (or coincides with) // this value for (m_minX = 0; XValues[m_minX + 1] < startX; ++m_minX) { } // Check the validity of endX and get the bin boundary that come after (or // coincides with) it if (endX >= XValues.back() || endX < startX) { g_log.warning("EndX out of range! Set to end of frame"); endX = XValues.back(); m_maxX = static_cast<int>(YValues.size()); } else { for (m_maxX = m_minX; XValues[m_maxX] < endX; ++m_maxX) { } } afterDataRangedDetermined(m_minX, m_maxX); // create and populate GSL data container warn user if l_data.n < l_data.p // since as a rule of thumb this is required as a minimum to obtained // 'accurate' // fitting parameter values. FitData l_data(this, getProperty("Fix")); l_data.n = m_maxX - m_minX; // m_minX and m_maxX are array index markers. I.e. e.g. 0 & 19. if (l_data.n == 0) { g_log.error("The data set is empty."); throw std::runtime_error("The data set is empty."); } if (l_data.n < l_data.p) { g_log.error( "Number of data points less than number of parameters to be fitted."); throw std::runtime_error( "Number of data points less than number of parameters to be fitted."); } l_data.X = new double[l_data.n]; l_data.sigmaData = new double[l_data.n]; l_data.forSimplexLSwrap = new double[l_data.n]; l_data.parameters = new double[nParams()]; // check if histogram data in which case use mid points of histogram bins const bool isHistogram = localworkspace->isHistogramData(); for (unsigned int i = 0; i < l_data.n; ++i) { if (isHistogram) l_data.X[i] = 0.5 * (XValues[m_minX + i] + XValues[m_minX + i + 1]); // take mid-point if histogram bin else l_data.X[i] = XValues[m_minX + i]; } l_data.Y = &YValues[m_minX]; // check that no error is negative or zero for (unsigned int i = 0; i < l_data.n; ++i) { if (YErrors[m_minX + i] <= 0.0) { l_data.sigmaData[i] = 1.0; } else l_data.sigmaData[i] = YErrors[m_minX + i]; } // create array of fitted parameter. Take these to those input by the user. // However, for doing the // underlying fitting it might be more efficient to actually perform the // fitting on some of other // form of the fitted parameters. For instance, take the Gaussian sigma // parameter. In practice it // in fact more efficient to perform the fitting not on sigma but 1/sigma^2. // The methods // modifyInitialFittedParameters() and modifyFinalFittedParameters() are used // to allow for this; // by default these function do nothing. m_fittedParameter.clear(); for (size_t i = 0; i < nParams(); i++) { m_fittedParameter.push_back(getProperty(m_parameterNames[i])); } modifyInitialFittedParameters( m_fittedParameter); // does nothing except if overwritten by derived class for (size_t i = 0; i < nParams(); i++) { l_data.parameters[i] = m_fittedParameter[i]; } // set-up initial guess for fit parameters gsl_vector *initFuncArg; initFuncArg = gsl_vector_alloc(l_data.p); for (size_t i = 0, j = 0; i < nParams(); i++) { if (l_data.active[i]) gsl_vector_set(initFuncArg, j++, m_fittedParameter[i]); } // set-up GSL container to be used with GSL simplex algorithm gsl_multimin_function gslSimplexContainer; gslSimplexContainer.n = l_data.p; // n here refers to number of parameters gslSimplexContainer.f = &gsl_costFunction; gslSimplexContainer.params = &l_data; // set-up GSL least squares container gsl_multifit_function_fdf f; f.f = &gsl_f; f.df = &gsl_df; f.fdf = &gsl_fdf; f.n = l_data.n; f.p = l_data.p; f.params = &l_data; // set-up remaining GSL machinery for least squared const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder; gsl_multifit_fdfsolver *s = NULL; if (isDerivDefined) { s = gsl_multifit_fdfsolver_alloc(T, l_data.n, l_data.p); gsl_multifit_fdfsolver_set(s, &f, initFuncArg); } // set-up remaining GSL machinery to use simplex algorithm const gsl_multimin_fminimizer_type *simplexType = gsl_multimin_fminimizer_nmsimplex; gsl_multimin_fminimizer *simplexMinimizer = NULL; gsl_vector *simplexStepSize = NULL; if (!isDerivDefined) { simplexMinimizer = gsl_multimin_fminimizer_alloc(simplexType, l_data.p); simplexStepSize = gsl_vector_alloc(l_data.p); gsl_vector_set_all(simplexStepSize, 1.0); // is this always a sensible starting step size? gsl_multimin_fminimizer_set(simplexMinimizer, &gslSimplexContainer, initFuncArg, simplexStepSize); } // finally do the fitting int iter = 0; int status; double finalCostFuncVal; double dof = static_cast<double>( l_data.n - l_data.p); // dof stands for degrees of freedom // Standard least-squares used if derivative function defined otherwise // simplex Progress prog(this, 0.0, 1.0, maxInterations); if (isDerivDefined) { do { iter++; status = gsl_multifit_fdfsolver_iterate(s); if (status) // break if error break; status = gsl_multifit_test_delta(s->dx, s->x, 1e-4, 1e-4); prog.report(); } while (status == GSL_CONTINUE && iter < maxInterations); double chi = gsl_blas_dnrm2(s->f); finalCostFuncVal = chi * chi / dof; // put final converged fitting values back into m_fittedParameter for (size_t i = 0, j = 0; i < nParams(); i++) if (l_data.active[i]) m_fittedParameter[i] = gsl_vector_get(s->x, j++); } else { do { iter++; status = gsl_multimin_fminimizer_iterate(simplexMinimizer); if (status) // break if error break; double size = gsl_multimin_fminimizer_size(simplexMinimizer); status = gsl_multimin_test_size(size, 1e-2); prog.report(); } while (status == GSL_CONTINUE && iter < maxInterations); finalCostFuncVal = simplexMinimizer->fval / dof; // put final converged fitting values back into m_fittedParameter for (unsigned int i = 0, j = 0; i < m_fittedParameter.size(); i++) if (l_data.active[i]) m_fittedParameter[i] = gsl_vector_get(simplexMinimizer->x, j++); } modifyFinalFittedParameters( m_fittedParameter); // do nothing except if overwritten by derived class // Output summary to log file std::string reportOfFit = gsl_strerror(status); g_log.information() << "Iteration = " << iter << "\n" << "Status = " << reportOfFit << "\n" << "Chi^2/DoF = " << finalCostFuncVal << "\n"; for (size_t i = 0; i < m_fittedParameter.size(); i++) g_log.information() << m_parameterNames[i] << " = " << m_fittedParameter[i] << " \n"; // also output summary to properties setProperty("OutputStatus", reportOfFit); setProperty("OutputChi2overDoF", finalCostFuncVal); for (size_t i = 0; i < m_fittedParameter.size(); i++) setProperty(m_parameterNames[i], m_fittedParameter[i]); std::string output = getProperty("Output"); if (!output.empty()) { // calculate covariance matrix if derivatives available gsl_matrix *covar(NULL); std::vector<double> standardDeviations; std::vector<double> sdExtended; if (isDerivDefined) { covar = gsl_matrix_alloc(l_data.p, l_data.p); gsl_multifit_covar(s->J, 0.0, covar); int iPNotFixed = 0; for (size_t i = 0; i < nParams(); i++) { sdExtended.push_back(1.0); if (l_data.active[i]) { sdExtended[i] = sqrt(gsl_matrix_get(covar, iPNotFixed, iPNotFixed)); iPNotFixed++; } } modifyFinalFittedParameters(sdExtended); for (size_t i = 0; i < nParams(); i++) if (l_data.active[i]) standardDeviations.push_back(sdExtended[i]); declareProperty( new WorkspaceProperty<API::ITableWorkspace>( "OutputNormalisedCovarianceMatrix", "", Direction::Output), "The name of the TableWorkspace in which to store the final " "covariance matrix"); setPropertyValue("OutputNormalisedCovarianceMatrix", output + "_NormalisedCovarianceMatrix"); Mantid::API::ITableWorkspace_sptr m_covariance = Mantid::API::WorkspaceFactory::Instance().createTable( "TableWorkspace"); m_covariance->addColumn("str", "Name"); std::vector<std::string> paramThatAreFitted; // used for populating 1st "name" column for (size_t i = 0; i < nParams(); i++) { if (l_data.active[i]) { m_covariance->addColumn("double", m_parameterNames[i]); paramThatAreFitted.push_back(m_parameterNames[i]); } } for (size_t i = 0; i < l_data.p; i++) { Mantid::API::TableRow row = m_covariance->appendRow(); row << paramThatAreFitted[i]; for (size_t j = 0; j < l_data.p; j++) { if (j == i) row << 1.0; else { row << 100.0 * gsl_matrix_get(covar, i, j) / sqrt(gsl_matrix_get(covar, i, i) * gsl_matrix_get(covar, j, j)); } } } setProperty("OutputNormalisedCovarianceMatrix", m_covariance); } declareProperty(new WorkspaceProperty<API::ITableWorkspace>( "OutputParameters", "", Direction::Output), "The name of the TableWorkspace in which to store the " "final fit parameters"); declareProperty( new WorkspaceProperty<MatrixWorkspace>("OutputWorkspace", "", Direction::Output), "Name of the output Workspace holding resulting simlated spectrum"); setPropertyValue("OutputParameters", output + "_Parameters"); setPropertyValue("OutputWorkspace", output + "_Workspace"); // Save the final fit parameters in the output table workspace Mantid::API::ITableWorkspace_sptr m_result = Mantid::API::WorkspaceFactory::Instance().createTable("TableWorkspace"); m_result->addColumn("str", "Name"); m_result->addColumn("double", "Value"); if (isDerivDefined) m_result->addColumn("double", "Error"); Mantid::API::TableRow row = m_result->appendRow(); row << "Chi^2/DoF" << finalCostFuncVal; for (size_t i = 0; i < nParams(); i++) { Mantid::API::TableRow row = m_result->appendRow(); row << m_parameterNames[i] << m_fittedParameter[i]; if (isDerivDefined && l_data.active[i]) { // perhaps want to scale standard deviations with sqrt(finalCostFuncVal) row << sdExtended[i]; } } setProperty("OutputParameters", m_result); // Save the fitted and simulated spectra in the output workspace MatrixWorkspace_const_sptr inputWorkspace = getProperty("InputWorkspace"); int iSpec = getProperty("WorkspaceIndex"); const MantidVec &inputX = inputWorkspace->readX(iSpec); const MantidVec &inputY = inputWorkspace->readY(iSpec); int histN = isHistogram ? 1 : 0; Mantid::DataObjects::Workspace2D_sptr ws = boost::dynamic_pointer_cast<Mantid::DataObjects::Workspace2D>( Mantid::API::WorkspaceFactory::Instance().create( "Workspace2D", 3, l_data.n + histN, l_data.n)); ws->setTitle(""); ws->getAxis(0)->unit() = inputWorkspace->getAxis(0) ->unit(); // UnitFactory::Instance().create("TOF"); for (int i = 0; i < 3; i++) ws->dataX(i) .assign(inputX.begin() + m_minX, inputX.begin() + m_maxX + histN); ws->dataY(0).assign(inputY.begin() + m_minX, inputY.begin() + m_maxX); MantidVec &Y = ws->dataY(1); MantidVec &E = ws->dataY(2); double *lOut = new double[l_data.n]; // to capture output from call to function() modifyInitialFittedParameters(m_fittedParameter); // does nothing except if // overwritten by derived // class function(&m_fittedParameter[0], lOut, l_data.X, l_data.n); modifyInitialFittedParameters(m_fittedParameter); // reverse the effect of // modifyInitialFittedParameters - if any for (unsigned int i = 0; i < l_data.n; i++) { Y[i] = lOut[i]; E[i] = l_data.Y[i] - Y[i]; } delete[] lOut; setProperty("OutputWorkspace", boost::dynamic_pointer_cast<MatrixWorkspace>(ws)); if (isDerivDefined) gsl_matrix_free(covar); } // clean up dynamically allocated gsl stuff if (isDerivDefined) gsl_multifit_fdfsolver_free(s); else { gsl_vector_free(simplexStepSize); gsl_multimin_fminimizer_free(simplexMinimizer); } delete[] l_data.X; delete[] l_data.sigmaData; delete[] l_data.forSimplexLSwrap; delete[] l_data.parameters; gsl_vector_free(initFuncArg); return; }
void ImageTile::FitBackground() { // Chose to use the Levenberg-Marquardt solver with scaling const gsl_multifit_fdfsolver_type * T = gsl_multifit_fdfsolver_lmsder; // Construct solver gsl_multifit_fdfsolver *solver = gsl_multifit_fdfsolver_alloc (T, _channelCount * _scanCount, _timeOrder + _freqOrder + 1); if(solver == 0) throw std::exception(); // Initialize function information structure gsl_multifit_function_fdf functionInfo; /*if(_useMPF) { functionInfo.f = &BaselineFunctionMPF; functionInfo.df = &BaselineDerivativeMPF; functionInfo.fdf = &BaselineCombinedMPF; // chose 256 bits precision for intermediate values in the evaluation of the function and its derivative mpf_set_default_prec (256); } else {*/ functionInfo.f = &BaselineFunction; functionInfo.df = &BaselineDerivative; functionInfo.fdf = &BaselineCombined; //} functionInfo.n = _channelCount * _scanCount; functionInfo.p = _timeOrder + _freqOrder + 1; functionInfo.params = this; // Initialize initial value of parameters //gsl_vector x; double x_init[_timeOrder + _freqOrder + 1]; for(int i = 0;i < _timeOrder + _freqOrder + 1;++i) x_init[i] = _baselineConsts[i]; gsl_vector_view x_view = gsl_vector_view_array (x_init, _timeOrder + _freqOrder + 1); gsl_multifit_fdfsolver_set (solver, &functionInfo, &x_view.vector); // Start iterating int status, iter=0; do { iter++; status = gsl_multifit_fdfsolver_iterate(solver); //PrintState(iter, solver); if (status && status != GSL_CONTINUE) { // std::cout << "Error: status = " << gsl_strerror (status) << std::endl; break; } status = gsl_multifit_test_delta(solver->dx, solver->x, 0, 0); } while (status == GSL_CONTINUE && iter < 250); // Save coefficients for(int i = 0;i<_freqOrder + _timeOrder + 1;++i) this->_baselineConsts[i] = gsl_vector_get(solver->x, i); //PrintState(iter, solver); // Clean up gsl_multifit_fdfsolver_free(solver); }
double fit_n(set_const* Init, double n0){ const gsl_multifit_fdfsolver_type *T; gsl_multifit_fdfsolver *s; int status; unsigned int i, iter = 0; const size_t n = 11; const size_t p = 5; double k = n0/0.16; gsl_matrix *covar = gsl_matrix_alloc (p, p); double y[11] = {4.45, 6.45 , 9.65, 13.29, 17.94, 22.92, 27.49, 38.82, 54.95, 75.13, 99.75}; double t[11] = {k*0.02,k*0.04, k*0.08,k*0.12,k*0.16,k*0.2,k*0.24, k*0.32, k*0.4,k*0.48, k*0.56}; struct data d = { n, y, t, Init}; gsl_multifit_function_fdf f; double x_init[5] = {Init->C_s,Init->C_o, Init->b,Init->c, Init->C_r}; //double x_init[6] = {11.56279437,7.49931859,0.00871711,0.00267620,0.86859184,0.5}; //double x_init[4] = { sqrt(130.746),sqrt(120.7244),1.0,10.0}; gsl_vector_view x = gsl_vector_view_array (x_init, p); const gsl_rng_type * type; gsl_rng * r; gsl_rng_env_setup(); type = gsl_rng_default; r = gsl_rng_alloc (type); f.f = &func_fit_n; f.df = NULL; f.fdf = NULL; f.n = n; f.p = p; f.params = &d; /* This is the data to be fitted */ /*for (i = 0; i < n; i++) { double t = i; y[i] = 1.0 + 5 * exp (-0.1 * t) + gsl_ran_gaussian (r, 0.1); sigma[i] = 0.1; printf ("data: %u %g %g\n", i, y[i], sigma[i]); };*/ T = gsl_multifit_fdfsolver_lmsder; s = gsl_multifit_fdfsolver_alloc (T, n, p); gsl_multifit_fdfsolver_set (s, &f, &x.vector); print_state (iter, s); do { iter++; status = gsl_multifit_fdfsolver_iterate (s); //printf ("status = %s\n", gsl_strerror (status)); print_state (iter, s); if (status) break; status = gsl_multifit_test_delta (s->dx, s->x, 1e-15, 0.0); } while (status == GSL_CONTINUE && iter < 2000); gsl_multifit_covar (s->J, 0.0, covar); #define FIT(i) gsl_vector_get(s->x, i) #define ERR(i) sqrt(gsl_matrix_get(covar,i,i)) cond(Init, FIT(0), FIT(1), FIT(2), FIT(3), FIT(4)); { double chi = gsl_blas_dnrm2(s->f); double dof = n - p; double c = GSL_MAX_DBL(1, chi / sqrt(dof)); //double c = 1.0; /*printf("chisq/dof = %g\n", pow(chi, 2.0) / dof); printf ("Cs = %.5f +/- %.5f\n", Init->C_s, c*ERR(0)); printf ("Co = %.5f +/- %.5f\n", Init->C_o, c*ERR(1)); printf ("b = %.5f +/- %.5f\n", Init->c, c*ERR(2)); printf ("c = %.5f +/- %.5f\n", Init->b, c*ERR(3)); printf ("Cr = %.5f +/- %.5f\n", Init->C_r, c*ERR(4));*/ } // printf ("status = %s\n", gsl_strerror (status)); double z = 0.65; gsl_matrix_free (covar); gsl_rng_free (r); double yi = 0; /*for (int i = 0; i < 11; i++){ double yi = EoS::t_E(t[i],0, Init)/(D*t[i]) - m_n ; printf("n = %.3f, %.3f %.3f %.3f \n", t[i], yi, y[i], yi-y[i]); }*/ /*return *(new set_const("APR_fit return constant set",FIT(0), FIT(1), 10.0, FIT(2),abs(FIT(3)), z, [](double f){return (1-f);}, [](double f){return 1.0;}, [=](double f){return eta_o(f);}, [](double f){return 1.0;}));*/ double rr = gsl_blas_dnrm2(s->x); gsl_multifit_fdfsolver_free (s); return rr; }
int main (void) { const gsl_multifit_fdfsolver_type *T; gsl_multifit_fdfsolver *s; int status; unsigned int i, iter = 0; const size_t n = N; const size_t p = 3; gsl_matrix *covar = gsl_matrix_alloc (p, p); double y[N], sigma[N]; struct data d = { n, y, sigma}; gsl_multifit_function_fdf f; double x_init[3] = { 1.0, 0.0, 0.0 }; gsl_vector_view x = gsl_vector_view_array (x_init, p); const gsl_rng_type * type; gsl_rng * r; gsl_rng_env_setup(); type = gsl_rng_default; r = gsl_rng_alloc (type); f.f = &expb_f; f.df = &expb_df; f.fdf = &expb_fdf; f.n = n; f.p = p; f.params = &d; /* This is the data to be fitted */ for (i = 0; i < n; i++) { double t = i; y[i] = 1.0 + 5 * exp (-0.1 * t) + gsl_ran_gaussian (r, 0.1); sigma[i] = 0.1; printf ("data: %u %g %g\n", i, y[i], sigma[i]); }; T = gsl_multifit_fdfsolver_lmsder; s = gsl_multifit_fdfsolver_alloc (T, n, p); gsl_multifit_fdfsolver_set (s, &f, &x.vector); print_state (iter, s); do { iter++; status = gsl_multifit_fdfsolver_iterate (s); printf ("status = %s\n", gsl_strerror (status)); print_state (iter, s); if (status) break; status = gsl_multifit_test_delta (s->dx, s->x, 1e-4, 1e-4); } while (status == GSL_CONTINUE && iter < 500); gsl_multifit_covar (s->J, 0.0, covar); #define FIT(i) gsl_vector_get(s->x, i) #define ERR(i) sqrt(gsl_matrix_get(covar,i,i)) { double chi = gsl_blas_dnrm2(s->f); double dof = n - p; double c = GSL_MAX_DBL(1, chi / sqrt(dof)); printf("chisq/dof = %g\n", pow(chi, 2.0) / dof); printf ("A = %.5f +/- %.5f\n", FIT(0), c*ERR(0)); printf ("lambda = %.5f +/- %.5f\n", FIT(1), c*ERR(1)); printf ("b = %.5f +/- %.5f\n", FIT(2), c*ERR(2)); } printf ("status = %s\n", gsl_strerror (status)); gsl_multifit_fdfsolver_free (s); gsl_matrix_free (covar); gsl_rng_free (r); return 0; }
void FitModel::train() { if (descriptor_matrix_.cols() == 0) { throw Exception::InconsistentUsage(__FILE__, __LINE__, "Data must be read into the model before training!"); } if (allEquations_.empty()) { cout<<"ERROR: No equations specified! Use method setEquations first."<<endl; return; } training_result_.resize(descriptor_matrix_.cols(), Y_.cols()); for (c = 0; c < (unsigned int)Y_.cols(); c++) { fitY = new Eigen::MatrixXd(Y_.rows(), 1); for (int n = 0; n < Y_.rows(); n++) { (*fitY)(n, 0) = Y_(n, c); } fitX = &descriptor_matrix_; equation = &allEquations_[c]; if (allDiffEquations_.size() < c) { diffEquations = &allDiffEquations_[c]; } else { diffEquations = NULL; } const gsl_multifit_fdfsolver_type* T = gsl_multifit_fdfsolver_lmsder; gsl_multifit_fdfsolver* s = gsl_multifit_fdfsolver_alloc(T, fitX->rows(), fitX->cols()); const size_t n = descriptor_matrix_.rows(); const size_t p = descriptor_matrix_.cols(); gsl_multifit_function_fdf fdf; fdf = make_fdf(&setF, &setDf, &setFdf, n, p, 0); double* g = new double[initial_guess_.size()]; for (unsigned int m = 0; m < initial_guess_.size(); m++) { g[m] = initial_guess_[m]; } gsl_vector_view ini = gsl_vector_view_array (g, p); gsl_multifit_fdfsolver_set(s, &fdf, &ini.vector); int status; for (unsigned int i = 0; i < 50; i++) { status = gsl_multifit_fdfsolver_iterate(s); } // save the predicted coefficients for (unsigned int m = 0; m < s->x->size; m++) { training_result_(m, c) = gsl_vector_get(s->x, m); } delete fitY; delete [] g; gsl_multifit_fdfsolver_free(s); } cout <<training_result_<<endl; }
int cspl_qrs_fit (void * params) { int status; unsigned int iter; struct cspl_qrs_data * data = (struct cspl_qrs_data *) params; /* This is the data to be fitted */ gsl_multifit_function_fdf f; // const gsl_rng_type * type; // gsl_rng * r; // gsl_rng_env_setup(); // type = gsl_rng_default; // r = gsl_rng_alloc (type); f.f = &cspl_qrs_f; f.df = &cspl_qrs_df; f.fdf = &cspl_qrs_fdf; f.n = data->n; f.p = data->p; f.params = data; gsl_multifit_fdfsolver_set (data->s, &f, &data->x.vector); iter = 0; //print_state (iter, data->s); do { iter++; status = gsl_multifit_fdfsolver_iterate (data->s); #ifdef DEBUG printf ("status = %s\n", gsl_strerror (status)); print_state (iter, data->s); #endif if (status) break; status = gsl_multifit_test_delta (data->s->dx, data->s->x, 1e-12, 1e-12); } while (status == GSL_CONTINUE && iter < 500); gsl_multifit_covar (data->s->J, 0.0, data->covar); double chi = gsl_blas_dnrm2(data->s->f); double dof = data->n - data->p; double c = GSL_MAX_DBL(1, chi / sqrt(dof)); data->c = c; data->chisq_pdof = pow(chi, 2.0) / dof; #ifdef DEBUG #define FIT(i) gsl_vector_get(data->s->x, i) #define ERR(i) sqrt(gsl_matrix_get(data->covar,i,i)) printf("chisq/dof = %g\n", pow(chi, 2.0) / dof); printf ("A = %.5f +/- %.5f\n", FIT(0), c*ERR(0)); printf ("t_beat = %.5f +/- %.5f\n", FIT(1), c*ERR(1)); printf ("S_0 = %.5f +/- %.5f\n", FIT(2), c*ERR(2)); printf ("S_1 = %.5f +/- %.5f\n", FIT(3), c*ERR(3)); printf ("status = %s\n", gsl_strerror (status)); #endif // gsl_rng_free (r); return GSL_SUCCESS; }
void test_fdf (const char * name, gsl_multifit_function_fdf * f, double x0[], double x_final[], double f_sumsq, double sigma[]) { const gsl_multifit_fdfsolver_type *T; gsl_multifit_fdfsolver *s; const size_t n = f->n; const size_t p = f->p; int status; size_t iter = 0; gsl_vector_view x = gsl_vector_view_array (x0, p); T = gsl_multifit_fdfsolver_lmsder; s = gsl_multifit_fdfsolver_alloc (T, n, p); gsl_multifit_fdfsolver_set (s, f, &x.vector); do { status = gsl_multifit_fdfsolver_iterate (s); #ifdef DEBUG printf("iter = %d status = %d |f| = %.18e x = \n", iter, status, gsl_blas_dnrm2 (s->f)); gsl_vector_fprintf(stdout, s->x, "%.8e"); #endif status = gsl_multifit_test_delta (s->dx, s->x, 0.0, 1e-7); iter++; } while (status == GSL_CONTINUE && iter < 1000); { size_t i; gsl_matrix * covar = gsl_matrix_alloc (p, p); gsl_multifit_covar (s->J, 0.0, covar); for (i = 0 ; i < p; i++) { gsl_test_rel (gsl_vector_get (s->x, i), x_final[i], 1e-5, "%s, lmsder, x%u", name, i); } { double s2 = pow(gsl_blas_dnrm2 (s->f), 2.0); gsl_test_rel (s2, f_sumsq, 1e-5, "%s, lmsder, |f|^2", name); for (i = 0; i < p; i++) { double ei = sqrt(s2/(n-p))*sqrt(gsl_matrix_get(covar,i,i)); gsl_test_rel (ei, sigma[i], 1e-4, "%s, sigma(%d)", name, i) ; } } gsl_matrix_free (covar); } gsl_multifit_fdfsolver_free (s); }
/******************************************************************************* * fit_gaussian * Fit data to a guassian and return the results. Ideally, this should give the * same results as scipy.optimize.curve_fit. * Input: * hist: Histogram to fit the gaussian to * Output: * chisq: Chi^2 of the histogram * ndf: Number of degrees of freedom of the fit * fit_params: Fit parameters ******************************************************************************/ gsl_vector *fit_gaussian(gsl_histogram *hist, double *chisq, long *ndf, gsl_matrix *covar){ double tol; double *hbin, *hrange, bin_width, xdata, min, max; double magnitude, mean, sigma; double error, ythr; int status; long gpars, nonzero, nbins; long i; gsl_vector *pars, *fit_params; gsl_multifit_fdfsolver *gfit; gsl_multifit_function_fdf gaus; const gsl_multifit_fdfsolver_type *ftype; /* Allowed relative error is what scipy uses */ /* tol = 1.49012e-8; scipy least squares default */ tol = 1e-14; /* get number of bins containing data */ nbins = hist -> n; hbin = hist -> bin; hrange = hist -> range; nonzero = 0; for (i=0; i<nbins; i++){ if (hbin[i]) nonzero++; } /* Set the function */ gaus.f = &gaus_f; gaus.df = &gaus_df; gaus.fdf = &gaus_fdf; gaus.n = nonzero; gaus.p = 3; gaus.params = hist; /* Initialize the solver */ gpars = 3; pars = gsl_vector_alloc(gpars); gsl_vector_set_all(pars, 1.0); ftype = gsl_multifit_fdfsolver_lmsder; gfit = gsl_multifit_fdfsolver_alloc(ftype, nonzero, gpars); gsl_multifit_fdfsolver_set(gfit, &gaus, pars); /* loop the solver and solve this thing */ do { status = gsl_multifit_fdfsolver_iterate(gfit); status = gsl_multifit_test_delta(gfit -> dx, gfit -> x, 0, tol); } while (status == GSL_CONTINUE); magnitude = gsl_vector_get(gfit -> x, 0); mean = gsl_vector_get(gfit -> x, 1); /* The fitted sigma might be negative, but it is squared when computing the * gaussian, so taking the absolute value of sigma is ok */ sigma = fabs(gsl_vector_get(gfit -> x, 2)); /* Compute the chi^2 */ min = hrange[0]; max = hrange[nbins]; bin_width = (max - min) / nbins; *chisq = 0; for (i = 0; i<nbins; i++){ if (hbin[i]){ xdata = hrange[i] + bin_width/2.0; error = sqrt(hbin[i]); ythr = gaussian(xdata, magnitude, mean, sigma); *chisq += pow((hbin[i] - ythr)/error, 2); } } *ndf = nonzero - gpars; /* Copy results to return vector */ fit_params = gsl_vector_alloc(gpars); gsl_vector_memcpy(fit_params, gfit -> x); /* Compute the covariance matrix */ gsl_multifit_covar(gfit -> J, 0.0, covar); /* Free the solver's memory */ gsl_vector_free(pars); gsl_multifit_fdfsolver_free(gfit); /* Return the results of the fit */ return fit_params; }
void PlaneDetector::solve() { // prepare calculation data DetectionData baseData; // prepare gsl variables const gsl_multifit_fdfsolver_type *T; gsl_multifit_fdfsolver *s; int n = (int)data.size(); #ifdef VECTOR_SOLVER const int p = 4; double x_init[p] = {0.0, 0.0, 1.0, 0.0}; #endif #ifdef ANGLE_SOLVER const int p = 3; // double x_init[p] = {0.0, 0.0, 0.0}; double x_init[p] = {0.0, 90.0 / 180.0 * M_PI, 0.0}; #endif #ifdef VECTOR2_SOLVER const int p = 6; // double x_init[p] = {1.0, 0.0, 0.0, 500.0, 0.0, 0.0}; double x_init[p] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0}; #endif #ifdef ANGLE2_SOLVER const int p = 5; double x_init[p] = {0.0, M_PI / 2.0 + 0.1, 000.0, 0.0, 0.0}; #endif gsl_multifit_function_fdf f; f.f = &pd_func_f; f.df = &pd_func_df; f.fdf = &pd_func_fdf; f.n = n; f.p = p; f.params = &data; gsl_vector_view x = gsl_vector_view_array(x_init, p); T = gsl_multifit_fdfsolver_lmsder; s = gsl_multifit_fdfsolver_alloc(T, n, p); gsl_multifit_fdfsolver_set(s, &f, &x.vector); gsl_vector *gradt = gsl_vector_alloc(p); int iter = 0; int status; do { iter ++; status = gsl_multifit_fdfsolver_iterate(s); if (status) { // printf ("error: %s\n", gsl_strerror (status)); break; } gsl_multifit_gradient(s->J, s->f, gradt); status = gsl_multifit_test_gradient(gradt, 1e-6); } while (status == GSL_CONTINUE && iter < 10000); #ifdef VECTOR_SOLVER vN = Vector( gsl_vector_get(s->x, 0), gsl_vector_get(s->x, 1), gsl_vector_get(s->x, 2)).getUnitVector(); fD = gsl_vector_get(s->x, 3); #endif #ifdef ANGLE_SOLVER double theta = gsl_vector_get(s->x, 0); double pi = gsl_vector_get(s->x, 1); vN = Vector(sin(pi)*cos(theta), sin(pi)*sin(theta), cos(pi)); double d = gsl_vector_get(s->x, 2); fD = - ((vN & vListener) + d); #endif #ifdef VECTOR2_SOLVER vN = Vector( gsl_vector_get(s->x, 0), gsl_vector_get(s->x, 1), gsl_vector_get(s->x, 2)).getUnitVector(); Vector vX1 = Vector( gsl_vector_get(s->x, 3), gsl_vector_get(s->x, 4), gsl_vector_get(s->x, 5)); fD = -(vN & vX1); #endif #ifdef ANGLE2_SOLVER double theta = gsl_vector_get(s->x, 0); double pi = gsl_vector_get(s->x, 1); vN = Vector(sin(pi)*cos(theta), sin(pi)*sin(theta), cos(pi)); Vector vX1 = Vector( gsl_vector_get(s->x, 2), gsl_vector_get(s->x, 3), gsl_vector_get(s->x, 4)); fD = -(vN & vX1); #endif #if 0 for (double pp = 0; pp < M_PI; pp += 0.1) { for (double tt = 0; tt < M_PI; tt += 0.1) { Vector vNN = Vector(sin(pp)*cos(tt), sin(pp)*sin(tt), cos(pp)); printf("vN = "); vNN.print(); double sum = 0; for (size_t i = 0; i < data.size(); i++) { sum += pow(data[i].getF(tt, pp, fD), 2); } printf(" , sum = %f\n", sum); } } #endif #if 0 double sqrsum = 0; for (size_t i = 0; i < data.size(); i++) { #ifdef VECTOR_SOLVER sqrsum += pow(data[i].getF(vN, fD), 2); #endif #ifdef ANGLE_SOLVER sqrsum += pow(data[i].getF(theta, pi, fD), 2); #endif #ifdef VECTOR2_SOLVER sqrsum += pow(data[i].getF(vN, fD), 2); #endif // printf ("%f/", sqrsum); } vN.print(); printf(" %f %f\n", fD, sqrt(sqrsum)); #endif // for (size_t i = 0; i < data.size(); i++) // printf ("F_%d = %f\n", i, data[i].getF(vN)); gsl_vector_free(gradt); gsl_multifit_fdfsolver_free(s); vP.clear(); for (size_t i = 0; i < data.size(); i++) { vP.push_back(data[i].getP(vN)); } }
//Fitting. Allow fitting multiple q curves simultaneously to decrease the chance of converging to local minimum. void ddm::fitting() { int cnum_fit=num_fit; int ctimeWindow=timeWindow; //Find the truncation time if time window is set for (int itert=0; itert<num_fit; ++itert) { if (tau[itert]>ctimeWindow) { cnum_fit=itert; break; } } //Local variables int cqsize=qsize-qIncreList[num_qCurve-1]; //number of fitting result int cnum_qCurve=num_qCurve; int ctnum_fit=cnum_fit*num_qCurve; int cnumOfPara=numOfPara+2*num_qCurve; //Total number of parameters fittedPara=gsl_matrix_alloc(cqsize, cnumOfPara); //To store the fitting result and error. fitErr=gsl_matrix_alloc(cqsize, cnumOfPara); status = new int[cqsize]; //Record the status of fitting. //Using Levenberg-Marquardt algorithm as implemented in the scaled lmder routine in minpack. Jacobian is given. const gsl_multifit_fdfsolver_type *solverType = gsl_multifit_fdfsolver_lmsder; int progress=0; //Indicator of progress. //Objects to do numerical inverse Laplace transformation #ifdef ISFRTD NILT NILT1(OMP_NUM_THREADS), NILT2(OMP_NUM_THREADS), NILT3(OMP_NUM_THREADS), NILT4(OMP_NUM_THREADS); #endif #ifdef ISFRTDP NILT NILT1(OMP_NUM_THREADS), NILT2(OMP_NUM_THREADS), NILT3(OMP_NUM_THREADS), NILT4(OMP_NUM_THREADS), NILT5(OMP_NUM_THREADS); #endif #ifdef ISFRTDPTT NILT NILT1(OMP_NUM_THREADS), NILT2(OMP_NUM_THREADS), NILT3(OMP_NUM_THREADS), NILT4(OMP_NUM_THREADS), NILT5(OMP_NUM_THREADS), NILT6(OMP_NUM_THREADS); #endif #ifdef ISFRTDPfix NILT NILT1(OMP_NUM_THREADS), NILT2(OMP_NUM_THREADS); const long double vbar=vbarGuess; const long double sigma=sigmaGuess; const long double vbsigma2=vbar/sigma/sigma; const long double vb2sigma2=vbsigma2*vbar; const long double logvbsigma2=log(vbsigma2); const long double logfactor=vb2sigma2*logvbsigma2-gsl_sf_lngamma(vb2sigma2); const long double cpsiz1=logvbsigma2-gsl_sf_psi(vb2sigma2); const long double vb2sigma3=vb2sigma2/sigma; #endif #ifdef ISFRTDPTTfix NILT NILT1(OMP_NUM_THREADS), NILT2(OMP_NUM_THREADS), NILT3(OMP_NUM_THREADS); const long double vbar=vbarGuess; const long double sigma=sigmaGuess; const long double vbsigma2=vbar/sigma/sigma; const long double vb2sigma2=vbsigma2*vbar; const long double logvbsigma2=log(vbsigma2); const long double logfactor=vb2sigma2*logvbsigma2-gsl_sf_lngamma(vb2sigma2); const long double cpsiz1=logvbsigma2-gsl_sf_psi(vb2sigma2); const long double vb2sigma3=vb2sigma2/sigma; #endif #pragma omp parallel for for (int iterq=0; iterq<cqsize; ++iterq) { //Data array which is going to present to the fitting algorithm double* datafit=new double[ctnum_fit]; double* qList=new double[cnum_qCurve]; double* time=new double[ctnum_fit]; //Truncate the data, and put multiple curves into one array for (int iterqc=0; iterqc<cnum_qCurve; ++iterqc) { for (int iterf = 0; iterf < cnum_fit; ++iterf) { datafit[iterf+iterqc*cnum_fit]=(gsl_matrix_get(datag, iterq+qIncreList[iterqc], iterf)); //Fitting in log scale. time[iterf+iterqc*cnum_fit]=tau[iterf]; } qList[iterqc]=qabs[iterq+qIncreList[iterqc]]; } gsl_multifit_function_fdf fitfun; //Pointer of function to fit. dataStruct sdata; //GSL data structure //Data is passed to ISFfun by sdata sdata.data=datafit; sdata.tau=time; sdata.q=qList; sdata.num_fit=cnum_fit; sdata.num_qCurve=cnum_qCurve; #ifdef ISFRTD sdata.ISFILT=&NILT1; sdata.dvISFILT=&NILT2; sdata.dDISFILT=&NILT3; sdata.dlambdaISFILT=&NILT4; #endif #ifdef ISFRTDP sdata.ISFILT=&NILT1; sdata.dvbarISFILT=&NILT2; sdata.dsigmaISFILT=&NILT3; sdata.dDISFILT=&NILT4; sdata.dlambdaISFILT=&NILT5; #endif #ifdef ISFRTDPTT sdata.ISFILT=&NILT1; sdata.dvbarISFILT=&NILT2; sdata.dsigmaISFILT=&NILT3; sdata.dDISFILT=&NILT4; sdata.dlambdaISFILT=&NILT5; sdata.dTTISFILT=&NILT6; #endif #ifdef ISFRTDPfix sdata.alpha=alphaGuess; sdata.D=DGuess; sdata.vbar=vbar; sdata.sigma=sigma; sdata.vbsigma2=vbsigma2; sdata.logfactor=logfactor; sdata.vb2sigma2=vb2sigma2; sdata.cpsiz1=cpsiz1; sdata.vb2sigma3=vb2sigma3; sdata.ISFILT=&NILT1; sdata.dlambdaISFILT=&NILT2; #endif #ifdef ISFRTDPTTfix sdata.alpha=alphaGuess; sdata.D=DGuess; sdata.vbar=vbar; sdata.sigma=sigma; sdata.vbsigma2=vbsigma2; sdata.logfactor=logfactor; sdata.vb2sigma2=vb2sigma2; sdata.cpsiz1=cpsiz1; sdata.vb2sigma3=vb2sigma3; sdata.ISFILT=&NILT1; sdata.dlambdaISFILT=&NILT2; sdata.dTTISFILT=&NILT3; #endif //API fitfun.f=&ISFfun; #ifdef NoJacobian fitfun.df=0; fitfun.fdf=0; #else fitfun.df=&dISFfun; fitfun.fdf=&fdISFfun; #endif fitfun.n=ctnum_fit; fitfun.p=cnumOfPara; fitfun.params=&sdata; //Initialization of the parameters double* localinipara=new double[cnumOfPara]; for (int iterp=0; iterp<numOfPara; ++iterp) { localinipara[iterp]=inipara[iterp]; } //Estimation of A(q) and B(q) for (int iterqc=0; iterqc<num_qCurve; ++iterqc) { localinipara[numOfPara+1+2*iterqc] = gsl_matrix_get(datag, iterq+qIncreList[iterqc], 0); localinipara[numOfPara+2*iterqc] = gsl_matrix_get(datag, iterq+qIncreList[iterqc], num_fit-1)-localinipara[numOfPara+1+2*iterqc]; } //Initiallization of the solver gsl_vector_view para=gsl_vector_view_array(localinipara, cnumOfPara); gsl_multifit_fdfsolver* solver = gsl_multifit_fdfsolver_alloc(solverType, ctnum_fit, cnumOfPara); gsl_multifit_fdfsolver_set(solver, &fitfun, ¶.vector); int iter=0; //gsl_vector* g=gsl_vector_alloc(numOfPara); //For debugging and monitering the iterations // cout << qList[0] << ' ' << qList[1] << '\n'; // for (int iterpara=0; iterpara<cnumOfPara; ++iterpara) // { // cout << gsl_vector_get(solver->x, iterpara) << '\n'; // } // cout << '\n'; int cstatus=GSL_CONTINUE; //Current status do { gsl_multifit_fdfsolver_iterate(solver); //Iterate one step. cstatus = norm0_rel_test(solver->dx, solver->x, 1e-7, 1e-7); //Test the exiting criteria //For debugging and monitering the iterations // for (int iterpara=0; iterpara<cnumOfPara; ++iterpara) // { // cout << gsl_vector_get(solver->x, iterpara) << '\n'; // } // cout << '\n'; //If to use other exiting criteria //gsl_multifit_gradient(solver->J,solver->f, g); //status[iterq-1]=gsl_multifit_test_gradient(g, 1e-5); // status[iterq - 1] = covar_rel_test(solver->J, solver->x, 1e-4); ++iter; //Number of iterations exceed certain limitation if (iter>maxIter) { cstatus=GSL_EMAXITER; } } while (cstatus == GSL_CONTINUE); status[iterq]=cstatus; //gsl_vector_free(g); //Estimating the error. gsl_matrix* covar=gsl_matrix_alloc(cnumOfPara, cnumOfPara); gsl_multifit_covar(solver->J, 0.0, covar); for (int iterpara=0; iterpara<cnumOfPara; ++iterpara) //Record result. { gsl_matrix_set(fittedPara, iterq, iterpara, gsl_vector_get(solver->x, iterpara) ); gsl_matrix_set(fitErr, iterq, iterpara, sqrt(gsl_matrix_get(covar, iterpara, iterpara)) ); //Not presice in log scale } gsl_matrix_free(covar); gsl_multifit_fdfsolver_free(solver); //Output to standard I/O progress+=1; cout << "Fitted q=" << qabs[iterq] << " at iter=" << iter << ", " << 100.0*progress / qsize << "% completed from thread No." << omp_get_thread_num() << ", "<< gsl_strerror(status[iterq]) << "." << '\n'; for (int iterpara=0; iterpara<cnumOfPara; ++iterpara) { cout << gsl_matrix_get(fittedPara, iterq, iterpara) << '\n'; } cout << '\n'; delete [] datafit; delete [] qList; delete [] localinipara; delete [] time; } }
int OptimizationOptions::gslOptimize( NLSFunction *F, gsl_vector* x_vec, gsl_matrix *v, IterationLogger *itLog ) { const gsl_multifit_fdfsolver_type *Tlm[] = { gsl_multifit_fdfsolver_lmder, gsl_multifit_fdfsolver_lmsder }; const gsl_multimin_fdfminimizer_type *Tqn[] = { gsl_multimin_fdfminimizer_vector_bfgs, gsl_multimin_fdfminimizer_vector_bfgs2, gsl_multimin_fdfminimizer_conjugate_fr, gsl_multimin_fdfminimizer_conjugate_pr }; const gsl_multimin_fminimizer_type *Tnm[] = { gsl_multimin_fminimizer_nmsimplex, gsl_multimin_fminimizer_nmsimplex2, gsl_multimin_fminimizer_nmsimplex2rand }; int gsl_submethod_max[] = { sizeof(Tlm) / sizeof(Tlm[0]), sizeof(Tqn) / sizeof(Tqn[0]), sizeof(Tnm) / sizeof(Tnm[0]) }; int status, status_dx, status_grad, k; double g_norm, x_norm; /* vectorize x row-wise */ size_t max_ind, min_ind; double max_val, min_val, abs_max_val = 0, abs_min_val; if (this->method < 0 || this->method > sizeof(gsl_submethod_max)/sizeof(gsl_submethod_max[0]) || this->submethod < 0 || this->submethod > gsl_submethod_max[this->method]) { throw new Exception("Unknown optimization method.\n"); } if (this->maxiter < 0 || this->maxiter > 5000) { throw new Exception("opt.maxiter should be in [0;5000].\n"); } /* LM */ gsl_multifit_fdfsolver* solverlm; gsl_multifit_function_fdf fdflm = { &(F->_f_ls), &(F->_df_ls), &(F->_fdf_ls), F->getNsq(), F->getNvar(), F }; gsl_vector *g; /* QN */ double stepqn = this->step; gsl_multimin_fdfminimizer* solverqn; gsl_multimin_function_fdf fdfqn = { &(F->_f), &(F->_df), &(F->_fdf), F->getNvar(), F }; /* NM */ double size; gsl_vector *stepnm; gsl_multimin_fminimizer* solvernm; gsl_multimin_function fnm = { &(F->_f), F->getNvar(), F }; /* initialize the optimization method */ switch (this->method) { case SLRA_OPT_METHOD_LM: /* LM */ solverlm = gsl_multifit_fdfsolver_alloc(Tlm[this->submethod], F->getNsq(), F->getNvar()); gsl_multifit_fdfsolver_set(solverlm, &fdflm, x_vec); g = gsl_vector_alloc(F->getNvar()); break; case SLRA_OPT_METHOD_QN: /* QN */ solverqn = gsl_multimin_fdfminimizer_alloc(Tqn[this->submethod], F->getNvar() ); gsl_multimin_fdfminimizer_set(solverqn, &fdfqn, x_vec, stepqn, this->tol); status_dx = GSL_CONTINUE; break; case SLRA_OPT_METHOD_NM: /* NM */ solvernm = gsl_multimin_fminimizer_alloc(Tnm[this->submethod], F->getNvar()); stepnm = gsl_vector_alloc(F->getNvar()); gsl_vector_set_all(stepnm, this->step); gsl_multimin_fminimizer_set( solvernm, &fnm, x_vec, stepnm ); break; } /* optimization loop */ Log::lprintf(Log::LOG_LEVEL_FINAL, "SLRA optimization:\n"); status = GSL_SUCCESS; status_dx = GSL_CONTINUE; status_grad = GSL_CONTINUE; this->iter = 0; switch (this->method) { case SLRA_OPT_METHOD_LM: gsl_blas_ddot(solverlm->f, solverlm->f, &this->fmin); gsl_multifit_gradient(solverlm->J, solverlm->f, g); gsl_vector_scale(g, 2); { gsl_vector *g2 = gsl_vector_alloc(g->size); F->computeFuncAndGrad(x_vec, NULL, g2); gsl_vector_sub(g2, g); if (gsl_vector_max(g2) > 1e-10 || gsl_vector_min(g2) < -1e-10) { Log::lprintf(Log::LOG_LEVEL_NOTIFY, "Gradient error, max = %14.10f, min = %14.10f ...", gsl_vector_max(g2), gsl_vector_min(g2)); print_vec(g2); } gsl_vector_free(g2); } if (itLog != NULL) { itLog->reportIteration(0, solverlm->x, this->fmin, g); } break; case SLRA_OPT_METHOD_QN: this->fmin = gsl_multimin_fdfminimizer_minimum(solverqn); if (itLog != NULL) { itLog->reportIteration(0, solverqn->x, this->fmin, solverqn->gradient); } break; case SLRA_OPT_METHOD_NM: this->fmin = gsl_multimin_fminimizer_minimum( solvernm ); if (itLog != NULL) { itLog->reportIteration(this->iter, solvernm->x, this->fmin, NULL); } break; } while (status_dx == GSL_CONTINUE && status_grad == GSL_CONTINUE && status == GSL_SUCCESS && this->iter < this->maxiter) { if (this->method == SLRA_OPT_METHOD_LM && this->maxx > 0) { if (gsl_vector_max(solverlm->x) > this->maxx || gsl_vector_min(solverlm->x) < -this->maxx ){ break; } } this->iter++; switch (this->method) { case SLRA_OPT_METHOD_LM: /* Levenberg-Marquardt */ status = gsl_multifit_fdfsolver_iterate(solverlm); gsl_multifit_gradient(solverlm->J, solverlm->f, g); gsl_vector_scale(g, 2); /* check the convergence criteria */ if (this->epsabs != 0 || this->epsrel != 0) { status_dx = gsl_multifit_test_delta(solverlm->dx, solverlm->x, this->epsabs, this->epsrel); } else { status_dx = GSL_CONTINUE; } status_grad = gsl_multifit_test_gradient(g, this->epsgrad); gsl_blas_ddot(solverlm->f, solverlm->f, &this->fmin); if (itLog != NULL) { itLog->reportIteration(this->iter, solverlm->x, this->fmin, g); } break; case SLRA_OPT_METHOD_QN: status = gsl_multimin_fdfminimizer_iterate( solverqn ); /* check the convergence criteria */ status_grad = gsl_multimin_test_gradient( gsl_multimin_fdfminimizer_gradient(solverqn), this->epsgrad); status_dx = gsl_multifit_test_delta(solverqn->dx, solverqn->x, this->epsabs, this->epsrel); this->fmin = gsl_multimin_fdfminimizer_minimum(solverqn); if (itLog != NULL) { itLog->reportIteration(this->iter, solverqn->x, this->fmin, solverqn->gradient); } break; case SLRA_OPT_METHOD_NM: status = gsl_multimin_fminimizer_iterate( solvernm ); /* check the convergence criteria */ size = gsl_multimin_fminimizer_size( solvernm ); status_dx = gsl_multimin_test_size( size, this->epsx ); this->fmin = gsl_multimin_fminimizer_minimum( solvernm ); if (itLog != NULL) { itLog->reportIteration(this->iter, solvernm->x, this->fmin, NULL); } break; } } if (this->iter >= this->maxiter) { status = EITER; } switch (this->method) { case SLRA_OPT_METHOD_LM: gsl_vector_memcpy(x_vec, solverlm->x); if (v != NULL) { gsl_multifit_covar(solverlm->J, this->epscov, v); /* ??? Different eps */ } gsl_blas_ddot(solverlm->f, solverlm->f, &this->fmin); break; case SLRA_OPT_METHOD_QN: gsl_vector_memcpy(x_vec, solverqn->x); this->fmin = solverqn->f; break; case SLRA_OPT_METHOD_NM: gsl_vector_memcpy(x_vec, solvernm->x); this->fmin = solvernm->fval; break; } /* print exit information */ if (Log::getMaxLevel() >= Log::LOG_LEVEL_FINAL) { /* unless "off" */ switch (status) { case EITER: Log::lprintf("SLRA optimization terminated by reaching " "the maximum number of iterations.\n" "The result could be far from optimal.\n"); break; case GSL_ETOLF: Log::lprintf("Lack of convergence: " "progress in function value < machine EPS.\n"); break; case GSL_ETOLX: Log::lprintf("Lack of convergence: " "change in parameters < machine EPS.\n"); break; case GSL_ETOLG: Log::lprintf("Lack of convergence: " "change in gradient < machine EPS.\n"); break; case GSL_ENOPROG: Log::lprintf("Possible lack of convergence: no progress.\n"); break; } if (status_grad != GSL_CONTINUE && status_dx != GSL_CONTINUE) { Log::lprintf("Optimization terminated by reaching the convergence " "tolerance for both X and the gradient.\n"); } else { if (status_grad != GSL_CONTINUE) { Log::lprintf("Optimization terminated by reaching the convergence " "tolerance for the gradient.\n"); } else { Log::lprintf("Optimization terminated by reaching the convergence " "tolerance for X.\n"); } } } /* Cleanup */ switch (this->method) { case SLRA_OPT_METHOD_LM: /* LM */ gsl_multifit_fdfsolver_free(solverlm); gsl_vector_free(g); break; case SLRA_OPT_METHOD_QN: /* QN */ gsl_multimin_fdfminimizer_free(solverqn); break; case SLRA_OPT_METHOD_NM: /* NM */ gsl_multimin_fminimizer_free(solvernm); gsl_vector_free(stepnm); break; } return GSL_SUCCESS; /* <- correct with status */ }
double *Fit::fitGslMultifit(int &iterations, int &status) { double *result = new double[d_p]; // declare input data struct FitData data = {static_cast<size_t>(d_n), static_cast<size_t>(d_p), d_x, d_y, d_y_errors, this}; gsl_multifit_function_fdf f; f.f = d_f; f.df = d_df; f.fdf = d_fdf; f.n = d_n; f.p = d_p; f.params = &data; // initialize solver const gsl_multifit_fdfsolver_type *T; switch (d_solver) { case ScaledLevenbergMarquardt: T = gsl_multifit_fdfsolver_lmsder; break; case UnscaledLevenbergMarquardt: T = gsl_multifit_fdfsolver_lmder; break; default: break; } gsl_multifit_fdfsolver *s = gsl_multifit_fdfsolver_alloc(T, d_n, d_p); gsl_multifit_fdfsolver_set(s, &f, d_param_init); // iterate solver algorithm for (iterations = 0; iterations < d_max_iterations; iterations++) { status = gsl_multifit_fdfsolver_iterate(s); if (status) break; status = gsl_multifit_test_delta(s->dx, s->x, d_tolerance, d_tolerance); if (status != GSL_CONTINUE) break; } // grab results for (int i = 0; i < d_p; i++) result[i] = gsl_vector_get(s->x, i); gsl_blas_ddot(s->f, s->f, &chi_2); #if GSL_MAJOR_VERSION < 2 gsl_multifit_covar(s->J, 0.0, covar); #else { gsl_matrix J; gsl_multifit_fdfsolver_jac(s, &J); gsl_multifit_covar(&J, 0.0, covar); } #endif if (d_y_error_source == UnknownErrors) { // multiply covar by variance of residuals, which is used as an estimate for // the // statistical errors (this relies on the Y errors being set to 1.0, so that // s->f is properly normalized) gsl_matrix_scale(covar, chi_2 / (d_n - d_p)); } // free memory allocated for fitting gsl_multifit_fdfsolver_free(s); return result; }
GammaDistributionFitter::GammaDistributionFitResult GammaDistributionFitter::fit(vector<DPosition<2> > & input) { const gsl_multifit_fdfsolver_type * T = NULL; gsl_multifit_fdfsolver * s = NULL; int status = 0; size_t iter = 0; const size_t p = 2; gsl_multifit_function_fdf f; double x_init[2] = { init_param_.b, init_param_.p }; gsl_vector_view x = gsl_vector_view_array(x_init, p); const gsl_rng_type * type = NULL; gsl_rng * r = NULL; gsl_rng_env_setup(); type = gsl_rng_default; r = gsl_rng_alloc(type); f.f = &gammaDistributionFitterf_; f.df = &gammaDistributionFitterdf_; f.fdf = &gammaDistributionFitterfdf_; f.n = input.size(); f.p = p; f.params = &input; T = gsl_multifit_fdfsolver_lmsder; s = gsl_multifit_fdfsolver_alloc(T, input.size(), p); gsl_multifit_fdfsolver_set(s, &f, &x.vector); #ifdef GAMMA_DISTRIBUTION_FITTER_VERBOSE printState_(iter, s); #endif do { ++iter; status = gsl_multifit_fdfsolver_iterate(s); #ifdef GAMMA_DISTRIBUTION_FITTER_VERBOSE printf("status = %s\n", gsl_strerror(status)); printState_(iter, s); #endif if (status) { break; } status = gsl_multifit_test_delta(s->dx, s->x, 1e-4, 1e-4); #ifdef GAMMA_DISTRIBUTION_FITTER_VERBOSE printf("Status = '%s'\n", gsl_strerror(status)); #endif } while (status == GSL_CONTINUE && iter < 1000); #ifdef GAMMA_DISTRIBUTION_FITTER_VERBOSE printf("Final status = '%s'\n", gsl_strerror(status)); #endif if (status != GSL_SUCCESS) { gsl_rng_free(r); gsl_multifit_fdfsolver_free(s); throw Exception::UnableToFit(__FILE__, __LINE__, __PRETTY_FUNCTION__, "UnableToFit-GammaDistributionFitter", "Could not fit the gamma distribution to the data"); } // write the result in a GammaDistributionFitResult struct GammaDistributionFitResult result; result.b = gsl_vector_get(s->x, 0); result.p = gsl_vector_get(s->x, 1); // build a formula with the fitted parameters for gnuplot stringstream formula; formula << "f(x)=" << "(" << result.b << " ** " << result.p << ") / gamma(" << result.p << ") * x ** (" << result.p << " - 1) * exp(- " << result.b << " * x)"; gnuplot_formula_ = formula.str(); #ifdef GAMMA_DISTRIBUTION_FITTER_VERBOSE cout << gnuplot_formula_ << endl; #endif gsl_rng_free(r); gsl_multifit_fdfsolver_free(s); return result; }
int K_minimize_lm(ok_kernel* k, int maxiter, double params[]) { double min_chi_par = 1e-4; K_calculate(k); double prev_chi2 = k->chi2; bool high_df = false; int max_iter_at_scale = 200; double initial_st = 1.; int max_kt = 1; for (int i = 0; i < k->ndata; i++) if (k->compiled[i][T_FLAG] == T_TIMING) { high_df = true; max_kt = 2; max_iter_at_scale = 500; break; } if (params != NULL) { int i = 0; while (true) { if (params[i] == DONE) break; if (params[i] == OPT_LM_MINCHI_PAR) min_chi_par = params[i+1]; else if (params[i] == OPT_LM_HIGH_DF) high_df = !((int) params[i+1] == 0); else if (params[i] == OPT_LM_MAX_ITER_AT_SCALE) max_iter_at_scale = (int) params[i+1]; else if (params[i] == OPT_LM_INITIAL_SCALE) initial_st = params[i+1]; i+=2; } } unsigned int npars = 0; // Count all the parameters to minimize on for (int i = 1; i < k->system->nplanets + 1; i++) for (int j = 0; j < ELEMENTS_SIZE; j++) npars += (MIGET(k->plFlags, i, j) & MINIMIZE ? 1 : 0); for (int i = 0; i < k->parFlags->size; i++) npars += (VIGET(k->parFlags, i) & MINIMIZE ? 1 : 0); if (npars == 0) return 0; // Create a pointer table (flat array -> matrices) double** pars = (double**) malloc(sizeof(double*) * npars); double prevpars[npars]; double* steps = (double*) malloc(npars * sizeof(double)); double* stepscale = (double*) malloc(npars * sizeof(double)); int* parstype = (int*) malloc(npars * sizeof(int)); gsl_vector* x = gsl_vector_alloc(npars); int idx = 0; for (int i = 1; i < k->system->nplanets + 1; i++) for (int j = 0; j < ELEMENTS_SIZE; j++) if (MIGET(k->plFlags, i, j) & MINIMIZE) { pars[idx] = gsl_matrix_ptr(k->system->elements, i, j); x->data[idx] = MGET(k->system->elements, i, j); prevpars[idx] = x->data[idx]; steps[idx] = stepscale[idx] = MGET(k->plSteps, i, j); parstype[idx] = j; if (steps[idx] < 1e-10) { printf("Warning: step for element %d of planet %d is <= 0\n", j, i); } idx++; } for (int i = 0; i < k->parFlags->size; i++) if (VIGET(k->parFlags, i) & MINIMIZE) { pars[idx] = gsl_vector_ptr(k->params, i); x->data[idx] = VGET(k->params, i); prevpars[idx] = x->data[idx]; steps[idx] = stepscale[idx] = VGET(k->parSteps, i); parstype[idx] = PARTYPE_PAR; if (steps[idx] < 1e-10) printf("Warning: step for parameter %d is <= 0\n", i); idx++; } gsl_multifit_fdfsolver * s = gsl_multifit_fdfsolver_alloc (gsl_multifit_fdfsolver_lmsder, k->ndata, npars); ok_lm_params sp; sp.k = k; sp.pars = pars; sp.best = (double*) malloc(sizeof(double) * npars); sp.stepscale = stepscale; sp.compiled = k->compiled; sp.f0 = (double*) malloc(sizeof(double)*k->ndata); sp.f1 = (double*) malloc(sizeof(double)*k->ndata); sp.f2 = (double*) malloc(sizeof(double)*k->ndata); sp.f3 = (double*) malloc(sizeof(double)*k->ndata); sp.parstype = parstype; sp.ndata = k->ndata; sp.iterations = 0; sp.maxiterations = maxiter; sp.npars = npars; sp.every = (k->intMethod == KEPLER ? 10 : 1); sp.status = PROGRESS_CONTINUE; sp.high_df = high_df; sp.min_chi = k->chi2; sp.st = initial_st; for (int i = 0; i < npars; i++) sp.best[i] = *(pars[i]); gsl_multifit_function_fdf fdf; fdf.f = &K_lm_f; fdf.df = &K_lm_jac; fdf.fdf = &K_lm_fdf; fdf.n = k->ndata; fdf.p = npars; fdf.params = &sp; gsl_multifit_fdfsolver_set (s, &fdf, x); bool improved = true; int status = 0; int kt = 0; int tot_iter = 0; int iter_at_scale = 0; bool last_ditch = false; while (improved || last_ditch) { k->flags |= NEEDS_SETUP; iter_at_scale = 0; while (true) { double chi2 = sp.min_chi; int status = gsl_multifit_fdfsolver_iterate (s); iter_at_scale++; tot_iter++; if (chi2 - sp.min_chi > min_chi_par) iter_at_scale = 0; if (status || iter_at_scale > max_iter_at_scale) { break; } } gsl_multifit_fdfsolver_set (s, &fdf, x); for (int i = 0; i < npars; i++) { *(pars[i]) = sp.best[i]; x->data[i] = sp.best[i]; } k->flags |= NEEDS_SETUP; K_calculate(k); if (fabs(prev_chi2 - sp.min_chi)/fabs(sp.min_chi) > 1e-2 && iter_at_scale > 1) { kt = 0; last_ditch = false; } else { sp.st *= 0.1; } improved = (kt < max_kt || fabs(sp.min_chi - prev_chi2)/fabs(sp.min_chi) > 1e-2); if (last_ditch) break; if (! improved && kt <= 3) { last_ditch = true; sp.st *= 0.1; } kt++; //printf("-> %d %d %d %e %e, last_ditch=%d\n", iter_at_scale, kt, improved, sp.st, sp.min_chi, last_ditch); prev_chi2 = k->chi2; for (int idx = 0; idx < npars; idx++) stepscale[idx] = steps[idx] * sp.st; if (sp.iterations > maxiter || sp.st < 1e-12) break; } for (int i = 0; i < npars; i++) { *(pars[i]) = sp.best[i]; x->data[i] = sp.best[i]; } k->flags |= NEEDS_SETUP; K_calculate(k); free(sp.stepscale); free(sp.f0); free(sp.f1); free(sp.f2); free(sp.f3); free(sp.pars); free(sp.parstype); free(sp.best); if (sp.status == PROGRESS_STOP) return PROGRESS_STOP; else return status; }