Blame doc/examples/fitreg2.c

Packit 67cb25
#include <gsl/gsl_math.h>
Packit 67cb25
#include <gsl/gsl_vector.h>
Packit 67cb25
#include <gsl/gsl_matrix.h>
Packit 67cb25
#include <gsl/gsl_multifit.h>
Packit 67cb25
#include <gsl/gsl_blas.h>
Packit 67cb25
Packit 67cb25
static int
Packit 67cb25
hilbert_matrix(gsl_matrix * m)
Packit 67cb25
{
Packit 67cb25
  const size_t N = m->size1;
Packit 67cb25
  const size_t M = m->size2;
Packit 67cb25
  size_t i, j;
Packit 67cb25
Packit 67cb25
  for (i = 0; i < N; i++)
Packit 67cb25
    {
Packit 67cb25
      for (j = 0; j < M; j++)
Packit 67cb25
        {
Packit 67cb25
          gsl_matrix_set(m, i, j, 1.0/(i+j+1.0));
Packit 67cb25
        }
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  return GSL_SUCCESS;
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
int
Packit 67cb25
main()
Packit 67cb25
{
Packit 67cb25
  const size_t n = 10; /* number of observations */
Packit 67cb25
  const size_t p = 8;  /* number of model parameters */
Packit 67cb25
  size_t i;
Packit 67cb25
  gsl_matrix *X = gsl_matrix_alloc(n, p);
Packit 67cb25
  gsl_vector *y = gsl_vector_alloc(n);
Packit 67cb25
Packit 67cb25
  /* construct Hilbert matrix and rhs vector */
Packit 67cb25
  hilbert_matrix(X);
Packit 67cb25
Packit 67cb25
  {
Packit 67cb25
    double val = 1.0;
Packit 67cb25
    for (i = 0; i < n; ++i)
Packit 67cb25
      {
Packit 67cb25
        gsl_vector_set(y, i, val);
Packit 67cb25
        val *= -1.0;
Packit 67cb25
      }
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  {
Packit 67cb25
    const size_t npoints = 200;                   /* number of points on L-curve and GCV curve */
Packit 67cb25
    gsl_multifit_linear_workspace *w =
Packit 67cb25
      gsl_multifit_linear_alloc(n, p);
Packit 67cb25
    gsl_vector *c = gsl_vector_alloc(p);          /* OLS solution */
Packit 67cb25
    gsl_vector *c_lcurve = gsl_vector_alloc(p);   /* regularized solution (L-curve) */
Packit 67cb25
    gsl_vector *c_gcv = gsl_vector_alloc(p);      /* regularized solution (GCV) */
Packit 67cb25
    gsl_vector *reg_param = gsl_vector_alloc(npoints);
Packit 67cb25
    gsl_vector *rho = gsl_vector_alloc(npoints);  /* residual norms */
Packit 67cb25
    gsl_vector *eta = gsl_vector_alloc(npoints);  /* solution norms */
Packit 67cb25
    gsl_vector *G = gsl_vector_alloc(npoints);    /* GCV function values */
Packit 67cb25
    double lambda_l;                              /* optimal regularization parameter (L-curve) */
Packit 67cb25
    double lambda_gcv;                            /* optimal regularization parameter (GCV) */
Packit 67cb25
    double G_gcv;                                 /* G(lambda_gcv) */
Packit 67cb25
    size_t reg_idx;                               /* index of optimal lambda */
Packit 67cb25
    double rcond;                                 /* reciprocal condition number of X */
Packit 67cb25
    double chisq, rnorm, snorm;
Packit 67cb25
Packit 67cb25
    /* compute SVD of X */
Packit 67cb25
    gsl_multifit_linear_svd(X, w);
Packit 67cb25
Packit 67cb25
    rcond = gsl_multifit_linear_rcond(w);
Packit 67cb25
    fprintf(stderr, "matrix condition number = %e\n", 1.0 / rcond);
Packit 67cb25
Packit 67cb25
    /* unregularized (standard) least squares fit, lambda = 0 */
Packit 67cb25
    gsl_multifit_linear_solve(0.0, X, y, c, &rnorm, &snorm, w);
Packit 67cb25
    chisq = pow(rnorm, 2.0);
Packit 67cb25
Packit 67cb25
    fprintf(stderr, "\n=== Unregularized fit ===\n");
Packit 67cb25
    fprintf(stderr, "residual norm = %g\n", rnorm);
Packit 67cb25
    fprintf(stderr, "solution norm = %g\n", snorm);
Packit 67cb25
    fprintf(stderr, "chisq/dof = %g\n", chisq / (n - p));
Packit 67cb25
Packit 67cb25
    /* calculate L-curve and find its corner */
Packit 67cb25
    gsl_multifit_linear_lcurve(y, reg_param, rho, eta, w);
Packit 67cb25
    gsl_multifit_linear_lcorner(rho, eta, &reg_idx);
Packit 67cb25
Packit 67cb25
    /* store optimal regularization parameter */
Packit 67cb25
    lambda_l = gsl_vector_get(reg_param, reg_idx);
Packit 67cb25
Packit 67cb25
    /* regularize with lambda_l */
Packit 67cb25
    gsl_multifit_linear_solve(lambda_l, X, y, c_lcurve, &rnorm, &snorm, w);
Packit 67cb25
    chisq = pow(rnorm, 2.0) + pow(lambda_l * snorm, 2.0);
Packit 67cb25
Packit 67cb25
    fprintf(stderr, "\n=== Regularized fit (L-curve) ===\n");
Packit 67cb25
    fprintf(stderr, "optimal lambda: %g\n", lambda_l);
Packit 67cb25
    fprintf(stderr, "residual norm = %g\n", rnorm);
Packit 67cb25
    fprintf(stderr, "solution norm = %g\n", snorm);
Packit 67cb25
    fprintf(stderr, "chisq/dof = %g\n", chisq / (n - p));
Packit 67cb25
Packit 67cb25
    /* calculate GCV curve and find its minimum */
Packit 67cb25
    gsl_multifit_linear_gcv(y, reg_param, G, &lambda_gcv, &G_gcv, w);
Packit 67cb25
Packit 67cb25
    /* regularize with lambda_gcv */
Packit 67cb25
    gsl_multifit_linear_solve(lambda_gcv, X, y, c_gcv, &rnorm, &snorm, w);
Packit 67cb25
    chisq = pow(rnorm, 2.0) + pow(lambda_gcv * snorm, 2.0);
Packit 67cb25
Packit 67cb25
    fprintf(stderr, "\n=== Regularized fit (GCV) ===\n");
Packit 67cb25
    fprintf(stderr, "optimal lambda: %g\n", lambda_gcv);
Packit 67cb25
    fprintf(stderr, "residual norm = %g\n", rnorm);
Packit 67cb25
    fprintf(stderr, "solution norm = %g\n", snorm);
Packit 67cb25
    fprintf(stderr, "chisq/dof = %g\n", chisq / (n - p));
Packit 67cb25
Packit 67cb25
    /* output L-curve and GCV curve */
Packit 67cb25
    for (i = 0; i < npoints; ++i)
Packit 67cb25
      {
Packit 67cb25
        printf("%e %e %e %e\n",
Packit 67cb25
               gsl_vector_get(reg_param, i),
Packit 67cb25
               gsl_vector_get(rho, i),
Packit 67cb25
               gsl_vector_get(eta, i),
Packit 67cb25
               gsl_vector_get(G, i));
Packit 67cb25
      }
Packit 67cb25
Packit 67cb25
    /* output L-curve corner point */
Packit 67cb25
    printf("\n\n%f %f\n",
Packit 67cb25
           gsl_vector_get(rho, reg_idx),
Packit 67cb25
           gsl_vector_get(eta, reg_idx));
Packit 67cb25
Packit 67cb25
    /* output GCV curve corner minimum */
Packit 67cb25
    printf("\n\n%e %e\n",
Packit 67cb25
           lambda_gcv,
Packit 67cb25
           G_gcv);
Packit 67cb25
Packit 67cb25
    gsl_multifit_linear_free(w);
Packit 67cb25
    gsl_vector_free(c);
Packit 67cb25
    gsl_vector_free(c_lcurve);
Packit 67cb25
    gsl_vector_free(reg_param);
Packit 67cb25
    gsl_vector_free(rho);
Packit 67cb25
    gsl_vector_free(eta);
Packit 67cb25
    gsl_vector_free(G);
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  gsl_matrix_free(X);
Packit 67cb25
  gsl_vector_free(y);
Packit 67cb25
Packit 67cb25
  return 0;
Packit 67cb25
}