1 // Copyright (C) 2004, 2006 International Business Machines and others.
2 // All Rights Reserved.
3 // This code is published under the Common Public License.
4 //
5 // $Id: IpIpoptApplication.cpp 759 2006-07-07 03:07:08Z andreasw $
6 //
7 // Authors: Carl Laird, Andreas Waechter IBM 2004-09-02
8
9 #include "IpoptConfig.h"
10 #include "IpIpoptApplication.hpp"
11 #include "IpTNLPAdapter.hpp"
12 #include "IpIpoptAlg.hpp"
13 #include "IpOrigIpoptNLP.hpp"
14 #include "IpIpoptData.hpp"
15 #include "IpIpoptCalculatedQuantities.hpp"
16 #include "IpAlgBuilder.hpp"
17 #include "IpSolveStatistics.hpp"
18 #include "IpLinearSolversRegOp.hpp"
19 #include "IpInterfacesRegOp.hpp"
20 #include "IpAlgorithmRegOp.hpp"
21
22 #ifdef HAVE_CMATH
23 # include <cmath>
24 #else
25 # ifdef HAVE_MATH_H
26 # include <math.h>
27 # else
28 # error "don't have header file for math"
29 # endif
30 #endif
31
32 #include <fstream>
33
34 namespace SimTKIpopt
35 {
36 #ifdef IP_DEBUG
37 static const Index dbg_verbosity = 0;
38 #endif
39
IpoptApplication(bool create_console_out)40 IpoptApplication::IpoptApplication(bool create_console_out)
41 :
42 jnlst_(new Journalist()),
43 options_(new OptionsList()),
44 statistics_(NULL),
45 alg_(NULL),
46 nlp_adapter_(NULL)
47 {
48 try {
49 # ifdef IP_DEBUG
50 DebugJournalistWrapper::SetJournalist(GetRawPtr(jnlst_));
51 SmartPtr<Journal> debug_jrnl = jnlst_->AddFileJournal("Debug", "debug.out", J_ITERSUMMARY);
52 debug_jrnl->SetPrintLevel(J_DBG, J_ALL);
53 # endif
54
55 DBG_START_METH("IpoptApplication::IpoptApplication()",
56 dbg_verbosity);
57
58 if (create_console_out) {
59 SmartPtr<Journal> stdout_jrnl =
60 jnlst_->AddFileJournal("console", "stdout", J_ITERSUMMARY);
61 stdout_jrnl->SetPrintLevel(J_DBG, J_NONE);
62 }
63
64 // Register the valid options
65 reg_options_ = new RegisteredOptions();
66 RegisterAllOptions(reg_options_);
67
68 options_->SetJournalist(jnlst_);
69 options_->SetRegisteredOptions(reg_options_);
70 }
71 catch(IpoptException& exc) {
72 exc.ReportException(*jnlst_);
73 THROW_EXCEPTION(IPOPT_APPLICATION_ERROR,
74 "Caught unknown Ipopt exception");
75 }
76 catch(std::bad_alloc) {
77 jnlst_->Printf(J_ERROR, J_MAIN, "\nEXIT: Not enough memory.\n");
78 THROW_EXCEPTION(IPOPT_APPLICATION_ERROR,
79 "Not enough memory");
80 }
81 catch(...) {
82 IpoptException exc("Unknown Exception caught in ipopt", "Unknown File", -1);
83 exc.ReportException(*jnlst_);
84 THROW_EXCEPTION(IPOPT_APPLICATION_ERROR,
85 "Caught unknown exception");
86 }
87 }
88
Initialize(std::string params_file)89 void IpoptApplication::Initialize(std::string params_file /*= "ipopt.opt"*/)
90 {
91 std::ifstream is;
92 if (params_file != "") {
93 try {
94 is.open(params_file.c_str());
95 }
96 catch(std::bad_alloc) {
97 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Not enough memory.\n");
98 exit(-1);
99 }
100 catch(...) {
101 IpoptException exc("Unknown Exception caught in ipopt", "Unknown File", -1);
102 exc.ReportException(*jnlst_);
103 exit(-1);
104 }
105 }
106 Initialize(is);
107 if (is) {
108 is.close();
109 }
110 }
111
Initialize(std::istream & is)112 void IpoptApplication::Initialize(std::istream& is)
113 {
114 try {
115 // Get the options
116 if (is.good()) {
117 // stream exists, read the content
118 options_->ReadFromStream(*jnlst_, is);
119 }
120
121 Index ivalue;
122 options_->GetIntegerValue("print_level", ivalue, "");
123 EJournalLevel print_level = (EJournalLevel)ivalue;
124 SmartPtr<Journal> stdout_jrnl = jnlst_->GetJournal("console");
125 if (IsValid(stdout_jrnl)) {
126 // Set printlevel for stdout
127 stdout_jrnl->SetAllPrintLevels(print_level);
128 stdout_jrnl->SetPrintLevel(J_DBG, J_NONE);
129 }
130
131 bool option_set;
132
133 #ifdef IP_DEBUG
134 // Set printlevel for debug
135 option_set = options_->GetIntegerValue("debug_print_level",
136 ivalue, "");
137 EJournalLevel debug_print_level;
138 if (option_set) {
139 debug_print_level = (EJournalLevel)ivalue;
140 }
141 else {
142 debug_print_level = print_level;
143 }
144 SmartPtr<Journal> debug_jrnl = jnlst_->GetJournal("Debug");
145 debug_jrnl->SetAllPrintLevels(debug_print_level);
146 debug_jrnl->SetPrintLevel(J_DBG, J_ALL);
147 #endif
148
149 // Open an output file if required
150 std::string output_filename;
151 options_->GetStringValue("output_file", output_filename, "");
152 if (output_filename != "") {
153 EJournalLevel file_print_level;
154 option_set = options_->GetIntegerValue("file_print_level", ivalue, "");
155 if (option_set) {
156 file_print_level = (EJournalLevel)ivalue;
157 }
158 else {
159 file_print_level = print_level;
160 }
161 OpenOutputFile(output_filename, file_print_level);
162 }
163
164 // output a description of all the options
165 bool print_options_documentation;
166 options_->GetBoolValue("print_options_documentation",
167 print_options_documentation, "");
168 if (print_options_documentation) {
169 bool latex;
170 options_->GetBoolValue("print_options_latex_mode", latex, "");
171 if (latex) {
172 std::list<std::string> options_to_print;
173 // Output
174 options_to_print.push_back("print_level");
175 options_to_print.push_back("print_user_options");
176 options_to_print.push_back("print_options_documentation");
177 options_to_print.push_back("output_file");
178 options_to_print.push_back("file_print_level");
179 // Termination
180 options_to_print.push_back("tol");
181 options_to_print.push_back("max_iter");
182 options_to_print.push_back("compl_inf_tol");
183 options_to_print.push_back("dual_inf_tol");
184 options_to_print.push_back("constr_viol_tol");
185 options_to_print.push_back("acceptable_tol");
186 options_to_print.push_back("acceptable_compl_inf_tol");
187 options_to_print.push_back("acceptable_constr_viol_tol");
188 options_to_print.push_back("acceptable_dual_inf_tol");
189 options_to_print.push_back("diverging_iterates_tol");
190 options_to_print.push_back("barrier_tol_factor");
191 // NLP scaling
192 options_to_print.push_back("obj_scaling_factor");
193 options_to_print.push_back("nlp_scaling_method");
194 options_to_print.push_back("nlp_scaling_max_gradient");
195 // NLP corrections
196 options_to_print.push_back("bound_relax_factor");
197 options_to_print.push_back("honor_original_bounds");
198 options_to_print.push_back("check_derivatives_for_naninf");
199 // Barrier parameter
200 options_to_print.push_back("mu_strategy");
201 options_to_print.push_back("mu_oracle");
202 options_to_print.push_back("quality_function_max_section_steps");
203 options_to_print.push_back("fixed_mu_oracle");
204 options_to_print.push_back("mu_init");
205 options_to_print.push_back("mu_max_fact");
206 options_to_print.push_back("mu_max");
207 options_to_print.push_back("mu_min");
208 options_to_print.push_back("mu_linear_decrease_factor");
209 options_to_print.push_back("mu_superlinear_decrease_power");
210 //options_to_print.push_back("corrector_type");
211 // Initialization
212 options_to_print.push_back("bound_frac");
213 options_to_print.push_back("bound_push");
214 options_to_print.push_back("bound_mult_init_val");
215 options_to_print.push_back("constr_mult_init_max");
216 options_to_print.push_back("bound_mult_init_val");
217 // Warm start
218 options_to_print.push_back("warm_start_init_point");
219 options_to_print.push_back("warm_start_bound_push");
220 options_to_print.push_back("warm_start_bound_frac");
221 options_to_print.push_back("warm_start_mult_bound_push");
222 options_to_print.push_back("warm_start_mult_init_max");
223 // Multiplier updates
224 options_to_print.push_back("alpha_for_y");
225 options_to_print.push_back("recalc_y");
226 options_to_print.push_back("recalc_y_feas_tol");
227 // Line search
228 options_to_print.push_back("max_soc");
229 options_to_print.push_back("watchdog_shortened_iter_trigger");
230 options_to_print.push_back("watchdog_trial_iter_max");
231 // Restoration phase
232 options_to_print.push_back("expect_infeasible_problem");
233 options_to_print.push_back("expect_infeasible_problem_ctol");
234 options_to_print.push_back("start_with_resto");
235 options_to_print.push_back("soft_resto_pderror_reduction_factor");
236 options_to_print.push_back("required_infeasibility_reduction");
237 options_to_print.push_back("bound_mult_reset_threshold");
238 options_to_print.push_back("constr_mult_reset_threshold");
239 options_to_print.push_back("evaluate_orig_obj_at_resto_trial");
240 // Linear solver
241 options_to_print.push_back("linear_solver");
242 options_to_print.push_back("linear_system_scaling");
243 options_to_print.push_back("linear_scaling_on_demand");
244 options_to_print.push_back("max_refinement_steps");
245 options_to_print.push_back("min_refinement_steps");
246 // Hessian perturbation
247 options_to_print.push_back("max_hessian_perturbation");
248 options_to_print.push_back("min_hessian_perturbation");
249 options_to_print.push_back("first_hessian_perturbation");
250 options_to_print.push_back("perturb_inc_fact_first");
251 options_to_print.push_back("perturb_inc_fact");
252 options_to_print.push_back("perturb_dec_fact");
253 options_to_print.push_back("jacobian_regularization_value");
254 // Quasi-Newton
255 options_to_print.push_back("hessian_approximation");
256 options_to_print.push_back("limited_memory_max_history");
257 options_to_print.push_back("limited_memory_max_skipping");
258 // Derivative test
259 options_to_print.push_back("derivative_test");
260 options_to_print.push_back("derivative_test_perturbation");
261 options_to_print.push_back("derivative_test_tol");
262 options_to_print.push_back("derivative_test_print_all");
263
264 // Special linear solver
265 #ifdef HAVE_MA27
266
267 options_to_print.push_back("ma27_pivtol");
268 options_to_print.push_back("ma27_pivtolmax");
269 options_to_print.push_back("ma27_liw_init_factor");
270 options_to_print.push_back("ma27_la_init_factor");
271 options_to_print.push_back("ma27_meminc_factor");
272 #endif
273
274 #ifdef HAVE_MA57
275
276 options_to_print.push_back("ma57_pivtol");
277 options_to_print.push_back("ma57_pivtolmax");
278 options_to_print.push_back("ma57_pre_alloc");
279 #endif
280
281 #ifdef HAVE_PARDISO
282
283 options_to_print.push_back("pardiso_matching_strategy");
284 options_to_print.push_back("pardiso_out_of_core_power");
285 #endif
286
287 #ifdef HAVE_WSMP
288
289 options_to_print.push_back("wsmp_num_threads");
290 options_to_print.push_back("wsmp_ordering_option");
291 options_to_print.push_back("wsmp_pivtol");
292 options_to_print.push_back("wsmp_pivtolmax");
293 options_to_print.push_back("wsmp_scaling");
294 #endif
295
296 reg_options_->OutputLatexOptionDocumentation(*jnlst_, options_to_print);
297 }
298 else {
299 std::list<std::string> categories;
300 categories.push_back("Output");
301 /*categories.push_back("Main Algorithm");*/
302 categories.push_back("Convergence");
303 categories.push_back("NLP Scaling");
304 categories.push_back("Barrier Parameter Update");
305 categories.push_back("Line Search");
306 categories.push_back("Initialization");
307 categories.push_back("Warm Start");
308 categories.push_back("Linear Solver");
309 categories.push_back("Step Calculation");
310 categories.push_back("Restoration Phase");
311 categories.push_back("NLP");
312 categories.push_back("Derivative Checker");
313 categories.push_back("Hessian Approximation");
314 #ifdef HAVE_MA27
315
316 categories.push_back("MA27 Linear Solver");
317 #endif
318 #ifdef HAVE_MA57
319
320 categories.push_back("MA57 Linear Solver");
321 #endif
322 #ifdef HAVE_PARDISO
323
324 categories.push_back("Pardiso Linear Solver");
325 #endif
326 #ifdef HAVE_WSMP
327
328 categories.push_back("WSMP Linear Solver");
329 #endif
330
331 categories.push_back("Uncategorized");
332 //categories.push_back("Undocumented Options");
333 reg_options_->OutputOptionDocumentation(*jnlst_, categories);
334 }
335 }
336
337 }
338 catch(OPTION_INVALID& exc) {
339 exc.ReportException(*jnlst_, J_ERROR);
340 exit(-1);
341 }
342 catch(IpoptException& exc) {
343 exc.ReportException(*jnlst_, J_ERROR);
344 exit(-1);
345 }
346 catch(std::bad_alloc) {
347 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Not enough memory.\n");
348 exit(-1);
349 }
350 }
351
~IpoptApplication()352 IpoptApplication::~IpoptApplication()
353 {
354 DBG_START_METH("IpoptApplication::~IpoptApplication()",
355 dbg_verbosity);
356 }
357
RegisterOptions(SmartPtr<RegisteredOptions> roptions)358 void IpoptApplication::RegisterOptions(SmartPtr<RegisteredOptions> roptions)
359 {
360 roptions->SetRegisteringCategory("Output");
361 roptions->AddBoundedIntegerOption(
362 "print_level",
363 "Output verbosity level.",
364 0, J_LAST_LEVEL-1, J_ITERSUMMARY,
365 "Sets the default verbosity level for console output. The "
366 "larger this value the more detailed is the output.");
367
368 roptions->AddStringOption1(
369 "output_file",
370 "File name of desired output file (leave unset for no file output).",
371 "",
372 "*", "Any acceptable standard file name",
373 "NOTE: This option only works when read from the ipopt.opt options file! "
374 "An output file with this name will be written (leave unset for no "
375 "file output). The verbosity level is by default set to \"print_level\", "
376 "but can be overridden with \"file_print_level\". The file name is "
377 "changed to use only small letters.");
378 roptions->AddBoundedIntegerOption(
379 "file_print_level",
380 "Verbosity level for output file.",
381 0, J_LAST_LEVEL-1, J_ITERSUMMARY,
382 "NOTE: This option only works when read from the ipopt.opt options file! "
383 "Determines the verbosity level for the file specified by "
384 "\"output_file\". By default it is the same as \"print_level\".");
385 roptions->AddStringOption2(
386 "print_user_options",
387 "Print all options set by the user.",
388 "no",
389 "no", "don't print options",
390 "yes", "print options",
391 "If selected, the algorithm will print the list of all options set by "
392 "the user including their values and whether they have been used.");
393 roptions->AddStringOption2(
394 "print_options_documentation",
395 "Switch to print all algorithmic options.",
396 "no",
397 "no", "don't print list",
398 "yes", "print list",
399 "If selected, the algorithm will print the list of all available "
400 "algorithmic options with some documentation before solving the "
401 "optimization problem.");
402
403 #ifdef IP_DEBUG
404
405 roptions->AddBoundedIntegerOption(
406 "debug_print_level",
407 "Verbosity level for debug file.",
408 0, J_LAST_LEVEL-1, J_ITERSUMMARY,
409 "This Ipopt library has been compiled in debug mode, and a file "
410 "\"debug.out\" is produced for every run. This option determines "
411 "the verbosity level for this file. By default it is the same as "
412 "\"print_level\".");
413
414 #endif
415
416 roptions->AddStringOption2(
417 "print_timing_statistics",
418 "Switch to print timing statistics.",
419 "no",
420 "no", "don't print statistics",
421 "yes", "print all timing statistics",
422 "If selected, the program will print the CPU usage (user time) for "
423 "selected tasks.");
424
425 roptions->SetRegisteringCategory("Undocumented");
426 roptions->AddStringOption2(
427 "print_options_latex_mode",
428 "Undocumented", "no",
429 "no", "Undocumented",
430 "yes", "Undocumented",
431 "Undocumented"
432 );
433 }
434
435 ApplicationReturnStatus
OptimizeTNLP(const SmartPtr<TNLP> & tnlp)436 IpoptApplication::OptimizeTNLP(const SmartPtr<TNLP>& tnlp)
437 {
438 nlp_adapter_ = new TNLPAdapter(GetRawPtr(tnlp), ConstPtr(jnlst_));
439
440 return OptimizeNLP(nlp_adapter_);
441 }
442
443 ApplicationReturnStatus
ReOptimizeTNLP(const SmartPtr<TNLP> & tnlp)444 IpoptApplication::ReOptimizeTNLP(const SmartPtr<TNLP>& tnlp)
445 {
446 ASSERT_EXCEPTION(IsValid(nlp_adapter_), INVALID_WARMSTART,
447 "ReOptimizeTNLP called before OptimizeTNLP.");
448 TNLPAdapter* adapter =
449 dynamic_cast<TNLPAdapter*> (GetRawPtr(nlp_adapter_));
450 DBG_ASSERT(adapter);
451 ASSERT_EXCEPTION(adapter->tnlp()==tnlp, INVALID_WARMSTART,
452 "ReOptimizeTNLP called for different TNLP.")
453
454 return ReOptimizeNLP(nlp_adapter_);
455 }
456
457 ApplicationReturnStatus
OptimizeNLP(const SmartPtr<NLP> & nlp,SmartPtr<AlgorithmBuilder> alg_builder)458 IpoptApplication::OptimizeNLP(const SmartPtr<NLP>& nlp, SmartPtr<AlgorithmBuilder> alg_builder)
459 {
460 ApplicationReturnStatus retValue = Internal_Error;
461
462 // Prepare internal data structures of the algorithm
463 try {
464
465 if (IsNull(alg_builder)) {
466 alg_builder = new AlgorithmBuilder();
467 }
468
469 alg_builder->BuildIpoptObjects(*jnlst_, *options_, "", nlp,
470 ip_nlp_, ip_data_, ip_cq_);
471
472 alg_ = GetRawPtr(alg_builder->BuildBasicAlgorithm(*jnlst_, *options_, ""));
473
474 // finally call the optimization
475 retValue = call_optimize();
476 }
477 catch(OPTION_INVALID& exc) {
478 exc.ReportException(*jnlst_, J_ERROR);
479 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Invalid option encountered.\n");
480 retValue = Invalid_Option;
481 }
482 catch(IpoptException& exc) {
483 exc.ReportException(*jnlst_, J_ERROR);
484 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Some uncaught Ipopt exception encountered.\n");
485 retValue = Unrecoverable_Exception;
486 }
487 catch(std::bad_alloc) {
488 retValue = Insufficient_Memory;
489 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Not enough memory.\n");
490 }
491
492 jnlst_->FlushBuffer();
493
494 return retValue;
495 }
496
497 ApplicationReturnStatus
ReOptimizeNLP(const SmartPtr<NLP> & nlp)498 IpoptApplication::ReOptimizeNLP(const SmartPtr<NLP>& nlp)
499 {
500 ASSERT_EXCEPTION(IsValid(alg_), INVALID_WARMSTART,
501 "ReOptimizeNLP called before OptimizeNLP.");
502 OrigIpoptNLP* orig_nlp =
503 dynamic_cast<OrigIpoptNLP*> (GetRawPtr(ip_nlp_));
504 DBG_ASSERT(orig_nlp);
505 ASSERT_EXCEPTION(orig_nlp->nlp()==nlp, INVALID_WARMSTART,
506 "ReOptimizeTNLP called for different NLP.")
507
508 return call_optimize();
509 }
510
511
call_optimize()512 ApplicationReturnStatus IpoptApplication::call_optimize()
513 {
514 // Reset the print-level for the screen output
515 Index ivalue;
516 options_->GetIntegerValue("print_level", ivalue, "");
517 EJournalLevel print_level = (EJournalLevel)ivalue;
518 SmartPtr<Journal> stdout_jrnl = jnlst_->GetJournal("console");
519 if (IsValid(stdout_jrnl)) {
520 // Set printlevel for stdout
521 stdout_jrnl->SetAllPrintLevels(print_level);
522 stdout_jrnl->SetPrintLevel(J_DBG, J_NONE);
523 }
524
525 statistics_ = NULL; /* delete old statistics */
526 // Reset Timing statistics
527 ip_data_->TimingStats().ResetTimes();
528
529 ApplicationReturnStatus retValue = Internal_Error;
530 try {
531 // Get the pointers to the real objects (need to do it that
532 // awkwardly since otherwise we would have to include so many
533 // things in IpoptApplication, which a user would have to
534 // include, too (SmartPtr doesn't work otherwise on AIX)
535 IpoptAlgorithm* p2alg = dynamic_cast<IpoptAlgorithm*> (GetRawPtr(alg_));
536 IpoptData* p2ip_data = dynamic_cast<IpoptData*> (GetRawPtr(ip_data_));
537 OrigIpoptNLP* p2ip_nlp = dynamic_cast<OrigIpoptNLP*> (GetRawPtr(ip_nlp_));
538 IpoptCalculatedQuantities* p2ip_cq = dynamic_cast<IpoptCalculatedQuantities*> (GetRawPtr(ip_cq_));
539 // Set up the algorithm
540 p2alg->Initialize(*jnlst_, *p2ip_nlp, *p2ip_data, *p2ip_cq,
541 *options_, "");
542
543 // Process the options used below
544 bool print_timing_statistics;
545 options_->GetBoolValue("print_timing_statistics",
546 print_timing_statistics, "");
547
548 // If selected, print the user options
549 bool print_user_options;
550 options_->GetBoolValue("print_user_options", print_user_options, "");
551 if (print_user_options) {
552 std::string liststr;
553 options_->PrintUserOptions(liststr);
554 jnlst_->Printf(J_ERROR, J_MAIN, "\nList of user-set options:\n\n%s", liststr.c_str());
555 }
556
557 if( jnlst_->ProduceOutput(J_DETAILED, J_MAIN) ) {
558 // Print out the options (including the number of times they were used
559 std::string liststr;
560 options_->PrintList(liststr);
561 // TODO UNCOMMENT WHEN DONE TESTING
562 /*
563 vatest( stdout, "\nList of user-set options:\n\n%s", liststr.c_str());
564 void vatest( FILE *, const char *, ... );
565
566 printf("strlen user-set options= %d\n",strlen(liststr.c_str()) );
567 printf("\nList of user-set options:\n\n%s", liststr.c_str());
568 */
569 jnlst_->Printf(J_DETAILED, J_MAIN, "\nList of options:\n\n%s", liststr.c_str());
570 }
571
572
573 // Run the algorithm
574 SolverReturn status = p2alg->Optimize();
575
576 // Since all the output below doesn't make any sense in this
577 // case, we rethrow the TOO_FEW_DOF exception here
578 ASSERT_EXCEPTION(status != TOO_FEW_DEGREES_OF_FREEDOM, TOO_FEW_DOF,
579 "Too few degrees of freedom (rethrown)!");
580
581 jnlst_->Printf(J_SUMMARY, J_SOLUTION,
582 "\nNumber of Iterations....: %d\n",
583 p2ip_data->iter_count());
584
585 if (status!=INVALID_NUMBER_DETECTED) {
586 jnlst_->Printf(J_SUMMARY, J_SOLUTION,
587 "\n (scaled) (unscaled)\n");
588 jnlst_->Printf(J_SUMMARY, J_SOLUTION,
589 "Objective...............: %24.16e %24.16e\n",
590 p2ip_cq->curr_f(),
591 p2ip_cq->unscaled_curr_f());
592 jnlst_->Printf(J_SUMMARY, J_SOLUTION,
593 "Dual infeasibility......: %24.16e %24.16e\n",
594 p2ip_cq->curr_dual_infeasibility(NORM_MAX),
595 p2ip_cq->unscaled_curr_dual_infeasibility(NORM_MAX));
596 jnlst_->Printf(J_SUMMARY, J_SOLUTION,
597 "Constraint violation....: %24.16e %24.16e\n",
598 p2ip_cq->curr_nlp_constraint_violation(NORM_MAX),
599 p2ip_cq->unscaled_curr_nlp_constraint_violation(NORM_MAX));
600 jnlst_->Printf(J_SUMMARY, J_SOLUTION,
601 "Complementarity.........: %24.16e %24.16e\n",
602 p2ip_cq->curr_complementarity(0., NORM_MAX),
603 p2ip_cq->unscaled_curr_complementarity(0., NORM_MAX));
604 jnlst_->Printf(J_SUMMARY, J_SOLUTION,
605 "Overall NLP error.......: %24.16e %24.16e\n\n",
606 p2ip_cq->curr_nlp_error(),
607 p2ip_cq->unscaled_curr_nlp_error());
608 }
609
610 p2ip_data->curr()->x()->Print(*jnlst_, J_VECTOR, J_SOLUTION, "x");
611 p2ip_data->curr()->y_c()->Print(*jnlst_, J_VECTOR, J_SOLUTION, "y_c");
612 p2ip_data->curr()->y_d()->Print(*jnlst_, J_VECTOR, J_SOLUTION, "y_d");
613 p2ip_data->curr()->z_L()->Print(*jnlst_, J_VECTOR, J_SOLUTION, "z_L");
614 p2ip_data->curr()->z_U()->Print(*jnlst_, J_VECTOR, J_SOLUTION, "z_U");
615 p2ip_data->curr()->v_L()->Print(*jnlst_, J_VECTOR, J_SOLUTION, "v_L");
616 p2ip_data->curr()->v_U()->Print(*jnlst_, J_VECTOR, J_SOLUTION, "v_U");
617
618 if (status==LOCAL_INFEASIBILITY) {
619 p2ip_cq->curr_c()->Print(*jnlst_, J_VECTOR, J_SOLUTION, "curr_c");
620 p2ip_cq->curr_d_minus_s()->Print(*jnlst_, J_VECTOR, J_SOLUTION,
621 "curr_d_minus_s");
622 }
623
624 jnlst_->Printf(J_SUMMARY, J_STATISTICS,
625 "\nNumber of objective function evaluations = %d\n",
626 p2ip_nlp->f_evals());
627 jnlst_->Printf(J_SUMMARY, J_STATISTICS,
628 "Number of objective gradient evaluations = %d\n",
629 p2ip_nlp->grad_f_evals());
630 jnlst_->Printf(J_SUMMARY, J_STATISTICS,
631 "Number of equality constraint evaluations = %d\n",
632 p2ip_nlp->c_evals());
633 jnlst_->Printf(J_SUMMARY, J_STATISTICS,
634 "Number of inequality constraint evaluations = %d\n",
635 p2ip_nlp->d_evals());
636 jnlst_->Printf(J_SUMMARY, J_STATISTICS,
637 "Number of equality constraint Jacobian evaluations = %d\n",
638 p2ip_nlp->jac_c_evals());
639 jnlst_->Printf(J_SUMMARY, J_STATISTICS,
640 "Number of inequality constraint Jacobian evaluations = %d\n",
641 p2ip_nlp->jac_d_evals());
642 jnlst_->Printf(J_SUMMARY, J_STATISTICS,
643 "Number of Lagrangian Hessian evaluations = %d\n",
644 p2ip_nlp->h_evals());
645 Number time_overall_alg = p2ip_data->TimingStats().OverallAlgorithm().TotalTime();
646 Number time_funcs = p2ip_nlp->TotalFunctionEvaluationCPUTime();
647 jnlst_->Printf(J_SUMMARY, J_STATISTICS,
648 "Total CPU secs in IPOPT (w/o function evaluations) = %10.3f\n",
649 time_overall_alg-time_funcs);
650 jnlst_->Printf(J_SUMMARY, J_STATISTICS,
651 "Total CPU secs in NLP function evaluations = %10.3f\n",
652 time_funcs);
653
654 // Write timing statistics information
655 if (print_timing_statistics) {
656 jnlst_->Printf(J_SUMMARY, J_TIMING_STATISTICS,
657 "\n\nTiming Statistics:\n\n");
658 p2ip_data->TimingStats().PrintAllTimingStatistics(*jnlst_, J_SUMMARY,
659 J_TIMING_STATISTICS);
660 p2ip_nlp->PrintTimingStatistics(*jnlst_, J_SUMMARY,
661 J_TIMING_STATISTICS);
662 }
663
664 // Write EXIT message
665 if (status == SUCCESS) {
666 retValue = Solve_Succeeded;
667 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Optimal Solution Found.\n");
668 }
669 else if (status == MAXITER_EXCEEDED) {
670 retValue = Maximum_Iterations_Exceeded;
671 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Maximum Number of Iterations Exceeded.\n");
672 }
673 else if (status == STOP_AT_TINY_STEP) {
674 retValue = Search_Direction_Becomes_Too_Small;
675 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Search Direction is becoming Too Small.\n");
676 }
677 else if (status == STOP_AT_ACCEPTABLE_POINT) {
678 retValue = Solved_To_Acceptable_Level;
679 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Solved To Acceptable Level.\n");
680 }
681 else if (status == DIVERGING_ITERATES) {
682 retValue = Diverging_Iterates;
683 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Iterates divering; problem might be unbounded.\n");
684 }
685 else if (status == RESTORATION_FAILURE) {
686 retValue = Restoration_Failed;
687 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Restoration Failed!\n");
688 }
689 else if (status == ERROR_IN_STEP_COMPUTATION) {
690 retValue = Error_In_Step_Computation;
691 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Error in step computation (regularization becomes too large?)!\n");
692 }
693 else if (status == LOCAL_INFEASIBILITY) {
694 retValue = Infeasible_Problem_Detected;
695 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Converged to a point of local infeasibility. Problem may be infeasible.\n");
696 }
697 else if (status == USER_REQUESTED_STOP) {
698 retValue = User_Requested_Stop;
699 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Stopping optimization at current point as requested by user.\n");
700 }
701 else if (status == INVALID_NUMBER_DETECTED) {
702 retValue = Invalid_Number_Detected;
703 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Invalid number in NLP function or derivative detected.\n");
704 }
705 else {
706 retValue = Internal_Error;
707 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: INTERNAL ERROR: Unknown SolverReturn value - Notify IPOPT Authors.\n");
708 return retValue;
709 }
710 p2ip_nlp->FinalizeSolution(status,
711 *p2ip_data->curr()->x(),
712 *p2ip_data->curr()->z_L(),
713 *p2ip_data->curr()->z_U(),
714 *p2ip_cq->curr_c(), *p2ip_cq->curr_d(),
715 *p2ip_data->curr()->y_c(),
716 *p2ip_data->curr()->y_d(),
717 p2ip_cq->curr_f());
718
719 if (status!=INVALID_NUMBER_DETECTED) {
720 // Create a SolveStatistics object
721 statistics_ = new SolveStatistics(p2ip_nlp, p2ip_data, p2ip_cq);
722 }
723 }
724 catch(TOO_FEW_DOF& exc) {
725 exc.ReportException(*jnlst_, J_MOREDETAILED);
726 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Problem has too few degrees of freedom.\n");
727 retValue = Not_Enough_Degrees_Of_Freedom;
728 }
729 catch(OPTION_INVALID& exc) {
730 exc.ReportException(*jnlst_, J_MOREDETAILED);
731 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Invalid option encountered.\n");
732 retValue = Invalid_Option;
733 }
734 catch(IpoptException& exc) {
735 exc.ReportException(*jnlst_, J_ERROR);
736 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Some uncaught Ipopt exception encountered.\n");
737 retValue = Unrecoverable_Exception;
738 }
739 catch(std::bad_alloc) {
740 retValue = Insufficient_Memory;
741 jnlst_->Printf(J_SUMMARY, J_MAIN, "\nEXIT: Not enough memory.\n");
742 }
743
744 jnlst_->FlushBuffer();
745
746 return retValue;
747 }
vatest(FILE * fp,const char * format,...)748 static void vatest( FILE *fp, const char *format, ... ) {
749 va_list ap;
750 va_start( ap, format );
751 vfprintf( fp, format, ap );
752 va_end(ap);
753 }
754
OpenOutputFile(std::string file_name,EJournalLevel print_level)755 bool IpoptApplication::OpenOutputFile(std::string file_name,
756 EJournalLevel print_level)
757 {
758 SmartPtr<Journal> file_jrnl = jnlst_->GetJournal("OutputFile:"+file_name);
759
760 if (IsNull(file_jrnl)) {
761 file_jrnl = jnlst_->AddFileJournal("OutputFile:"+file_name,
762 file_name.c_str(),
763 print_level);
764 }
765
766 file_jrnl->SetPrintLevel(J_DBG, J_NONE);
767
768 return true;
769 }
770
RegisterAllOptions(const SmartPtr<RegisteredOptions> & roptions)771 void IpoptApplication::RegisterAllOptions(const SmartPtr<RegisteredOptions>& roptions)
772 {
773 RegisterOptions_Interfaces(roptions);
774 RegisterOptions_Algorithm(roptions);
775 RegisterOptions_LinearSolvers(roptions);
776 }
777
Statistics()778 SmartPtr<SolveStatistics> IpoptApplication::Statistics()
779 {
780 return statistics_;
781 }
782
783 } // namespace Ipopt
784