|
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() */
|