Blame multifit/test_nonlinear.c.tol

Packit f2184d
/* multifit/test_nonlinear.c
Packit f2184d
 * 
Packit f2184d
 * Copyright (C) 2007, 2013, 2014 Brian Gough, Patrick Alken
Packit f2184d
 * 
Packit f2184d
 * This program is free software; you can redistribute it and/or modify
Packit f2184d
 * it under the terms of the GNU General Public License as published by
Packit f2184d
 * the Free Software Foundation; either version 3 of the License, or (at
Packit f2184d
 * your option) any later version.
Packit f2184d
 * 
Packit f2184d
 * This program is distributed in the hope that it will be useful, but
Packit f2184d
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit f2184d
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit f2184d
 * General Public License for more details.
Packit f2184d
 * 
Packit f2184d
 * You should have received a copy of the GNU General Public License
Packit f2184d
 * along with this program; if not, write to the Free Software
Packit f2184d
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Packit f2184d
 */
Packit f2184d
Packit f2184d
typedef struct
Packit f2184d
{
Packit f2184d
  const char *name;
Packit f2184d
  double *x0;       /* initial parameters (size p) */
Packit f2184d
  double *sigma;
Packit f2184d
  double *epsrel;   /* relative tolerance for solution checking */
Packit f2184d
  size_t ntries;
Packit f2184d
  void (*checksol) (const double x[], const double sumsq,
Packit f2184d
                    const double epsrel, const char *sname,
Packit f2184d
                    const char *pname);
Packit f2184d
  gsl_multifit_function_fdf *fdf;
Packit f2184d
} test_fdf_problem;
Packit f2184d
Packit f2184d
#include "test_bard.c"
Packit f2184d
#include "test_beale.c"
Packit f2184d
#include "test_biggs.c"
Packit f2184d
#include "test_box.c"
Packit f2184d
#include "test_boxbod.c"
Packit f2184d
#include "test_brown1.c"
Packit f2184d
#include "test_brown2.c"
Packit f2184d
#include "test_brown3.c"
Packit f2184d
#include "test_eckerle.c"
Packit f2184d
#include "test_enso.c"
Packit f2184d
#include "test_exp1.c"
Packit f2184d
#include "test_gaussian.c"
Packit f2184d
#include "test_hahn1.c"
Packit f2184d
#include "test_helical.c"
Packit f2184d
#include "test_jennrich.c"
Packit f2184d
#include "test_kirby2.c"
Packit f2184d
#include "test_kowalik.c"
Packit f2184d
#include "test_lin1.c"
Packit f2184d
#include "test_lin2.c"
Packit f2184d
#include "test_lin3.c"
Packit f2184d
#include "test_meyer.c"
Packit f2184d
#include "test_meyerscal.c"
Packit f2184d
#include "test_osborne.c"
Packit f2184d
#include "test_penalty1.c"
Packit f2184d
#include "test_penalty2.c"
Packit f2184d
#include "test_powell1.c"
Packit f2184d
#include "test_powell2.c"
Packit f2184d
#include "test_powell3.c"
Packit f2184d
#include "test_rat42.c"
Packit f2184d
#include "test_rat43.c"
Packit f2184d
#include "test_rosenbrock.c"
Packit f2184d
#include "test_rosenbrocke.c"
Packit f2184d
#include "test_roth.c"
Packit f2184d
#include "test_thurber.c"
Packit f2184d
#include "test_vardim.c"
Packit f2184d
#include "test_watson.c"
Packit f2184d
#include "test_wood.c"
Packit f2184d
Packit f2184d
#include "test_wnlin.c"
Packit f2184d
Packit f2184d
static void test_fdf(const gsl_multifit_fdfsolver_type * T,
Packit f2184d
                     const double xtol, const double gtol,
Packit f2184d
                     const double ftol, const double epsrel,
Packit f2184d
                     const double x0_scale, test_fdf_problem *problem,
Packit f2184d
                     const double *wts);
Packit f2184d
static void test_fdfridge(const gsl_multifit_fdfsolver_type * T,
Packit f2184d
                          const double xtol, const double gtol,
Packit f2184d
                          const double ftol, const double epsrel,
Packit f2184d
                          const double x0_scale, test_fdf_problem *problem,
Packit f2184d
                          const double *wts);
