|
Packit |
67cb25 |
#include <stdlib.h>
|
|
Packit |
67cb25 |
#include <stdio.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_vector.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_matrix.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_blas.h>
|
|
Packit |
67cb25 |
#include <gsl/gsl_multifit_nlinear.h>
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* parameters to model */
|
|
Packit |
67cb25 |
struct model_params
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double a1;
|
|
Packit |
67cb25 |
double a2;
|
|
Packit |
67cb25 |
double a3;
|
|
Packit |
67cb25 |
double a4;
|
|
Packit |
67cb25 |
double a5;
|
|
Packit |
67cb25 |
};
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* Branin function */
|
|
Packit |
67cb25 |
int
|
|
Packit |
67cb25 |
func_f (const gsl_vector * x, void *params, gsl_vector * f)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
struct model_params *par = (struct model_params *) params;
|
|
Packit |
67cb25 |
double x1 = gsl_vector_get(x, 0);
|
|
Packit |
67cb25 |
double x2 = gsl_vector_get(x, 1);
|
|
Packit |
67cb25 |
double f1 = x2 + par->a1 * x1 * x1 + par->a2 * x1 + par->a3;
|
|
Packit |
67cb25 |
double f2 = sqrt(par->a4) * sqrt(1.0 + (1.0 - par->a5) * cos(x1));
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_vector_set(f, 0, f1);
|
|
Packit |
67cb25 |
gsl_vector_set(f, 1, f2);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return GSL_SUCCESS;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
int
|
|
Packit |
67cb25 |
func_df (const gsl_vector * x, void *params, gsl_matrix * J)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
struct model_params *par = (struct model_params *) params;
|
|
Packit |
67cb25 |
double x1 = gsl_vector_get(x, 0);
|
|
Packit |
67cb25 |
double f2 = sqrt(par->a4) * sqrt(1.0 + (1.0 - par->a5) * cos(x1));
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_matrix_set(J, 0, 0, 2.0 * par->a1 * x1 + par->a2);
|
|
Packit |
67cb25 |
gsl_matrix_set(J, 0, 1, 1.0);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_matrix_set(J, 1, 0, -0.5 * par->a4 / f2 * (1.0 - par->a5) * sin(x1));
|
|
Packit |
67cb25 |
gsl_matrix_set(J, 1, 1, 0.0);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return GSL_SUCCESS;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
int
|
|
Packit |
67cb25 |
func_fvv (const gsl_vector * x, const gsl_vector * v,
|
|
Packit |
67cb25 |
void *params, gsl_vector * fvv)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
struct model_params *par = (struct model_params *) params;
|
|
Packit |
67cb25 |
double x1 = gsl_vector_get(x, 0);
|
|
Packit |
67cb25 |
double v1 = gsl_vector_get(v, 0);
|
|
Packit |
67cb25 |
double c = cos(x1);
|
|
Packit |
67cb25 |
double s = sin(x1);
|
|
Packit |
67cb25 |
double f2 = sqrt(par->a4) * sqrt(1.0 + (1.0 - par->a5) * c);
|
|
Packit |
67cb25 |
double t = 0.5 * par->a4 * (1.0 - par->a5) / f2;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_vector_set(fvv, 0, 2.0 * par->a1 * v1 * v1);
|
|
Packit |
67cb25 |
gsl_vector_set(fvv, 1, -t * (c + s*s/f2) * v1 * v1);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return GSL_SUCCESS;
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
void
|
|
Packit |
67cb25 |
callback(const size_t iter, void *params,
|
|
Packit |
67cb25 |
const gsl_multifit_nlinear_workspace *w)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
gsl_vector * x = gsl_multifit_nlinear_position(w);
|
|
Packit |
67cb25 |
double x1 = gsl_vector_get(x, 0);
|
|
Packit |
67cb25 |
double x2 = gsl_vector_get(x, 1);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* print out current location */
|
|
Packit |
67cb25 |
printf("%f %f\n", x1, x2);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
void
|
|
Packit |
67cb25 |
solve_system(gsl_vector *x0, gsl_multifit_nlinear_fdf *fdf,
|
|
Packit |
67cb25 |
gsl_multifit_nlinear_parameters *params)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
const gsl_multifit_nlinear_type *T = gsl_multifit_nlinear_trust;
|
|
Packit |
67cb25 |
const size_t max_iter = 200;
|
|
Packit |
67cb25 |
const double xtol = 1.0e-8;
|
|
Packit |
67cb25 |
const double gtol = 1.0e-8;
|
|
Packit |
67cb25 |
const double ftol = 1.0e-8;
|
|
Packit |
67cb25 |
const size_t n = fdf->n;
|
|
Packit |
67cb25 |
const size_t p = fdf->p;
|
|
Packit |
67cb25 |
gsl_multifit_nlinear_workspace *work =
|
|
Packit |
67cb25 |
gsl_multifit_nlinear_alloc(T, params, n, p);
|
|
Packit |
67cb25 |
gsl_vector * f = gsl_multifit_nlinear_residual(work);
|
|
Packit |
67cb25 |
gsl_vector * x = gsl_multifit_nlinear_position(work);
|
|
Packit |
67cb25 |
int info;
|
|
Packit |
67cb25 |
double chisq0, chisq, rcond;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
printf("# %s/%s\n",
|
|
Packit |
67cb25 |
gsl_multifit_nlinear_name(work),
|
|
Packit |
67cb25 |
gsl_multifit_nlinear_trs_name(work));
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* initialize solver */
|
|
Packit |
67cb25 |
gsl_multifit_nlinear_init(x0, fdf, work);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* store initial cost */
|
|
Packit |
67cb25 |
gsl_blas_ddot(f, f, &chisq0);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* iterate until convergence */
|
|
Packit |
67cb25 |
gsl_multifit_nlinear_driver(max_iter, xtol, gtol, ftol,
|
|
Packit |
67cb25 |
callback, NULL, &info, work);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* store final cost */
|
|
Packit |
67cb25 |
gsl_blas_ddot(f, f, &chisq);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* store cond(J(x)) */
|
|
Packit |
67cb25 |
gsl_multifit_nlinear_rcond(&rcond, work);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* print summary */
|
|
Packit |
67cb25 |
fprintf(stderr, "%-25s %-6zu %-5zu %-5zu %-13.4e %-12.4e %-13.4e (%.2e, %.2e)\n",
|
|
Packit |
67cb25 |
gsl_multifit_nlinear_trs_name(work),
|
|
Packit |
67cb25 |
gsl_multifit_nlinear_niter(work),
|
|
Packit |
67cb25 |
fdf->nevalf,
|
|
Packit |
67cb25 |
fdf->nevaldf,
|
|
Packit |
67cb25 |
chisq0,
|
|
Packit |
67cb25 |
chisq,
|
|
Packit |
67cb25 |
1.0 / rcond,
|
|
Packit |
67cb25 |
gsl_vector_get(x, 0),
|
|
Packit |
67cb25 |
gsl_vector_get(x, 1));
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
printf("\n\n");
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_multifit_nlinear_free(work);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
int
|
|
Packit |
67cb25 |
main (void)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
const size_t n = 2;
|
|
Packit |
67cb25 |
const size_t p = 2;
|
|
Packit |
67cb25 |
gsl_vector *f = gsl_vector_alloc(n);
|
|
Packit |
67cb25 |
gsl_vector *x = gsl_vector_alloc(p);
|
|
Packit |
67cb25 |
gsl_multifit_nlinear_fdf fdf;
|
|
Packit |
67cb25 |
gsl_multifit_nlinear_parameters fdf_params =
|
|
Packit |
67cb25 |
gsl_multifit_nlinear_default_parameters();
|
|
Packit |
67cb25 |
struct model_params params;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
params.a1 = -5.1 / (4.0 * M_PI * M_PI);
|
|
Packit |
67cb25 |
params.a2 = 5.0 / M_PI;
|
|
Packit |
67cb25 |
params.a3 = -6.0;
|
|
Packit |
67cb25 |
params.a4 = 10.0;
|
|
Packit |
67cb25 |
params.a5 = 1.0 / (8.0 * M_PI);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* print map of Phi(x1, x2) */
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
double x1, x2, chisq;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
for (x1 = -5.0; x1 < 15.0; x1 += 0.1)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
for (x2 = -5.0; x2 < 15.0; x2 += 0.1)
|
|
Packit |
67cb25 |
{
|
|
Packit |
67cb25 |
gsl_vector_set(x, 0, x1);
|
|
Packit |
67cb25 |
gsl_vector_set(x, 1, x2);
|
|
Packit |
67cb25 |
func_f(x, ¶ms, f);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_blas_ddot(f, f, &chisq);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
printf("%f %f %f\n", x1, x2, chisq);
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
printf("\n");
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
printf("\n\n");
|
|
Packit |
67cb25 |
}
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* define function to be minimized */
|
|
Packit |
67cb25 |
fdf.f = func_f;
|
|
Packit |
67cb25 |
fdf.df = func_df;
|
|
Packit |
67cb25 |
fdf.fvv = func_fvv;
|
|
Packit |
67cb25 |
fdf.n = n;
|
|
Packit |
67cb25 |
fdf.p = p;
|
|
Packit |
67cb25 |
fdf.params = ¶m;;
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
/* starting point */
|
|
Packit |
67cb25 |
gsl_vector_set(x, 0, 6.0);
|
|
Packit |
67cb25 |
gsl_vector_set(x, 1, 14.5);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
fprintf(stderr, "%-25s %-6s %-5s %-5s %-13s %-12s %-13s %-15s\n",
|
|
Packit |
67cb25 |
"Method", "NITER", "NFEV", "NJEV", "Initial Cost",
|
|
Packit |
67cb25 |
"Final cost", "Final cond(J)", "Final x");
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
fdf_params.trs = gsl_multifit_nlinear_trs_lm;
|
|
Packit |
67cb25 |
solve_system(x, &fdf, &fdf_params);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
fdf_params.trs = gsl_multifit_nlinear_trs_lmaccel;
|
|
Packit |
67cb25 |
solve_system(x, &fdf, &fdf_params);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
fdf_params.trs = gsl_multifit_nlinear_trs_dogleg;
|
|
Packit |
67cb25 |
solve_system(x, &fdf, &fdf_params);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
fdf_params.trs = gsl_multifit_nlinear_trs_ddogleg;
|
|
Packit |
67cb25 |
solve_system(x, &fdf, &fdf_params);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
fdf_params.trs = gsl_multifit_nlinear_trs_subspace2D;
|
|
Packit |
67cb25 |
solve_system(x, &fdf, &fdf_params);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
gsl_vector_free(f);
|
|
Packit |
67cb25 |
gsl_vector_free(x);
|
|
Packit |
67cb25 |
|
|
Packit |
67cb25 |
return 0;
|
|
Packit |
67cb25 |
}
|