25 #include <boost/numeric/conversion/cast.hpp>
27 #include "ipopt_problem.h"
28 #include "../../exceptions.h"
30 using namespace Ipopt;
36 affects_obj.resize(0);
37 dv.resize(m_pop->problem().get_dimension());
38 fit.resize(m_pop->problem().get_f_dimension());
39 con.resize(m_pop->problem().get_c_dimension());
45 std::vector< ::Ipopt::Index> iGfun,jGvar;
47 std::vector< boost::array< ::Ipopt::Index,2> > duples(0);
48 boost::array< ::Ipopt::Index,2> tmp;
53 m_pop->problem().set_sparsity(lenG,iGfun,jGvar);
54 for (::Ipopt::Index i = 0; i<lenG; ++i)
58 tmp[0] = iGfun[i] - 1;
60 duples.push_back(tmp);
65 affects_obj.push_back(jGvar[i]);
70 std::sort (duples.begin(), duples.end(), cache_efficiency_criterion);
73 catch (not_implemented_error)
77 affects_obj.push_back(j);
82 duples.push_back(tmp);
89 iJfun.resize(len_jac);
90 jJvar.resize(len_jac);
91 for (::Ipopt::Index i = 0;i<len_jac;++i)
93 iJfun[i] = duples[i][0];
94 jJvar[i] = duples[i][1];
99 ipopt_problem::~ipopt_problem()
110 bool ipopt_problem::cache_efficiency_criterion(boost::array<int,2> one,boost::array<int,2> two)
112 if (one[1] < two[1]) {
116 if (one[1] > two[1])
return false;
118 if (one[0] < two[0])
return true;
125 bool ipopt_problem::get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g,
126 Ipopt::Index& nnz_h_lag, IndexStyleEnum& index_style)
130 n = m_pop->problem().get_dimension();
133 m = m_pop->problem().get_c_dimension();
139 index_style = C_STYLE;
144 bool ipopt_problem::get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u,
145 Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u)
148 for (::Ipopt::Index i=0; i<n;++i)
150 x_l[i] = m_pop->problem().get_lb()[i];
151 x_u[i] = m_pop->problem().get_ub()[i];
155 for (::Ipopt::Index i=0; i < boost::numeric_cast< ::Ipopt::Index>(m-m_pop->problem().get_ic_dimension());++i)
157 g_l[i] = g_u[i] = 0.0;
161 for (::Ipopt::Index i = ( m - m_pop->problem().get_ic_dimension()); i < m;++i)
171 bool ipopt_problem::get_starting_point(Ipopt::Index n,
bool init_x, Ipopt::Number* x,
172 bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U,
173 Ipopt::Index m,
bool init_lambda,
174 Ipopt::Number* lambda)
179 pagmo_assert(init_x ==
true);
180 pagmo_assert(init_z ==
false);
181 pagmo_assert(init_lambda ==
false);
182 pagmo_assert(n == boost::numeric_cast<Index>(m_pop->problem().get_dimension()));
183 pagmo_assert(m == boost::numeric_cast<Index>(m_pop->problem().get_c_dimension()));
197 std::copy(m_pop->get_individual(bestidx).cur_x.begin(),m_pop->get_individual(bestidx).cur_x.end(),x);
203 bool ipopt_problem::eval_f(Ipopt::Index n,
const Ipopt::Number* x,
bool new_x, Ipopt::Number& obj_value)
207 std::copy(x,x+n,dv.begin());
208 m_pop->problem().objfun(fit,dv);
213 bool ipopt_problem::eval_grad_f(Ipopt::Index n,
const Ipopt::Number* x,
bool new_x, Ipopt::Number* grad_f)
217 const double h0=1e-8;
219 std::copy(x,x+n,dv.begin());
220 for (pagmo::decision_vector::size_type i=0; i<dv.size();++i)
226 for (
size_t i =0;i<affects_obj.size();++i)
228 h = h0 * std::max(1.,fabs(dv[affects_obj[i]]));
229 mem = dv[affects_obj[i]];
230 dv[affects_obj[i]] += h;
231 m_pop->problem().objfun(fit,dv);
232 central_diff = fit[0];
233 dv[affects_obj[i]] -= 2*h;
234 m_pop->problem().objfun(fit,dv);
235 central_diff = (central_diff-fit[0]) / 2 / h;
236 grad_f[affects_obj[i]] = central_diff;
237 dv[affects_obj[i]] = mem;
243 bool ipopt_problem::eval_g(Ipopt::Index n,
const Ipopt::Number* x,
bool new_x, Ipopt::Index m, Ipopt::Number* g)
248 std::copy(x,x+n,dv.begin());
249 m_pop->problem().compute_constraints(con,dv);
250 std::copy(con.begin(),con.end(),g);
254 bool ipopt_problem::eval_jac_g(Ipopt::Index n,
const Ipopt::Number* x,
bool new_x,
255 Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, Ipopt::Index *jCol,
256 Ipopt::Number* values)
260 pagmo_assert(n == boost::numeric_cast<Index>(m_pop->problem().get_dimension()));
261 pagmo_assert(m == boost::numeric_cast<Index>(m_pop->problem().get_c_dimension()));
262 if (values == NULL) {
264 for (Ipopt::Index i=0;i<nele_jac;++i)
272 const double h0 = 1e-8;
275 std::copy(x,x+n,dv.begin());
276 for (Ipopt::Index i=0;i<nele_jac;++i)
278 h = h0 * std::max(1.,fabs(dv[jJvar[i]]));
281 m_pop->problem().compute_constraints(con,dv);
282 central_diff = con[iJfun[i]];
283 dv[jJvar[i]] -= 2 * h;
284 m_pop->problem().compute_constraints(con,dv);
285 central_diff = (central_diff - con[iJfun[i]])/2/h;
286 values[i] = central_diff;
294 void ipopt_problem::finalize_solution(Ipopt::SolverReturn status,
295 Ipopt::Index n,
const Ipopt::Number* x,
const Ipopt::Number* z_L,
const Ipopt::Number* z_U,
296 Ipopt::Index m,
const Ipopt::Number* g,
const Ipopt::Number* lambda,
297 Ipopt::Number obj_value,
298 const Ipopt::IpoptData* ip_data,
299 Ipopt::IpoptCalculatedQuantities* ip_cq)
311 for (::Ipopt::Index i=0;i<n;i++) dv[i] = x[i];
312 int bestidx = m_pop->get_best_idx();
314 std::transform(dv.begin(), dv.end(), m_pop->get_individual(bestidx).cur_x.begin(), dv.begin(),std::minus<double>());
315 for (
int i=0;i<n;i++)
317 newx[i] = std::min(std::max(m_pop->problem().get_lb()[i],newx[i]),m_pop->problem().get_ub()[i]);
319 m_pop->set_x(bestidx,newx);
320 m_pop->set_v(bestidx,dv);
std::vector< double > decision_vector
Decision vector type.
container_type::size_type size_type
Population size type.
decision_vector::size_type size_type
Problem's size type: the same as pagmo::decision_vector's size type.