derivativeMinimizer.hpp
Go to the documentation of this file.
1 #ifndef JULIAN_DERIVATIVEMINIMIZER_HPP
2 #define JULIAN_DERIVATIVEMINIMIZER_HPP
3 
4 #include <gsl/gsl_multimin.h>
6 
7 namespace julian {
8 
53  };
54 
71  template<typename F, typename dF, typename FdF>
72  std::vector<double> derivativeMinimizer(F f,
73  dF df,
74  FdF fdf,
75  std::vector<double> x_init,
77  double step_size = 0.1,
78  double tol = 1e-4,
79  double abs = 1e-6,
80  unsigned int max_iter = 200) {
81 
82  int n = x_init.size();
84 
85  size_t iter = 0;
86  int status;
87 
88  const gsl_multimin_fdfminimizer_type *T;
89 
90  switch(type) {
92  T = gsl_multimin_fdfminimizer_conjugate_fr;
93  break;
95  T = gsl_multimin_fdfminimizer_conjugate_pr;
96  break;
98  T = gsl_multimin_fdfminimizer_vector_bfgs2;
99  break;
101  T = gsl_multimin_fdfminimizer_steepest_descent;
102  break;
103  }
104 
105  gsl_multimin_fdfminimizer *s;
106  gsl_vector *x;
107  x = gsl_vector_alloc (n);
108  for (int i = 0; i < n; ++i) {
109  gsl_vector_set(x, i, x_init.at(i));
110  }
111  s = gsl_multimin_fdfminimizer_alloc (T, n);
112  gsl_multimin_fdfminimizer_set (s, &Func, x, step_size, tol);
113 
114  do {
115  iter++;
116  status = gsl_multimin_fdfminimizer_iterate (s);
117  if (status)
118  break;
119  status = gsl_multimin_test_gradient (s->gradient, abs);
120  } while (status == GSL_CONTINUE && iter < max_iter);
121 
122  std::vector<double> ret;
123  for (unsigned int i = 0; i < n; ++i) {
124  ret.push_back(gsl_vector_get(s -> x, i));
125  }
126 
127  gsl_multimin_fdfminimizer_free (s);
128  gsl_vector_free (x);
129 
130  return ret;
131  }
132 
150  template<typename F>
151  std::vector<double> derivativeMinimizer(F f,
152  std::vector<double> x_init,
153  DerivativeMinimizer type,
154  double step_size = 0.1,
155  double tol = 1e-4,
156  double increment = 1e-5,
157  double abs = 1e-6,
158  unsigned int max_iter = 200) {
159  int n = x_init.size();
160 
161  auto inverse_increment = 1.0 / increment;
162  auto df = [f,n,increment,inverse_increment](std::vector<double> x)->std::vector<double> {
163  std::vector<double> ret;
164  double val = f(x);
165  for (int i = 0; i < n; ++i) {
166  x[i] += increment;
167  ret.push_back( (f(x) -val) * inverse_increment);
168  x[i] -= increment;
169  }
170  return ret;
171  };
172 
173  auto fdf = [f,n,increment,inverse_increment](std::vector<double> x)-> std::pair<double, std::vector<double> > {
174  std::vector<double> ret;
175  double val = f(x);
176  auto inverse_increment = 1.0 / increment;
177  for (int i = 0; i < n; ++i) {
178  x[i] += increment;
179  ret.push_back( (f(x) -val) * inverse_increment);
180  x[i] -= increment;
181  }
182  return std::make_pair(val,ret);
183  };
184 
186 
187  size_t iter = 0;
188  int status ;
189 
190  const gsl_multimin_fdfminimizer_type *T;
191 
192  switch(type) {
194  T = gsl_multimin_fdfminimizer_conjugate_fr;
195  break;
197  T = gsl_multimin_fdfminimizer_conjugate_pr;
198  break;
200  T = gsl_multimin_fdfminimizer_vector_bfgs2;
201  break;
203  T = gsl_multimin_fdfminimizer_steepest_descent;
204  break;
205  }
206 
207  gsl_multimin_fdfminimizer *s;
208  gsl_vector *x;
209 
210  x = gsl_vector_alloc (n);
211 
212  for (int i = 0; i < n; ++i) {
213  gsl_vector_set(x, i, x_init.at(i));
214  }
215 
216  s = gsl_multimin_fdfminimizer_alloc (T, n);
217  gsl_multimin_fdfminimizer_set (s, &Func, x, step_size, tol);
218 
219  do {
220  iter++;
221  status = gsl_multimin_fdfminimizer_iterate (s);
222  if (status) {
223  break;
224  }
225  status = gsl_multimin_test_gradient (s->gradient, abs);
226  } while (status == GSL_CONTINUE && iter < max_iter);
227 
228  std::vector<double> ret;
229  for (int i = 0; i < n; ++i) {
230  ret.push_back(gsl_vector_get(s -> x, i));
231  }
232 
233  gsl_multimin_fdfminimizer_free (s);
234  gsl_vector_free (x);
235 
236  return ret;
237  }
238 } // namespace julian
239 #endif
Class implements adapter for gsl_multimin_function.
Definition: GslMultiminFunctionFdfAdapter.hpp:27
Definition: cadHoliday.cpp:3
File contains adapter of GSL Function.
DerivativeMinimizer
Types of multi-dimension minimizer that requires gradient of function.
Definition: derivativeMinimizer.hpp:49
Broyden-Fletcher-Goldfarb-Shanno.
Fletcher-Reeves conjugate gradient.
std::vector< double > derivativeMinimizer(F f, std::vector< double > x_init, DerivativeMinimizer type, double step_size=0.1, double tol=1e-4, double increment=1e-5, double abs=1e-6, unsigned int max_iter=200)
Multidimension minimizer that requires derivative of function.
Definition: derivativeMinimizer.hpp:151
Polak-Ribiere conjugate gradient.