Ipopt
trunk
|
00001 // Copyright (C) 2004, 2009 International Business Machines and others. 00002 // All Rights Reserved. 00003 // This code is published under the Eclipse Public License. 00004 // 00005 // $Id$ 00006 // 00007 // Authors: Carl Laird, Andreas Waechter IBM 2004-08-13 00008 00009 #ifndef __IPAMPLTNLP_HPP__ 00010 #define __IPAMPLTNLP_HPP__ 00011 00012 #include "IpUtils.hpp" 00013 #include "IpTNLP.hpp" 00014 #include "IpJournalist.hpp" 00015 #include "IpOptionsList.hpp" 00016 00017 #include <map> 00018 #include <string> 00019 00020 /* non Ipopt forward declaration */ 00021 struct ASL_pfgh; 00022 struct SufDecl; 00023 struct SufDesc; 00024 00025 namespace Ipopt 00026 { 00027 class AmplSuffixHandler : public ReferencedObject 00028 { 00029 public: 00030 AmplSuffixHandler(); 00031 00032 ~AmplSuffixHandler(); 00033 00034 enum Suffix_Type 00035 { 00036 Index_Type, 00037 Number_Type 00038 }; 00039 00040 enum Suffix_Source 00041 { 00042 Variable_Source, 00043 Constraint_Source, 00044 Objective_Source, 00045 Problem_Source 00046 }; 00047 00048 void AddAvailableSuffix(std::string suffix_string, Suffix_Source source, Suffix_Type type) 00049 { 00050 suffix_ids_.push_back(suffix_string); 00051 suffix_types_.push_back(type); 00052 suffix_sources_.push_back(source); 00053 // suffix_values_.push_back(); 00054 } 00055 00056 const Index* GetIntegerSuffixValues(std::string suffix_string, Suffix_Source source) const; 00057 00058 const Number* GetNumberSuffixValues(std::string suffix_string, Suffix_Source source) const; 00059 00060 std::vector<Index> GetIntegerSuffixValues(Index n, std::string suffix_string, Suffix_Source source) const; 00061 00062 std::vector<Number> GetNumberSuffixValues(Index n, std::string suffix_string, Suffix_Source source) const; 00063 00064 private: 00074 //AmplSuffixHandler(); 00075 00077 AmplSuffixHandler(const AmplSuffixHandler&); 00078 00080 void operator=(const AmplSuffixHandler&); 00082 00083 mutable ASL_pfgh* asl_; 00084 00085 SufDecl* suftab_; 00086 00087 std::vector<std::string> suffix_ids_; 00088 std::vector<Suffix_Type> suffix_types_; 00089 std::vector<Suffix_Source> suffix_sources_; 00090 00092 void PrepareAmplForSuffixes(ASL_pfgh* asl); 00093 00095 // void RetrieveSuffixesFromAmpl(ASL_pfgh* asl); 00096 00097 friend class AmplTNLP; 00098 }; 00099 00102 class AmplOptionsList : public ReferencedObject 00103 { 00104 public: 00105 enum AmplOptionType { 00106 String_Option, 00107 Number_Option, 00108 Integer_Option, 00109 WS_Option, /* this is for AMPL's internal wantsol callback */ 00110 HaltOnError_Option /* this is for our setting of the nerror_ member */ 00111 }; 00112 00115 class AmplOption : public ReferencedObject 00116 { 00117 public: 00118 AmplOption(const std::string ipopt_option_name, 00119 AmplOptionType type, 00120 const std::string description); 00121 00122 ~AmplOption() 00123 { 00124 delete [] description_; 00125 } 00126 00127 const std::string& IpoptOptionName() const 00128 { 00129 return ipopt_option_name_; 00130 } 00131 AmplOptionType Type() const 00132 { 00133 return type_; 00134 } 00135 char* Description() const 00136 { 00137 return description_; 00138 } 00139 private: 00149 AmplOption(); 00150 00152 AmplOption(const AmplOption&); 00153 00155 void operator=(const AmplOption&); 00157 00158 const std::string ipopt_option_name_; 00159 const AmplOptionType type_; 00160 char* description_; 00161 }; 00162 00163 class PrivatInfo 00164 { 00165 public: 00166 PrivatInfo(const std::string ipopt_name, 00167 SmartPtr<OptionsList> options, 00168 SmartPtr<const Journalist> jnlst, 00169 void** nerror = NULL) 00170 : 00171 ipopt_name_(ipopt_name), 00172 options_(options), 00173 jnlst_(jnlst), 00174 nerror_(nerror) 00175 {} 00176 const std::string& IpoptName() const 00177 { 00178 return ipopt_name_; 00179 } 00180 const SmartPtr<OptionsList>& Options() const 00181 { 00182 return options_; 00183 } 00184 const SmartPtr<const Journalist>& Jnlst() const 00185 { 00186 return jnlst_; 00187 } 00188 void** NError() 00189 { 00190 return nerror_; 00191 } 00192 private: 00193 const std::string ipopt_name_; 00194 const SmartPtr<OptionsList> options_; 00195 const SmartPtr<const Journalist> jnlst_; 00196 void** nerror_; 00197 }; 00198 00199 public: 00201 AmplOptionsList() 00202 : 00203 keywds_(NULL), 00204 nkeywds_(0) 00205 {} 00206 00208 ~AmplOptionsList(); 00209 00211 void AddAmplOption(const std::string ampl_option_name, 00212 const std::string ipopt_option_name, 00213 AmplOptionsList::AmplOptionType type, 00214 const std::string description) 00215 { 00216 SmartPtr<AmplOption> new_option = 00217 new AmplOption(ipopt_option_name, type, description); 00218 ampl_options_map_[ampl_option_name] = ConstPtr(new_option); 00219 } 00220 00222 Index NumberOfAmplOptions() 00223 { 00224 return (Index)ampl_options_map_.size(); 00225 } 00226 00228 void* Keywords(const SmartPtr<OptionsList>& options, 00229 SmartPtr<const Journalist> jnlst, 00230 void** nerror); 00231 00232 private: 00242 //AmplOptionsList(); 00243 00245 AmplOptionsList(const AmplOptionsList&); 00246 00248 void operator=(const AmplOptionsList&); 00250 00251 void MakeValidLatexString(std::string source, std::string& dest) const; 00252 00253 void PrintLatex(SmartPtr<const Journalist> jnlst); 00254 00256 std::map<std::string, SmartPtr<const AmplOption> > ampl_options_map_; 00257 // AW: I think it should be with const like in the following line 00258 // but with const the AIX compiler fails 00259 // std::map<const std::string, SmartPtr<const AmplOption> > ampl_options_map_; 00260 00262 void* keywds_; 00263 00265 Index nkeywds_; 00266 }; 00267 00271 class AmplTNLP : public TNLP 00272 { 00273 public: 00277 AmplTNLP(const SmartPtr<const Journalist>& jnlst, 00278 const SmartPtr<OptionsList> options, 00279 char**& argv, SmartPtr<AmplSuffixHandler> 00280 suffix_handler = NULL, bool allow_discrete = false, 00281 SmartPtr<AmplOptionsList> ampl_options_list = NULL, 00282 const char* ampl_option_string = NULL, 00283 const char* ampl_invokation_string = NULL, 00284 const char* ampl_banner_string = NULL, 00285 std::string* nl_file_content = NULL); 00286 00288 virtual ~AmplTNLP(); 00290 00292 DECLARE_STD_EXCEPTION(NONPOSITIVE_SCALING_FACTOR); 00293 00299 virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g, 00300 Index& nnz_h_lag, IndexStyleEnum& index_style); 00301 00304 virtual bool get_var_con_metadata(Index n, 00305 StringMetaDataMapType& var_string_md, 00306 IntegerMetaDataMapType& var_integer_md, 00307 NumericMetaDataMapType& var_numeric_md, 00308 Index m, 00309 StringMetaDataMapType& con_string_md, 00310 IntegerMetaDataMapType& con_integer_md, 00311 NumericMetaDataMapType& con_numeric_md); 00312 00314 virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u, 00315 Index m, Number* g_l, Number* g_u); 00316 00320 virtual bool get_constraints_linearity(Index m, 00321 LinearityType* const_types); 00322 00325 virtual bool get_starting_point(Index n, bool init_x, Number* x, 00326 bool init_z, Number* z_L, Number* z_U, 00327 Index m, bool init_lambda, Number* lambda); 00328 00330 virtual bool eval_f(Index n, const Number* x, bool new_x, 00331 Number& obj_value); 00332 00335 virtual bool eval_grad_f(Index n, const Number* x, bool new_x, 00336 Number* grad_f); 00337 00339 virtual bool eval_g(Index n, const Number* x, bool new_x, 00340 Index m, Number* g); 00341 00345 virtual bool eval_jac_g(Index n, const Number* x, bool new_x, 00346 Index m, Index nele_jac, Index* iRow, 00347 Index *jCol, Number* values); 00348 00352 virtual bool eval_h(Index n, const Number* x, bool new_x, 00353 Number obj_factor, Index m, const Number* lambda, 00354 bool new_lambda, Index nele_hess, Index* iRow, 00355 Index* jCol, Number* values); 00356 00359 virtual bool get_scaling_parameters(Number& obj_scaling, 00360 bool& use_x_scaling, Index n, 00361 Number* x_scaling, 00362 bool& use_g_scaling, Index m, 00363 Number* g_scaling); 00365 00368 virtual void finalize_solution(SolverReturn status, 00369 Index n, const Number* x, const Number* z_L, const Number* z_U, 00370 Index m, const Number* g, const Number* lambda, 00371 Number obj_value, 00372 const IpoptData* ip_data, 00373 IpoptCalculatedQuantities* ip_cq); 00375 00378 virtual Index get_number_of_nonlinear_variables(); 00379 virtual bool get_list_of_nonlinear_variables(Index num_nonlin_vars, 00380 Index* pos_nonlin_vars); 00382 00383 00387 ASL_pfgh* AmplSolverObject() 00388 { 00389 return asl_; 00390 } 00391 00395 void write_solution_file(const std::string& message) const; 00396 00402 void get_discrete_info(Index& nlvb_, 00403 Index& nlvbi_, 00404 Index& nlvc_, 00405 Index& nlvci_, 00406 Index& nlvo_, 00407 Index& nlvoi_, 00408 Index& nbv_, 00409 Index& niv_) const; 00411 00417 void set_active_objective(Index obj_no); 00418 00424 void set_string_metadata_for_var(std::string tag, std::vector<std::string> meta_data) 00425 { 00426 var_string_md_[tag] = meta_data; 00427 } 00428 00429 void set_integer_metadata_for_var(std::string tag, std::vector<Index> meta_data) 00430 { 00431 var_integer_md_[tag] = meta_data; 00432 } 00433 00434 void set_numeric_metadata_for_var(std::string tag, std::vector<Number> meta_data) 00435 { 00436 var_numeric_md_[tag] = meta_data; 00437 } 00438 00439 void set_string_metadata_for_con(std::string tag, std::vector<std::string> meta_data) 00440 { 00441 con_string_md_[tag] = meta_data; 00442 } 00443 00444 void set_integer_metadata_for_con(std::string tag, std::vector<Index> meta_data) 00445 { 00446 con_integer_md_[tag] = meta_data; 00447 } 00448 00449 void set_numeric_metadata_for_con(std::string tag, std::vector<Number> meta_data) 00450 { 00451 con_numeric_md_[tag] = meta_data; 00452 } 00454 00456 SmartPtr<AmplSuffixHandler> get_suffix_handler() 00457 { 00458 return suffix_handler_; 00459 } 00460 00461 private: 00471 AmplTNLP(); 00472 00474 AmplTNLP(const AmplTNLP&); 00475 00477 void operator=(const AmplTNLP&); 00479 00481 SmartPtr<const Journalist> jnlst_; 00482 00484 ASL_pfgh* asl_; 00485 00487 double obj_sign_; 00488 00491 Index nz_h_full_; // number of nonzeros in the full_x hessian 00492 /* the rest of the problem size data is available easily through the ampl variables */ 00494 00498 Number* x_sol_; 00499 Number* z_L_sol_; 00500 Number* z_U_sol_; 00501 Number* g_sol_; 00502 Number* lambda_sol_; 00503 Number obj_sol_; 00505 00511 bool objval_called_with_current_x_; 00515 bool conval_called_with_current_x_; 00517 bool hesset_called_; 00519 bool set_active_objective_called_; 00521 00523 void* Oinfo_ptr_; 00524 00526 void* nerror_; 00527 00529 SmartPtr<AmplSuffixHandler> suffix_handler_; 00530 00532 bool internal_objval(const Number* x, Number& obj_val); 00533 00535 bool internal_conval(const Number* x, Index m, Number* g=NULL); 00536 00539 bool apply_new_x(bool new_x, Index n, const Number* x); 00540 00544 char* get_options(const SmartPtr<OptionsList>& options, 00545 SmartPtr<AmplOptionsList>& ampl_options_list, 00546 const char* ampl_option_string, 00547 const char* ampl_invokation_string, 00548 const char* ampl_banner_string, char**& argv); 00549 00551 bool nerror_ok(void* nerror); 00552 00554 void call_hesset(); 00555 00557 StringMetaDataMapType var_string_md_; 00558 IntegerMetaDataMapType var_integer_md_; 00559 NumericMetaDataMapType var_numeric_md_; 00560 StringMetaDataMapType con_string_md_; 00561 IntegerMetaDataMapType con_integer_md_; 00562 NumericMetaDataMapType con_numeric_md_; 00563 }; 00564 00565 00566 00567 } // namespace Ipopt 00568 00569 #endif