/build/buildd/coinor-ipopt-3.10.1/Ipopt/src/Apps/AmplSolver/AmplTNLP.hpp
Go to the documentation of this file.
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: AmplTNLP.hpp 2005 2011-06-06 12:55:16Z stefan $
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 
00252     std::map<std::string, SmartPtr<const AmplOption> > ampl_options_map_;
00253     // AW: I think it should be with const like in the following line
00254     //     but with const the AIX compiler fails
00255     // std::map<const std::string, SmartPtr<const AmplOption> > ampl_options_map_;
00256 
00258     void* keywds_;
00259 
00261     Index nkeywds_;
00262   };
00263 
00267   class AmplTNLP : public TNLP
00268   {
00269   public:
00273     AmplTNLP(const SmartPtr<const Journalist>& jnlst,
00274              const SmartPtr<OptionsList> options,
00275              char**& argv, SmartPtr<AmplSuffixHandler>
00276              suffix_handler = NULL, bool allow_discrete = false,
00277              SmartPtr<AmplOptionsList> ampl_options_list = NULL,
00278              const char* ampl_option_string = NULL,
00279              const char* ampl_invokation_string = NULL,
00280              const char* ampl_banner_string = NULL,
00281              std::string* nl_file_content = NULL);
00282 
00284     virtual ~AmplTNLP();
00286 
00288     DECLARE_STD_EXCEPTION(NONPOSITIVE_SCALING_FACTOR);
00289 
00295     virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
00296                               Index& nnz_h_lag, IndexStyleEnum& index_style);
00297 
00300     virtual bool get_var_con_metadata(Index n,
00301                                       StringMetaDataMapType& var_string_md,
00302                                       IntegerMetaDataMapType& var_integer_md,
00303                                       NumericMetaDataMapType& var_numeric_md,
00304                                       Index m,
00305                                       StringMetaDataMapType& con_string_md,
00306                                       IntegerMetaDataMapType& con_integer_md,
00307                                       NumericMetaDataMapType& con_numeric_md);
00308 
00310     virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u,
00311                                  Index m, Number* g_l, Number* g_u);
00312 
00316     virtual bool get_constraints_linearity(Index m,
00317                                            LinearityType* const_types);
00318 
00321     virtual bool get_starting_point(Index n, bool init_x, Number* x,
00322                                     bool init_z, Number* z_L, Number* z_U,
00323                                     Index m, bool init_lambda, Number* lambda);
00324 
00326     virtual bool eval_f(Index n, const Number* x, bool new_x,
00327                         Number& obj_value);
00328 
00331     virtual bool eval_grad_f(Index n, const Number* x, bool new_x,
00332                              Number* grad_f);
00333 
00335     virtual bool eval_g(Index n, const Number* x, bool new_x,
00336                         Index m, Number* g);
00337 
00341     virtual bool eval_jac_g(Index n, const Number* x, bool new_x,
00342                             Index m, Index nele_jac, Index* iRow,
00343                             Index *jCol, Number* values);
00344 
00348     virtual bool eval_h(Index n, const Number* x, bool new_x,
00349                         Number obj_factor, Index m, const Number* lambda,
00350                         bool new_lambda, Index nele_hess, Index* iRow,
00351                         Index* jCol, Number* values);
00352 
00355     virtual bool get_scaling_parameters(Number& obj_scaling,
00356                                         bool& use_x_scaling, Index n,
00357                                         Number* x_scaling,
00358                                         bool& use_g_scaling, Index m,
00359                                         Number* g_scaling);
00361 
00364     virtual void finalize_solution(SolverReturn status,
00365                                    Index n, const Number* x, const Number* z_L, const Number* z_U,
00366                                    Index m, const Number* g, const Number* lambda,
00367                                    Number obj_value,
00368                                    const IpoptData* ip_data,
00369                                    IpoptCalculatedQuantities* ip_cq);
00371 
00374     virtual Index get_number_of_nonlinear_variables();
00375     virtual bool get_list_of_nonlinear_variables(Index num_nonlin_vars,
00376         Index* pos_nonlin_vars);
00378 
00379 
00383     ASL_pfgh* AmplSolverObject()
00384     {
00385       return asl_;
00386     }
00387 
00391     void write_solution_file(const std::string& message) const;
00392 
00398     void get_discrete_info(Index& nlvb_,
00399                            Index& nlvbi_,
00400                            Index& nlvc_,
00401                            Index& nlvci_,
00402                            Index& nlvo_,
00403                            Index& nlvoi_,
00404                            Index& nbv_,
00405                            Index& niv_) const;
00407 
00413     void set_active_objective(Index obj_no);
00414 
00420     void set_string_metadata_for_var(std::string tag, std::vector<std::string> meta_data)
00421     {
00422       var_string_md_[tag] = meta_data;
00423     }
00424 
00425     void set_integer_metadata_for_var(std::string tag, std::vector<Index> meta_data)
00426     {
00427       var_integer_md_[tag] = meta_data;
00428     }
00429 
00430     void set_numeric_metadata_for_var(std::string tag, std::vector<Number> meta_data)
00431     {
00432       var_numeric_md_[tag] = meta_data;
00433     }
00434 
00435     void set_string_metadata_for_con(std::string tag, std::vector<std::string> meta_data)
00436     {
00437       con_string_md_[tag] = meta_data;
00438     }
00439 
00440     void set_integer_metadata_for_con(std::string tag, std::vector<Index> meta_data)
00441     {
00442       con_integer_md_[tag] = meta_data;
00443     }
00444 
00445     void set_numeric_metadata_for_con(std::string tag, std::vector<Number> meta_data)
00446     {
00447       con_numeric_md_[tag] = meta_data;
00448     }
00450 
00452     SmartPtr<AmplSuffixHandler> get_suffix_handler()
00453     {
00454       return suffix_handler_;
00455     }
00456 
00457   private:
00467     AmplTNLP();
00468 
00470     AmplTNLP(const AmplTNLP&);
00471 
00473     void operator=(const AmplTNLP&);
00475 
00477     SmartPtr<const Journalist> jnlst_;
00478 
00480     ASL_pfgh* asl_;
00481 
00483     double obj_sign_;
00484 
00487     Index nz_h_full_; // number of nonzeros in the full_x hessian
00488     /* the rest of the problem size data is available easily through the ampl variables */
00490 
00494     Number* x_sol_;
00495     Number* z_L_sol_;
00496     Number* z_U_sol_;
00497     Number* g_sol_;
00498     Number* lambda_sol_;
00499     Number obj_sol_;
00501 
00507     bool objval_called_with_current_x_;
00511     bool conval_called_with_current_x_;
00513     bool hesset_called_;
00515     bool set_active_objective_called_;
00517 
00519     void* Oinfo_ptr_;
00520 
00522     void* nerror_;
00523 
00525     SmartPtr<AmplSuffixHandler> suffix_handler_;
00526 
00528     bool internal_objval(const Number* x, Number& obj_val);
00529 
00531     bool internal_conval(const Number* x, Index m, Number* g=NULL);
00532 
00535     bool apply_new_x(bool new_x, Index n, const Number* x);
00536 
00540     char* get_options(const SmartPtr<OptionsList>& options,
00541                       SmartPtr<AmplOptionsList>& ampl_options_list,
00542                       const char* ampl_option_string,
00543                       const char* ampl_invokation_string,
00544                       const char* ampl_banner_string, char**& argv);
00545 
00547     bool nerror_ok(void* nerror);
00548 
00550     void call_hesset();
00551 
00553     StringMetaDataMapType var_string_md_;
00554     IntegerMetaDataMapType var_integer_md_;
00555     NumericMetaDataMapType var_numeric_md_;
00556     StringMetaDataMapType con_string_md_;
00557     IntegerMetaDataMapType con_integer_md_;
00558     NumericMetaDataMapType con_numeric_md_;
00559   };
00560 
00561 
00562 
00563 } // namespace Ipopt
00564 
00565 #endif