Using the GSL function minimization routines to minimize the twodimensional function used as an example in the Optimization Methods note using the Nelder-Mead Simplex Method Define the function using the GSL matrix and vector facility (note that it is possible to pass a parameter vector to be used in this definition but we do not make use of it here) #include<stdio.h> #include<stdlib.h> #include<gsl/gsl_vector.h> double my_f (const gsl_vector *v, void *params) { double x, y; double *dp = (double *)params; x = gsl_vector_get(v, 0); y = gsl_vector_get(v, 1); return 100.0 * pow((x - 15.0),2) + 20.0* pow((28.0-x),2) + 100.0*pow((y-x),2) + 20.0*pow((38.0-x-y),2); } Below we use s = gsl_multimin_fminimizer_alloc (gsl_multimin_fminimizer_nmsimplex , np); and gsl_multimin_fminimizer_set (s, &ex4_fn, x, ss); to initialize the minimizer to minimize the function ex4_fn, starting from the initial point x. The size of the initial trial steps is given in vector ss. The ex4_fn function is of the data type gsl_multimin_function which is a structure. We set values to the components of ex4_fn using the statements: ex4_fn.f = &my_f; ex4_fn.n = np; ex4_fn.params = (void *)&par; /* Address of the function */ /* Dimension of the problem*/ /* Additional parms to define the fn*/ and the step size vector ss using the statements: ss = gsl_vector_alloc (np); gsl_vector_set_all (ss, 1.0); These are followed by the main loop that uses the function gsl_multimin_fminimizer_iterate to drive the iteration. This function performs one iteration to update the state of the minimizer. If the iteration encounters an unexpected problem then an error code will be returned. It also calculates the minimizer specific characteristic size as the average distance from the geometrical center of the simplex to all its vertices. This size can be used as a stopping criteria, as the simplex contracts itself near the minimum. The size is returned by the function gsl_multimin_fminimizer_size. #include<stdio.h> #include<stdlib.h> #include<gsl/gsl_multimin.h> double my_f (const gsl_vector *, void *); int main(void) { size_t np = 2; /* The parameter vector for the function defn: UNUSED */ double par[2] = {1.0, 2.0}; gsl_multimin_fminimizer *s ; gsl_vector *ss, *x; gsl_multimin_function ex4_fn; size_t iter = 0, i; int status; double size; /* Initial vertex size vector */ ss = gsl_vector_alloc (np); /* Set all step sizes to 1 */ gsl_vector_set_all (ss, 1.0); /* Starting point */ x = gsl_vector_alloc (np); gsl_vector_set (x, 0, 10.0); gsl_vector_set (x, 1, 14.0); /* Initialize method and iterate */ ex4_fn.f = &my_f; ex4_fn.n = np; ex4_fn.params = (void *)&par s = gsl_multimin_fminimizer_alloc (gsl_multimin_fminimizer_nmsimplex , np); gsl_multimin_fminimizer_set (s, &ex4_fn, x, ss); do { iter++; status = gsl_multimin_fminimizer_iterate(s); if (status) break; size = gsl_multimin_fminimizer_size (s); status = gsl_multimin_test_size (size, 1e-3); if (status == GSL_SUCCESS) { printf ("converged to minimum at\n"); } printf ("%5d ", iter); for (i = 0; i < np; i++) { printf ("%10.3e ", gsl_vector_get (s->x, i)); } printf ("f() = %7.3f size = %.3f\n", s->fval, size); } while (status == GSL_CONTINUE && iter < 100); gsl_vector_free(x); gsl_vector_free(ss); gsl_multimin_fminimizer_free (s); return status; } Compiling and running as usual: gcc -c nmfunc.c gcc -o nmsimplex.exe nmsimplex.c nmfunc.o -lgsl -lgslcblas –lm ./nmsimplex.exe > nmsimplex.output Results: 1 1.100e+01 1.400e+01 f() = 11660.000 size = 0.654 2 1.300e+01 1.250e+01 f() = 8050.000 size = 1.082 3 1.400e+01 1.375e+01 f() = 6127.500 size = 1.372 4 1.400e+01 1.375e+01 f() = 6127.500 size = 1.372 5 1.700e+01 1.350e+01 f() = 5170.000 size = 1.372 6 1.450e+01 1.638e+01 f() = 5036.875 size = 1.823 7 1.925e+01 1.731e+01 f() = 3754.219 size = 2.517 8 1.925e+01 1.731e+01 f() = 3754.219 size = 2.517 9 1.625e+01 1.756e+01 f() = 3440.469 size = 1.823 10 1.725e+01 1.881e+01 f() = 3136.719 size = 1.372 11 1.800e+01 1.775e+01 f() = 3007.500 size = 0.898 12 1.831e+01 1.864e+01 f() = 3006.904 size = 0.638 13 1.770e+01 1.850e+01 f() = 2979.621 size = 0.458 14 1.800e+01 1.816e+01 f() = 2970.597 size = 0.318 15 1.762e+01 1.818e+01 f() = 2969.089 size = 0.225 16 1.776e+01 1.834e+01 f() = 2964.699 size = 0.171 17 1.785e+01 1.821e+01 f() = 2960.902 size = 0.114 18 1.785e+01 1.821e+01 f() = 2960.902 size = 0.079 19 1.785e+01 1.821e+01 f() = 2960.902 size = 0.057 20 1.785e+01 1.821e+01 f() = 2960.902 size = 0.057 21 1.785e+01 1.821e+01 f() = 2960.902 size = 0.040 22 1.780e+01 1.821e+01 f() = 2960.817 size = 0.028 23 1.782e+01 1.823e+01 f() = 2960.757 size = 0.021 24 1.783e+01 1.821e+01 f() = 2960.724 size = 0.014 25 1.783e+01 1.821e+01 f() = 2960.724 size = 0.010 26 1.783e+01 1.821e+01 f() = 2960.724 size = 0.010 27 1.782e+01 1.821e+01 f() = 2960.717 size = 0.007 28 1.782e+01 1.821e+01 f() = 2960.717 size = 0.007 29 1.782e+01 1.821e+01 f() = 2960.717 size = 0.005 30 1.782e+01 1.822e+01 f() = 2960.716 size = 0.004 31 1.782e+01 1.822e+01 f() = 2960.715 size = 0.003 32 1.782e+01 1.821e+01 f() = 2960.714 size = 0.002 33 1.782e+01 1.821e+01 f() = 2960.714 size = 0.001 34 1.782e+01 1.821e+01 f() = 2960.714 size = 0.001 converged to minimum at 35 1.782e+01 1.821e+01 f() = 2960.714 size = 0.001