70 gaussian(
const double a,
const double b,
const double c,
const double t)
72 const double z = (t - b) / c;
73 return (a * exp(-0.5 * z * z));
77 func_f (
const gsl_vector * x,
void *params, gsl_vector * f)
79 struct data *d = (
struct data *) params;
80 double a = gsl_vector_get(x, 0);
81 double b = gsl_vector_get(x, 1);
82 double c = gsl_vector_get(x, 2);
85 for (i = 0; i < d->
n; ++i)
91 gsl_vector_set(f, i, yi - y);
98 func_df (
const gsl_vector * x,
void *params, gsl_matrix * J)
100 struct data *d = (
struct data *) params;
101 double a = gsl_vector_get(x, 0);
102 double b = gsl_vector_get(x, 1);
103 double c = gsl_vector_get(x, 2);
106 for (i = 0; i < d->
n; ++i)
109 double zi = (ti - b) / c;
110 double ei = exp(-0.5 * zi * zi);
112 gsl_matrix_set(J, i, 0, -ei);
113 gsl_matrix_set(J, i, 1, -(a / c) * ei * zi);
114 gsl_matrix_set(J, i, 2, -(a / c) * ei * zi * zi);
121 func_fvv (
const gsl_vector * x,
const gsl_vector * v,
122 void *params, gsl_vector * fvv)
124 struct data *d = (
struct data *) params;
125 double a = gsl_vector_get(x, 0);
126 double b = gsl_vector_get(x, 1);
127 double c = gsl_vector_get(x, 2);
128 double va = gsl_vector_get(v, 0);
129 double vb = gsl_vector_get(v, 1);
130 double vc = gsl_vector_get(v, 2);
133 for (i = 0; i < d->
n; ++i)
136 double zi = (ti - b) / c;
137 double ei = exp(-0.5 * zi * zi);
138 double Dab = -zi * ei / c;
139 double Dac = -zi * zi * ei / c;
140 double Dbb = a * ei / (c * c) * (1.0 - zi*zi);
141 double Dbc = a * zi * ei / (c * c) * (2.0 - zi*zi);
142 double Dcc = a * zi * zi * ei / (c * c) * (3.0 - zi*zi);
145 sum = 2.0 * va * vb * Dab +
146 2.0 * va * vc * Dac +
148 2.0 * vb * vc * Dbc +
151 gsl_vector_set(fvv, i, sum);
159 const gsl_multifit_nlinear_workspace *w)
161 gsl_vector *f = gsl_multifit_nlinear_residual(w);
162 gsl_vector *x = gsl_multifit_nlinear_position(w);
163 double avratio = gsl_multifit_nlinear_avratio(w);
169 gsl_multifit_nlinear_rcond(&rcond, w);
173 fprintf(stderr,
"iter %2zu: a = %.4f, b = %.4f, c = %.4f, |a|/|v| = %.4f cond(J) = %e, |f(x)| = %.4f\n",
175 gsl_vector_get(x, 0),
176 gsl_vector_get(x, 1),
177 gsl_vector_get(x, 2),
186 gsl_multifit_nlinear_parameters *params)
188 const gsl_multifit_nlinear_type *T = gsl_multifit_nlinear_trust;
189 const size_t max_iter = 200;
190 const double xtol = 1.0e-8;
191 const double gtol = 1.0e-8;
192 const double ftol = 1.0e-8;
193 const size_t n = fdf->n;
194 const size_t p = fdf->p;
195 gsl_multifit_nlinear_workspace *work = gsl_multifit_nlinear_alloc(T, params, n, p);
196 gsl_vector * f = gsl_multifit_nlinear_residual(work);
197 gsl_vector *
y = gsl_multifit_nlinear_position(work);
199 double chisq0, chisq, rcond;
202 gsl_multifit_nlinear_init(x, fdf, work);
205 gsl_blas_ddot(f, f, &chisq0);
208 gsl_multifit_nlinear_driver(max_iter, xtol, gtol, ftol,
212 gsl_blas_ddot(f, f, &chisq);
215 gsl_multifit_nlinear_rcond(&rcond, work);
217 gsl_vector_memcpy(x, y);
223 fprintf(stderr,
"NITER = %zu\n", gsl_multifit_nlinear_niter(work));
224 fprintf(stderr,
"NFEV = %zu\n", fdf->nevalf);
225 fprintf(stderr,
"NJEV = %zu\n", fdf->nevaldf);
226 fprintf(stderr,
"NAEV = %zu\n", fdf->nevalfvv);
227 fprintf(stderr,
"chisq0 = %f\n", chisq0);
228 fprintf(stderr,
"chisq = %f\n", chisq);
229 fprintf(stderr,
"final = (%f, %f, %f)\n", gsl_vector_get(x, 0), gsl_vector_get(x, 1), gsl_vector_get(x, 2));
230 fprintf(stderr,
"final cond(J) = %f\n", 1.0 / rcond);
233 gsl_multifit_nlinear_free(work);
246 const gsl_rng_type * T = gsl_rng_default;
247 gsl_vector *f = gsl_vector_alloc(n);
248 gsl_vector *x = gsl_vector_alloc(p);
249 gsl_multifit_nlinear_fdf fdf;
250 gsl_multifit_nlinear_parameters fdf_params = gsl_multifit_nlinear_default_parameters();
251 struct data fit_data;
255 gsl_rng_env_setup ();
256 r = gsl_rng_alloc (T);
258 fit_data.
t = malloc(n *
sizeof(
double));
259 fit_data.
y = malloc(n *
sizeof(
double));
265 fit_data.
t[i] = xd[i];
266 fit_data.
y[i] = yd[i];
275 fdf.params = &fit_data;
278 gsl_vector_set(x, 0, aa[0]);
279 gsl_vector_set(x, 1, aa[1]);
280 gsl_vector_set(x, 2, aa[2]);
282 fdf_params.trs = gsl_multifit_nlinear_trs_lmaccel;
286 aa[0] = gsl_vector_get(x, 0);
287 aa[1] = gsl_vector_get(x, 1);
288 aa[2] = gsl_vector_get(x, 2);
int gaussian_fit_gsl(double *xd, double *yd, const size_t n, double *aa)
int func_fvv(const gsl_vector *x, const gsl_vector *v, void *params, gsl_vector *fvv)
int func_f(const gsl_vector *x, void *params, gsl_vector *f)
double gaussian(const double a, const double b, const double c, const double t)
void solve_system(gsl_vector *x, gsl_multifit_nlinear_fdf *fdf, gsl_multifit_nlinear_parameters *params)
void callback(const size_t iter, void *params, const gsl_multifit_nlinear_workspace *w)
int func_df(const gsl_vector *x, void *params, gsl_matrix *J)