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