|
Packit |
67cb25 |
#include <stdio.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_multifit.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_randist.h>
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
int
|
|
Packit |
67cb25 |
dofit(const gsl_multifit_robust_type *T,
|
|
Packit |
67cb25 |
const gsl_matrix *X, const gsl_vector *y,
|
|
Packit |
67cb25 |
gsl_vector *c, gsl_matrix *cov)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
int s;
|
|
Packit |
67cb25 |
gsl_multifit_robust_workspace * work
|
|
Packit |
67cb25 |
= gsl_multifit_robust_alloc (T, X->size1, X->size2);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
s = gsl_multifit_robust (X, y, c, cov, work);
|
|
Packit |
67cb25 |
gsl_multifit_robust_free (work);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return s;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
int
|
|
Packit |
67cb25 |
main (int argc, char **argv)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
size_t i;
|
|
Packit |
67cb25 |
size_t n;
|
|
Packit |
67cb25 |
const size_t p = 2; /* linear fit */
|
|
Packit |
67cb25 |
gsl_matrix *X, *cov;
|
|
Packit |
67cb25 |
gsl_vector *x, *y, *c, *c_ols;
|
|
Packit |
67cb25 |
const double a = 1.45; /* slope */
|
|
Packit |
67cb25 |
const double b = 3.88; /* intercept */
|
|
Packit |
67cb25 |
gsl_rng *r;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
if (argc != 2)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
fprintf (stderr,"usage: robfit n\n");
|
|
Packit |
67cb25 |
exit (-1);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
n = atoi (argv[1]);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
X = gsl_matrix_alloc (n, p);
|
|
Packit |
67cb25 |
x = gsl_vector_alloc (n);
|
|
Packit |
67cb25 |
y = gsl_vector_alloc (n);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
c = gsl_vector_alloc (p);
|
|
Packit |
67cb25 |
c_ols = gsl_vector_alloc (p);
|
|
Packit |
67cb25 |
cov = gsl_matrix_alloc (p, p);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
r = gsl_rng_alloc(gsl_rng_default);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* generate linear dataset */
|
|
Packit |
67cb25 |
for (i = 0; i < n - 3; i++)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double dx = 10.0 / (n - 1.0);
|
|
Packit |
67cb25 |
double ei = gsl_rng_uniform(r);
|
|
Packit |
67cb25 |
double xi = -5.0 + i * dx;
|
|
Packit |
67cb25 |
double yi = a * xi + b;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_vector_set (x, i, xi);
|
|
Packit |
67cb25 |
gsl_vector_set (y, i, yi + ei);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* add a few outliers */
|
|
Packit |
67cb25 |
gsl_vector_set(x, n - 3, 4.7);
|
|
Packit |
67cb25 |
gsl_vector_set(y, n - 3, -8.3);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_vector_set(x, n - 2, 3.5);
|
|
Packit |
67cb25 |
gsl_vector_set(y, n - 2, -6.7);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_vector_set(x, n - 1, 4.1);
|
|
Packit |
67cb25 |
gsl_vector_set(y, n - 1, -6.0);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* construct design matrix X for linear fit */
|
|
Packit |
67cb25 |
for (i = 0; i < n; ++i)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double xi = gsl_vector_get(x, i);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_matrix_set (X, i, 0, 1.0);
|
|
Packit |
67cb25 |
gsl_matrix_set (X, i, 1, xi);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* perform robust and OLS fit */
|
|
Packit |
67cb25 |
dofit(gsl_multifit_robust_ols, X, y, c_ols, cov);
|
|
Packit |
67cb25 |
dofit(gsl_multifit_robust_bisquare, X, y, c, cov);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* output data and model */
|
|
Packit |
67cb25 |
for (i = 0; i < n; ++i)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double xi = gsl_vector_get(x, i);
|
|
Packit |
67cb25 |
double yi = gsl_vector_get(y, i);
|
|
Packit |
67cb25 |
gsl_vector_view v = gsl_matrix_row(X, i);
|
|
Packit |
67cb25 |
double y_ols, y_rob, y_err;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_multifit_robust_est(&v.vector, c, cov, &y_rob, &y_err);
|
|
Packit |
67cb25 |
gsl_multifit_robust_est(&v.vector, c_ols, cov, &y_ols, &y_err);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
printf("%g %g %g %g\n", xi, yi, y_rob, y_ols);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
#define C(i) (gsl_vector_get(c,(i)))
|
|
Packit |
67cb25 |
#define COV(i,j) (gsl_matrix_get(cov,(i),(j)))
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
printf ("# best fit: Y = %g + %g X\n",
|
|
Packit |
67cb25 |
C(0), C(1));
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
printf ("# covariance matrix:\n");
|
|
Packit |
67cb25 |
printf ("# [ %+.5e, %+.5e\n",
|
|
Packit |
67cb25 |
COV(0,0), COV(0,1));
|
|
Packit |
67cb25 |
printf ("# %+.5e, %+.5e\n",
|
|
Packit |
67cb25 |
COV(1,0), COV(1,1));
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_matrix_free (X);
|
|
Packit |
67cb25 |
gsl_vector_free (x);
|
|
Packit |
67cb25 |
gsl_vector_free (y);
|
|
Packit |
67cb25 |
gsl_vector_free (c);
|
|
Packit |
67cb25 |
gsl_vector_free (c_ols);
|
|
Packit |
67cb25 |
gsl_matrix_free (cov);
|
|
Packit |
67cb25 |
gsl_rng_free(r);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return 0;
|
|
Packit |
67cb25 |
}
|