Blame doc/examples/nlfit2.c

Packit 67cb25
#include <stdlib.h>
Packit 67cb25
#include <stdio.h>
Packit 67cb25
#include <gsl/gsl_vector.h>
Packit 67cb25
#include <gsl/gsl_matrix.h>
Packit 67cb25
#include <gsl/gsl_blas.h>
Packit 67cb25
#include <gsl/gsl_multifit_nlinear.h>
Packit 67cb25
Packit 67cb25
int
Packit 67cb25
func_f (const gsl_vector * x, void *params, gsl_vector * f)
Packit 67cb25
{
Packit 67cb25
  double x1 = gsl_vector_get(x, 0);
Packit 67cb25
  double x2 = gsl_vector_get(x, 1);
Packit 67cb25
Packit 67cb25
  gsl_vector_set(f, 0, 100.0 * (x2 - x1*x1));
Packit 67cb25
  gsl_vector_set(f, 1, 1.0 - x1);
Packit 67cb25
Packit 67cb25
  return GSL_SUCCESS;
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
int
Packit 67cb25
func_df (const gsl_vector * x, void *params, gsl_matrix * J)
Packit 67cb25
{
Packit 67cb25
  double x1 = gsl_vector_get(x, 0);
Packit 67cb25
Packit 67cb25
  gsl_matrix_set(J, 0, 0, -200.0*x1);
Packit 67cb25
  gsl_matrix_set(J, 0, 1, 100.0);
Packit 67cb25
  gsl_matrix_set(J, 1, 0, -1.0);
Packit 67cb25
  gsl_matrix_set(J, 1, 1, 0.0);
Packit 67cb25
Packit 67cb25
  return GSL_SUCCESS;
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
int
Packit 67cb25
func_fvv (const gsl_vector * x, const gsl_vector * v,
Packit 67cb25
          void *params, gsl_vector * fvv)
Packit 67cb25
{
Packit 67cb25
  double v1 = gsl_vector_get(v, 0);
Packit 67cb25
Packit 67cb25
  gsl_vector_set(fvv, 0, -200.0 * v1 * v1);
Packit 67cb25
  gsl_vector_set(fvv, 1, 0.0);
Packit 67cb25
Packit 67cb25
  return GSL_SUCCESS;
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
void
Packit 67cb25
callback(const size_t iter, void *params,
Packit 67cb25
         const gsl_multifit_nlinear_workspace *w)
Packit 67cb25
{
Packit 67cb25
  gsl_vector * x = gsl_multifit_nlinear_position(w);
Packit 67cb25
Packit 67cb25
  /* print out current location */
Packit 67cb25
  printf("%f %f\n",
Packit 67cb25
         gsl_vector_get(x, 0),
Packit 67cb25
         gsl_vector_get(x, 1));
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
void
Packit 67cb25
solve_system(gsl_vector *x0, gsl_multifit_nlinear_fdf *fdf,
Packit 67cb25
             gsl_multifit_nlinear_parameters *params)
Packit 67cb25
{
Packit 67cb25
  const gsl_multifit_nlinear_type *T = gsl_multifit_nlinear_trust;
Packit 67cb25
  const size_t max_iter = 200;
Packit 67cb25
  const double xtol = 1.0e-8;
Packit 67cb25
  const double gtol = 1.0e-8;
Packit 67cb25
  const double ftol = 1.0e-8;
Packit 67cb25
  const size_t n = fdf->n;
Packit 67cb25
  const size_t p = fdf->p;
Packit 67cb25
  gsl_multifit_nlinear_workspace *work =
Packit 67cb25
    gsl_multifit_nlinear_alloc(T, params, n, p);
Packit 67cb25
  gsl_vector * f = gsl_multifit_nlinear_residual(work);
Packit 67cb25
  gsl_vector * x = gsl_multifit_nlinear_position(work);
Packit 67cb25
  int info;
Packit 67cb25
  double chisq0, chisq, rcond;
Packit 67cb25
Packit 67cb25
  /* initialize solver */
Packit 67cb25
  gsl_multifit_nlinear_init(x0, fdf, work);
Packit 67cb25
Packit 67cb25
  /* store initial cost */
Packit 67cb25
  gsl_blas_ddot(f, f, &chisq0);
Packit 67cb25
Packit 67cb25
  /* iterate until convergence */
Packit 67cb25
  gsl_multifit_nlinear_driver(max_iter, xtol, gtol, ftol,
Packit 67cb25
                              callback, NULL, &info, work);
Packit 67cb25
Packit 67cb25
  /* store final cost */
Packit 67cb25
  gsl_blas_ddot(f, f, &chisq);
Packit 67cb25
Packit 67cb25
  /* store cond(J(x)) */
Packit 67cb25
  gsl_multifit_nlinear_rcond(&rcond, work);
Packit 67cb25
Packit 67cb25
  /* print summary */
Packit 67cb25
Packit 67cb25
  fprintf(stderr, "NITER         = %zu\n", gsl_multifit_nlinear_niter(work));
Packit 67cb25
  fprintf(stderr, "NFEV          = %zu\n", fdf->nevalf);
Packit 67cb25
  fprintf(stderr, "NJEV          = %zu\n", fdf->nevaldf);
Packit 67cb25
  fprintf(stderr, "NAEV          = %zu\n", fdf->nevalfvv);
Packit 67cb25
  fprintf(stderr, "initial cost  = %.12e\n", chisq0);
Packit 67cb25
  fprintf(stderr, "final cost    = %.12e\n", chisq);
Packit 67cb25
  fprintf(stderr, "final x       = (%.12e, %.12e)\n",
Packit 67cb25
          gsl_vector_get(x, 0), gsl_vector_get(x, 1));
Packit 67cb25
  fprintf(stderr, "final cond(J) = %.12e\n", 1.0 / rcond);
Packit 67cb25
Packit 67cb25
  printf("\n\n");
Packit 67cb25
Packit 67cb25
  gsl_multifit_nlinear_free(work);
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
int
Packit 67cb25
main (void)
Packit 67cb25
{
Packit 67cb25
  const size_t n = 2;
Packit 67cb25
  const size_t p = 2;
Packit 67cb25
  gsl_vector *f = gsl_vector_alloc(n);
Packit 67cb25
  gsl_vector *x = gsl_vector_alloc(p);
Packit 67cb25
  gsl_multifit_nlinear_fdf fdf;
Packit 67cb25
  gsl_multifit_nlinear_parameters fdf_params =
Packit 67cb25
    gsl_multifit_nlinear_default_parameters();
Packit 67cb25
Packit 67cb25
  /* print map of Phi(x1, x2) */
Packit 67cb25
  {
Packit 67cb25
    double x1, x2, chisq;
Packit 67cb25
    double *f1 = gsl_vector_ptr(f, 0);
Packit 67cb25
    double *f2 = gsl_vector_ptr(f, 1);
Packit 67cb25
Packit 67cb25
    for (x1 = -1.2; x1 < 1.3; x1 += 0.1)
Packit 67cb25
      {
Packit 67cb25
        for (x2 = -0.5; x2 < 2.1; x2 += 0.1)
Packit 67cb25
          {
Packit 67cb25
            gsl_vector_set(x, 0, x1);
Packit 67cb25
            gsl_vector_set(x, 1, x2);
Packit 67cb25
            func_f(x, NULL, f);
Packit 67cb25
Packit 67cb25
            chisq = (*f1) * (*f1) + (*f2) * (*f2);
Packit 67cb25
            printf("%f %f %f\n", x1, x2, chisq);
Packit 67cb25
          }
Packit 67cb25
        printf("\n");
Packit 67cb25
      }
Packit 67cb25
    printf("\n\n");
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  /* define function to be minimized */
Packit 67cb25
  fdf.f = func_f;
Packit 67cb25
  fdf.df = func_df;
Packit 67cb25
  fdf.fvv = func_fvv;
Packit 67cb25
  fdf.n = n;
Packit 67cb25
  fdf.p = p;
Packit 67cb25
  fdf.params = NULL;
Packit 67cb25
Packit 67cb25
  /* starting point */
Packit 67cb25
  gsl_vector_set(x, 0, -0.5);
Packit 67cb25
  gsl_vector_set(x, 1, 1.75);
Packit 67cb25
Packit 67cb25
  fprintf(stderr, "=== Solving system without acceleration ===\n");
Packit 67cb25
  fdf_params.trs = gsl_multifit_nlinear_trs_lm;
Packit 67cb25
  solve_system(x, &fdf, &fdf_params);
Packit 67cb25
Packit 67cb25
  fprintf(stderr, "=== Solving system with acceleration ===\n");
Packit 67cb25
  fdf_params.trs = gsl_multifit_nlinear_trs_lmaccel;
Packit 67cb25
  solve_system(x, &fdf, &fdf_params);
Packit 67cb25
Packit 67cb25
  gsl_vector_free(f);
Packit 67cb25
  gsl_vector_free(x);
Packit 67cb25
Packit 67cb25
  return 0;
Packit 67cb25
}