Example #1
0
File: magcal.c Project: pa345/lib
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 = &params;

  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() */
Example #2
0
static void
test_fdfridge(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_fdfridge *w = gsl_multifit_fdfridge_alloc (T, n, p);
  const char *pname = problem->name;
  char sname[2048];
  int status, info;
  double lambda = 0.0;

  sprintf(sname, "ridge/%s", gsl_multifit_fdfridge_name(w));

  /* scale starting point x0 */
  gsl_vector_memcpy(x0, &x0v.vector);
  test_scale_x0(x0, x0_scale);

  /* test undamped case with lambda = 0 */
  if (wts)
    {
      gsl_vector_const_view wv = gsl_vector_const_view_array(wts, n);
      gsl_multifit_fdfridge_wset(w, fdf, x0, lambda, &wv.vector);
    }
  else
    gsl_multifit_fdfridge_set(w, fdf, x0, lambda);

  status = gsl_multifit_fdfridge_driver(w, 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, w->s, problem);

  /* test for self consisent solution with L = \lambda I */
  {
    const double eps = 1.0e-10;
    gsl_matrix *L = gsl_matrix_calloc(p, p);
    gsl_vector_view diag = gsl_matrix_diagonal(L);
    gsl_multifit_fdfridge *w2 = gsl_multifit_fdfridge_alloc (T, n, p);
    gsl_vector *y0 = gsl_vector_alloc(p);
    size_t i;

    /* pick some value for lambda and set L = \lambda I */
    lambda = 5.0;
    gsl_vector_set_all(&diag.vector, lambda);

    /* scale initial vector */
    gsl_vector_memcpy(x0, &x0v.vector);
    test_scale_x0(x0, x0_scale);
    gsl_vector_memcpy(y0, x0);

    if (wts)
      {
        gsl_vector_const_view wv = gsl_vector_const_view_array(wts, n);
        gsl_multifit_fdfridge_wset(w, fdf, x0, lambda, &wv.vector);
        gsl_multifit_fdfridge_wset3(w2, fdf, y0, L, &wv.vector);
      }
    else
      {
        gsl_multifit_fdfridge_set(w, fdf, x0, lambda);
        gsl_multifit_fdfridge_set3(w2, fdf, y0, L);
      }

    /* solve with scalar lambda routine */
    status = gsl_multifit_fdfridge_driver(w, max_iter, xtol, gtol,
                                          ftol, &info);
    gsl_test(status, "%s/lambda/%s did not converge, status=%s",
             sname, pname, gsl_strerror(status));

    /* solve with general matrix routine */
    status = gsl_multifit_fdfridge_driver(w2, max_iter, xtol, gtol,
                                          ftol, &info);
    gsl_test(status, "%s/L/%s did not converge, status=%s",
             sname, pname, gsl_strerror(status));

    /* test x = y */
    for (i = 0; i < p; ++i)
      {
        double xi = gsl_vector_get(w->s->x, i);
        double yi = gsl_vector_get(w2->s->x, i);

        if (fabs(xi) < eps)
          {
            gsl_test_abs(yi, xi, eps, "%s/%s ridge lambda=%g i="F_ZU,
                         sname, pname, lambda, i);
          }
        else
          {
            gsl_test_rel(yi, xi, eps, "%s/%s ridge lambda=%g i="F_ZU,
                         sname, pname, lambda, i);
          }
      }

    gsl_matrix_free(L);
    gsl_vector_free(y0);
    gsl_multifit_fdfridge_free(w2);
  }

  gsl_multifit_fdfridge_free(w);
  gsl_vector_free(x0);
}