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; }
/* Calculates covariance matrix * * @param epsrel :: Is used to remove linear-dependent columns * @param covar :: Returned covariance matrix, here as */ void LevenbergMarquardtMinimizer::calCovarianceMatrix(double epsrel, gsl_matrix *covar) { #if GSL_MAJOR_VERSION < 2 gsl_multifit_covar(m_gslSolver->J, epsrel, covar); #else gsl_matrix *J = gsl_matrix_alloc(gslContainer.n, gslContainer.p); gsl_multifit_fdfsolver_jac(m_gslSolver, J); gsl_multifit_covar(J, epsrel, covar); gsl_matrix_free(J); #endif }
gboolean _ncm_fit_gsl_ls_run (NcmFit *fit, NcmFitRunMsgs mtype) { NcmFitGSLLS *fit_gsl_ls = NCM_FIT_GSL_LS (fit); gint status, info = 0; if (ncm_fit_has_equality_constraints (fit) || ncm_fit_has_inequality_constraints (fit)) g_error ("_ncm_fit_gsl_ls_run: GSL algorithms do not support constraints."); g_assert (fit->fstate->fparam_len != 0); ncm_mset_fparams_get_vector (fit->mset, fit->fstate->fparams); gsl_multifit_fdfsolver_set (fit_gsl_ls->ls, &fit_gsl_ls->f, ncm_vector_gsl (fit->fstate->fparams)); status = gsl_multifit_fdfsolver_driver (fit_gsl_ls->ls, fit->maxiter, ncm_fit_get_params_reltol (fit), ncm_fit_get_m2lnL_reltol (fit), ncm_fit_get_m2lnL_reltol (fit), &info ); { NcmVector *_x = ncm_vector_new_gsl_static (fit_gsl_ls->ls->x); NcmVector *_f = ncm_vector_new_gsl_static (fit_gsl_ls->ls->f); NcmMatrix *_J = ncm_matrix_new (fit_gsl_ls->f.p, fit_gsl_ls->f.p); gsl_multifit_fdfsolver_jac (fit_gsl_ls->ls, ncm_matrix_gsl (_J)); ncm_fit_params_set_vector (fit, _x); ncm_fit_state_set_params_prec (fit->fstate, ncm_fit_get_params_reltol (fit)); ncm_fit_state_set_ls (fit->fstate, _f, _J); ncm_fit_state_set_niter (fit->fstate, gsl_multifit_fdfsolver_niter (fit_gsl_ls->ls)); ncm_vector_free (_x); ncm_vector_free (_f); ncm_matrix_free (_J); } if (status == GSL_SUCCESS) return TRUE; else return FALSE; }
static void test_fdf_checksol(const char *sname, const char *pname, const double epsrel, gsl_multifit_fdfsolver *s, test_fdf_problem *problem) { gsl_multifit_function_fdf *fdf = problem->fdf; const double *sigma = problem->sigma; gsl_vector *f = gsl_multifit_fdfsolver_residual(s); gsl_vector *x = gsl_multifit_fdfsolver_position(s); double sumsq; /* check solution vector x and sumsq = ||f||^2 */ gsl_blas_ddot(f, f, &sumsq); (problem->checksol)(x->data, sumsq, epsrel, sname, pname); #if 1 /* check variances */ if (sigma) { const size_t n = fdf->n; const size_t p = fdf->p; size_t i; gsl_matrix * J = gsl_matrix_alloc(n, p); gsl_matrix * covar = gsl_matrix_alloc (p, p); gsl_multifit_fdfsolver_jac (s, J); gsl_multifit_covar(J, 0.0, covar); for (i = 0; i < p; i++) { double ei = sqrt(sumsq/(n-p))*sqrt(gsl_matrix_get(covar,i,i)); gsl_test_rel (ei, sigma[i], epsrel, "%s/%s, sigma(%d)", sname, pname, i) ; } gsl_matrix_free (J); gsl_matrix_free (covar); } #endif }
int main (void) { const gsl_multifit_fdfsolver_type *T = gsl_multifit_fdfsolver_lmsder; gsl_multifit_fdfsolver *s; int status, info; size_t i; const size_t n = N; const size_t p = 3; gsl_matrix *J = gsl_matrix_alloc(n, p); gsl_matrix *covar = gsl_matrix_alloc (p, p); double y[N], weights[N]; struct data d = { n, y }; 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); gsl_vector_view w = gsl_vector_view_array(weights, n); const gsl_rng_type * type; gsl_rng * r; gsl_vector *res_f; double chi, chi0; const double xtol = 1e-8; const double gtol = 1e-8; const double ftol = 0.0; gsl_rng_env_setup(); type = gsl_rng_default; r = gsl_rng_alloc (type); f.f = &expb_f; f.df = &expb_df; /* set to NULL for finite-difference Jacobian */ 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; double yi = 1.0 + 5 * exp (-0.1 * t); double si = 0.1 * yi; double dy = gsl_ran_gaussian(r, si); weights[i] = 1.0 / (si * si); y[i] = yi + dy; printf ("data: %zu %g %g\n", i, y[i], si); }; s = gsl_multifit_fdfsolver_alloc (T, n, p); /* initialize solver with starting point and weights */ gsl_multifit_fdfsolver_wset (s, &f, &x.vector, &w.vector); /* compute initial residual norm */ res_f = gsl_multifit_fdfsolver_residual(s); chi0 = gsl_blas_dnrm2(res_f); /* solve the system with a maximum of 20 iterations */ status = gsl_multifit_fdfsolver_driver(s, 20, xtol, gtol, ftol, &info); gsl_multifit_fdfsolver_jac(s, J); gsl_multifit_covar (J, 0.0, covar); /* compute final residual norm */ chi = gsl_blas_dnrm2(res_f); #define FIT(i) gsl_vector_get(s->x, i) #define ERR(i) sqrt(gsl_matrix_get(covar,i,i)) fprintf(stderr, "summary from method '%s'\n", gsl_multifit_fdfsolver_name(s)); fprintf(stderr, "number of iterations: %zu\n", gsl_multifit_fdfsolver_niter(s)); fprintf(stderr, "function evaluations: %zu\n", f.nevalf); fprintf(stderr, "Jacobian evaluations: %zu\n", f.nevaldf); fprintf(stderr, "reason for stopping: %s\n", (info == 1) ? "small step size" : "small gradient"); fprintf(stderr, "initial |f(x)| = %g\n", chi0); fprintf(stderr, "final |f(x)| = %g\n", chi); { double dof = n - p; double c = GSL_MAX_DBL(1, chi / sqrt(dof)); fprintf(stderr, "chisq/dof = %g\n", pow(chi, 2.0) / dof); fprintf (stderr, "A = %.5f +/- %.5f\n", FIT(0), c*ERR(0)); fprintf (stderr, "lambda = %.5f +/- %.5f\n", FIT(1), c*ERR(1)); fprintf (stderr, "b = %.5f +/- %.5f\n", FIT(2), c*ERR(2)); } fprintf (stderr, "status = %s\n", gsl_strerror (status)); gsl_multifit_fdfsolver_free (s); gsl_matrix_free (covar); gsl_matrix_free (J); gsl_rng_free (r); return 0; }
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; }
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; }