Packit f2184d
static void test_fdf_checksol(const char *sname, const char *pname,
Packit f2184d
                              const double epsrel,
Packit f2184d
                              gsl_multifit_fdfsolver *s,
Packit f2184d
                              test_fdf_problem *problem);
Packit f2184d
static void test_scale_x0(gsl_vector *x0, const double scale);
Packit f2184d
Packit f2184d
/*
Packit f2184d
 * These test problems are taken from
Packit f2184d
 *
Packit f2184d
 * H. B. Nielsen, UCTP test problems for unconstrained optimization,
Packit f2184d
 * IMM Department of Mathematical Modeling, Tech. Report IMM-REP-2000-17,
Packit f2184d
 * 2000.
Packit f2184d
 */
Packit f2184d
static test_fdf_problem *test_fdf_nielsen[] = {
Packit f2184d
  &lin1_problem,       /* 1 */
Packit f2184d
  &lin2_problem,       /* 2 */
Packit f2184d
  &lin3_problem,       /* 3 */
Packit f2184d
  &rosenbrock_problem, /* 4 */
Packit f2184d
  &helical_problem,    /* 5 */
Packit f2184d
  &powell1_problem,    /* 6 */
Packit f2184d
  &roth_problem,       /* 7 */
Packit f2184d
  &bard_problem,       /* 8 */
Packit f2184d
  &kowalik_problem,    /* 9 */
Packit f2184d
  &meyer_problem,      /* 10 */
Packit f2184d
  &watson_problem,     /* 11 */
Packit f2184d
  &box_problem,        /* 12 */
Packit f2184d
  &jennrich_problem,   /* 13 */
Packit f2184d
  &brown1_problem,     /* 14 */
Packit f2184d
  &brown2_problem,     /* 16 */
Packit f2184d
  &osborne_problem,    /* 17 */
Packit f2184d
  &exp1_problem,       /* 18 */
Packit f2184d
  &meyerscal_problem,  /* 20 */
Packit f2184d
Packit f2184d
  &powell2_problem,
Packit f2184d
Packit f2184d
  NULL
Packit f2184d
};
Packit f2184d
Packit f2184d
/*
Packit f2184d
 * These tests are from
Packit f2184d
 *
Packit f2184d
 * J. J. More, B. S. Garbow and K. E. Hillstrom, Testing
Packit f2184d
 * Unconstrained Optimization Software, ACM Trans. Math. Soft.
Packit f2184d
 * Vol 7, No 1, 1981.
Packit f2184d
 *
Packit f2184d
 * Many of these overlap with the Nielsen tests
Packit f2184d
 */
