1 /* multimin/fdfminimizer.c
2  *
3  * Copyright (C) 1996, 1997, 1998, 1999, 2000 Fabrice Rossi
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or (at
8  * your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19 
20 #include <config.h>
21 #include <gsl/gsl_errno.h>
22 #include <gsl/gsl_multimin.h>
23 
24 gsl_multimin_fdfminimizer *
gsl_multimin_fdfminimizer_alloc(const gsl_multimin_fdfminimizer_type * T,size_t n)25 gsl_multimin_fdfminimizer_alloc (const gsl_multimin_fdfminimizer_type * T,
26                                  size_t n)
27 {
28   int status;
29 
30   gsl_multimin_fdfminimizer *s =
31     (gsl_multimin_fdfminimizer *) malloc (sizeof (gsl_multimin_fdfminimizer));
32 
33   if (s == 0)
34     {
35       GSL_ERROR_VAL ("failed to allocate space for minimizer struct",
36                      GSL_ENOMEM, 0);
37     }
38 
39   s->type = T;
40 
41   s->x = gsl_vector_calloc (n);
42 
43   if (s->x == 0)
44     {
45       free (s);
46       GSL_ERROR_VAL ("failed to allocate space for x", GSL_ENOMEM, 0);
47     }
48 
49   s->gradient = gsl_vector_calloc (n);
50 
51   if (s->gradient == 0)
52     {
53       gsl_vector_free (s->x);
54       free (s);
55       GSL_ERROR_VAL ("failed to allocate space for gradient", GSL_ENOMEM, 0);
56     }
57 
58   s->dx = gsl_vector_calloc (n);
59 
60   if (s->dx == 0)
61     {
62       gsl_vector_free (s->x);
63       gsl_vector_free (s->gradient);
64       free (s);
65       GSL_ERROR_VAL ("failed to allocate space for dx", GSL_ENOMEM, 0);
66     }
67 
68   s->state = malloc (T->size);
69 
70   if (s->state == 0)
71     {
72       gsl_vector_free (s->x);
73       gsl_vector_free (s->gradient);
74       gsl_vector_free (s->dx);
75       free (s);
76       GSL_ERROR_VAL ("failed to allocate space for minimizer state",
77                      GSL_ENOMEM, 0);
78     }
79 
80   status = (T->alloc) (s->state, n);
81 
82   if (status != GSL_SUCCESS)
83     {
84       free (s->state);
85       gsl_vector_free (s->x);
86       gsl_vector_free (s->gradient);
87       gsl_vector_free (s->dx);
88       free (s);
89 
90       GSL_ERROR_VAL ("failed to initialize minimizer state", GSL_ENOMEM, 0);
91     }
92 
93   return s;
94 }
95 
96 int
gsl_multimin_fdfminimizer_set(gsl_multimin_fdfminimizer * s,gsl_multimin_function_fdf * fdf,const gsl_vector * x,double step_size,double tol)97 gsl_multimin_fdfminimizer_set (gsl_multimin_fdfminimizer * s,
98                                gsl_multimin_function_fdf * fdf,
99                                const gsl_vector * x,
100                                double step_size, double tol)
101 {
102   if (s->x->size != fdf->n)
103     {
104       GSL_ERROR ("function incompatible with solver size", GSL_EBADLEN);
105     }
106 
107   if (x->size != fdf->n)
108     {
109       GSL_ERROR ("vector length not compatible with function", GSL_EBADLEN);
110     }
111 
112   s->fdf = fdf;
113 
114   gsl_vector_memcpy (s->x,x);
115   gsl_vector_set_zero (s->dx);
116 
117   return (s->type->set) (s->state, s->fdf, s->x, &(s->f), s->gradient, step_size, tol);
118 }
119 
120 void
gsl_multimin_fdfminimizer_free(gsl_multimin_fdfminimizer * s)121 gsl_multimin_fdfminimizer_free (gsl_multimin_fdfminimizer * s)
122 {
123   RETURN_IF_NULL (s);
124   (s->type->free) (s->state);
125   free (s->state);
126   gsl_vector_free (s->dx);
127   gsl_vector_free (s->gradient);
128   gsl_vector_free (s->x);
129   free (s);
130 }
131 
132 int
gsl_multimin_fdfminimizer_iterate(gsl_multimin_fdfminimizer * s)133 gsl_multimin_fdfminimizer_iterate (gsl_multimin_fdfminimizer * s)
134 {
135   return (s->type->iterate) (s->state, s->fdf, s->x, &(s->f), s->gradient, s->dx);
136 }
137 
138 int
gsl_multimin_fdfminimizer_restart(gsl_multimin_fdfminimizer * s)139 gsl_multimin_fdfminimizer_restart (gsl_multimin_fdfminimizer * s)
140 {
141   return (s->type->restart) (s->state);
142 }
143 
144 const char *
gsl_multimin_fdfminimizer_name(const gsl_multimin_fdfminimizer * s)145 gsl_multimin_fdfminimizer_name (const gsl_multimin_fdfminimizer * s)
146 {
147   return s->type->name;
148 }
149 
150 
151 gsl_vector *
gsl_multimin_fdfminimizer_x(const gsl_multimin_fdfminimizer * s)152 gsl_multimin_fdfminimizer_x (const gsl_multimin_fdfminimizer * s)
153 {
154   return s->x;
155 }
156 
157 gsl_vector *
gsl_multimin_fdfminimizer_dx(const gsl_multimin_fdfminimizer * s)158 gsl_multimin_fdfminimizer_dx (const gsl_multimin_fdfminimizer * s)
159 {
160   return s->dx;
161 }
162 
163 gsl_vector *
gsl_multimin_fdfminimizer_gradient(const gsl_multimin_fdfminimizer * s)164 gsl_multimin_fdfminimizer_gradient (const gsl_multimin_fdfminimizer * s)
165 {
166   return s->gradient;
167 }
168 
169 double
gsl_multimin_fdfminimizer_minimum(const gsl_multimin_fdfminimizer * s)170 gsl_multimin_fdfminimizer_minimum (const gsl_multimin_fdfminimizer * s)
171 {
172   return s->f;
173 }
174 
175