#include /*----------------------------------------------------------------------- ------------------------------------------------------------------------- This file contains GSL solver related functions ------------------------------------------------------------------------- -----------------------------------------------------------------------*/ #define DX 0.00001 struct FuncParam { double (*function)(const double*, void* externalParams); void (*gradient)(const double*, double*, void *externalParams); void* externalParams; }; #ifndef NDEBUG static void printCurrentValue(size_t iter, double fx, const gsl_vector* x, size_t N) { printf("Iter: %ld, fx = %.12f", iter, fx); /*size_t i; for (i=0; ifunction(gsl_vector_const_ptr(v, 0), p->externalParams); } /************************************************************************ * This function numerically computes the gradient of func using finite differences ************************************************************************/ static void grad(const gsl_vector *v, void *internalParams, gsl_vector *df) { struct FuncParam* p = (struct FuncParam*)internalParams; if (p->gradient != 0) { p->gradient(gsl_vector_const_ptr(v, 0), gsl_vector_ptr(df, 0), p->externalParams); return; } double f = func(v, internalParams); size_t N = v->size; size_t i; size_t j; for (i=0; ifunction(coef2, p->externalParams); gsl_vector_set(df,i, (f2 - f) / DX); } } static void fdf(const gsl_vector *x, void *params, double *f, gsl_vector *df) { *f = func(x, params); grad(x, params, df); } /* Public function Perform an optimization on provided function with N independent variables. minimizer contains the initial guess and on output contains the optimal values of the independent function that minimizes the function. */ void optimizeGsl(double (*function)(const double*, void *externalParams), void (*gradient)(const double*, double*, void *externalParams), double* minimizer, size_t N, void *externalParams) { struct FuncParam internalParams; internalParams.function = function; internalParams.gradient = gradient; internalParams.externalParams = externalParams; size_t iter = 0; int status; const gsl_multimin_fdfminimizer_type *T; gsl_multimin_fdfminimizer *s; gsl_vector *x; gsl_multimin_function_fdf my_func; my_func.n = N; my_func.f = func; my_func.df = grad; my_func.fdf = fdf; my_func.params = &internalParams; /* Starting point, x = */ x = gsl_vector_alloc (N); size_t i; for (i=0;igradient, 1e-1); #ifndef NDEBUG if (status == GSL_SUCCESS) printf ("Minimum found at:\n"); printCurrentValue(iter, s->f, s->x, N); #endif } while (status == GSL_CONTINUE && iter < 50); for (i=0;ix, i); #ifndef NDEBUG printf("GSL optimization terminated with status code = %d\n", status); printCurrentValue(iter, function(minimizer, externalParams), s->x, N); printf("\n"); #endif gsl_multimin_fdfminimizer_free (s); gsl_vector_free (x); }