source: branches/dev/Interfaces/IpIpoptApplication.cpp @ 500

Last change on this file since 500 was 500, checked in by andreasw, 14 years ago

changed error message for tiny step

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 17.7 KB
Line 
1// Copyright (C) 2004, 2005 International Business Machines and others.
2// All Rights Reserved.
3// This code is published under the Common Public License.
4//
5// $Id: IpIpoptApplication.cpp 500 2005-08-25 20:58:50Z andreasw $
6//
7// Authors:  Carl Laird, Andreas Waechter     IBM    2004-09-02
8
9#include "IpIpoptApplication.hpp"
10#include "IpTNLPAdapter.hpp"
11#include "IpIpoptAlg.hpp"
12#include "IpOrigIpoptNLP.hpp"
13#include "IpIpoptData.hpp"
14#include "IpIpoptCalculatedQuantities.hpp"
15#include "IpAlgBuilder.hpp"
16#include "IpUserScaling.hpp"
17#include "IpGradientScaling.hpp"
18
19#include "IpLinearSolversRegOp.hpp"
20#include "IpInterfacesRegOp.hpp"
21#include "IpAlgorithmRegOp.hpp"
22
23namespace Ipopt
24{
25#ifdef IP_DEBUG
26  static const Index dbg_verbosity = 0;
27#endif
28
29  IpoptApplication::IpoptApplication(bool read_params_dat,
30                                     bool create_console_out)
31      :
32      jnlst_(new Journalist()),
33      options_(new OptionsList()),
34      statistics_(NULL)
35  {
36    try {
37# ifdef IP_DEBUG
38      DebugJournalistWrapper::SetJournalist(GetRawPtr(jnlst_));
39      SmartPtr<Journal> debug_jrnl = jnlst_->AddFileJournal("Debug", "debug.out", J_SUMMARY);
40      debug_jrnl->SetPrintLevel(J_DBG, J_ALL);
41# endif
42
43      DBG_START_METH("IpoptApplication::IpoptApplication()",
44                     dbg_verbosity);
45
46
47      SmartPtr<Journal> stdout_jrnl = NULL;
48      if (create_console_out) {
49        stdout_jrnl =
50          jnlst_->AddFileJournal("console", "stdout", J_SUMMARY);
51        stdout_jrnl->SetPrintLevel(J_DBG, J_NONE);
52      }
53
54      // Register the valid options
55      SmartPtr<RegisteredOptions> reg_options = new RegisteredOptions();
56      RegisterAllOptions(reg_options);
57
58      options_->SetJournalist(jnlst_);
59      options_->SetRegisteredOptions(reg_options);
60
61      // Get the options
62      if (read_params_dat) {
63        FILE* fp_options = fopen("PARAMS.DAT", "r");
64        if (fp_options) {
65          // PARAMS.DAT exists, read the content
66          options_->ReadFromFile(*jnlst_, fp_options);
67          fclose(fp_options);
68          fp_options=NULL;
69        }
70      }
71
72      Index ivalue;
73      options_->GetIntegerValue("print_level", ivalue, "");
74      EJournalLevel print_level = (EJournalLevel)ivalue;
75      if (create_console_out) {
76        // Set printlevel for stdout
77        stdout_jrnl->SetAllPrintLevels(print_level);
78        stdout_jrnl->SetPrintLevel(J_DBG, J_NONE);
79      }
80
81      bool option_set;
82
83#ifdef IP_DEBUG
84      // Set printlevel for debug
85      option_set = options_->GetIntegerValue("debug_print_level",
86                                             ivalue, "");
87      EJournalLevel debug_print_level;
88      if (option_set) {
89        debug_print_level = (EJournalLevel)ivalue;
90      }
91      else {
92        debug_print_level = print_level;
93      }
94      debug_jrnl->SetAllPrintLevels(debug_print_level);
95      debug_jrnl->SetPrintLevel(J_DBG, J_ALL);
96#endif
97
98      // Open an output file if required
99      std::string output_filename;
100      options_->GetStringValue("output_file", output_filename, "");
101      if (output_filename != "") {
102        EJournalLevel file_print_level;
103        option_set = options_->GetIntegerValue("file_print_level", ivalue, "");
104        if (option_set) {
105          file_print_level = (EJournalLevel)ivalue;
106        }
107        else {
108          file_print_level = print_level;
109        }
110        OpenOutputFile(output_filename, file_print_level);
111      }
112
113      // output a description of all the options
114      bool print_options_documentation;
115      options_->GetBoolValue("print_options_documentation",
116                             print_options_documentation, "");
117      if (print_options_documentation) {
118        bool latex;
119        options_->GetBoolValue("print_options_latex_mode", latex, "");
120        if (latex) {
121          std::list<std::string> options_to_print;
122          options_to_print.push_back("print_level");
123          options_to_print.push_back("pivtol");
124          options_to_print.push_back("pivtolmax");
125          options_to_print.push_back("tol");
126          options_to_print.push_back("compl_inf_tol");
127          options_to_print.push_back("dual_inf_tol");
128          options_to_print.push_back("constr_mult_init_max");
129          options_to_print.push_back("constr_viol_tol");
130          options_to_print.push_back("mu_strategy");
131          options_to_print.push_back("mu_init");
132          options_to_print.push_back("mu_oracle");
133          options_to_print.push_back("corrector_type");
134          options_to_print.push_back("obj_scaling_factor");
135          options_to_print.push_back("nlp_scaling_method");
136          options_to_print.push_back("nlp_scaling_max_gradient");
137          options_to_print.push_back("bound_frac");
138          options_to_print.push_back("bound_mult_init_val");
139          options_to_print.push_back("bound_push");
140          options_to_print.push_back("bound_relax_factor");
141          options_to_print.push_back("acceptable_compl_inf_tol");
142          options_to_print.push_back("acceptable_constr_viol_tol");
143          options_to_print.push_back("acceptable_dual_inf_tol");
144          options_to_print.push_back("acceptable_tol");
145          options_to_print.push_back("alpha_for_y");
146          options_to_print.push_back("expect_infeasible_problem");
147          options_to_print.push_back("max_iter");
148          options_to_print.push_back("max_refinement_steps");
149          options_to_print.push_back("max_soc");
150          options_to_print.push_back("min_refinement_steps");
151          options_to_print.push_back("output_file");
152          options_to_print.push_back("file_print_level");
153
154          reg_options->OutputLatexOptionDocumentation(*jnlst_, options_to_print);
155        }
156        else {
157          std::list<std::string> categories;
158          categories.push_back("Output");
159          categories.push_back("Main Algorithm");
160          categories.push_back("Convergence");
161          categories.push_back("NLP Scaling");
162          categories.push_back("Mu Update");
163          categories.push_back("Line Search");
164          categories.push_back("Initialization");
165          categories.push_back("Linear Solver");
166          categories.push_back("Step Calculation");
167          categories.push_back("Restoration");
168          categories.push_back("NLP");
169          categories.push_back("Warm Start");
170          categories.push_back("MA27 Linear Solver");
171          categories.push_back("Uncategorized");
172          reg_options->OutputOptionDocumentation(*jnlst_, categories);
173        }
174      }
175
176    }
177    catch(OPTION_INVALID& exc) {
178      exc.ReportException(*jnlst_);
179      exit(-1);
180    }
181    catch(IpoptException& exc) {
182      exc.ReportException(*jnlst_);
183      exit(-1);
184    }
185    catch(std::bad_alloc& exc) {
186      jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Not enough memory.\n");
187      exit(-1);
188    }
189    catch(...) {
190      IpoptException exc("Unknown Exception caught in ipopt", "Unknown File", -1);
191      exc.ReportException(*jnlst_);
192      exit(-1);
193    }
194  }
195
196  IpoptApplication::~IpoptApplication()
197  {
198    DBG_START_METH("IpoptApplication::~IpoptApplication()",
199                   dbg_verbosity);
200  }
201
202  void IpoptApplication::RegisterOptions(SmartPtr<RegisteredOptions> roptions)
203  {
204    roptions->SetRegisteringCategory("Output");
205    roptions->AddBoundedIntegerOption(
206      "print_level",
207      "Output verbosity level.",
208      0, J_LAST_LEVEL-1, J_SUMMARY,
209      "Sets the default verbosity level for console output. The "
210      "larger this value the more detailed is the output.");
211
212    roptions->AddStringOption1(
213      "output_file",
214      "File name of desired output file (leave unset for no file output).",
215      "",
216      "*", "Any acceptable standard file name",
217      "NOTE: This option only works when read from the PARAMS.DAT options file! "
218      "An output file with this name will be written (leave unset for no "
219      "file output).  The verbosity level is by default set to \"print_level\", or "
220      "but can be overridden with \"file_print_level\".");
221    roptions->AddBoundedIntegerOption(
222      "file_print_level",
223      "Verbosity level for output file.",
224      0, J_LAST_LEVEL-1, J_SUMMARY,
225      "NOTE: This option only works when read from the PARAMS.DAT options file! "
226      "Determines the verbosity level for the file specified by "
227      "\"output_file\".  By default it is the same as \"print_level\".");
228    roptions->AddStringOption2(
229      "print_options_documentation",
230      "Switch to print all algorithmic options.",
231      "no",
232      "no", "don't print list",
233      "yes", "print list",
234      "If selected, the algorithm will print the list of all available "
235      "algorithmic options with some documentation before solving the "
236      "optimization problem.");
237
238#if IP_DEBUG
239
240    roptions->AddBoundedIntegerOption(
241      "debug_print_level",
242      "Verbosity level for debug file.",
243      0, J_LAST_LEVEL-1, J_SUMMARY,
244      "This Ipopt library has been compiled in debug mode, and a file "
245      "\"debug.out\" is produced for every run.  This option determines "
246      "the verbosity level for this file.  By default it is the same as "
247      "\"print_level\".");
248
249#endif
250
251    roptions->SetRegisteringCategory("NLP Scaling");
252    roptions->AddStringOption3(
253      "nlp_scaling_method",
254      "Select the technique used for scaling the NLP", "gradient_based",
255      "none", "no problem scaling will be performed",
256      "user_scaling", "scaling parameters will come from the user",
257      "gradient_based", "scale the problem so the maximum gradient at the starting point is scaling_max_gradient",
258      "Selects the technique used for scaling the problem before it is solved."
259      " For user-scaling, the parameters come from the NLP. If you are using "
260      "AMPL, they can be specified through suffixes (scaling_factor)");
261
262    roptions->SetRegisteringCategory("Undocumented Options");
263    roptions->AddStringOption2(
264      "print_options_latex_mode",
265      "Undocumented", "no",
266      "no", "Undocumented",
267      "yes", "Undocumented",
268      "Undocumented"
269    );
270  }
271
272  ApplicationReturnStatus IpoptApplication::OptimizeTNLP(const SmartPtr<TNLP>& nlp)
273  {
274    SmartPtr<NLP> nlp_adapter =
275      new TNLPAdapter(GetRawPtr(nlp));
276
277    return OptimizeNLP(nlp_adapter);
278  }
279
280  ApplicationReturnStatus
281  IpoptApplication::OptimizeNLP(const SmartPtr<NLP>& nlp)
282  {
283    statistics_ = NULL; /* delete old statistics */
284    ApplicationReturnStatus retValue = Internal_Error;
285    SmartPtr<IpoptData> ip_data;
286    SmartPtr<IpoptCalculatedQuantities> ip_cq;
287    SmartPtr<IpoptNLP> ip_nlp;
288    try {
289
290      SmartPtr<NLPScalingObject> nlp_scaling;
291      std::string nlp_scaling_method;
292      options_->GetStringValue("nlp_scaling_method", nlp_scaling_method, "");
293      if (nlp_scaling_method == "user_scaling") {
294        nlp_scaling = new UserScaling(ConstPtr(nlp));
295      }
296      else if (nlp_scaling_method == "gradient_based") {
297        nlp_scaling = new GradientScaling(nlp);
298      }
299      else {
300        nlp_scaling = new NoNLPScalingObject();
301      }
302
303      ip_nlp =  new OrigIpoptNLP(ConstPtr(jnlst_), GetRawPtr(nlp), nlp_scaling);
304
305      // Create the IpoptData
306      if (IsNull(ip_data)) {
307        ip_data = new IpoptData();
308      }
309
310      // Create the IpoptCalculators
311      if (IsNull(ip_cq)) {
312        ip_cq = new IpoptCalculatedQuantities(ip_nlp, ip_data);
313      }
314
315      // Create the Algorithm object
316      SmartPtr<IpoptAlgorithm> alg
317      = AlgorithmBuilder::BuildBasicAlgorithm(*jnlst_, *options_, "");
318
319      // Set up the algorithm
320      alg->Initialize(*jnlst_, *ip_nlp, *ip_data, *ip_cq, *options_, "");
321
322      if( jnlst_->ProduceOutput(J_DETAILED, J_MAIN) ) {
323        // Print out the options (including the number of times they were used
324        std::string liststr;
325        options_->PrintList(liststr);
326        jnlst_->Printf(J_DETAILED, J_MAIN, "\nList of options:\n\n%s", liststr.c_str());
327      }
328
329      // Run the algorithm
330      SolverReturn status = alg->Optimize();
331
332      jnlst_->Printf(J_SUMMARY, J_SOLUTION,
333                     "\nNumber of Iterations....: %d\n",
334                     ip_data->iter_count());
335
336      jnlst_->Printf(J_SUMMARY, J_SOLUTION,
337                     "\n                                   (scaled)                 (unscaled)\n");
338      jnlst_->Printf(J_SUMMARY, J_SOLUTION,
339                     "Objective...............: %24.16e  %24.16e\n", ip_cq->curr_f(), ip_cq->unscaled_curr_f());
340      jnlst_->Printf(J_SUMMARY, J_SOLUTION,
341                     "Dual infeasibility......: %24.16e  %24.16e\n", ip_cq->curr_dual_infeasibility(NORM_MAX), ip_cq->unscaled_curr_dual_infeasibility(NORM_MAX));
342      jnlst_->Printf(J_SUMMARY, J_SOLUTION,
343                     "Constraint violation....: %24.16e  %24.16e\n", ip_cq->curr_nlp_constraint_violation(NORM_MAX), ip_cq->unscaled_curr_nlp_constraint_violation(NORM_MAX));
344      jnlst_->Printf(J_SUMMARY, J_SOLUTION,
345                     "Complementarity.........: %24.16e  %24.16e\n", ip_cq->curr_complementarity(0., NORM_MAX), ip_cq->unscaled_curr_complementarity(0., NORM_MAX));
346      jnlst_->Printf(J_SUMMARY, J_SOLUTION,
347                     "Overall NLP error.......: %24.16e  %24.16e\n\n", ip_cq->curr_nlp_error(), ip_cq->unscaled_curr_nlp_error());
348
349      ip_data->curr()->x()->Print(*jnlst_, J_VECTOR, J_SOLUTION, "x");
350      ip_data->curr()->y_c()->Print(*jnlst_, J_VECTOR, J_SOLUTION, "y_c");
351      ip_data->curr()->y_d()->Print(*jnlst_, J_VECTOR, J_SOLUTION, "y_d");
352      ip_data->curr()->z_L()->Print(*jnlst_, J_VECTOR, J_SOLUTION, "z_L");
353      ip_data->curr()->z_U()->Print(*jnlst_, J_VECTOR, J_SOLUTION, "z_U");
354      ip_data->curr()->v_L()->Print(*jnlst_, J_VECTOR, J_SOLUTION, "v_L");
355      ip_data->curr()->v_U()->Print(*jnlst_, J_VECTOR, J_SOLUTION, "v_U");
356
357      jnlst_->Printf(J_SUMMARY, J_STATISTICS,
358                     "\nNumber of objective function evaluations             = %d\n",
359                     ip_nlp->f_evals());
360      jnlst_->Printf(J_SUMMARY, J_STATISTICS,
361                     "Number of objective gradient evaluations             = %d\n",
362                     ip_nlp->grad_f_evals());
363      jnlst_->Printf(J_SUMMARY, J_STATISTICS,
364                     "Number of equality constraint evaluations            = %d\n",
365                     ip_nlp->c_evals());
366      jnlst_->Printf(J_SUMMARY, J_STATISTICS,
367                     "Number of inequality constraint evaluations          = %d\n",
368                     ip_nlp->d_evals());
369      jnlst_->Printf(J_SUMMARY, J_STATISTICS,
370                     "Number of equality constraint Jacobian evaluations   = %d\n",
371                     ip_nlp->jac_c_evals());
372      jnlst_->Printf(J_SUMMARY, J_STATISTICS,
373                     "Number of inequality constraint Jacobian evaluations = %d\n",
374                     ip_nlp->jac_d_evals());
375      jnlst_->Printf(J_SUMMARY, J_STATISTICS,
376                     "Number of Lagrangian Hessian evaluations             = %d\n",
377                     ip_nlp->h_evals());
378
379      // Write EXIT message
380      if (status == SUCCESS) {
381        retValue = Solve_Succeeded;
382        jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Optimal Solution Found.\n");
383      }
384      else if (status == MAXITER_EXCEEDED) {
385        retValue = Maximum_Iterations_Exceeded;
386        jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Maximum Number of Iterations Exceeded.\n");
387      }
388      else if (status == STOP_AT_TINY_STEP) {
389        retValue = Search_Direction_Becomes_Too_Small;
390        jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Search Direction becomes Too Small.\n");
391      }
392      else if (status == STOP_AT_ACCEPTABLE_POINT) {
393        retValue = Solved_To_Acceptable_Level;
394        jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Solved To Acceptable Level.\n");
395      }
396      else if (status == RESTORATION_FAILURE) {
397        retValue = Restoration_Failed;
398        jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Restoration Failed!\n");
399      }
400      else if (status == LOCAL_INFEASIBILITY) {
401        retValue = Infeasible_Problem_Detected;
402        jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Converged to a point of local infeasibility. Problem may be infeasible.\n");
403      }
404      else {
405        retValue = Internal_Error;
406        jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: INTERNAL ERROR: Unknown SolverReturn value - Notify IPOPT Authors.\n");
407        return retValue;
408      }
409      ip_nlp->FinalizeSolution(status,
410                               *ip_data->curr()->x(), *ip_data->curr()->z_L(), *ip_data->curr()->z_U(),
411                               *ip_cq->curr_c(), *ip_cq->curr_d(), *ip_data->curr()->y_c(), *ip_data->curr()->y_d(),
412                               ip_cq->curr_f());
413      // Create a SolveStatistics object
414      statistics_ = new SolveStatistics(ip_nlp, ip_data, ip_cq);
415    }
416    catch(TOO_FEW_DOF& exc) {
417      exc.ReportException(*jnlst_);
418      retValue = Not_Enough_Degrees_Of_Freedom;
419    }
420    catch(OPTION_INVALID& exc) {
421      exc.ReportException(*jnlst_);
422      retValue = Invalid_Option;
423    }
424    catch(IpoptException& exc) {
425      exc.ReportException(*jnlst_);
426      retValue = Unrecoverable_Exception;
427    }
428    catch(std::bad_alloc& exc) {
429      retValue = Insufficient_Memory;
430      jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Not enough memory.\n");
431    }
432    catch(...) {
433      IpoptException exc("Unknown Exception caught in ipopt", "Unknown File", -1);
434      exc.ReportException(*jnlst_);
435      retValue = NonIpopt_Exception_Thrown;
436    }
437
438    jnlst_->FlushBuffer();
439
440    return retValue;
441
442  }
443
444  bool IpoptApplication::OpenOutputFile(std::string file_name,
445                                        EJournalLevel print_level)
446  {
447    SmartPtr<Journal> file_jrnl = jnlst_->AddFileJournal("OutputFile:"+file_name,
448                                  file_name.c_str(),
449                                  print_level);
450    file_jrnl->SetPrintLevel(J_DBG, J_NONE);
451
452    return true;
453  }
454
455  void IpoptApplication::RegisterAllOptions(const SmartPtr<RegisteredOptions>& roptions)
456  {
457    RegisterOptions_Interfaces(roptions);
458    RegisterOptions_Algorithm(roptions);
459    RegisterOptions_LinearSolvers(roptions);
460  }
461
462} // namespace Ipopt
Note: See TracBrowser for help on using the repository browser.