Packit f2184d
static test_fdf_problem *test_fdf_more[] = {
Packit f2184d
  &rosenbrock_problem,   /* 1 */
Packit f2184d
  &roth_problem,         /* 2 */
Packit f2184d
  &powell3_problem,      /* 3 */
Packit f2184d
  &brown3_problem,       /* 4 */
Packit f2184d
  &beale_problem,        /* 5 */
Packit f2184d
  &jennrich_problem,     /* 6 */
Packit f2184d
  &helical_problem,      /* 7 */
Packit f2184d
  &bard_problem,         /* 8 */
Packit f2184d
  &gaussian_problem,     /* 9 */
Packit f2184d
  &meyer_problem,        /* 10 */
Packit f2184d
  &box_problem,          /* 12 */
Packit f2184d
  &powell1_problem,      /* 13 */
Packit f2184d
  &wood_problem,         /* 14 */
Packit f2184d
  &kowalik_problem,      /* 15 */
Packit f2184d
  &brown1_problem,       /* 16 */
Packit f2184d
  &osborne_problem,      /* 17 */
Packit f2184d
  &biggs_problem,        /* 18 */
Packit f2184d
  &watson_problem,       /* 20 */
Packit f2184d
  &rosenbrocke_problem,  /* 21 */
Packit f2184d
  &penalty1_problem,     /* 23 */
Packit f2184d
  &penalty2_problem,     /* 24 */
Packit f2184d
  &vardim_problem,       /* 25 */
Packit f2184d
  &brown2_problem,       /* 27 */
Packit f2184d
  &lin1_problem,         /* 32 */
Packit f2184d
  &lin2_problem,         /* 33 */
Packit f2184d
  &lin3_problem,         /* 34 */
Packit f2184d
Packit f2184d
  NULL
Packit f2184d
};
Packit f2184d
Packit f2184d
/* NIST test cases */
Packit f2184d
static test_fdf_problem *test_fdf_nist[] = {
Packit f2184d
  &kirby2_problem,
Packit f2184d
  &hahn1_problem,
Packit f2184d
  &enso_problem,
Packit f2184d
  &thurber_problem,
Packit f2184d
  &boxbod_problem,
Packit f2184d
  &rat42_problem,
Packit f2184d
  &eckerle_problem,
Packit f2184d
  &rat43_problem,
Packit f2184d
Packit f2184d
  NULL
Packit f2184d
};
Packit f2184d
Packit f2184d
static void
Packit f2184d
test_nonlinear(void)
Packit f2184d
{
Packit f2184d
  const double xtol = pow(GSL_DBL_EPSILON, 0.9);
Packit f2184d
  const double gtol = pow(GSL_DBL_EPSILON, 0.9);
Packit f2184d
  const double ftol = 0.0;
Packit f2184d
  size_t i, j;
Packit f2184d
Packit f2184d
  /* Nielsen tests */
Packit f2184d
  for (i = 0; test_fdf_nielsen[i] != NULL; ++i)
Packit f2184d
    {
Packit f2184d
      test_fdf_problem *problem = test_fdf_nielsen[i];
Packit f2184d
      double epsrel = *(problem->epsrel);
Packit f2184d
      double scale = 1.0;
Packit f2184d
Packit f2184d
      for (j = 0; j < problem->ntries; ++j)
Packit f2184d
        {
Packit f2184d
          double eps_scale = epsrel * scale;
Packit f2184d
Packit f2184d
          test_fdf(gsl_multifit_fdfsolver_lmsder, xtol, gtol, ftol,
Packit f2184d
                   eps_scale, scale, problem, NULL);
Packit f2184d
          test_fdfridge(gsl_multifit_fdfsolver_lmsder, xtol, gtol, ftol,
Packit f2184d
                        eps_scale, scale, problem, NULL);
Packit f2184d
Packit f2184d
          /* test finite difference Jacobian */
Packit f2184d
          {
Packit f2184d
            gsl_multifit_function_fdf fdf;
Packit f2184d
            fdf.df = problem->fdf->df;
Packit f2184d
            problem->fdf->df = NULL;
Packit f2184d
            test_fdf(gsl_multifit_fdfsolver_lmsder, xtol, gtol, ftol,
Packit f2184d
                     1.0e5 * eps_scale, 1.0, problem, NULL);
Packit f2184d
            test_fdfridge(gsl_multifit_fdfsolver_lmsder, xtol, gtol, ftol,
Packit f2184d
                          1.0e5 * eps_scale, 1.0, problem, NULL);
Packit f2184d
            problem->fdf->df = fdf.df;
Packit f2184d
          }
Packit f2184d
Packit f2184d
          scale *= 10.0;
Packit f2184d
        }
Packit f2184d
Packit f2184d
      test_fdf(gsl_multifit_fdfsolver_lmniel, xtol, gtol, ftol,
Packit f2184d
               10.0 * epsrel, 1.0, problem, NULL);
Packit f2184d
    }
Packit f2184d
Packit f2184d
  /* More tests */
Packit f2184d
  for (i = 0; test_fdf_more[i] != NULL; ++i)
Packit f2184d
    {
Packit f2184d
      test_fdf_problem *problem = test_fdf_more[i];
Packit f2184d
      double epsrel = *(problem->epsrel);
Packit f2184d
      double scale = 1.0;
Packit f2184d
Packit f2184d
      for (j = 0; j < problem->ntries; ++j)
Packit f2184d
        {
Packit f2184d
          double eps_scale = epsrel * scale;
Packit f2184d
Packit f2184d
          test_fdf(gsl_multifit_fdfsolver_lmsder, xtol, gtol, ftol,
Packit f2184d
                   eps_scale, scale, problem, NULL);
Packit f2184d
          test_fdfridge(gsl_multifit_fdfsolver_lmsder, xtol, gtol, ftol,
Packit f2184d
                        eps_scale, scale, problem, NULL);
Packit f2184d
Packit f2184d
          /* test finite difference Jacobian */
Packit f2184d
          {
Packit f2184d
            gsl_multifit_function_fdf fdf;
Packit f2184d
            fdf.df = problem->fdf->df;
Packit f2184d
            problem->fdf->df = NULL;
Packit f2184d
            test_fdf(gsl_multifit_fdfsolver_lmsder, xtol, gtol, ftol,
Packit f2184d
                     1.0e5 * eps_scale, 1.0, problem, NULL);
Packit f2184d
            test_fdfridge(gsl_multifit_fdfsolver_lmsder, xtol, gtol, ftol,
Packit f2184d
                          1.0e5 * eps_scale, 1.0, problem, NULL);
Packit f2184d
            problem->fdf->df = fdf.df;
Packit f2184d
          }
Packit f2184d
Packit f2184d
          scale *= 10.0;
Packit f2184d
        }
Packit f2184d
Packit f2184d
      test_fdf(gsl_multifit_fdfsolver_lmniel, xtol, gtol, ftol,
Packit f2184d
               10.0 * epsrel, 1.0, problem, NULL);
Packit f2184d
    }
Packit f2184d
Packit f2184d
  /* NIST tests */
Packit f2184d
  for (i = 0; test_fdf_nist[i] != NULL; ++i)
Packit f2184d
    {
Packit f2184d
      test_fdf_problem *problem = test_fdf_nist[i];
Packit f2184d
      double epsrel = *(problem->epsrel);
Packit f2184d
      double scale = 1.0;
Packit f2184d
Packit f2184d
      for (j = 0; j < problem->ntries; ++j)
Packit f2184d
        {
Packit f2184d
          double eps_scale = epsrel * scale;
Packit f2184d
Packit f2184d
          test_fdf(gsl_multifit_fdfsolver_lmsder, xtol, gtol, ftol,
Packit f2184d
                   eps_scale, scale, problem, NULL);
Packit f2184d
          test_fdf(gsl_multifit_fdfsolver_lmder, xtol, gtol, ftol,
Packit f2184d
                   eps_scale, scale, problem, NULL);
Packit f2184d
Packit f2184d
          /* test finite difference Jacobian */
Packit f2184d
          {
Packit f2184d
            gsl_multifit_function_fdf fdf;
Packit f2184d
            fdf.df = problem->fdf->df;
Packit f2184d
            problem->fdf->df = NULL;
Packit f2184d
            test_fdf(gsl_multifit_fdfsolver_lmsder, xtol, gtol, ftol,
Packit f2184d
                     eps_scale, 1.0, problem, NULL);
Packit f2184d
            test_fdf(gsl_multifit_fdfsolver_lmder, xtol, gtol, ftol,
Packit f2184d
                     eps_scale, scale, problem, NULL);
Packit f2184d
            problem->fdf->df = fdf.df;
Packit f2184d
          }
Packit f2184d
Packit f2184d
          scale *= 10.0;
Packit f2184d
        }
Packit f2184d
Packit f2184d
      test_fdf(gsl_multifit_fdfsolver_lmniel, xtol, gtol, ftol,
Packit f2184d
               epsrel, 1.0, problem, NULL);
Packit f2184d
    }
Packit f2184d
Packit f2184d
  /* test weighted nonlinear least squares */
Packit f2184d
Packit f2184d
  /* internal weighting in _f and _df functions */
Packit f2184d
  test_fdf(gsl_multifit_fdfsolver_lmsder, xtol, gtol, ftol,
Packit f2184d
           wnlin_epsrel, 1.0, &wnlin_problem1, NULL);
Packit f2184d
  test_fdf(gsl_multifit_fdfsolver_lmniel, xtol, gtol, ftol,
Packit f2184d
           wnlin_epsrel, 1.0, &wnlin_problem1, NULL);
Packit f2184d
  test_fdfridge(gsl_multifit_fdfsolver_lmsder, xtol, gtol, ftol,
Packit f2184d
                wnlin_epsrel, 1.0, &wnlin_problem1, NULL);
Packit f2184d
  test_fdfridge(gsl_multifit_fdfsolver_lmniel, xtol, gtol, ftol,
Packit f2184d
                wnlin_epsrel, 1.0, &wnlin_problem1, NULL);
Packit f2184d
Packit f2184d
  /* weighting through fdfsolver_wset */
Packit f2184d
  test_fdf(gsl_multifit_fdfsolver_lmsder, xtol, gtol, ftol,
Packit f2184d
           wnlin_epsrel, 1.0, &wnlin_problem2, wnlin_W);
Packit f2184d
  test_fdf(gsl_multifit_fdfsolver_lmniel, xtol, gtol, ftol,
Packit f2184d
           wnlin_epsrel, 1.0, &wnlin_problem2, wnlin_W);
Packit f2184d
  test_fdfridge(gsl_multifit_fdfsolver_lmsder, xtol, gtol, ftol,
Packit f2184d
                wnlin_epsrel, 1.0, &wnlin_problem2, wnlin_W);
Packit f2184d
  test_fdfridge(gsl_multifit_fdfsolver_lmniel, xtol, gtol, ftol,
Packit f2184d
                wnlin_epsrel, 1.0, &wnlin_problem2, wnlin_W);
Packit f2184d
}
Packit f2184d
Packit f2184d
/*
Packit f2184d
test_fdf()
Packit f2184d
  Test a weighted nonlinear least squares problem
Packit f2184d
Packit f2184d
Inputs: T        - solver to use
Packit f2184d
        xtol     - tolerance in x
Packit f2184d
        gtol     - tolerance in gradient
Packit f2184d
        ftol     - tolerance in residual vector
Packit f2184d
        epsrel   - relative error tolerance in solution
Packit f2184d
        x0_scale - to test robustness against starting points,
Packit f2184d
                   the standard starting point in 'problem' is
Packit f2184d
                   multiplied by this scale factor:
Packit f2184d
                   x0 <- x0 * x0_scale
Packit f2184d
                   If x0 = 0, then all components of x0 are set to
Packit f2184d
                   x0_scale
Packit f2184d
        problem  - contains the nonlinear problem and solution point
Packit f2184d
        wts      - weight vector (NULL for unweighted)
Packit f2184d
*/
Packit f2184d
Packit f2184d
static void
Packit f2184d
test_fdf(const gsl_multifit_fdfsolver_type * T, const double xtol,
Packit f2184d
         const double gtol, const double ftol,
Packit f2184d
         const double epsrel, const double x0_scale,
Packit f2184d
         test_fdf_problem *problem,
Packit f2184d
         const double *wts)
