PaGMO  1.1.5
ipopt.cpp
1 /*****************************************************************************
2  * Copyright (C) 2004-2015 The PaGMO development team, *
3  * Advanced Concepts Team (ACT), European Space Agency (ESA) *
4  * http://apps.sourceforge.net/mediawiki/pagmo *
5  * http://apps.sourceforge.net/mediawiki/pagmo/index.php?title=Developers *
6  * http://apps.sourceforge.net/mediawiki/pagmo/index.php?title=Credits *
7  * act@esa.int *
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  * This program is distributed in the hope that it will be useful, *
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
17  * GNU General Public License for more details. *
18  * *
19  * You should have received a copy of the GNU General Public License *
20  * along with this program; if not, write to the *
21  * Free Software Foundation, Inc., *
22  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
23  *****************************************************************************/
24 
25 #include "ipopt.h"
26 #include "../exceptions.h"
27 #include "../types.h"
28 
29 
30 #include "ipopt_cpp_wrapper/ipopt_problem.h"
31 #include <coin/IpIpoptApplication.hpp>
32 #include <coin/IpSolveStatistics.hpp>
33 #include <limits.h>
34 
35 
36 namespace pagmo { namespace algorithm {
37 
39 
53 ipopt::ipopt( const int &max_iter,
54  const double &constr_viol_tol,
55  const double &dual_inf_tol,
56  const double &compl_inf_tol,
57  const bool &nlp_scaling_method,
58  const double &obj_scaling_factor,
59  const double &mu_init) :
60  m_max_iter(max_iter),m_constr_viol_tol(constr_viol_tol),
61  m_dual_inf_tol(dual_inf_tol), m_compl_inf_tol(compl_inf_tol),
62  m_nlp_scaling_method(nlp_scaling_method), m_obj_scaling_factor(obj_scaling_factor), m_mu_init(mu_init)
63 
64 {
65  if (max_iter < 0) {
66  pagmo_throw(value_error,"number of maximum iterations cannot be negative");
67  }
68  if (constr_viol_tol < 0) {
69  pagmo_throw(value_error,"tolerance is not in ]0,1[");
70  }
71  if (dual_inf_tol < 0) {
72  pagmo_throw(value_error,"obj_tol is not in ]0,1[");
73  }
74  if (compl_inf_tol < 0) {
75  pagmo_throw(value_error,"obj_tol is not in ]0,1[");
76  }
77  if (mu_init <= 0) {
78  pagmo_throw(value_error,"mu_init is not in ]0, inf[");
79  }
80 
81 }
82 
85 {
86  return base_ptr(new ipopt(*this));
87 }
88 
90 
97 void ipopt::evolve(population &pop) const
98 {
99  // Let's store some useful variables.
100  const problem::base &prob = pop.problem();
101  const problem::base::size_type D = prob.get_dimension(), prob_i_dimension = prob.get_i_dimension(), prob_f_dimension = prob.get_f_dimension();
102  const population::size_type NP = pop.size();
103  const problem::base::size_type Dc = D - prob_i_dimension;
104  const std::string name = prob.get_name();
105 
106  //We perform some checks to determine wether the problem/population are suitable for IPOPT
107  if ( prob_i_dimension != 0 ) {
108  pagmo_throw(value_error,"No integer part allowed yet....");
109  }
110 
111  if ( Dc == 0 ) {
112  pagmo_throw(value_error,"No continuous part....");
113  }
114 
115  if ( prob_f_dimension != 1 ) {
116  pagmo_throw(value_error,"The problem is not single objective and IPOPT is not suitable to solve it");
117  }
118 
119  // Get out if there is nothing to do.
120  if (NP == 0 || m_max_iter == 0) {
121  return;
122  }
123 
124  //create an instance of the ipopt_problem
125  ::Ipopt::SmartPtr< ::Ipopt::TNLP> pagmo_nlp = new ipopt_problem(&pop);
126 
127  //create an instance of the IpoptApplication
128  ::Ipopt::SmartPtr< ::Ipopt::IpoptApplication> m_app = new ::Ipopt::IpoptApplication(m_screen_output,false);
129 
130  if (!m_nlp_scaling_method) {
131  m_app->Options()->SetStringValue("nlp_scaling_method", "none");
132  }
133  m_app->Options()->SetStringValue("hessian_approximation", "limited-memory");
134  m_app->Options()->SetIntegerValue("print_level", 5);
135 
136  // Termination Criteria 1: iterations
137  m_app->Options()->SetIntegerValue("max_iter", m_max_iter);
138 
139  // Termination Criteria 2: tolerance
140  m_app->Options()->SetNumericValue("tol", 1.);
141  m_app->Options()->SetNumericValue("dual_inf_tol", m_dual_inf_tol);
142  m_app->Options()->SetNumericValue("constr_viol_tol", m_constr_viol_tol);
143  m_app->Options()->SetNumericValue("compl_inf_tol", m_compl_inf_tol);
144  m_app->Options()->SetNumericValue("obj_scaling_factor", m_obj_scaling_factor);
145  m_app->Options()->SetNumericValue("mu_init", m_mu_init);
146 
147 
148 
149  // Intialize the IpoptApplication and process the options
150  Ipopt::ApplicationReturnStatus status;
151  status = m_app->Initialize();
152  if (status != Ipopt::Solve_Succeeded) {
153  pagmo_throw(value_error, "Error during IPOPT initialization!");
154  }
155 
156  // Ask Ipopt to solve the problem
157  status = m_app->OptimizeTNLP(pagmo_nlp);
158 }
159 
161 std::string ipopt::get_name() const
162 {
163  return "IPOPT";
164 }
165 
167 
170 std::string ipopt::human_readable_extra() const
171 {
172  std::ostringstream s;
173  s << "major_iter:" << m_max_iter << " ";
174  s << "constr_viol_tol:"<< m_constr_viol_tol<<" ";
175  s << "dual_inf_tol:"<< m_dual_inf_tol<<" ";
176  s << "compl_inf_tol:"<< m_compl_inf_tol<<" ";
177  s << "nlp_scaling_method:"<< (m_nlp_scaling_method? "True":"False") << " ";
178  s << "obj_scaling_factor:"<< m_obj_scaling_factor<<" ";
179  s << "mu_init:"<< m_mu_init;
180  return s.str();
181 }
182 
183 }} //namespaces
184 
185 BOOST_CLASS_EXPORT_IMPLEMENT(pagmo::algorithm::ipopt)
boost::shared_ptr< base > base_ptr
Alias for shared pointer to base algorithm.
Root PaGMO namespace.
void evolve(population &) const
Evolve implementation.
Definition: ipopt.cpp:97
base_ptr clone() const
Clone method.
Definition: ipopt.cpp:84
ipopt(const int &max_iter=100, const double &constr_viol_tol=1e-8, const double &dual_inf_tol=1e-8, const double &compl_inf_tol=1e-8, const bool &nlp_scaling_method=true, const double &obj_scaling_factor=1.0, const double &mu_init=0.1)
Constructor.
Definition: ipopt.cpp:53
Base problem class.
Definition: problem/base.h:148
Population class.
Definition: population.h:70
size_type get_dimension() const
Return global dimension.
bool m_screen_output
Indicates to the derived class whether to print stuff on screen.
size_type get_i_dimension() const
Return integer dimension.
std::string human_readable_extra() const
Extra human readable algorithm info.
Definition: ipopt.cpp:170
Wrapper for the IPOPT solver.
Definition: ipopt.h:59
std::string get_name() const
Algorithm name.
Definition: ipopt.cpp:161
container_type::size_type size_type
Population size type.
Definition: population.h:192
f_size_type get_f_dimension() const
Return fitness dimension.
virtual std::string get_name() const
Get problem's name.
decision_vector::size_type size_type
Problem's size type: the same as pagmo::decision_vector's size type.
Definition: problem/base.h:160