Beispiel #1
0
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;
}