26 #include <boost/numeric/conversion/cast.hpp> 
   29 #include <gsl/gsl_deriv.h> 
   30 #include <gsl/gsl_multimin.h> 
   31 #include <gsl/gsl_vector.h> 
   37 #include "../exceptions.h" 
   38 #include "../population.h" 
   39 #include "../problem/base.h" 
   42 #include "gsl_gradient.h" 
   44 namespace pagmo { 
namespace algorithm {
 
   57 gsl_gradient::gsl_gradient(
int max_iter, 
const double &grad_tol, 
const double &numdiff_step_size, 
const double &step_size, 
const double &tol):
 
   59         m_max_iter(
boost::numeric_cast<
std::size_t>(max_iter)),m_grad_tol(grad_tol),m_numdiff_step_size(numdiff_step_size),
 
   60         m_step_size(step_size),m_tol(tol)
 
   63                 pagmo_throw(value_error,
"step size must be positive");
 
   66                 pagmo_throw(value_error,
"tolerance must be positive");
 
   68         if (numdiff_step_size <= 0) {
 
   69                 pagmo_throw(value_error,
"step size for numerical differentiation must be positive");
 
   72                 pagmo_throw(value_error,
"gradient tolerance must be positive");
 
   77 double gsl_gradient::objfun_numdiff_wrapper(
double x, 
void *params)
 
   79         objfun_numdiff_wrapper_params *pars = (objfun_numdiff_wrapper_params *)params;
 
   80         pars->x[pars->coord] = x;
 
   81         pars->prob->objfun(pars->f,pars->x);
 
   86 void gsl_gradient::objfun_numdiff_central(gsl_vector *retval, 
const problem::base &prob, 
const decision_vector &input, 
const double &step_size)
 
   89                 pagmo_throw(value_error,
"invalid input vector dimension in numerical differentiation of the objective function");
 
   92                 pagmo_throw(value_error,
"numerical differentiation of the objective function cannot work on multi-objective problems");
 
   97         objfun_numdiff_wrapper_params pars;
 
  103         F.function = &objfun_numdiff_wrapper;
 
  104         F.params = (
void *)&pars;
 
  105         double result, abserr;
 
  109                 gsl_deriv_central(&F,input[i],step_size,&result,&abserr);
 
  110                 gsl_vector_set(retval,i,result);
 
  115 void gsl_gradient::d_objfun_wrapper(
const gsl_vector *v, 
void *params, gsl_vector *df)
 
  117         objfun_wrapper_params *par = (objfun_wrapper_params *)params;
 
  122                 par->x[i] = gsl_vector_get(v,i);
 
  125         objfun_numdiff_central(df,*par->p,par->x,par->step_size);
 
  129 void gsl_gradient::fd_objfun_wrapper(
const gsl_vector *v, 
void *params, 
double *retval, gsl_vector *df)
 
  132         d_objfun_wrapper(v,params,df);
 
  154                 pagmo_throw(value_error,
"this algorithm does not support multi-objective optimisation");
 
  157                 pagmo_throw(value_error,
"this algorithm does not support constrained optimisation");
 
  161                 pagmo_throw(value_error,
"the problem has no continuous part");
 
  172         std::copy(best_ind.
cur_x.begin() + cont_size, best_ind.
cur_x.end(), params.
x.begin() + cont_size);
 
  176         gsl_multimin_function_fdf gsl_func;
 
  177         gsl_func.n = boost::numeric_cast<std::size_t>(cont_size);
 
  179         gsl_func.df = &d_objfun_wrapper;
 
  180         gsl_func.fdf = &fd_objfun_wrapper;
 
  181         gsl_func.params = (
void *)¶ms;
 
  183         gsl_multimin_fdfminimizer *s = 0;
 
  188         const std::size_t s_cont_size = boost::numeric_cast<std::size_t>(cont_size);
 
  190         x = gsl_vector_alloc(s_cont_size);
 
  192         pagmo_assert(minimiser);
 
  193         s = gsl_multimin_fdfminimizer_alloc(minimiser,s_cont_size);
 
  197         for (std::size_t i = 0; i < s_cont_size; ++i) {
 
  198                 gsl_vector_set(x,i,best_ind.
cur_x[i]);
 
  201         gsl_multimin_fdfminimizer_set(s,&gsl_func,x,m_step_size,m_tol);
 
  203         std::size_t iter = 0;
 
  209                         status = gsl_multimin_fdfminimizer_iterate(s);
 
  213                         status = gsl_multimin_test_gradient(s->gradient,m_grad_tol);
 
  214                 } 
while (status == GSL_CONTINUE && iter < m_max_iter);
 
  215         } 
catch (
const std::exception &e) {
 
  222                 pagmo_throw(std::runtime_error,
"unknown exception caught in gsl_gradient::evolve");
 
  228                 if (params.
x[i] < problem.
get_lb()[i]) {
 
  229                         params.
x[i] = problem.
get_lb()[i];
 
  231                 if (params.
x[i] > problem.
get_ub()[i]) {
 
  232                         params.
x[i] = problem.
get_ub()[i];
 
  236         pop.set_x(best_ind_idx,params.
x);
 
  240 void gsl_gradient::check_allocs(gsl_vector *x, gsl_multimin_fdfminimizer *s)
 
  245                 throw std::bad_alloc();
 
  250 void gsl_gradient::cleanup(gsl_vector *x, gsl_multimin_fdfminimizer *s)
 
  256                 gsl_multimin_fdfminimizer_free(s);
 
  266         std::ostringstream oss;
 
  267         oss << 
"max_iter: " << m_max_iter << 
' ';
 
  268         oss << 
"step_size: " << m_step_size << 
' ';
 
  269         oss << 
"tol: " << m_tol << 
' ';
 
  270         oss << 
"grad_step_size: " << m_numdiff_step_size << 
' ';
 
  271         oss << 
"grad_tol: " << m_grad_tol << 
' ';
 
std::vector< double > decision_vector
Decision vector type. 
virtual const gsl_multimin_fdfminimizer_type * get_gsl_minimiser_ptr() const =0
Selected minimiser. 
double step_size
Initial step size for the computation of the gradient. 
const individual_type & get_individual(const size_type &) const 
Get constant reference to individual at position n. 
Individuals stored in the population. 
void evolve(population &) const 
Evolve method. 
size_type get_dimension() const 
Return global dimension. 
Base class for GSL algorithms. 
gsl_gradient(int, const double &, const double &, const double &, const double &)
Constructor. 
std::string human_readable_extra() const 
Extra information in human-readable format. 
fitness_vector f
Fitness vector. 
size_type get_i_dimension() const 
Return integer dimension. 
c_size_type get_c_dimension() const 
Return global constraints dimension. 
const decision_vector & get_ub() const 
Upper bounds getter. 
container_type::size_type size_type
Population size type. 
static double objfun_wrapper(const gsl_vector *, void *)
Objective function wrapper. 
decision_vector cur_x
Current decision vector. 
Structure to feed parameters to the wrappers for the objective function and its derivative. 
f_size_type get_f_dimension() const 
Return fitness dimension. 
decision_vector x
Decision vector. 
problem::base const * p
Pointer to the problem. 
const decision_vector & get_lb() const 
Lower bounds getter. 
decision_vector::size_type size_type
Problem's size type: the same as pagmo::decision_vector's size type.