27 #include <queso/Defines.h>
28 #include <queso/GslVector.h>
29 #include <queso/VectorSpace.h>
30 #include <queso/ScalarFunction.h>
31 #include <queso/GslOptimizer.h>
32 #include <queso/OptimizerMonitor.h>
34 #include <gsl/gsl_multimin.h>
35 #include <gsl/gsl_blas.h>
43 double c_evaluate(
const gsl_vector * x,
void * context) {
51 for (
unsigned int i = 0; i < state.sizeLocal(); i++) {
52 state[i] = gsl_vector_get(x, i);
68 gsl_vector * derivative) {
77 for (
unsigned int i = 0; i < state.sizeLocal(); i++) {
78 state[i] = gsl_vector_get(x, i);
88 for (
unsigned int i = 0; i < deriv.sizeLocal(); i++) {
89 gsl_vector_set(derivative, i, GSL_NAN);
103 bool userComputedDerivative =
true;
104 for (
unsigned int i = 0; i < deriv.sizeLocal(); i++) {
107 if (gsl_isnan(deriv[i])) {
108 userComputedDerivative =
false;
113 if (userComputedDerivative) {
114 for (
unsigned int i = 0; i < deriv.sizeLocal(); i++) {
115 gsl_vector_set(derivative, i, -deriv[i]);
123 for (
unsigned int i = 0; i < deriv.sizeLocal(); i++) {
124 double tempState = state[i];
132 state[i] = tempState;
135 if (!gsl_isnan(fx) && !gsl_isnan(fxph)) {
136 gsl_vector_set(derivative, i, (fxph - fx) / h);
139 gsl_vector_set(derivative, i, GSL_NAN);
148 double * f, gsl_vector * derivative) {
158 m_objectiveFunction(objectiveFunction),
159 m_initialPoint(new
GslVector(objectiveFunction.domainSet().
160 vectorSpace().zeroVector())),
161 m_minimizer(new
GslVector(this->m_objectiveFunction.domainSet().
162 vectorSpace().zeroVector())),
163 m_solver_type(BFGS2),
164 m_fstep_size(this->m_objectiveFunction.domainSet().vectorSpace().zeroVector()),
165 m_fdfstep_size(getFdfstepSize()),
166 m_line_tol(getLineTolerance())
182 m_objectiveFunction(objectiveFunction),
183 m_initialPoint(new
GslVector(objectiveFunction.domainSet().
184 vectorSpace().zeroVector())),
185 m_minimizer(new
GslVector(this->m_objectiveFunction.domainSet().
186 vectorSpace().zeroVector())),
187 m_solver_type(BFGS2),
188 m_fstep_size(this->m_objectiveFunction.domainSet().vectorSpace().zeroVector()),
189 m_fdfstep_size(getFdfstepSize()),
190 m_line_tol(getLineTolerance())
214 std::cerr <<
"Minimization was given initial point outside of domain"
221 zeroVector().sizeLocal();
245 for (
unsigned int i = 0; i < initialPoint.
sizeLocal(); i++) {
264 bool gradient_needed =
false;
274 gradient_needed =
true;
290 return gradient_needed;
296 gsl_vector * x = gsl_vector_alloc(dim);
297 for (
unsigned int i = 0; i <
dim; i++) {
302 const gsl_multimin_fdfminimizer_type* type = NULL;
308 type = gsl_multimin_fdfminimizer_conjugate_fr;
311 type = gsl_multimin_fdfminimizer_conjugate_pr;
314 type = gsl_multimin_fdfminimizer_vector_bfgs;
317 type = gsl_multimin_fdfminimizer_vector_bfgs2;
320 type = gsl_multimin_fdfminimizer_steepest_descent;
331 gsl_multimin_fdfminimizer * solver =
332 gsl_multimin_fdfminimizer_alloc(type, dim);
335 gsl_multimin_function_fdf minusLogPosterior;
336 minusLogPosterior.n =
dim;
340 minusLogPosterior.params = (
void *)(
this);
349 status = gsl_multimin_fdfminimizer_iterate(solver);
354 std::cerr <<
"Error while GSL does optimisation. "
355 <<
"See below for GSL error type." << std::endl;
356 std::cerr <<
"Gsl error: " << gsl_strerror(status) << std::endl;
361 status = gsl_multimin_test_gradient(solver->gradient, this->getTolerance());
365 gsl_vector* x = gsl_multimin_fdfminimizer_x(solver);
366 std::vector<double> x_min(dim);
367 for(
unsigned int i = 0; i <
dim; i++)
368 x_min[i] = gsl_vector_get(x,i);
370 double f = gsl_multimin_fdfminimizer_minimum(solver);
372 gsl_vector* grad = gsl_multimin_fdfminimizer_gradient(solver);
373 double grad_norm = gsl_blas_dnrm2(grad);
375 monitor->
append( x_min, f, grad_norm );
380 for (
unsigned int i = 0; i <
dim; i++) {
381 (*m_minimizer)[i] = gsl_vector_get(solver->x, i);
385 gsl_multimin_fdfminimizer_free(solver);
394 gsl_vector* x = gsl_vector_alloc(dim);
395 for (
unsigned int i = 0; i <
dim; i++) {
400 const gsl_multimin_fminimizer_type* type = NULL;
405 type = gsl_multimin_fminimizer_nmsimplex;
408 type = gsl_multimin_fminimizer_nmsimplex2;
411 type = gsl_multimin_fminimizer_nmsimplex2rand;
424 gsl_multimin_fminimizer* solver =
425 gsl_multimin_fminimizer_alloc(type, dim);
428 gsl_multimin_function minusLogPosterior;
429 minusLogPosterior.n =
dim;
431 minusLogPosterior.params = (
void *)(
this);
434 gsl_vector* step_size = gsl_vector_alloc(dim);
436 for(
unsigned int i = 0; i <
dim; i++) {
440 gsl_multimin_fminimizer_set(solver, &minusLogPosterior, x, step_size);
449 status = gsl_multimin_fminimizer_iterate(solver);
454 std::cerr <<
"Error while GSL does optimisation. "
455 <<
"See below for GSL error type." << std::endl;
456 std::cerr <<
"Gsl error: " << gsl_strerror(status) << std::endl;
461 size = gsl_multimin_fminimizer_size(solver);
463 status = gsl_multimin_test_size (size, this->
getTolerance());
467 gsl_vector* x = gsl_multimin_fminimizer_x(solver);
468 std::vector<double> x_min(dim);
469 for(
unsigned int i = 0; i <
dim; i++)
470 x_min[i] = gsl_vector_get(x,i);
472 double f = gsl_multimin_fminimizer_minimum(solver);
474 monitor->
append( x_min, f, size );
481 for (
unsigned int i = 0; i <
dim; i++) {
482 (*m_minimizer)[i] = gsl_vector_get(solver->x, i);
486 gsl_vector_free(step_size);
487 gsl_multimin_fminimizer_free(solver);
509 if( solver == std::string(
"fletcher_reeves_cg") )
511 else if( solver == std::string(
"polak_ribiere_cg") )
513 else if( solver == std::string(
"bfgs") )
515 else if( solver == std::string(
"bfgs2") )
517 else if( solver == std::string(
"steepest_decent") ) {
521 else if( solver == std::string(
"steepest_descent") )
523 else if( solver == std::string(
"nelder_mead") )
525 else if( solver == std::string(
"nelder_mead2") )
527 else if( solver == std::string(
"nelder_mead2_rand") )
533 std::cerr <<
"Error: Invalid GslOptimizer solver name: " << solver << std::endl
534 <<
" Valids choices are: fletcher_reeves_cg" << std::endl
535 <<
" polak_ribiere_cg" << std::endl
536 <<
" bfgs" << std::endl
537 <<
" bfgs2" << std::endl
538 <<
" steepest_descent" << std::endl
539 <<
" nelder_mead" << std::endl
540 <<
" nelder_mead2" << std::endl
541 <<
" nelder_mead2_rand" << std::endl;
569 fstepSizeVector.
cwSet(fstepSize);
virtual void setSolverType(std::string solverType)
Sets the algorithm to use for minimisation.
const GslVector & minimizer() const
Return the point that minimizes the objective function.
void cwSet(double value)
Component-wise sets all values to this with value.
GslOptimizer(const BaseScalarFunction< GslVector, GslMatrix > &objectiveFunction)
Constructs an object that will maximize a scalar function.
A templated (base) class for handling scalar functions.
virtual void setLineTolerance(double lineTolerance)
Sets the tolerance to use for line minimisation.
virtual void minimize(OptimizerMonitor *monitor=NULL)
Minimize the objective function, starting at m_initialPoint.
const BaseScalarFunction< GslVector, GslMatrix > & m_objectiveFunction
ScopedPtr< OptimizerOptions >::Type m_optionsObj
double getTolerance() const
Returns the tolerance used to test for an extremum in the optimizer.
A base class for handling optimisation of scalar functions.
double m_fdfstep_size
For use in gradient-based algorithms.
bool solver_needs_gradient(SolverType solver)
Helper function.
void minimize_with_gradient(unsigned int dim, OptimizerMonitor *monitor)
virtual double getLineTolerance() const
Gets the tolerance to use for line minimisation.
void set_solver_type(SolverType solver)
double getFiniteDifferenceStepSize() const
Returns the step size used in the finite difference formula.
virtual ~GslOptimizer()
Destructor.
void setInitialPoint(const GslVector &intialPoint)
Set the point at which the optimization starts.
void c_evaluate_derivative(const gsl_vector *x, void *context, gsl_vector *derivative)
double c_evaluate(const gsl_vector *x, void *context)
void set_step_size(const GslVector &step_size)
Sets step size used in gradient-free solvers.
void minimize_no_gradient(unsigned int dim, OptimizerMonitor *monitor)
void c_evaluate_with_derivative(const gsl_vector *x, void *context, double *f, gsl_vector *derivative)
virtual std::string getSolverType() const
Gets the algorithm to use for minimisation.
Class for vector operations using GSL library.
This class provides options for a Optimizer.
void append(std::vector< double > &x_min, double objective, double norm)
Add current value of minimizer, objective, and error norm.
virtual void setFstepSize(double fstepSize)
Sets the step size to use in gradient-free solvers.
virtual double getFdfstepSize() const
Gets the step to use in gradient-based solvers.
GslVector m_fstep_size
For use in gradient-free algorithms.
unsigned int sizeLocal() const
Returns the length of this vector.
virtual void setFdfstepSize(double fdfstepSize)
Sets the step to use in gradient-based solvers.
Object to monitor convergence of optimizers.
const BaseScalarFunction< GslVector, GslMatrix > & objectiveFunction() const
Returns the objective function.
GslVector * m_initialPoint
virtual double getFstepSize() const
Gets the step size to use in gradient-free solvers.
unsigned int getMaxIterations() const
Returns the maximum number of iterations the optimizer will do.
SolverType string_to_enum(std::string &solver)
A base class for handling optimisation of scalar functions.