Blame doc/examples/bspline.c

Packit 67cb25
#include <stdio.h>
Packit 67cb25
#include <stdlib.h>
Packit 67cb25
#include <math.h>
Packit 67cb25
#include <gsl/gsl_bspline.h>
Packit 67cb25
#include <gsl/gsl_multifit.h>
Packit 67cb25
#include <gsl/gsl_rng.h>
Packit 67cb25
#include <gsl/gsl_randist.h>
Packit 67cb25
#include <gsl/gsl_statistics.h>
Packit 67cb25
Packit 67cb25
/* number of data points to fit */
Packit 67cb25
#define N        200
Packit 67cb25
Packit 67cb25
/* number of fit coefficients */
Packit 67cb25
#define NCOEFFS  12
Packit 67cb25
Packit 67cb25
/* nbreak = ncoeffs + 2 - k = ncoeffs - 2 since k = 4 */
Packit 67cb25
#define NBREAK   (NCOEFFS - 2)
Packit 67cb25
Packit 67cb25
int
Packit 67cb25
main (void)
Packit 67cb25
{
Packit 67cb25
  const size_t n = N;
Packit 67cb25
  const size_t ncoeffs = NCOEFFS;
Packit 67cb25
  const size_t nbreak = NBREAK;
Packit 67cb25
  size_t i, j;
Packit 67cb25
  gsl_bspline_workspace *bw;
Packit 67cb25
  gsl_vector *B;
Packit 67cb25
  double dy;
Packit 67cb25
  gsl_rng *r;
Packit 67cb25
  gsl_vector *c, *w;
Packit 67cb25
  gsl_vector *x, *y;
Packit 67cb25
  gsl_matrix *X, *cov;
Packit 67cb25
  gsl_multifit_linear_workspace *mw;
Packit 67cb25
  double chisq, Rsq, dof, tss;
Packit 67cb25
Packit 67cb25
  gsl_rng_env_setup();
Packit 67cb25
  r = gsl_rng_alloc(gsl_rng_default);
Packit 67cb25
Packit 67cb25
  /* allocate a cubic bspline workspace (k = 4) */
Packit 67cb25
  bw = gsl_bspline_alloc(4, nbreak);
Packit 67cb25
  B = gsl_vector_alloc(ncoeffs);
Packit 67cb25
Packit 67cb25
  x = gsl_vector_alloc(n);
Packit 67cb25
  y = gsl_vector_alloc(n);
Packit 67cb25
  X = gsl_matrix_alloc(n, ncoeffs);
Packit 67cb25
  c = gsl_vector_alloc(ncoeffs);
Packit 67cb25
  w = gsl_vector_alloc(n);
Packit 67cb25
  cov = gsl_matrix_alloc(ncoeffs, ncoeffs);
Packit 67cb25
  mw = gsl_multifit_linear_alloc(n, ncoeffs);
Packit 67cb25
Packit 67cb25
  /* this is the data to be fitted */
Packit 67cb25
  for (i = 0; i < n; ++i)
Packit 67cb25
    {
Packit 67cb25
      double sigma;
Packit 67cb25
      double xi = (15.0 / (N - 1)) * i;
Packit 67cb25
      double yi = cos(xi) * exp(-0.1 * xi);
Packit 67cb25
Packit 67cb25
      sigma = 0.1 * yi;
Packit 67cb25
      dy = gsl_ran_gaussian(r, sigma);
Packit 67cb25
      yi += dy;
Packit 67cb25
Packit 67cb25
      gsl_vector_set(x, i, xi);
Packit 67cb25
      gsl_vector_set(y, i, yi);
Packit 67cb25
      gsl_vector_set(w, i, 1.0 / (sigma * sigma));
Packit 67cb25
Packit 67cb25
      printf("%f %f\n", xi, yi);
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  /* use uniform breakpoints on [0, 15] */
Packit 67cb25
  gsl_bspline_knots_uniform(0.0, 15.0, bw);
Packit 67cb25
Packit 67cb25
  /* construct the fit matrix X */
Packit 67cb25
  for (i = 0; i < n; ++i)
Packit 67cb25
    {
Packit 67cb25
      double xi = gsl_vector_get(x, i);
Packit 67cb25
Packit 67cb25
      /* compute B_j(xi) for all j */
Packit 67cb25
      gsl_bspline_eval(xi, B, bw);
Packit 67cb25
Packit 67cb25
      /* fill in row i of X */
Packit 67cb25
      for (j = 0; j < ncoeffs; ++j)
Packit 67cb25
        {
Packit 67cb25
          double Bj = gsl_vector_get(B, j);
Packit 67cb25
          gsl_matrix_set(X, i, j, Bj);
Packit 67cb25
        }
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  /* do the fit */
Packit 67cb25
  gsl_multifit_wlinear(X, w, y, c, cov, &chisq, mw);
Packit 67cb25
Packit 67cb25
  dof = n - ncoeffs;
Packit 67cb25
  tss = gsl_stats_wtss(w->data, 1, y->data, 1, y->size);
Packit 67cb25
  Rsq = 1.0 - chisq / tss;
Packit 67cb25
Packit 67cb25
  fprintf(stderr, "chisq/dof = %e, Rsq = %f\n", 
Packit 67cb25
                   chisq / dof, Rsq);
Packit 67cb25
Packit 67cb25
  printf("\n\n");
Packit 67cb25
Packit 67cb25
  /* output the smoothed curve */
Packit 67cb25
  {
Packit 67cb25
    double xi, yi, yerr;
Packit 67cb25
Packit 67cb25
    for (xi = 0.0; xi < 15.0; xi += 0.1)
Packit 67cb25
      {
Packit 67cb25
        gsl_bspline_eval(xi, B, bw);
Packit 67cb25
        gsl_multifit_linear_est(B, c, cov, &yi, &yerr);
Packit 67cb25
        printf("%f %f\n", xi, yi);
Packit 67cb25
      }
Packit 67cb25
  }
Packit 67cb25
Packit 67cb25
  gsl_rng_free(r);
Packit 67cb25
  gsl_bspline_free(bw);
Packit 67cb25
  gsl_vector_free(B);
Packit 67cb25
  gsl_vector_free(x);
Packit 67cb25
  gsl_vector_free(y);
Packit 67cb25
  gsl_matrix_free(X);
Packit 67cb25
  gsl_vector_free(c);
Packit 67cb25
  gsl_vector_free(w);
Packit 67cb25
  gsl_matrix_free(cov);
Packit 67cb25
  gsl_multifit_linear_free(mw);
Packit 67cb25
Packit 67cb25
  return 0;
Packit 67cb25
} /* main() */