Using the GSL function minimization routines to minimize the two-

advertisement
Using the GSL function minimization routines to minimize the twodimensional function used as an example in the Optimization Methods
note using the Steepest Descent Method
Define the functions ex4_f, ex4_df, and ex4_fdf 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 ex4_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);
}
#include<stdio.h>
#include<stdlib.h>
#include<gsl/gsl_vector.h>
void ex4_df (const gsl_vector *v, void *m, gsl_vector *df)
{
double x,y,g0,g1;
x = gsl_vector_get(v, 0);
y = gsl_vector_get(v, 1);
g0= 200.0 * (x - 15.0) - 40.0* (28.0-x) - 200.0*(y-x) - 40.0*(38.0-x-y);
g1= 200.0*(y-x)- 40.0*(38.0-x-y);
gsl_vector_set(df, 0, g0);
gsl_vector_set(df, 1, g1);
}
#include<stdio.h>
#include<stdlib.h>
#include<gsl/gsl_vector.h>
double ex4_f (const gsl_vector *, void *);
void ex4_df (const gsl_vector *, void *, gsl_vector *);
/* Compute both f and df together. */
void ex4_fdf (const gsl_vector *x, void *m, double *f, gsl_vector *df)
{
*f = ex4_f(x, m);
ex4_df(x, m, df);
}
The staring values are set using the statements:
x = gsl_vector_alloc (np);
gsl_vector_set (x, 0, 10.0);
gsl_vector_set (x, 1, 14.0);
Then we use
s = gsl_multimin_fdfminimizer_alloc (gsl_multimin_fdfminimizer_steepest_descent, np);
and
gsl_multimin_fdfminimizer_set (s, &ex4_funs, x, 0.1, 0.01);
to initialize the minimizer to minimize the function ex4_funs, starting from the initial point x.
The steepest descent algorithm follows the downhill gradient of the function at each step. When a
downhill step is successful the step-size (here =0.1) is increased by a factor of two. If the
downhill step leads to a higher function value then the algorithm backtracks and the step size is
decreased using the parameter tol (here=0.01).
The ex4_funs function is of the data type gsl_multimin_function_fdf which is a structure. It is
declared in the statement
gsl_multimin_function_fdf ex4_funs;
We set values to the components of ex4_funs using the statements:
ex4_funs.f = &ex4_f;
ex4_funs.df = &ex4_df;
ex4_funs.fdf = &ex4_fdf;
ex4_funs.n = np;
ex4_funs.params = (void *)∥
/* Address of the function */
/* Address of the first derivative */
/* Address of the combined function */
/* Dimension of the problem*/
/* Additional parms to define the fn*/
These are followed by the main loop that uses the function
gsl_multimin_fdfminimizer_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. The function
gsl_multimin_test_gradient is used to test the norm of the gradient against a tolerance. The test
returns GSL_SUCCESS if the absolute gradient is below the tolerance.
#include<stdio.h>
#include<stdlib.h>
#include<gsl/gsl_multimin.h>
#include<gsl/gsl_vector.h>
double ex4_f (const gsl_vector *, void *);
void ex4_df (const gsl_vector *, void *, gsl_vector *);
void ex4_fdf (const gsl_vector *, void *, double *,gsl_vector *);
int main(void)
{
size_t iter = 0, np=2;
int status;
gsl_multimin_fdfminimizer *s;
gsl_vector *ss,*x;
double par;
/* Initial vertex size vector */
ss = gsl_vector_alloc (np);
/* Set all step sizes to 1 */
gsl_vector_set_all (ss,2.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 */
gsl_multimin_function_fdf ex4_funs;
ex4_funs.f = &ex4_f;
ex4_funs.df = &ex4_df;
ex4_funs.fdf = &ex4_fdf;
ex4_funs.n = np;
ex4_funs.params = (void *)∥
s = gsl_multimin_fdfminimizer_alloc (gsl_multimin_fdfminimizer_steepest_descent, np);
gsl_multimin_fdfminimizer_set (s, &ex4_funs, x, 0.1, 0.01);
do
{
iter++;
status = gsl_multimin_fdfminimizer_iterate (s);
if (status)
break;
status = gsl_multimin_test_gradient (s->gradient, .001);
if (status == GSL_SUCCESS)
printf ("Minimum found at:\n");
printf ("%5zd %15.10f %15.10f %17.10f\n", iter,
gsl_vector_get (s->x, 0),
gsl_vector_get (s->x, 1),
s->f);
}
while (status == GSL_CONTINUE && iter < 1000);
gsl_multimin_fdfminimizer_free (s);
gsl_vector_free (x);
return 0;
}
Compiling and running as usual:
$ gcc -Wall -c ex4.c
$ gcc -Wall -c ex4_f.c
$ gcc -Wall -c ex4_df.c
$ gcc -Wall -c ex4_fdf.c
$ gcc –Wall -I/usr/local/include -o ex4.exe ex4.o ex4_f.o ex4_df.o ex4_fdf.o -lgsl - lgslcblas –lm
$ ./ex4.exe
1 10.0996977831 13.9922313416 14193.5830308027
2 10.2991625595 13.9776093392 13595.8170475800
3 10.6983540041 13.9521890610 12460.2591775553
4 11.4976267683 13.9180855650 10426.3762711687
5 13.0975728343 13.9312227560 7280.4133637707
6 16.2512679276 14.4736315124 4291.7621344991
7 17.7448996335 20.6968994905 3732.1231152058
8 17.8192544344 20.5927104144 3640.3712700156
9 17.8199654974 20.5916460886 3639.4924020177
10 17.8213869401 20.5895169806 3637.7369357875
11 17.8242270856 20.5852569367 3634.2350783967
12 17.8298963631 20.5767295167 3627.2676317901
13 17.8411904332 20.5596451853 3613.4775518256
14 17.8635971063 20.5253572486 3586.4745265093
15 17.9076551137 20.4562936664 3534.7593536356
16 17.9924922445 20.3161287391 3440.3388070236
17 18.1465746387 20.0269353813 3286.0707894928
18 18.3629283970 19.4083177443 3098.7221772648
19 17.9360104226 18.1690728284 2964.9394426503
20 17.9122761637 18.1802029554 2963.3298841092
21 17.9120382813 18.1803130982 2963.3157308607
22 17.9115625036 18.1805333559 2963.2875397378
23 17.9106108964 18.1809737595 2963.2316189865
24 17.9087074717 18.1818541124 2963.1216234446
25 17.9048997566 18.1836129448 2962.9090160580
26
27
28
29
30
17.8972806463
17.8820256765
17.8514255463
17.8508048261
17.8507986158
. . . . . . .
50 17.8241650566
51 17.8235213612
52 17.8223841830
53 17.8215573403
54 17.8215176663
55 17.8215172852
56 17.8215165231
57 17.8215150005
58 17.8215119609
59 17.8215059046
60 17.8214938880
61 17.8214702704
62 17.8214250111
63 17.8213463078
. . . . . . .
70 17.8213434821
71 17.8213451652
72 17.8213485325
73 17.8213552712
74 17.8213687668
75 17.8213958541
76 17.8214508536
77 17.8214498251
78 17.8214498148
79 17.8214497943
80 17.8214497532
81 17.8214496710
82 17.8214495066
83 17.8214491779
84 17.8214485207
85 17.8214472071
86 17.8214445837
87 17.8214393550
88 17.8214290142
89 17.8214288582
90 17.8214288567
91 17.8214288537
92 17.8214288477
93 17.8214288358
94 17.8214288119
95 17.8214287646
Minimum found at:
96 17.8214286714
18.1871226317
18.1941055304
18.2078725901
18.2081276713
18.2081302146
. . . . . . .
18.2175624944
18.2172781842
18.2164490102
18.2137584438
18.2137983825
18.2137987968
18.2137996256
18.2138012846
18.2138046077
18.2138112749
18.2138246958
18.2138519039
18.2139079743
18.2140287012
. . . . . . .
18.2143136645
18.2143129097
18.2143114021
18.2143083961
18.2143024254
18.2142907036
18.2142692665
18.2142698463
18.2142698521
18.2142698637
18.2142698870
18.2142699335
18.2142700266
18.2142702128
18.2142705856
18.2142713326
18.2142728333
18.2142758661
18.2142821286
18.2142823133
18.2142823152
18.2142823190
18.2142823266
18.2142823418
18.2142823723
18.2142824335
2962.5133348117
2961.8400944041
2960.9659574252
2960.9548917724
2960.9547823845
. . . . . . . .
2960.7159366955
2960.7154094264
2960.7147356993
2960.7143339189
2960.7143230655
2960.7143229652
2960.7143227650
2960.7143223667
2960.7143215779
2960.7143200311
2960.7143170607
2960.7143116089
2960.7143026246
2960.7142918823
. . . . . . . .
2960.7142879262
2960.7142878355
2960.7142876599
2960.7142873315
2960.7142867661
2960.7142860003
2960.7142859245
2960.7142859069
2960.7142859067
2960.7142859064
2960.7142859057
2960.7142859043
2960.7142859016
2960.7142858961
2960.7142858856
2960.7142858653
2960.7142858287
2960.7142857708
2960.7142857161
2960.7142857158
2960.7142857158
2960.7142857158
2960.7142857158
2960.7142857158
2960.7142857158
2960.7142857157
18.2142825570 2960.7142857155
Download