/** * C++ version of gsl_multifit_fdfsolver_driver(). * @param maxiter Maximum iterations * @param epsabs Absolute error bounds * @param epsrel Relative error bounds * @return Error code on failure. */ int driver( size_t const maxiter, double const epsabs, double const epsrel ){ int const result = gsl_multifit_fdfsolver_driver( get(), maxiter, epsabs, epsrel ); x_v.wrap_gsl_vector_without_ownership( get()->x ); f_v.wrap_gsl_vector_without_ownership( get()->x ); dx_v.wrap_gsl_vector_without_ownership( get()->dx ); J_m.wrap_gsl_matrix_without_ownership( get()->J ); return result; }
/** * C++ version of gsl_multifit_fdfsolver_driver(). * @param s The fdfsolver * @param maxiter Maximum iterations * @param epsabs Absolute error bounds * @param epsrel Relative error bounds * @return Error code on failure. */ inline static int driver( fdfsolver& s, size_t const maxiter, double const epsabs, double const epsrel ){ int const result = gsl_multifit_fdfsolver_driver( s.get(), maxiter, epsabs, epsrel ); 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; }
int gsl_multifit_fdfridge_driver (gsl_multifit_fdfridge * w, const size_t maxiter, const double xtol, const double gtol, const double ftol, int *info) { int status = gsl_multifit_fdfsolver_driver(w->s, maxiter, xtol, gtol, ftol, info); return status; } /* gsl_multifit_fdfridge_driver() */
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; }
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 magcal_proc(gsl_vector *m, const satdata_mag *data, magcal_workspace *w) { int s; gsl_multifit_function_fdf f; gsl_multifit_fdfsolver *fdf_s; magcal_params params; gsl_vector_view v; const double xtol = 1e-10; const double gtol = 1e-10; const double ftol = 0.0; int info; /* copy data arrays */ s = magcal_init(data, w); if (s) return s; /* scale parameters to dimensionless units */ magcal_scale(1, m, w); params.w = w; f.f = &magcal_f; f.df = &magcal_df; f.n = w->n; f.p = w->p; f.params = ¶ms; v = gsl_vector_subvector(m, MAGCAL_IDX_DT, w->p); gsl_multifit_fdfsolver_set (w->fdf_s, &f, &v.vector); gsl_multifit_fdfridge_set (w->fdf_ridge, &f, &v.vector, w->lambda); #if 0 s = gsl_multifit_fdfsolver_driver(w->fdf_s, 500, xtol, gtol, ftol, &info); fdf_s = w->fdf_s; #else s = gsl_multifit_fdfridge_driver(w->fdf_ridge, 500, xtol, gtol, ftol, &info); fdf_s = w->fdf_ridge->s; #endif if (s != GSL_SUCCESS) { fprintf(stderr, "magcal_proc: error computing parameters: %s\n", gsl_strerror(s)); } else { magcal_print_state (w, fdf_s); fprintf(stderr, "magcal_proc: total data processed: %zu\n", w->n); fprintf(stderr, "magcal_proc: number of iterations: %zu\n", fdf_s->niter); fprintf(stderr, "magcal_proc: function evaluations: %zu\n", fdf_s->fdf->nevalf); fprintf(stderr, "magcal_proc: jacobian evaluations: %zu\n", fdf_s->fdf->nevaldf); fprintf(stderr, "magcal_proc: reason for convergence: %d\n", info); /* save calibration parameters */ gsl_vector_memcpy(&v.vector, fdf_s->x); /* restore time shift parameter */ gsl_vector_set(m, MAGCAL_IDX_DT, 0.0); /* scale offsets back to nT */ magcal_scale(-1, m, w); #if 0 /* compute covariance matrix */ gsl_multifit_covar(fdf_s->J, 0.0, w->covar); #endif } return s; } /* magcal_proc() */
static void test_fdf(const gsl_multifit_fdfsolver_type * T, const double xtol, const double gtol, const double ftol, const double epsrel, const double x0_scale, test_fdf_problem *problem, const double *wts) { gsl_multifit_function_fdf *fdf = problem->fdf; const size_t n = fdf->n; const size_t p = fdf->p; const size_t max_iter = 1500; gsl_vector *x0 = gsl_vector_alloc(p); gsl_vector_view x0v = gsl_vector_view_array(problem->x0, p); gsl_multifit_fdfsolver *s = gsl_multifit_fdfsolver_alloc (T, n, p); const char *pname = problem->name; char sname[2048]; int status, info; sprintf(sname, "%s/scale=%g%s", gsl_multifit_fdfsolver_name(s), x0_scale, problem->fdf->df ? "" : "/fdiff"); /* scale starting point x0 */ gsl_vector_memcpy(x0, &x0v.vector); test_scale_x0(x0, x0_scale); if (wts) { gsl_vector_const_view wv = gsl_vector_const_view_array(wts, n); gsl_multifit_fdfsolver_wset(s, fdf, x0, &wv.vector); } else gsl_multifit_fdfsolver_set(s, fdf, x0); status = gsl_multifit_fdfsolver_driver(s, max_iter, xtol, gtol, ftol, &info); gsl_test(status, "%s/%s did not converge, status=%s", sname, pname, gsl_strerror(status)); /* check solution */ test_fdf_checksol(sname, pname, epsrel, s, problem); if (wts == NULL) { /* test again with weighting matrix W = I */ gsl_vector *wv = gsl_vector_alloc(n); sprintf(sname, "%s/scale=%g%s/weights", gsl_multifit_fdfsolver_name(s), x0_scale, problem->fdf->df ? "" : "/fdiff"); gsl_vector_memcpy(x0, &x0v.vector); test_scale_x0(x0, x0_scale); gsl_vector_set_all(wv, 1.0); gsl_multifit_fdfsolver_wset(s, fdf, x0, wv); status = gsl_multifit_fdfsolver_driver(s, max_iter, xtol, gtol, ftol, &info); gsl_test(status, "%s/%s did not converge, status=%s", sname, pname, gsl_strerror(status)); test_fdf_checksol(sname, pname, epsrel, s, problem); gsl_vector_free(wv); } gsl_multifit_fdfsolver_free(s); gsl_vector_free(x0); }