Packit f2184d
{
Packit f2184d
  gsl_multifit_function_fdf *fdf = problem->fdf;
Packit f2184d
  const size_t n = fdf->n;
Packit f2184d
  const size_t p = fdf->p;
Packit f2184d
  const size_t max_iter = 1500;
Packit f2184d
  gsl_vector *x0 = gsl_vector_alloc(p);
Packit f2184d
  gsl_vector_view x0v = gsl_vector_view_array(problem->x0, p);
Packit f2184d
  gsl_multifit_fdfsolver *s = gsl_multifit_fdfsolver_alloc (T, n, p);
Packit f2184d
  const char *pname = problem->name;
Packit f2184d
  char sname[2048];
Packit f2184d
  int status, info;
Packit f2184d
Packit f2184d
  sprintf(sname, "%s/scale=%g%s",
Packit f2184d
    gsl_multifit_fdfsolver_name(s), x0_scale,
Packit f2184d
    problem->fdf->df ? "" : "/fdiff");
Packit f2184d
Packit f2184d
  /* scale starting point x0 */
Packit f2184d
  gsl_vector_memcpy(x0, &x0v.vector);
Packit f2184d
  test_scale_x0(x0, x0_scale);
Packit f2184d
Packit f2184d
  if (wts)
Packit f2184d
    {
Packit f2184d
      gsl_vector_const_view wv = gsl_vector_const_view_array(wts, n);
Packit f2184d
      gsl_multifit_fdfsolver_wset(s, fdf, x0, &wv.vector);
Packit f2184d
    }
Packit f2184d
  else
Packit f2184d
    gsl_multifit_fdfsolver_set(s, fdf, x0);
Packit f2184d
Packit f2184d
  status = gsl_multifit_fdfsolver_driver(s, max_iter, xtol, gtol,
Packit f2184d
                                         ftol, &info;;
Packit f2184d
  gsl_test(status, "%s/%s did not converge, status=%s",
Packit f2184d
           sname, pname, gsl_strerror(status));
Packit f2184d
Packit f2184d
  /* check solution */
Packit f2184d
  test_fdf_checksol(sname, pname, epsrel, s, problem);
Packit f2184d
Packit f2184d
  if (wts == NULL)
Packit f2184d
    {
Packit f2184d
      /* test again with weighting matrix W = I */
Packit f2184d
      gsl_vector *wv = gsl_vector_alloc(n);
Packit f2184d
Packit f2184d
      sprintf(sname, "%s/scale=%g%s/weights",
Packit f2184d
        gsl_multifit_fdfsolver_name(s), x0_scale,
Packit f2184d
        problem->fdf->df ? "" : "/fdiff");
Packit f2184d
Packit f2184d
      gsl_vector_memcpy(x0, &x0v.vector);
Packit f2184d
      test_scale_x0(x0, x0_scale);
Packit f2184d
Packit f2184d
      gsl_vector_set_all(wv, 1.0);
Packit f2184d
      gsl_multifit_fdfsolver_wset(s, fdf, x0, wv);
Packit f2184d
  
Packit f2184d
      status = gsl_multifit_fdfsolver_driver(s, max_iter, xtol, gtol,
Packit f2184d
                                             ftol, &info;;
Packit f2184d
      gsl_test(status, "%s/%s did not converge, status=%s",
Packit f2184d
               sname, pname, gsl_strerror(status));
Packit f2184d
Packit f2184d
      test_fdf_checksol(sname, pname, epsrel, s, problem);
Packit f2184d
Packit f2184d
      gsl_vector_free(wv);
Packit f2184d
    }
Packit f2184d
Packit f2184d
  gsl_multifit_fdfsolver_free(s);
Packit f2184d
  gsl_vector_free(x0);
Packit f2184d
}
Packit f2184d
Packit f2184d
/*
Packit f2184d
test_fdfridge()
Packit f2184d
  Test a nonlinear least squares problem
Packit f2184d
Packit f2184d
Inputs: T        - solver to use
Packit f2184d
        xtol     - tolerance in x
Packit f2184d
        gtol     - tolerance in gradient
Packit f2184d
        ftol     - tolerance in residual vector
Packit f2184d
        epsrel   - relative error tolerance in solution
Packit f2184d
        x0_scale - to test robustness against starting points,
Packit f2184d
                   the standard starting point in 'problem' is
Packit f2184d
                   multiplied by this scale factor:
Packit f2184d
                   x0 <- x0 * x0_scale
Packit f2184d
                   If x0 = 0, then all components of x0 are set to
Packit f2184d
                   x0_scale
Packit f2184d
        problem  - contains the nonlinear problem and solution point
Packit f2184d
        wts      - weight vector
Packit f2184d
*/
Packit f2184d
Packit f2184d
static void
Packit f2184d
test_fdfridge(const gsl_multifit_fdfsolver_type * T, const double xtol,
Packit f2184d
              const double gtol, const double ftol,
Packit f2184d
              const double epsrel, const double x0_scale,
Packit f2184d
              test_fdf_problem *problem, const double *wts)
Packit f2184d
{
Packit f2184d
  gsl_multifit_function_fdf *fdf = problem->fdf;
Packit f2184d
  const size_t n = fdf->n;
Packit f2184d
  const size_t p = fdf->p;
Packit f2184d
  const size_t max_iter = 1500;
Packit f2184d
  gsl_vector *x0 = gsl_vector_alloc(p);
Packit f2184d
  gsl_vector_view x0v = gsl_vector_view_array(problem->x0, p);
Packit f2184d
  gsl_multifit_fdfridge *w = gsl_multifit_fdfridge_alloc (T, n, p);
Packit f2184d
  const char *pname = problem->name;
Packit f2184d
  char sname[2048];
Packit f2184d
  int status, info;
Packit f2184d
  double lambda = 0.0;
Packit f2184d
Packit f2184d
  sprintf(sname, "ridge/%s", gsl_multifit_fdfridge_name(w));
Packit f2184d
Packit f2184d
  /* scale starting point x0 */
Packit f2184d
  gsl_vector_memcpy(x0, &x0v.vector);
Packit f2184d
  test_scale_x0(x0, x0_scale);
Packit f2184d
Packit f2184d
  /* test undamped case with lambda = 0 */
Packit f2184d
  if (wts)
Packit f2184d
    {
Packit f2184d
      gsl_vector_const_view wv = gsl_vector_const_view_array(wts, n);
Packit f2184d
      gsl_multifit_fdfridge_wset(w, fdf, x0, lambda, &wv.vector);
Packit f2184d
    }
Packit f2184d
  else
Packit f2184d
    gsl_multifit_fdfridge_set(w, fdf, x0, lambda);
Packit f2184d
Packit f2184d
  status = gsl_multifit_fdfridge_driver(w, max_iter, xtol, gtol,
Packit f2184d
                                        ftol, &info;;
Packit f2184d
  gsl_test(status, "%s/%s did not converge, status=%s",
Packit f2184d
           sname, pname, gsl_strerror(status));
Packit f2184d
Packit f2184d
  /* check solution */
Packit f2184d
  test_fdf_checksol(sname, pname, epsrel, w->s, problem);
Packit f2184d
Packit f2184d
  /* test for self consisent solution with L = \lambda I */
Packit f2184d
  {
Packit f2184d
    const double eps = 1.0e-10;
Packit f2184d
    gsl_matrix *L = gsl_matrix_calloc(p, p);
Packit f2184d
    gsl_vector_view diag = gsl_matrix_diagonal(L);
Packit f2184d
    gsl_multifit_fdfridge *w2 = gsl_multifit_fdfridge_alloc (T, n, p);
Packit f2184d
    gsl_vector *y0 = gsl_vector_alloc(p);
Packit f2184d
    size_t i;
Packit f2184d
Packit f2184d
    /* pick some value for lambda and set L = \lambda I */
Packit f2184d
    lambda = 5.0;
Packit f2184d
    gsl_vector_set_all(&diag.vector, lambda);
Packit f2184d
Packit f2184d
    /* scale initial vector */
Packit f2184d
    gsl_vector_memcpy(x0, &x0v.vector);
Packit f2184d
    test_scale_x0(x0, x0_scale);
Packit f2184d
    gsl_vector_memcpy(y0, x0);
Packit f2184d
Packit f2184d
    if (wts)
Packit f2184d
      {
Packit f2184d
        gsl_vector_const_view wv = gsl_vector_const_view_array(wts, n);
Packit f2184d
        gsl_multifit_fdfridge_wset(w, fdf, x0, lambda, &wv.vector);
Packit f2184d
        gsl_multifit_fdfridge_wset3(w2, fdf, y0, L, &wv.vector);
Packit f2184d
      }
Packit f2184d
    else
Packit f2184d
      {
Packit f2184d
        gsl_multifit_fdfridge_set(w, fdf, x0, lambda);
Packit f2184d
        gsl_multifit_fdfridge_set3(w2, fdf, y0, L);
Packit f2184d
      }
Packit f2184d
Packit f2184d
    /* solve with scalar lambda routine */
Packit f2184d
    status = gsl_multifit_fdfridge_driver(w, max_iter, xtol, gtol,
Packit f2184d
                                          ftol, &info;;
Packit f2184d
    gsl_test(status, "%s/lambda/%s did not converge, status=%s",
Packit f2184d
             sname, pname, gsl_strerror(status));
Packit f2184d
Packit f2184d
    /* solve with general matrix routine */
Packit f2184d
    status = gsl_multifit_fdfridge_driver(w2, max_iter, xtol, gtol,
Packit f2184d
                                          ftol, &info;;
Packit f2184d
    gsl_test(status, "%s/L/%s did not converge, status=%s",
Packit f2184d
             sname, pname, gsl_strerror(status));
Packit f2184d
Packit f2184d
    /* test x = y */
Packit f2184d
    for (i = 0; i < p; ++i)
Packit f2184d
      {
Packit f2184d
        double xi = gsl_vector_get(w->s->x, i);
Packit f2184d
        double yi = gsl_vector_get(w2->s->x, i);
Packit f2184d
Packit f2184d
        if (fabs(xi) < eps)
Packit f2184d
          {
Packit f2184d
            gsl_test_abs(yi, xi, eps, "%s/%s ridge lambda=%g i=%zu",
Packit f2184d
                         sname, pname, lambda, i);
Packit f2184d
          }
Packit f2184d
        else
Packit f2184d
          {
Packit f2184d
            gsl_test_rel(yi, xi, eps, "%s/%s ridge lambda=%g i=%zu",
Packit f2184d
                         sname, pname, lambda, i);
Packit f2184d
          }
Packit f2184d
      }
Packit f2184d
Packit f2184d
    gsl_matrix_free(L);
Packit f2184d
    gsl_vector_free(y0);
Packit f2184d
    gsl_multifit_fdfridge_free(w2);
Packit f2184d
  }
Packit f2184d
Packit f2184d
  gsl_multifit_fdfridge_free(w);
Packit f2184d
  gsl_vector_free(x0);
Packit f2184d
}
Packit f2184d
Packit f2184d
static void
Packit f2184d
test_fdf_checksol(const char *sname, const char *pname,
Packit f2184d
                  const double epsrel, gsl_multifit_fdfsolver *s,
Packit f2184d
                  test_fdf_problem *problem)
Packit f2184d
{
Packit f2184d
  gsl_multifit_function_fdf *fdf = problem->fdf;
Packit f2184d
  const double *sigma = problem->sigma;
Packit f2184d
  gsl_vector *f = gsl_multifit_fdfsolver_residual(s);
Packit f2184d
  gsl_vector *x = gsl_multifit_fdfsolver_position(s);
Packit f2184d
  double sumsq;
Packit f2184d
Packit f2184d
  /* check solution vector x and sumsq = ||f||^2 */
Packit f2184d
  gsl_blas_ddot(f, f, &sumsq);
Packit f2184d
  (problem->checksol)(x->data, sumsq, epsrel, sname, pname);
Packit f2184d
Packit f2184d
#if 1
Packit f2184d
  /* check variances */
Packit f2184d
  if (sigma)
Packit f2184d
    {
Packit f2184d
      const size_t n = fdf->n;
Packit f2184d
      const size_t p = fdf->p;
Packit f2184d
      size_t i;
Packit f2184d
      gsl_matrix * J = gsl_matrix_alloc(n, p);
Packit f2184d
      gsl_matrix * covar = gsl_matrix_alloc (p, p);
Packit f2184d
Packit f2184d
      gsl_multifit_fdfsolver_jac (s, J);
Packit f2184d
      gsl_multifit_covar(J, 0.0, covar);
Packit f2184d
Packit f2184d
      for (i = 0; i < p; i++) 
Packit f2184d
        {
Packit f2184d
          double ei = sqrt(sumsq/(n-p))*sqrt(gsl_matrix_get(covar,i,i));
Packit f2184d
          gsl_test_rel (ei, sigma[i], epsrel, 
Packit f2184d
                        "%s/%s, sigma(%d)", sname, pname, i) ;
Packit f2184d
        }
Packit f2184d
Packit f2184d
      gsl_matrix_free (J);
Packit f2184d
      gsl_matrix_free (covar);
Packit f2184d
    }
Packit f2184d
#endif
Packit f2184d
}
Packit f2184d
Packit f2184d
static void
Packit f2184d
test_scale_x0(gsl_vector *x0, const double scale)
Packit f2184d
{
Packit f2184d
  double nx = gsl_blas_dnrm2(x0);
Packit f2184d
Packit f2184d
  if (nx == 0.0)
Packit f2184d
    gsl_vector_set_all(x0, scale);
Packit f2184d
  else
Packit f2184d
    gsl_vector_scale(x0, scale);
Packit f2184d
} /* test_scale_x0() */