MoochoPack : Framework for Large-Scale Optimization Algorithms  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
MoochoPack_NLPAlgoConfigMamaJama.cpp
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
5 // Copyright (2003) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
38 //
39 // ***********************************************************************
40 // @HEADER
41 
42 #include <assert.h>
43 
44 #include <sstream>
45 #include <typeinfo>
46 #include <iostream>
47 
48 #include "MoochoPack_NLPAlgoConfigMamaJama.hpp"
49 #include "MoochoPack_NLPAlgo.hpp"
50 #include "MoochoPack_NLPAlgoContainer.hpp"
51 #include "IterationPack_AlgorithmSetOptions.hpp"
52 #include "AbstractLinAlgPack_MatrixSymPosDefCholFactor.hpp" // rHL
53 //#include "ConstrainedOptPack_MatrixSymPosDefInvCholFactor.hpp" // .
54 #include "ConstrainedOptPack_MatrixSymPosDefLBFGS.hpp" // .
55 //#include "ConstrainedOptPack_MatrixHessianSuperBasicInitDiagonal.hpp/ | rHL (super basics)
56 //#include "AbstractLinAlgPack/src/AbstractLinAlgPack_MatrixSymDiagStd.hpp" // |
57 
58 #include "ConstrainedOptPack_VariableBoundsTester.hpp"
59 
60 #include "NLPInterfacePack_NLPDirect.hpp"
61 
62 #include "NLPInterfacePack_CalcFiniteDiffProd.hpp"
63 #include "NLPInterfacePack_NLPVarReductPerm.hpp"
64 
65 // line search
66 #include "ConstrainedOptPack_DirectLineSearchArmQuad_Strategy.hpp"
67 #include "ConstrainedOptPack_DirectLineSearchArmQuad_StrategySetOptions.hpp"
68 #include "ConstrainedOptPack_MeritFuncNLPL1.hpp"
69 #include "ConstrainedOptPack_MeritFuncNLPModL1.hpp"
70 
71 // Basis permutations and direct sparse solvers
72 #ifndef MOOCHO_NO_BASIS_PERM_DIRECT_SOLVERS
73 #include "ConstrainedOptPack_DecompositionSystemVarReductPerm.hpp"
74 #endif
75 
76 #include "ConstrainedOptPack_QPSolverRelaxedTester.hpp"
77 #include "ConstrainedOptPack_QPSolverRelaxedTesterSetOptions.hpp"
78 #include "ConstrainedOptPack_QPSolverRelaxedQPSchur.hpp"
79 #include "ConstrainedOptPack_QPSolverRelaxedQPSchurSetOptions.hpp"
80 #include "ConstrainedOptPack_QPSchurInitKKTSystemHessianFull.hpp"
81 //#include "ConstrainedOptPack_QPSchurInitKKTSystemHessianSuperBasic.hpp"
82 #ifdef CONSTRAINED_OPTIMIZATION_PACK_USE_QPKWIK
83 #include "ConstrainedOptPack_QPSolverRelaxedQPKWIK.hpp"
84 #endif
85 #ifdef CONSTRAINED_OPTIMIZATION_PACK_USE_QPOPT
86 //#include "ConstrainedOptPack_QPSolverRelaxedQPOPT.hpp"
87 #endif
88 
89 #include "MoochoPack_MoochoAlgorithmStepNames.hpp"
90 
91 /*
92 #include "MoochoPack_EvalNewPointStd_StepSetOptions.hpp"
93 #include "MoochoPack_EvalNewPointTailoredApproach_StepSetOptions.hpp"
94 #include "MoochoPack_EvalNewPointTailoredApproachCoordinate_Step.hpp"
95 #include "MoochoPack_EvalNewPointTailoredApproachOrthogonal_Step.hpp"
96 */
97 
98 #include "MoochoPack_ReducedGradientStd_Step.hpp"
99 #include "MoochoPack_InitFinDiffReducedHessian_Step.hpp"
100 #include "MoochoPack_InitFinDiffReducedHessian_StepSetOptions.hpp"
101 #include "MoochoPack_ReducedHessianSerialization_Step.hpp"
102 #include "MoochoPack_ReducedHessianSerialization_StepSetOptions.hpp"
103 #include "MoochoPack_ReducedHessianSecantUpdateStd_Step.hpp"
104 #include "MoochoPack_ReducedHessianSecantUpdateBFGSFull_Strategy.hpp"
105 
106 
107 //#include "MoochoPack_ReducedHessianSecantUpdateBFGSProjected_Strategy.hpp"
108 //#include "MoochoPack_ReducedHessianSecantUpdateBFGSProjected_StrategySetOptions.hpp"
109 //#include "MoochoPack_ReducedHessianSecantUpdateLPBFGS_Strategy.hpp"
110 //#include "MoochoPack_ReducedHessianSecantUpdateLPBFGS_StrategySetOptions.hpp"
111 #include "MoochoPack_BFGSUpdate_Strategy.hpp"
112 #include "MoochoPack_BFGSUpdate_StrategySetOptions.hpp"
113 #include "MoochoPack_QuasiNormalStepStd_Step.hpp"
114 #include "MoochoPack_CheckDescentQuasiNormalStep_Step.hpp"
115 #include "MoochoPack_CheckDecompositionFromPy_Step.hpp"
116 #include "MoochoPack_CheckDecompositionFromRPy_Step.hpp"
117 #include "MoochoPack_TangentialStepWithoutBounds_Step.hpp"
118 #include "MoochoPack_TangentialStepWithInequStd_Step.hpp"
119 #include "MoochoPack_TangentialStepWithInequStd_StepSetOptions.hpp"
120 #include "MoochoPack_SetDBoundsStd_AddedStep.hpp"
121 #include "MoochoPack_QPFailureReinitReducedHessian_Step.hpp"
122 #include "MoochoPack_CalcDFromYPYZPZ_Step.hpp"
123 #include "MoochoPack_CalcDFromYPY_Step.hpp"
124 #include "MoochoPack_CalcDFromZPZ_Step.hpp"
125 #include "MoochoPack_LineSearchFailureNewDecompositionSelection_Step.hpp"
126 #include "MoochoPack_LineSearchFilter_Step.hpp"
127 #include "MoochoPack_LineSearchFilter_StepSetOptions.hpp"
128 #include "MoochoPack_LineSearchFullStep_Step.hpp"
129 #include "MoochoPack_LineSearchDirect_Step.hpp"
130 #include "MoochoPack_LineSearchNLE_Step.hpp"
131 //#include "MoochoPack_LineSearch2ndOrderCorrect_Step.hpp"
132 //#include "MoochoPack_LineSearch2ndOrderCorrect_StepSetOptions.hpp"
133 //#include "MoochoPack_FeasibilityStepReducedStd_Strategy.hpp"
134 //#include "MoochoPack_FeasibilityStepReducedStd_StrategySetOptions.hpp"
135 //#include "MoochoPack_QuasiRangeSpaceStepStd_Strategy.hpp"
136 //#include "MoochoPack_QuasiRangeSpaceStepTailoredApproach_Strategy.hpp"
137 //#include "MoochoPack_LineSearchWatchDog_Step.hpp"
138 //#include "MoochoPack_LineSearchWatchDog_StepSetOptions.hpp"
139 //#include "MoochoPack_LineSearchFullStepAfterKIter_Step.hpp"
140 //#include "MoochoPack_CalcLambdaIndepStd_AddedStep.hpp"
141 #include "MoochoPack_CalcReducedGradLagrangianStd_AddedStep.hpp"
142 #include "MoochoPack_CheckConvergenceStd_AddedStep.hpp"
143 #include "MoochoPack_CheckConvergenceStd_Strategy.hpp"
144 #include "MoochoPack_CheckSkipBFGSUpdateStd_StepSetOptions.hpp"
145 #include "MoochoPack_MeritFunc_DummyUpdate_Step.hpp"
146 #include "MoochoPack_MeritFunc_PenaltyParamUpdate_AddedStepSetOptions.hpp"
147 #include "MoochoPack_MeritFunc_PenaltyParamUpdateMultFree_AddedStep.hpp"
148 //#include "MoochoPack_MeritFunc_PenaltyParamUpdateWithMult_AddedStep.hpp"
149 //#include "MoochoPack_MeritFunc_PenaltyParamsUpdateWithMult_AddedStep.hpp"
150 //#include "MoochoPack_MeritFunc_ModifiedL1LargerSteps_AddedStep.hpp"
151 //#include "MoochoPack_MeritFunc_ModifiedL1LargerSteps_AddedStepSetOptions.hpp"
152 //#include "MoochoPack_ActSetStats_AddedStep.hpp"
153 //#include "MoochoPack_NumFixedDepIndep_AddedStep.hpp"
154 
155 #include "MoochoPack_act_set_stats.hpp"
156 #include "MoochoPack_qp_solver_stats.hpp"
157 #include "MoochoPack_quasi_newton_stats.hpp"
158 
159 //#include "AbstractLinAlgPack_sparse_bounds.hpp"
160 
161 // Misc utilities
162 #include "Teuchos_AbstractFactoryStd.hpp"
163 #include "Teuchos_dyn_cast.hpp"
164 #include "ReleaseResource_ref_count_ptr.hpp"
165 #include "Teuchos_Assert.hpp"
166 
167 // Stuff to read in options
168 #include "OptionsFromStreamPack_StringToIntMap.hpp"
169 #include "OptionsFromStreamPack_StringToBool.hpp"
170 
171 // Stuff for exact reduced hessian
172 //#include "MoochoPack_ReducedHessianExactStd_Step.hpp"
173 //#include "MoochoPack_CrossTermExactStd_Step.hpp"
174 //#include "MoochoPack_DampenCrossTermStd_Step.hpp"
175 
176 namespace {
177  const double INF_BASIS_COND_CHANGE_FRAC = 1e+20;
178 }
179 
180 namespace MoochoPack {
181 
182 //
183 // Here is where we define the default values for the algorithm. These
184 // should agree with what are in the Moocho.opt.NLPAlgoConfigMamaJama file.
185 //
186 NLPAlgoConfigMamaJama::SOptionValues::SOptionValues()
187  :max_basis_cond_change_frac_(-1.0)
188  ,exact_reduced_hessian_(false)
189  ,quasi_newton_(QN_AUTO)
190  ,num_lbfgs_updates_stored_(-1)
191  ,lbfgs_auto_scaling_(true)
192  ,hessian_initialization_(INIT_HESS_AUTO)
193  ,qp_solver_type_(QP_AUTO)
194  ,reinit_hessian_on_qp_fail_(true)
195  ,line_search_method_(LINE_SEARCH_AUTO)
196  ,merit_function_type_(MERIT_FUNC_AUTO)
197  ,l1_penalty_param_update_(L1_PENALTY_PARAM_AUTO)
198  ,full_steps_after_k_(-1)
199  ,max_pz_norm_(-1.0)
200  ,num_pz_damp_iters_(0)
201 {}
202 
204 {}
205 
207 {}
208 
209 // overridden from NLPAlgoConfig
210 
212 {
213  options_ = options;
214  decomp_sys_step_builder_.set_options(options);
215 }
216 
219 {
220  return options_;
221 }
222 
224  NLPAlgoContainer *algo_cntr
225  ,std::ostream *trase_out
226  )
227 {
228  using Teuchos::RCP;
229  using Teuchos::dyn_cast;
230 
231  if(trase_out) {
232  *trase_out
233  << std::endl
234  << "*****************************************************************\n"
235  << "*** NLPAlgoConfigMamaJama Configuration ***\n"
236  << "*** ***\n"
237  << "*** Here, summary information about how the algorithm is ***\n"
238  << "*** configured is printed so that the user can see how the ***\n"
239  << "*** properties of the NLP and the set options influence ***\n"
240  << "*** how an algorithm is configured. ***\n"
241  << "*****************************************************************\n";
242  }
243 
244  // ////////////////////////////////////////////////////////////
245  // A. ???
246 
247  // /////////////////////////////////////////////////////////////////////////
248  // B. Create an algo object, give to algo_cntr, then give algo_cntr to algo
249 
250  if(trase_out)
251  *trase_out << "\n*** Creating the NLPAlgo algo object ...\n";
252 
253  typedef Teuchos::RCP<NLPAlgo> algo_ptr_t;
254  algo_ptr_t algo = Teuchos::rcp(new NLPAlgo);
255  TEUCHOS_TEST_FOR_EXCEPTION(!algo.get(),std::runtime_error,"Error!");
256  if(options_.get()) {
258  opt_setter( algo.get() );
259  opt_setter.set_options( *options_ );
260  }
261  algo_cntr->set_algo(algo);
262  algo->set_algo_cntr(algo_cntr);
263 
264  // /////////////////////////////////////////////
265  // C. Configure algo
266 
267  // /////////////////////////////////////////////////////
268  // C.0 Set the nlp and track objects
269 
270  if(trase_out)
271  *trase_out << "\n*** Setting the NLP and track objects to the algo object ...\n";
272 
273  algo->set_nlp( algo_cntr->get_nlp().get() );
274  algo->set_track( algo_cntr->get_track() );
275 
276  // ////////////////////////////////////////////////
277  // Determine what the options are:
278 
279  // Readin the options
280  if(options_.get()) {
281  readin_options( *options_, &uov_, trase_out );
282  }
283  else {
284  if(trase_out) {
285  *trase_out
286  << "\n*** Warning, no OptionsFromStream object was set so a default set"
287  " of options will be used!\n";
288  }
289  }
290 
291  NLP &nlp = algo->nlp();
292  nlp.initialize(algo->algo_cntr().check_results());
293  // Get the dimensions of the NLP
294  const size_type
295  n = nlp.n(),
296  m = nlp.m(),
297  r = m, // ToDo: Compute this for real!
298  //dof = n - r,
299  nb = nlp.num_bounded_x();
300 
301  // Process the NLP
302  NLPFirstOrder *nlp_foi = NULL;
303  NLPSecondOrder *nlp_soi = NULL;
304  NLPDirect *nlp_fod = NULL;
305  bool tailored_approach = false;
306  decomp_sys_step_builder_.process_nlp_and_options(
307  trase_out, nlp
308  ,&nlp_foi, &nlp_soi, &nlp_fod, &tailored_approach
309  );
310 
311  const int max_dof_quasi_newton_dense
312  = decomp_sys_step_builder_.current_option_values().max_dof_quasi_newton_dense_;
313 
314  // //////////////////////////////////////////////////////
315  // C.1. Sort out the options
316 
317  if(trase_out)
318  *trase_out
319  << "\n*** Sorting out some of the options given input options ...\n";
320 
321  if( m ) {
322  if( tailored_approach ) {
323  // Change the options for the tailored approach.
324  if(trase_out) {
325  *trase_out
326  << "\nThis is a tailored approach NLP (NLPDirect) which forces the following options:\n"
327  << "merit_function_type = L1;\n"
328  << "l1_penalty_parameter_update = MULT_FREE;\n"
329  << "null_space_matrix = EXPLICIT;\n"
330  ;
331  }
332  cov_.merit_function_type_
333  = MERIT_FUNC_L1;
334  cov_.l1_penalty_param_update_
335  = L1_PENALTY_PARAM_MULT_FREE;
336  decomp_sys_step_builder_.current_option_values().null_space_matrix_type_
337  = DecompositionSystemStateStepBuilderStd::NULL_SPACE_MATRIX_EXPLICIT;
338  }
339 
340  if( !tailored_approach && uov_.merit_function_type_ != MERIT_FUNC_L1 ) {
341  if(trase_out) {
342  *trase_out
343  << "\nThe only merit function currently supported is:\n"
344  << "merit_function_type = L1;\n"
345  ;
346  }
347  cov_.merit_function_type_ = MERIT_FUNC_L1;
348  }
349  }
350  else {
351  if( uov_.line_search_method_ == LINE_SEARCH_NONE ) {
352  if(trase_out) {
353  *trase_out
354  << "\nThere are no equality constraints (m == 0) and line_search_method==NONE so set the following options:\n"
355  << "line_search_method = NONE;\n"
356  << "merit_function_type = L1;\n"
357  ;
358  }
359  cov_.line_search_method_ = LINE_SEARCH_NONE;
360  cov_.merit_function_type_ = MERIT_FUNC_L1;
361  }
362  else {
363  if(trase_out) {
364  *trase_out
365  << "\nThere are no equality constraints (m == 0) and line_search_method==AUTO so set the following options:\n"
366  << "line_search_method = DIRECT;\n"
367  << "merit_function_type = L1;\n"
368  ;
369  }
370  cov_.line_search_method_ = LINE_SEARCH_DIRECT;
371  cov_.merit_function_type_ = MERIT_FUNC_L1;
372  }
373  }
374 
375  // Decide what type of quasi-newton update to use
376  switch( uov_.quasi_newton_ ) {
377  case QN_AUTO: {
378  if(trase_out)
379  *trase_out
380  << "\nquasi_newton == AUTO:"
381  << "\nnlp.num_bounded_x() == " << nlp.num_bounded_x() << ":\n";
382  if( n - r > max_dof_quasi_newton_dense ) {
383  if(trase_out)
384  *trase_out
385  << "n-r = " << n-r << " > max_dof_quasi_newton_dense = "
386  << max_dof_quasi_newton_dense << ":\n"
387  << "setting quasi_newton == LBFGS\n";
388  cov_.quasi_newton_ = QN_LBFGS;
389  }
390  else {
391  if(trase_out)
392  *trase_out
393  << "n-r = " << n-r << " <= max_dof_quasi_newton_dense = "
394  << max_dof_quasi_newton_dense << ":\n"
395  << "setting quasi_newton == BFGS\n";
396  cov_.quasi_newton_ = QN_BFGS;
397  }
398  break;
399  }
400  case QN_BFGS:
401  case QN_PBFGS:
402  case QN_LBFGS:
403  case QN_LPBFGS:
404  cov_.quasi_newton_ = uov_.quasi_newton_;
405  break;
406  default:
407  TEUCHOS_TEST_FOR_EXCEPT(true); // Invalid option!
408  }
409 
410  if( uov_.qp_solver_type_ == QP_AUTO && nb == 0 ) {
411  cov_.qp_solver_type_ = QP_AUTO;
412  }
413 
414  // ToDo: Sort out the rest of the options!
415 
416  // Set the default options that where not already set yet
417  set_default_options(uov_,&cov_,trase_out);
418 
419  // ToDo: Implement the 2nd order correction linesearch
420  if( cov_.line_search_method_ == LINE_SEARCH_2ND_ORDER_CORRECT ) {
421  if(trase_out)
422  *trase_out <<
423  "\nline_search_method == 2ND_ORDER_CORRECT:\n"
424  "Sorry, the second order corrrection linesearch is not updated yet!\n"
425  "setting line_search_method = FILTER ...\n";
426  cov_.line_search_method_ = LINE_SEARCH_FILTER;
427  }
428  if( cov_.line_search_method_ == LINE_SEARCH_WATCHDOG ) {
429  if(trase_out)
430  *trase_out <<
431  "\nline_search_method ==WATCHDOG:\n"
432  "Sorry, the watchdog linesearch is not updated yet!\n"
433  "setting line_search_method = DIRECT ...\n";
434  cov_.line_search_method_ = LINE_SEARCH_DIRECT;
435  }
436 
437  // Adjust the Quasi-Newton if QPKWIK is used!
438  if( cov_.qp_solver_type_ == QP_QPKWIK && nb ) {
439  if(trase_out)
440  *trase_out
441  << "\nqp_solver == QPKWIK and nlp.num_bounded_x() == " << nb << " > 0:\n"
442  << "Setting quasi_newton == BFGS...\n";
443  cov_.quasi_newton_ = QN_BFGS;
444  }
445 
446  // /////////////////////////////////////////////////////
447  // C.1. Create the decomposition system object
448 
449  typedef RCP<DecompositionSystem> decomp_sys_ptr_t;
450  decomp_sys_ptr_t decomp_sys;
451  if(
452 #ifndef MOOCHO_NO_BASIS_PERM_DIRECT_SOLVERS
453  true
454 #else
455  n > m
456 #endif
457  )
458  {
459  decomp_sys_step_builder_.create_decomp_sys(
460  trase_out, nlp, nlp_foi, nlp_soi, nlp_fod, tailored_approach
461  ,&decomp_sys
462  );
463  }
464 
465 #ifndef MOOCHO_NO_BASIS_PERM_DIRECT_SOLVERS
467  decomp_sys_perm = Teuchos::rcp_dynamic_cast<DecompositionSystemVarReductPerm>(decomp_sys);
468 #endif
469 
470  // /////////////////////////////////////////////////////
471  // C.2. Create and set the state object
472 
473  if(trase_out)
474  *trase_out
475  << "\n*** Creating the state object and setting up iteration quantity objects ...\n";
476 
477  {
478  //
479  // Create the state object with the vector spaces
480  //
481 
482  typedef RCP<NLPAlgoState> state_ptr_t;
483  state_ptr_t
484  state = Teuchos::rcp(
485  new NLPAlgoState(
486  decomp_sys
487  ,nlp.space_x()
488  ,nlp.space_c()
489  ,( m
490  ? ( tailored_approach
491  ? ( nlp_fod->var_dep().size()
492  ? nlp.space_x()->sub_space(nlp_fod->var_dep())->clone()
493  : Teuchos::null )
494  : decomp_sys->space_range() // could be NULL for BasisSystemPerm
495  )
496  : Teuchos::null
497  )
498  ,( m
499  ? ( tailored_approach
500  ?( nlp_fod->var_indep().size()
501  ? nlp.space_x()->sub_space(nlp_fod->var_indep())->clone()
502  : Teuchos::null )
503  : decomp_sys->space_null() // could be NULL for BasisSystemPerm
504  )
505  : nlp.space_x()
506  )
507  )
508  );
509 
510  //
511  // Set the iteration quantities for the NLP matrix objects
512  //
513 
514  decomp_sys_step_builder_.add_iter_quantities(
515  trase_out, nlp, nlp_foi, nlp_soi, nlp_fod, tailored_approach, decomp_sys
516  ,state
517  );
518 
519  // Add reduced Hessian
520 
521  if( !cov_.exact_reduced_hessian_ ) {
523  abstract_factory_rHL = Teuchos::null;
524  // Only maintain the orginal matrix if we have inequality constraints and therefore will be
525  // needing a QP solver (which may be QPSchur which needs an accurate original matrix for
526  // iterative refinement).
527  const bool
528  maintain_original = nb;
529  // Maintain the factor if a QP solver is needed, QPSchur is being used, or we are checking
530  // results
531  const bool
532  maintain_inverse = ( (!nb && m==r) || cov_.qp_solver_type_==QP_QPSCHUR
533  || algo->algo_cntr().check_results() );
534  switch( cov_.quasi_newton_ ) {
535  case QN_BFGS:
536  abstract_factory_rHL = Teuchos::rcp(
538  MatrixSymPosDefCholFactor::PostMod(
539  maintain_original // maintain_original
540  ,maintain_inverse // maintain_factor
541  ,true // allow_factor (always!)
542  )
543  )
544  );
545  break;
546  case QN_LBFGS:
547  abstract_factory_rHL = Teuchos::rcp(
549  MatrixSymPosDefLBFGS::PostMod(
550  cov_.num_lbfgs_updates_stored_ //
551  ,maintain_original // maintain_original
552  ,maintain_inverse // maintain_inverse
553  ,cov_.lbfgs_auto_scaling_ //
554  )
555  )
556  );
557  break;
558  default:
559  TEUCHOS_TEST_FOR_EXCEPT(true); // Should not be called for now!
560  }
561 
562  state->set_iter_quant(
563  rHL_name
564  ,Teuchos::rcp(
565  new IterQuantityAccessContiguous<MatrixSymOp>(
566  1
567  ,rHL_name
568  ,abstract_factory_rHL
569  )
570  )
571  );
572  }
573  else {
574  TEUCHOS_TEST_FOR_EXCEPT(true); // ToDo: Add rHL for an exact reduced Hessian!
575  }
576 
577  //
578  // Set the NLP merit function
579  //
580 
581  if( cov_.line_search_method_ != LINE_SEARCH_NONE
582  && cov_.line_search_method_ != LINE_SEARCH_FILTER) {
584  merit_func_factory = Teuchos::null;
585  switch( cov_.merit_function_type_ ) {
586  case MERIT_FUNC_L1:
587  merit_func_factory = Teuchos::rcp(
589  break;
590  case MERIT_FUNC_MOD_L1:
591  case MERIT_FUNC_MOD_L1_INCR:
592  merit_func_factory = Teuchos::rcp(
594  break;
595  default:
596  TEUCHOS_TEST_FOR_EXCEPT(true); // local programming error
597  }
598  state->set_iter_quant(
599  merit_func_nlp_name
600  ,Teuchos::rcp(
601  new IterQuantityAccessContiguous<MeritFuncNLP>(
602  1
603  ,merit_func_nlp_name
604  ,merit_func_factory
605  )
606  )
607  );
608  }
609 
610  if (cov_.line_search_method_ == LINE_SEARCH_FILTER)
611  {
612  // Add the filter iteration quantity
613  state->set_iter_quant(
614  FILTER_IQ_STRING
615  ,Teuchos::rcp(
616  new IterQuantityAccessContiguous<Filter_T>(1,FILTER_IQ_STRING)
617  )
618  );
619  }
620 
621  if( nb ) {
622  // Add bounds on d
623  state->set_iter_quant(
624  dl_name
625  ,Teuchos::rcp(
626  new IterQuantityAccessContiguous<VectorMutable>(
627  2, dl_name
628  , nlp.space_x() ) )
629  );
630  state->set_iter_quant(
631  du_name
632  ,Teuchos::rcp(
633  new IterQuantityAccessContiguous<VectorMutable>(
634  2, du_name
635  , nlp.space_x() ) )
636  );
637  // Add active-set iteration quantity
638  state->set_iter_quant(
639  act_set_stats_name
640  ,Teuchos::rcp(
641  new IterQuantityAccessContiguous<ActSetStats>( 1, act_set_stats_name ) )
642  );
643  // Add QP solver stats iteration quantity
644  state->set_iter_quant(
645  qp_solver_stats_name
646  ,Teuchos::rcp(
647  new IterQuantityAccessContiguous<QPSolverStats>( 1, qp_solver_stats_name ) )
648  );
649  }
650 
651  //
652  // Resize the number of storage locations (these can be changed later).
653  //
654  // Also, touch all of the value_type, index_type and vector iteration quantities
655  // that we know about so that when state.dump_iter_quant() is called, all of the
656  // iteration quantities will be included.
657  //
658 
659  typedef IterQuantityAccessContiguous<value_type> IQ_scalar_cngs;
660  typedef IterQuantityAccessContiguous<VectorMutable> IQ_vector_cngs;
661 
662  dyn_cast<IQ_vector_cngs>(state->x()).resize(2);
663  dyn_cast<IQ_scalar_cngs>(state->f()).resize(2);
664  if(m) dyn_cast<IQ_vector_cngs>(state->c()).resize(2);
665  state->Gf();
666  if(m && nlp_foi) state->Gc();
667 
668  if( m
669 #ifndef MOOCHO_NO_BASIS_PERM_DIRECT_SOLVERS
670  && decomp_sys_perm.get() == NULL
671 #endif
672  ) state->py();
673  if(m) dyn_cast<IQ_vector_cngs>(state->Ypy()).resize(2);
674  if( m
675 #ifndef MOOCHO_NO_BASIS_PERM_DIRECT_SOLVERS
676  && decomp_sys_perm.get() == NULL
677 #endif
678  ) state->pz();
679  if(m) dyn_cast<IQ_vector_cngs>(state->Zpz()).resize(2);
680  dyn_cast<IQ_vector_cngs>(state->d()).resize(2);
681 
682  if( n > m ) {
683  dyn_cast<IQ_vector_cngs>(state->rGf()).resize(2);
684  state->w();
685  state->zeta();
686  state->qp_grad();
687  }
688  state->eta();
689 
690  dyn_cast<IQ_scalar_cngs>(state->alpha()).resize(2);
691  dyn_cast<IQ_scalar_cngs>(state->mu()).resize(2);
692  dyn_cast<IQ_scalar_cngs>(state->phi()).resize(2);
693 
694  dyn_cast<IQ_scalar_cngs>(state->opt_kkt_err()).resize(2);
695  dyn_cast<IQ_scalar_cngs>(state->feas_kkt_err()).resize(2);
696  if( n > m ) {
697  dyn_cast<IQ_vector_cngs>(state->rGL()).resize(2);
698  }
699  if(m) dyn_cast<IQ_vector_cngs>(state->lambda()).resize(2);
700  dyn_cast<IQ_vector_cngs>(state->nu()).resize(2);
701 
702  // Set the state object
703  algo->set_state( state );
704  }
705 
706  // /////////////////////////////////////////////////////
707  // C.3 Create and set the step objects
708 
709  if(trase_out)
710  *trase_out << "\n*** Creating and setting the step objects ...\n";
711 
712 // typedef RCP<QPSolverRelaxed> qp_solver_ptr_t;
713 // qp_solver_ptr_t qp_solver;
714 // typedef ConstrainedOptPack::QPSolverRelaxedTester QPSolverRelaxedTester;
715 // typedef RCP<QPSolverRelaxedTester> qp_tester_ptr_t;
716 // qp_tester_ptr_t qp_tester;
717 // typedef RCP<FeasibilityStepReducedStd_Strategy> feasibility_step_strategy_ptr_t;
718 // feasibility_step_strategy_ptr_t feasibility_step_strategy;
719 
720  {
721 
722  //
723  // Create some standard step objects that will be used by many different
724  // specific algorithms
725  //
726 
727  typedef RCP<AlgorithmStep> algo_step_ptr_t;
728 
729  // Create the EvalNewPoint step and associated objects
730  algo_step_ptr_t eval_new_point_step = Teuchos::null;
731  RCP<CalcFiniteDiffProd> calc_fd_prod = Teuchos::null;
732  RCP<VariableBoundsTester> bounds_tester = Teuchos::null;
733  RCP<NewDecompositionSelection_Strategy> new_decomp_selection_strategy = Teuchos::null;
734  decomp_sys_step_builder_.create_eval_new_point(
735  trase_out, nlp, nlp_foi, nlp_soi, nlp_fod, tailored_approach, decomp_sys
736  ,&eval_new_point_step, &calc_fd_prod, &bounds_tester, &new_decomp_selection_strategy
737  );
738 
739  // QuasiNormal_Step
740  algo_step_ptr_t quansi_normal_step_step = Teuchos::null;
741  if( !tailored_approach ) {
742  quansi_normal_step_step = Teuchos::rcp(new QuasiNormalStepStd_Step());
743  }
744 
745  // Check and change decomposition
746  algo_step_ptr_t check_decomp_from_py_step = Teuchos::null;
747  algo_step_ptr_t check_decomp_from_Rpy_step = Teuchos::null;
748  if( new_decomp_selection_strategy.get() && cov_.max_basis_cond_change_frac_ < INF_BASIS_COND_CHANGE_FRAC ) {
749  check_decomp_from_py_step = Teuchos::rcp(
751  new_decomp_selection_strategy
752  ,cov_.max_basis_cond_change_frac_
753  ) );
754  check_decomp_from_Rpy_step = Teuchos::rcp(
756  new_decomp_selection_strategy
757  ,cov_.max_basis_cond_change_frac_
758  ) );
759  }
760 
761  // CheckDescentQuasiNormalStep
762  algo_step_ptr_t check_descent_quansi_normal_step_step = Teuchos::null;
763  if( algo->algo_cntr().check_results() ) {
764  check_descent_quansi_normal_step_step = Teuchos::rcp(new CheckDescentQuasiNormalStep_Step(calc_fd_prod));
765  }
766 
767  // ReducedGradient_Step
768  algo_step_ptr_t reduced_gradient_step = Teuchos::null;
769  if( !tailored_approach ) {
770  reduced_gradient_step = Teuchos::rcp(new ReducedGradientStd_Step());
771  }
772 
773  // CheckSkipBFGSUpdate
774  algo_step_ptr_t check_skip_bfgs_update_step = Teuchos::null;
775  if(!cov_.exact_reduced_hessian_) {
778  if(options_.get()) {
780  opt_setter( step.get() );
781  opt_setter.set_options( *options_ );
782  }
783  check_skip_bfgs_update_step = step;
784  }
785 
786  // ReducedHessian_Step
787  algo_step_ptr_t reduced_hessian_step = Teuchos::null;
788  {
789  // Get the strategy object that will perform the actual secant update.
791  secant_update_strategy = Teuchos::null;
792  switch( cov_.quasi_newton_ )
793  {
794  case QN_BFGS:
795  case QN_PBFGS:
796  case QN_LBFGS:
797  case QN_LPBFGS:
798  {
799  // create and setup the actual BFGS strategy object
800  typedef RCP<BFGSUpdate_Strategy> bfgs_strategy_ptr_t;
801  bfgs_strategy_ptr_t
802  bfgs_strategy = Teuchos::rcp(new BFGSUpdate_Strategy);
803  if(options_.get()) {
805  opt_setter( bfgs_strategy.get() );
806  opt_setter.set_options( *options_ );
807  }
808  switch( cov_.quasi_newton_ ) {
809  case QN_BFGS:
810  case QN_LBFGS:
811  {
812  secant_update_strategy = Teuchos::rcp(new ReducedHessianSecantUpdateBFGSFull_Strategy(bfgs_strategy));
813  break;
814  }
815  case QN_PBFGS:
816  case QN_LPBFGS:
817  {
819  true, std::logic_error
820  ,"NLPAlgoConfigMamaJama::config_algo_cntr(...) : Error, "
821  "The quansi_newton options of PBFGS and LPBFGS have not been updated yet!" );
822  break;
823  }
824  }
825  break;
826  }
827  default:
829  }
830 
831  // Finally build the step object
832  reduced_hessian_step = Teuchos::rcp(
833  new ReducedHessianSecantUpdateStd_Step( secant_update_strategy ) );
834  // Add the QuasiNewtonStats iteration quantity
835  algo->state().set_iter_quant(
836  quasi_newton_stats_name
837  ,Teuchos::rcp(new IterQuantityAccessContiguous<QuasiNewtonStats>(
838  1
839  ,quasi_newton_stats_name
840 #ifdef _MIPS_CXX
843 #endif
844  )
845  ));
846  }
847 
848  // Initialization of the Reduced Hessian
849  algo_step_ptr_t init_red_hess_step = Teuchos::null;
850  if(
851  cov_.hessian_initialization_ == INIT_HESS_FIN_DIFF_SCALE_IDENTITY
852  || cov_.hessian_initialization_ == INIT_HESS_FIN_DIFF_SCALE_DIAGONAL
853  || cov_.hessian_initialization_ == INIT_HESS_FIN_DIFF_SCALE_DIAGONAL_ABS
854  )
855  {
856  // InitFinDiffReducedHessian_Step
858  TEUCHOS_TEST_FOR_EXCEPT( !( poss = algo->get_step_poss( ReducedHessian_name ) ) );
860  init_hess;
861  switch( cov_.hessian_initialization_ ) {
862  case INIT_HESS_FIN_DIFF_SCALE_IDENTITY:
863  init_hess = InitFinDiffReducedHessian_Step::SCALE_IDENTITY;
864  break;
865  case INIT_HESS_FIN_DIFF_SCALE_DIAGONAL:
866  init_hess = InitFinDiffReducedHessian_Step::SCALE_DIAGONAL;
867  break;
868  case INIT_HESS_FIN_DIFF_SCALE_DIAGONAL_ABS:
869  init_hess = InitFinDiffReducedHessian_Step::SCALE_DIAGONAL_ABS;
870  break;
871  default:
872  TEUCHOS_TEST_FOR_EXCEPT(true); // only local programming error?
873  }
875  _init_red_hess_step = Teuchos::rcp(new InitFinDiffReducedHessian_Step(init_hess));
876  if(options_.get()) {
878  opt_setter( _init_red_hess_step.get() );
879  opt_setter.set_options( *options_ );
880  }
881  init_red_hess_step = _init_red_hess_step;
882  }
883  else if(cov_.hessian_initialization_==INIT_HESS_SERIALIZE ) {
885  _init_red_hess_step = Teuchos::rcp(new ReducedHessianSerialization_Step());
886  if(options_.get()) {
887  ReducedHessianSerialization_StepSetOptions
888  opt_setter( _init_red_hess_step.get() );
889  opt_setter.set_options( *options_ );
890  }
891  init_red_hess_step = _init_red_hess_step;
892  }
893 
894  // NullSpace_Step
895  algo_step_ptr_t set_d_bounds_step = Teuchos::null;
896  algo_step_ptr_t tangential_step_step = Teuchos::null;
897  if( nb == 0 ) {
899  tangental_step_output_bounds_step
901  tangental_step_output_bounds_step->max_pz_norm(cov_.max_pz_norm_);
902  tangental_step_output_bounds_step->num_pz_damp_iters(cov_.num_pz_damp_iters_);
903  tangential_step_step = tangental_step_output_bounds_step;
904  }
905  else {
906  // Step object that sets bounds for QP subproblem
907  set_d_bounds_step = Teuchos::rcp(new SetDBoundsStd_AddedStep());
908  // QP Solver object
909  Teuchos::RCP<QPSolverRelaxed> qp_solver = Teuchos::null;
910  switch( cov_.qp_solver_type_ ) {
911  case QP_QPSCHUR: {
915 // using ConstrainedOptPack::QPSchurInitKKTSystemHessianSuperBasic;
917  init_kkt_sys = Teuchos::null;
918  switch( cov_.quasi_newton_ ) {
919  case QN_BFGS:
920  case QN_LBFGS:
921  init_kkt_sys = Teuchos::rcp(new QPSchurInitKKTSystemHessianFull());
922  break;
923  case QN_PBFGS:
924  case QN_LPBFGS:
925  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,"Error! PBFGS and LPBFGS are not updated yet!");
926 /*
927  init_kkt_sys = new QPSchurInitKKTSystemHessianSuperBasic();
928 */
929  break;
930  default:
932  }
934  _qp_solver = Teuchos::rcp(new QPSolverRelaxedQPSchur(init_kkt_sys));
935  if(options_.get()) {
936  QPSolverRelaxedQPSchurSetOptions
937  qp_options_setter(_qp_solver.get());
938  qp_options_setter.set_options( *options_ );
939  }
940  qp_solver = _qp_solver; // give ownership to delete!
941  break;
942  }
943  case QP_QPKWIK: {
944 #ifdef CONSTRAINED_OPTIMIZATION_PACK_USE_QPKWIK
947  _qp_solver = Teuchos::rcp(new QPSolverRelaxedQPKWIK());
948  qp_solver = _qp_solver; // give ownership to delete!
949 #else
951  true,std::logic_error,"Error! QPKWIK interface is not supported since "
952  "CONSTRAINED_OPTIMIZATION_PACK_USE_QPKWIK is not defined!");
953 #endif
954  break;
955  }
956  case QP_QPOPT: {
957  TEUCHOS_TEST_FOR_EXCEPTION(true,std::logic_error,"Error! QPOPT interface is not updated yet!");
958 /*
959 #ifdef CONSTRAINED_OPTIMIZATION_PACK_USE_QPOPT
960  using ConstrainedOptPack::QPSolverRelaxedQPOPT;
961  QPSolverRelaxedQPOPT
962  *_qp_solver = new QPSolverRelaxedQPOPT();
963  qp_solver = _qp_solver; // give ownership to delete!
964 #else
965  throw std::logic_error(
966  "NLPAlgoConfigMamaJama::config_algo_cntr(...) : QPOPT is not supported,"
967  " must define CONSTRAINED_OPTIMIZATION_PACK_USE_QPOPT!" );
968 #endif
969 */
970  break;
971  }
972  default:
974  }
975  // QP solver tester
977  qp_solver_tester = Teuchos::rcp(new QPSolverRelaxedTester());
978  if(options_.get()) {
979  QPSolverRelaxedTesterSetOptions
980  opt_setter( qp_solver_tester.get() );
981  opt_setter.set_options( *options_ );
982  }
983  // The null-space step
985  tangential_step_with_inequ_step = Teuchos::rcp(
987  qp_solver, qp_solver_tester ) );
988  if(options_.get()) {
990  opt_setter( tangential_step_with_inequ_step.get() );
991  opt_setter.set_options( *options_ );
992  }
993  tangential_step_step = tangential_step_with_inequ_step;
994  // Step for reinitialization reduced Hessian on QP failure
995  tangential_step_step = Teuchos::rcp(
996  new QPFailureReinitReducedHessian_Step(tangential_step_step)
997  );
998  }
999 
1000  // CalcDFromYPYZPZ_Step
1001  algo_step_ptr_t calc_d_from_Ypy_Zpy_step = Teuchos::null;
1002  {
1003  calc_d_from_Ypy_Zpy_step = Teuchos::rcp(new CalcDFromYPYZPZ_Step());
1004  }
1005 
1006  // CalcReducedGradLagrangianStd_AddedStep
1007  algo_step_ptr_t calc_reduced_grad_lagr_step = Teuchos::null;
1008  {
1009  calc_reduced_grad_lagr_step = Teuchos::rcp(
1011  }
1012 
1013  // CheckConvergence_Step
1014  algo_step_ptr_t check_convergence_step = Teuchos::null;
1015  {
1016  // Create the strategy object
1018  check_convergence_strategy = Teuchos::rcp(new CheckConvergenceStd_Strategy());
1019 
1020  if(options_.get())
1021  {
1023  opt_setter( check_convergence_strategy.get() );
1024  opt_setter.set_options( *options_ );
1025  }
1026 
1028  _check_convergence_step = Teuchos::rcp(new CheckConvergenceStd_AddedStep(check_convergence_strategy));
1029 
1030  check_convergence_step = _check_convergence_step;
1031  }
1032 
1033  // MeritFuncPenaltyParamUpdate_Step
1034  algo_step_ptr_t merit_func_penalty_param_update_step = Teuchos::null;
1035  if( cov_.line_search_method_ == LINE_SEARCH_FILTER ) {
1036  // We don't need to update a penalty parameter for the filter method :-)
1037  }
1038  else if( cov_.line_search_method_ != LINE_SEARCH_NONE ) {
1040  param_update_step = Teuchos::null;
1041  switch( cov_.merit_function_type_ ) {
1042  case MERIT_FUNC_L1: {
1043  switch(cov_.l1_penalty_param_update_) {
1044  case L1_PENALTY_PARAM_WITH_MULT:
1045 // param_update_step
1046 // = Teuchos::rcp(new MeritFunc_PenaltyParamUpdateWithMult_AddedStep());
1048  true, std::logic_error
1049  ,"NLPAlgoConfigMamaJama::config_algo_cntr(...) : Error, "
1050  "The l1_penalty_parameter_update option of MULT_FREE has not been updated yet!" );
1051  break;
1052  case L1_PENALTY_PARAM_MULT_FREE:
1053  param_update_step
1055  break;
1056  default:
1058  }
1059  break;
1060  }
1061  case MERIT_FUNC_MOD_L1:
1062  case MERIT_FUNC_MOD_L1_INCR:
1063 // param_update_step = new MeritFunc_PenaltyParamsUpdateWithMult_AddedStep(
1064 // Teuchos::rcp_implicit_cast<MeritFuncNLP>(merit_func) );
1066  true, std::logic_error
1067  ,"NLPAlgoConfigMamaJama::config_algo_cntr(...) : Error, "
1068  "The merit_function_type options of MODIFIED_L1 and MODIFIED_L1_INCR have not been updated yet!" );
1069  break;
1070  default:
1071  TEUCHOS_TEST_FOR_EXCEPT(true); // local programming error
1072  }
1073  if(options_.get()) {
1075  ppu_options_setter( param_update_step.get() );
1076  ppu_options_setter.set_options( *options_ );
1077  }
1078  merit_func_penalty_param_update_step = param_update_step;
1079  }
1080 
1081  // LineSearchFull_Step
1082  algo_step_ptr_t line_search_full_step_step = Teuchos::null;
1083  {
1084  line_search_full_step_step = Teuchos::rcp(new LineSearchFullStep_Step(bounds_tester));
1085  }
1086 
1087  // LineSearch_Step
1088  algo_step_ptr_t line_search_step = Teuchos::null;
1089  if( cov_.line_search_method_ != LINE_SEARCH_NONE ) {
1091  direct_line_search = Teuchos::rcp(new DirectLineSearchArmQuad_Strategy());
1092  if(options_.get()) {
1094  ls_options_setter( direct_line_search.get(), "DirectLineSearchArmQuadSQPStep" );
1095  ls_options_setter.set_options( *options_ );
1096  }
1097  if( n > m ) {
1098  switch( cov_.line_search_method_ ) {
1099  case LINE_SEARCH_DIRECT: {
1100  line_search_step = Teuchos::rcp(new LineSearchDirect_Step(direct_line_search));
1101  break;
1102  }
1103  case LINE_SEARCH_2ND_ORDER_CORRECT: {
1105  true, std::logic_error
1106  ,"NLPAlgoConfigMamaJama::config_algo_cntr(...) : Error, "
1107  "The line_search_method option of 2ND_ORDER_CORRECT has not been updated yet!" );
1108  break;
1109  }
1110  case LINE_SEARCH_WATCHDOG: {
1112  true, std::logic_error
1113  ,"NLPAlgoConfigMamaJama::config_algo_cntr(...) : Error, "
1114  "The line_search_method option of WATCHDOG has not been updated yet!" );
1115  break;
1116  }
1117  case LINE_SEARCH_FILTER: {
1119  line_search_filter_step = Teuchos::rcp(
1120  new LineSearchFilter_Step(algo_cntr->get_nlp())
1121  );
1122 
1123  if(options_.get())
1124  {
1125  LineSearchFilter_StepSetOptions options_setter(line_search_filter_step.get());
1126  options_setter.set_options(*options_);
1127  }
1128 
1129  line_search_step = line_search_filter_step;
1130  break;
1131  }
1132  case LINE_SEARCH_AUTO:
1133  case LINE_SEARCH_NONE:
1134  default:
1135  TEUCHOS_TEST_FOR_EXCEPT(true); // Should not get here!
1136  }
1137  }
1138  else {
1139  line_search_step = Teuchos::rcp( new LineSearchNLE_Step(direct_line_search) );
1140  }
1141  }
1142 
1143  // LineSearchFailure
1144  if( new_decomp_selection_strategy.get() ) {
1145  line_search_step = Teuchos::rcp(
1147  line_search_step
1148  ,new_decomp_selection_strategy
1149  )
1150  );
1151  }
1152 
1153  //
1154  // Create the algorithm depending on the type of NLP we are trying to solve.
1155  //
1156 
1157  if( m == 0 ) {
1158 
1159  if( nb == 0 ) {
1160  //
1161  // Unconstrained NLP (m == 0, num_bounded_x == 0)
1162  //
1163  if(trase_out)
1164  *trase_out
1165  << "\nConfiguring an algorithm for an unconstrained "
1166  << "NLP (m == 0, num_bounded_x == 0) ...\n";
1167  }
1168  else {
1169  //
1170  // Simple bound constrained NLP (m == 0, num_bounded_x > 0)
1171  //
1172  if(trase_out)
1173  *trase_out
1174  << "\nConfiguring an algorithm for a simple bound constrained "
1175  << "NLP (m == 0, num_bounded_x > 0) ...\n";
1176  }
1177 
1178  int step_num = 0;
1179 
1180  // EvalNewPoint
1181  algo->insert_step( ++step_num, EvalNewPoint_name, eval_new_point_step );
1182 
1183  // ReducedGradient
1184  algo->insert_step( ++step_num, ReducedGradient_name, reduced_gradient_step );
1185 
1186  if( nb == 0 ) {
1187 
1188  // CalcReducedGradLagrangian
1189  algo->insert_step( ++step_num, CalcReducedGradLagrangian_name, calc_reduced_grad_lagr_step );
1190 
1191  // CheckConvergence
1192  algo->insert_step( ++step_num, CheckConvergence_name, check_convergence_step );
1193 
1194  }
1195 
1196  // ReducedHessian
1197  algo->insert_step( ++step_num, ReducedHessian_name, reduced_hessian_step );
1198 
1199  // (.-1) Initialize reduced Hessian
1200  if(init_red_hess_step.get()) {
1201  algo->insert_assoc_step(
1202  step_num, IterationPack::PRE_STEP, 1
1203  ,"ReducedHessianInitialization"
1204  ,init_red_hess_step
1205  );
1206  }
1207 
1208  // TangentialStep
1209  algo->insert_step( ++step_num, TangentialStep_name, tangential_step_step );
1210  if( nb > 0 ) {
1211  // SetDBoundsStd
1212  algo->insert_assoc_step(
1213  step_num
1214  ,IterationPack::PRE_STEP
1215  ,1
1216  ,"SetDBoundsStd"
1217  ,set_d_bounds_step
1218  );
1219  }
1220 
1221  // CalcDFromZPZ
1222  algo->insert_step( ++step_num, "CalcDFromZpz", Teuchos::rcp(new CalcDFromZPZ_Step()) );
1223 
1224  if( nb > 0 ) {
1225 
1226  // CalcReducedGradLagrangian
1227  algo->insert_step( ++step_num, CalcReducedGradLagrangian_name, calc_reduced_grad_lagr_step );
1228 
1229  // CheckConvergence
1230  algo->insert_step( ++step_num, CheckConvergence_name, check_convergence_step );
1231 
1232  }
1233 
1234  // LineSearch
1235  if( cov_.line_search_method_ == LINE_SEARCH_NONE ) {
1236  algo->insert_step( ++step_num, LineSearch_name, line_search_full_step_step );
1237  }
1238  else {
1239  // Main line search step
1240  algo->insert_step( ++step_num, LineSearch_name, line_search_step );
1241  // Insert presteps
1243  pre_step_i = 0;
1244  // (.-?) LineSearchFullStep
1245  algo->insert_assoc_step(
1246  step_num
1247  ,IterationPack::PRE_STEP
1248  ,++pre_step_i
1249  ,"LineSearchFullStep"
1250  ,line_search_full_step_step
1251  );
1252  // (.-?) MeritFunc_DummyUpdate
1253  algo->insert_assoc_step(
1254  step_num
1255  ,IterationPack::PRE_STEP
1256  ,++pre_step_i
1257  ,"MeritFunc_DummyUpdate"
1259  );
1260  }
1261 
1262  }
1263  else if( n == m ) {
1264  //
1265  // System of Nonlinear equations (n == m)
1266  //
1267  if(trase_out)
1268  *trase_out
1269  << "\nConfiguring an algorithm for a system of nonlinear equations "
1270  << "NLP (n == m) ...\n";
1271 
1272  if(algo->state().get_iter_quant_id(merit_func_nlp_name)!=IterationPack::AlgorithmState::DOES_NOT_EXIST)
1273  algo->state().erase_iter_quant(merit_func_nlp_name);
1274 
1275  int step_num = 0;
1276  int assoc_step_num = 0;
1277 
1278  // EvalNewPoint
1279  algo->insert_step( ++step_num, EvalNewPoint_name, eval_new_point_step );
1280  if( check_descent_quansi_normal_step_step.get() && tailored_approach && algo->algo_cntr().check_results() )
1281  {
1282  algo->insert_assoc_step(
1283  step_num
1284  ,IterationPack::POST_STEP
1285  ,1
1286  ,"CheckDescentQuasiNormalStep"
1287  ,check_descent_quansi_normal_step_step
1288  );
1289  }
1290 
1291  // QuasiNormalStep
1292  if( !tailored_approach ) {
1293  algo->insert_step( ++step_num, QuasiNormalStep_name, quansi_normal_step_step );
1294  assoc_step_num = 0;
1295  if( check_decomp_from_py_step.get() )
1296  algo->insert_assoc_step(
1297  step_num
1298  ,IterationPack::POST_STEP
1299  ,++assoc_step_num
1300  ,"CheckDecompositionFromPy"
1301  ,check_decomp_from_py_step
1302  );
1303  if( check_decomp_from_Rpy_step.get() )
1304  algo->insert_assoc_step(
1305  step_num
1306  ,IterationPack::POST_STEP
1307  ,++assoc_step_num
1308  ,"CheckDecompositionFromRPy"
1309  ,check_decomp_from_Rpy_step
1310  );
1311  if( check_descent_quansi_normal_step_step.get() )
1312  algo->insert_assoc_step(
1313  step_num
1314  ,IterationPack::POST_STEP
1315  ,++assoc_step_num
1316  ,"CheckDescentQuasiNormalStep"
1317  ,check_descent_quansi_normal_step_step
1318  );
1319  }
1320 
1321  // CheckConvergence
1322  algo->insert_step( ++step_num, CheckConvergence_name, check_convergence_step );
1323 
1324  // CalcDFromYPY
1325  algo->insert_step( ++step_num, "CalcDFromYpy", Teuchos::rcp(new CalcDFromYPY_Step()) );
1326 
1327  // LineSearch
1328  if( cov_.line_search_method_ == LINE_SEARCH_NONE ) {
1329  algo->insert_step( ++step_num, LineSearch_name, line_search_full_step_step );
1330  }
1331  else {
1332  // Main line search step
1333  algo->insert_step( ++step_num, LineSearch_name, line_search_step );
1334  // Insert presteps
1336  pre_step_i = 0;
1337  // (.-?) LineSearchFullStep
1338  algo->insert_assoc_step(
1339  step_num
1340  ,IterationPack::PRE_STEP
1341  ,++pre_step_i
1342  ,"LineSearchFullStep"
1343  ,line_search_full_step_step
1344  );
1345  }
1346 
1347  }
1348  else if ( m > 0 || nb > 0 ) {
1349  //
1350  // General nonlinear NLP ( m > 0 )
1351  //
1352  if( nb == 0 ) {
1353  //
1354  // Nonlinear equality constrained NLP ( m > 0 && num_bounded_x == 0 )
1355  //
1356  if(trase_out)
1357  *trase_out
1358  << "\nConfiguring an algorithm for a nonlinear equality constrained "
1359  << "NLP ( m > 0 && num_bounded_x == 0) ...\n";
1360  }
1361  else {
1362  //
1363  // Nonlinear inequality constrained NLP ( num_bounded_x > 0 )
1364  //
1365  if(trase_out)
1366  *trase_out
1367  << "\nConfiguring an algorithm for a nonlinear generally constrained "
1368  << "NLP ( num_bounded_x > 0 ) ...\n";
1369  }
1370 
1371  int step_num = 0;
1372  int assoc_step_num = 0;
1373 
1374  // EvalNewPoint
1375  algo->insert_step( ++step_num, EvalNewPoint_name, eval_new_point_step );
1376  if( check_descent_quansi_normal_step_step.get() && tailored_approach && algo->algo_cntr().check_results() )
1377  {
1378  algo->insert_assoc_step(
1379  step_num
1380  ,IterationPack::POST_STEP
1381  ,1
1382  ,"CheckDescentQuasiNormalStep"
1383  ,check_descent_quansi_normal_step_step
1384  );
1385  }
1386 
1387  // QuasiNormalStep
1388  if( !tailored_approach ) {
1389  algo->insert_step( ++step_num, QuasiNormalStep_name, quansi_normal_step_step );
1390  assoc_step_num = 0;
1391  if( check_decomp_from_py_step.get() )
1392  algo->insert_assoc_step(
1393  step_num
1394  ,IterationPack::POST_STEP
1395  ,++assoc_step_num
1396  ,"CheckDecompositionFromPy"
1397  ,check_decomp_from_py_step
1398  );
1399  if( check_decomp_from_Rpy_step.get() )
1400  algo->insert_assoc_step(
1401  step_num
1402  ,IterationPack::POST_STEP
1403  ,++assoc_step_num
1404  ,"CheckDecompositionFromRPy"
1405  ,check_decomp_from_Rpy_step
1406  );
1407  if( check_descent_quansi_normal_step_step.get() )
1408  algo->insert_assoc_step(
1409  step_num
1410  ,IterationPack::POST_STEP
1411  ,++assoc_step_num
1412  ,"CheckDescentQuasiNormalStep"
1413  ,check_descent_quansi_normal_step_step
1414  );
1415  }
1416 
1417  // ReducedGradient
1418  if( !tailored_approach ) {
1419  algo->insert_step( ++step_num, ReducedGradient_name, reduced_gradient_step );
1420  }
1421 
1422  if( nb == 0 ) {
1423 
1424  // CalcReducedGradLagrangian
1425  algo->insert_step( ++step_num, CalcReducedGradLagrangian_name, calc_reduced_grad_lagr_step );
1426 
1427  // CalcLagrangeMultDecomposed
1428  // Compute these here so that in case we converge we can report them
1429  if( !tailored_approach ) {
1430  // ToDo: Insert this step
1431  }
1432 
1433  // CheckConvergence
1434  algo->insert_step( ++step_num, CheckConvergence_name, check_convergence_step );
1435  }
1436 
1437  // ReducedHessian
1438  algo->insert_step( ++step_num, ReducedHessian_name, reduced_hessian_step );
1439 
1440  // (.-1) Initialize reduced Hessian
1441  if(init_red_hess_step.get()) {
1442  algo->insert_assoc_step(
1443  step_num, IterationPack::PRE_STEP, 1
1444  ,"ReducedHessianInitialization"
1445  ,init_red_hess_step
1446  );
1447  }
1448 
1449  // (.-1) CheckSkipBFGSUpdate
1450  algo->insert_assoc_step(
1451  step_num
1452  ,IterationPack::PRE_STEP
1453  ,1
1454  ,CheckSkipBFGSUpdate_name
1455  ,check_skip_bfgs_update_step
1456  );
1457 
1458  // TangentialStep
1459  algo->insert_step( ++step_num, TangentialStep_name, tangential_step_step );
1460  if( nb > 0 ) {
1461  // SetDBoundsStd
1462  algo->insert_assoc_step(
1463  step_num
1464  ,IterationPack::PRE_STEP
1465  ,1
1466  ,"SetDBoundsStd"
1467  ,set_d_bounds_step
1468  );
1469  }
1470 
1471  // CalcDFromYPYZPZ
1472  algo->insert_step( ++step_num, CalcDFromYPYZPZ_name, calc_d_from_Ypy_Zpy_step );
1473 
1474  if( nb > 0 ) {
1475 
1476  // CalcReducedGradLagrangian
1477  algo->insert_step( ++step_num, CalcReducedGradLagrangian_name, calc_reduced_grad_lagr_step );
1478 
1479  // CalcLagrangeMultDecomposed
1480  // Compute these here so that in case we converge we can report them
1481  if( !tailored_approach ) {
1482  // ToDo: Insert this step
1483  }
1484 
1485  // CheckConvergence
1486  algo->insert_step( ++step_num, CheckConvergence_name, check_convergence_step );
1487  }
1488 
1489  // LineSearch
1490  if( cov_.line_search_method_ == LINE_SEARCH_NONE ) {
1491  algo->insert_step( ++step_num, LineSearch_name, line_search_full_step_step );
1492  }
1493  else {
1494  // Main line search step
1495  algo->insert_step( ++step_num, LineSearch_name, line_search_step );
1496  // Insert presteps
1498  pre_step_i = 0;
1499  // (.-?) LineSearchFullStep
1500  algo->insert_assoc_step(
1501  step_num
1502  ,IterationPack::PRE_STEP
1503  ,++pre_step_i
1504  ,"LineSearchFullStep"
1505  ,line_search_full_step_step
1506  );
1507  // (.-?) MeritFunc_PenaltyPramUpdate
1508  if(merit_func_penalty_param_update_step.get()) {
1509  algo->insert_assoc_step(
1510  step_num
1511  ,IterationPack::PRE_STEP
1512  ,++pre_step_i
1513  ,"MeritFunc_PenaltyParamUpdate"
1514  ,merit_func_penalty_param_update_step
1515  );
1516  }
1517  }
1518 
1519  }
1520  else {
1521  TEUCHOS_TEST_FOR_EXCEPT(true); // Error, this should not ever be called!
1522  }
1523  }
1524 
1525 }
1526 
1528 {
1529  using Teuchos::dyn_cast;
1530 
1532  _algo == NULL, std::invalid_argument
1533  ,"NLPAlgoConfigMamaJama::init_algo(_algo) : Error, "
1534  "_algo can not be NULL" );
1535 
1536  NLPAlgo &algo = dyn_cast<NLPAlgo>(*_algo);
1537  NLPAlgoState &state = algo.rsqp_state();
1538  NLP &nlp = algo.nlp();
1539 
1540  algo.max_iter( algo.algo_cntr().max_iter() );
1541  algo.max_run_time( algo.algo_cntr().max_run_time() );
1542 
1543  // Reset the iteration count to zero
1544  state.k(0);
1545 
1546  // Get organized output of vectors and matrices even if setw is not used by Step objects.
1547  algo.track().journal_out()
1548  << std::setprecision(algo.algo_cntr().journal_print_digits())
1549  << std::scientific;
1550 
1551  // set the first step
1552  algo.do_step_first(1);
1553 
1554  // The rest of the algorithm should initialize itself
1555 }
1556 
1557 // private
1558 
1559 void NLPAlgoConfigMamaJama::readin_options(
1561  , SOptionValues *ov
1562  , std::ostream *trase_out
1563  )
1564 {
1565  namespace ofsp = OptionsFromStreamPack;
1566  using ofsp::OptionsFromStream;
1567  typedef OptionsFromStream::options_group_t options_group_t;
1568  using ofsp::StringToIntMap;
1569  using ofsp::StringToBool;
1570 
1571  TEUCHOS_TEST_FOR_EXCEPT( !( ov ) ); // only a local class error
1572 
1573  // Get the options group for "NLPAlgoConfigMamaJama"
1574  const std::string opt_grp_name = "NLPAlgoConfigMamaJama";
1575  const OptionsFromStream::options_group_t optgrp = options.options_group( opt_grp_name );
1576  if( OptionsFromStream::options_group_exists( optgrp ) ) {
1577 
1578  // Define map for options group "MamaJama".
1579  const int num_opts = 13;
1580  enum EMamaJama {
1581  MAX_BASIS_COND_CHANGE_FRAC
1582  ,EXACT_REDUCED_HESSIAN
1583  ,QUASI_NEWTON
1584  ,NUM_LBFGS_UPDATES_STORED
1585  ,LBFGS_AUTO_SCALING
1586  ,HESSIAN_INITIALIZATION
1587  ,QP_SOLVER
1588  ,REINIT_HESSIAN_ON_QP_FAIL
1589  ,LINE_SEARCH_METHOD
1590  ,MERIT_FUNCTION_TYPE
1591  ,L1_PENALTY_PARAM_UPDATE
1592  ,MAX_PZ_NORM
1593  ,NUM_PZ_DAMP_ITERS
1594  };
1595  const char* SMamaJama[num_opts] = {
1596  "max_basis_cond_change_frac"
1597  ,"exact_reduced_hessian"
1598  ,"quasi_newton"
1599  ,"num_lbfgs_updates_stored"
1600  ,"lbfgs_auto_scaling"
1601  ,"hessian_initialization"
1602  ,"qp_solver"
1603  ,"reinit_hessian_on_qp_fail"
1604  ,"line_search_method"
1605  ,"merit_function_type"
1606  ,"l1_penalty_parameter_update"
1607  ,"max_pz_norm"
1608  ,"num_pz_damp_iters"
1609  };
1610  StringToIntMap mama_jama_map( opt_grp_name, num_opts, SMamaJama );
1611 
1612  options_group_t::const_iterator itr = optgrp.begin();
1613  for( ; itr != optgrp.end(); ++itr ) {
1614  switch( (EMamaJama)mama_jama_map( ofsp::option_name(itr) ) ) {
1615  case MAX_BASIS_COND_CHANGE_FRAC:
1616  ov->max_basis_cond_change_frac_ = std::atof( ofsp::option_value(itr).c_str() );
1617  break;
1618  case EXACT_REDUCED_HESSIAN:
1619  ov->exact_reduced_hessian_ = StringToBool( "exact_reduced_hessian", ofsp::option_value(itr).c_str() );
1620  break;
1621  case QUASI_NEWTON:
1622  {
1623  const std::string &opt_val = ofsp::option_value(itr);
1624  if( opt_val == "AUTO" )
1625  ov->quasi_newton_ = QN_AUTO;
1626  else if( opt_val == "BFGS" )
1627  ov->quasi_newton_ = QN_BFGS;
1628  else if( opt_val == "PBFGS" )
1629  ov->quasi_newton_ = QN_PBFGS;
1630  else if( opt_val == "LBFGS" )
1631  ov->quasi_newton_ = QN_LBFGS;
1632  else if( opt_val == "LPBFGS" )
1633  ov->quasi_newton_ = QN_LPBFGS;
1634  else
1636  true, std::invalid_argument
1637  ,"NLPAlgoConfigMamaJama::readin_options(...) : "
1638  "Error, incorrect value for \"quasi_newton\" "
1639  ", Only options of BFGS, PBFGS"
1640  ", LBFGS, LPBFGS and AUTO are avalible."
1641  );
1642  break;
1643  }
1644  case NUM_LBFGS_UPDATES_STORED:
1645  ov->num_lbfgs_updates_stored_ = std::atoi( ofsp::option_value(itr).c_str() );
1646  break;
1647  case LBFGS_AUTO_SCALING:
1648  ov->lbfgs_auto_scaling_
1649  = StringToBool( "lbfgs_auto_scaling", ofsp::option_value(itr).c_str() );
1650  break;
1651  case HESSIAN_INITIALIZATION:
1652  {
1653  const std::string &opt_val = ofsp::option_value(itr);
1654  if( opt_val == "IDENTITY" )
1655  ov->hessian_initialization_ = INIT_HESS_IDENTITY;
1656  else if( opt_val == "FINITE_DIFF_SCALE_IDENTITY" )
1657  ov->hessian_initialization_ = INIT_HESS_FIN_DIFF_SCALE_IDENTITY;
1658  else if( opt_val == "FINITE_DIFF_DIAGONAL" )
1659  ov->hessian_initialization_ = INIT_HESS_FIN_DIFF_SCALE_DIAGONAL;
1660  else if( opt_val == "FINITE_DIFF_DIAGONAL_ABS" )
1661  ov->hessian_initialization_ = INIT_HESS_FIN_DIFF_SCALE_DIAGONAL_ABS;
1662  else if( opt_val == "AUTO" )
1663  ov->hessian_initialization_ = INIT_HESS_AUTO;
1664  else if( opt_val == "SERIALIZE" )
1665  ov->hessian_initialization_ = INIT_HESS_SERIALIZE;
1666  else
1668  true, std::invalid_argument
1669  ,"NLPAlgoConfigMamaJama::readin_options(...) : "
1670  "Error, incorrect value for \"hessian_initialization\" "
1671  ", Only options of IDENTITY, SERIALIZE, FINITE_DIFF_SCALE_IDENTITY,"
1672  " FINITE_DIFF_DIAGONAL, FINITE_DIFF_DIAGONAL_ABS and AUTO"
1673  " are available" );
1674  break;
1675  }
1676  case QP_SOLVER:
1677  {
1678  const std::string &qp_solver = ofsp::option_value(itr);
1679  if( qp_solver == "AUTO" ) {
1680  ov->qp_solver_type_ = QP_AUTO;
1681  } else if( qp_solver == "QPSOL" ) {
1682  ov->qp_solver_type_ = QP_QPSOL;
1683  } else if( qp_solver == "QPOPT" ) {
1684 #ifdef CONSTRAINED_OPTIMIZATION_PACK_USE_QPOPT
1685  ov->qp_solver_type_ = QP_QPOPT;
1686 #else
1688  true, std::invalid_argument
1689  ,"NLPAlgoConfigMamaJama::readin_options(...) : QPOPT is not supported,"
1690  " must define CONSTRAINED_OPTIMIZATION_PACK_USE_QPOPT!" );
1691 #endif
1692  } else if( qp_solver == "QPKWIK" ) {
1693 #ifdef CONSTRAINED_OPTIMIZATION_PACK_USE_QPKWIK
1694  ov->qp_solver_type_ = QP_QPKWIK;
1695 #else
1697  true, std::invalid_argument
1698  ,"NLPAlgoConfigMamaJama::readin_options(...) : QPKWIK is not supported,"
1699  " must define CONSTRAINED_OPTIMIZATION_PACK_USE_QPKWIK!" );
1700 #endif
1701  } else if( qp_solver == "QPSCHUR" ) {
1702  ov->qp_solver_type_ = QP_QPSCHUR;
1703  } else {
1705  true, std::invalid_argument
1706  ,"NLPAlgoConfigMamaJama::readin_options(...) : "
1707  "Error, incorrect value for \"qp_solver\" "
1708  "Only qp solvers QPOPT, QPSOL, QPKWIK, QPSCHUR and AUTO are avalible." );
1709  }
1710  break;
1711  }
1712  case REINIT_HESSIAN_ON_QP_FAIL:
1713  ov->reinit_hessian_on_qp_fail_ = StringToBool( "reinit_hessian_on_qp_fail", ofsp::option_value(itr).c_str() );
1714  break;
1715  case LINE_SEARCH_METHOD:
1716  {
1717  const std::string &option = ofsp::option_value(itr);
1718  if( option == "NONE" ) {
1719  ov->line_search_method_ = LINE_SEARCH_NONE;
1720  } else if( option == "DIRECT" ) {
1721  ov->line_search_method_ = LINE_SEARCH_DIRECT;
1722  } else if( option == "2ND_ORDER_CORRECT" ) {
1723  ov->line_search_method_ = LINE_SEARCH_2ND_ORDER_CORRECT;
1724  } else if( option == "WATCHDOG" ) {
1725  ov->line_search_method_ = LINE_SEARCH_WATCHDOG;
1726  } else if( option == "AUTO" ) {
1727  ov->line_search_method_ = LINE_SEARCH_AUTO;
1728  } else if( option == "FILTER" ) {
1729  ov->line_search_method_ = LINE_SEARCH_FILTER;
1730  } else {
1732  true, std::invalid_argument
1733  ,"NLPAlgoConfigMamaJama::readin_options(...) : "
1734  "Error, incorrect value for \"line_search_method\".\n"
1735  "Only the options NONE, DIRECT, 2ND_ORDER_CORRECT, FILTER, WATCHDOG "
1736  "and AUTO are avalible." );
1737  }
1738  break;
1739  }
1740  case MERIT_FUNCTION_TYPE:
1741  {
1742  const std::string &option = ofsp::option_value(itr);
1743  if( option == "L1" )
1744  ov->merit_function_type_ = MERIT_FUNC_L1;
1745  else if( option == "MODIFIED_L1" )
1746  ov->merit_function_type_ = MERIT_FUNC_MOD_L1;
1747  else if( option == "MODIFIED_L1_INCR" )
1748  ov->merit_function_type_ = MERIT_FUNC_MOD_L1_INCR;
1749  else if( option == "AUTO" )
1750  ov->merit_function_type_ = MERIT_FUNC_AUTO;
1751  else
1753  true, std::invalid_argument
1754  ,"NLPAlgoConfigMamaJama::readin_options(...) : "
1755  "Error, incorrect value for \"merit_function_type\".\n"
1756  "Only the options L1, MODIFIED_L1, MODIFIED_L1_INCR "
1757  "and AUTO are avalible." );
1758  break;
1759  }
1760  case L1_PENALTY_PARAM_UPDATE:
1761  {
1762  const std::string &option = ofsp::option_value(itr);
1763  if( option == "WITH_MULT" )
1764  ov->l1_penalty_param_update_
1765  = L1_PENALTY_PARAM_WITH_MULT;
1766  else if( option == "MULT_FREE" )
1767  ov->l1_penalty_param_update_
1768  = L1_PENALTY_PARAM_MULT_FREE;
1769  else if( option == "AUTO" )
1770  ov->l1_penalty_param_update_
1771  = L1_PENALTY_PARAM_AUTO;
1772  else
1774  true, std::invalid_argument
1775  ,"NLPAlgoConfigMamaJama::readin_options(...) : "
1776  "Error, incorrect value for \"l1_penalty_param_update\".\n"
1777  "Only the options WITH_MULT, MULT_FREE and AUTO"
1778  "are avalible." );
1779  break;
1780  }
1781  case MAX_PZ_NORM: {
1782  const std::string &option = ofsp::option_value(itr);
1783  ov->max_pz_norm_ = std::atof(option.c_str());
1784  break;
1785  }
1786  case NUM_PZ_DAMP_ITERS: {
1787  const std::string &option = ofsp::option_value(itr);
1788  ov->num_pz_damp_iters_ = std::atoi(option.c_str());
1789  break;
1790  }
1791 
1792  default:
1793  TEUCHOS_TEST_FOR_EXCEPT(true); // this would be a local programming error only.
1794  }
1795  }
1796  }
1797  else {
1798  if(trase_out)
1799  *trase_out
1800  << "\n\n*** Warning! The options group \"NLPAlgoConfigMamaJama\" was not found.\n"
1801  << "Using a default set of options instead ... \n";
1802  }
1803 }
1804 
1805 //
1806 // This is where some of the default options are set and the user is alerted to what their
1807 // value is.
1808 //
1809 void NLPAlgoConfigMamaJama::set_default_options(
1810  const SOptionValues &uov
1811  ,SOptionValues *cov
1812  ,std::ostream *trase_out
1813  )
1814 {
1815  if(trase_out)
1816  *trase_out
1817  << "\n*** Setting option defaults for options not set by the user or determined some other way ...\n";
1818 
1819  if( cov->max_basis_cond_change_frac_ < 0.0 && uov.max_basis_cond_change_frac_ < 0.0 ) {
1820  if(trase_out)
1821  *trase_out
1822  << "\nmax_basis_cond_change_frac < 0 : setting max_basis_cond_change_frac = 1e+4 \n";
1823  cov->max_basis_cond_change_frac_ = 1e+4;
1824  }
1825  else {
1826  cov->max_basis_cond_change_frac_ = uov.max_basis_cond_change_frac_;
1827  }
1828  cov->exact_reduced_hessian_ = uov.exact_reduced_hessian_;
1829  if( cov->quasi_newton_ == QN_AUTO && uov.quasi_newton_ == QN_AUTO ) {
1830  if(trase_out)
1831  *trase_out
1832  << "\nquasi_newton == AUTO: setting quasi_newton = BFGS\n";
1833  cov->quasi_newton_ = QN_BFGS;
1834  }
1835  else if(cov->quasi_newton_ == QN_AUTO) {
1836  cov->quasi_newton_ = uov.quasi_newton_;
1837  }
1838  if( cov->num_lbfgs_updates_stored_ < 0 && uov.num_lbfgs_updates_stored_ < 0 ) {
1839  if(trase_out)
1840  *trase_out
1841  << "\nnum_lbfgs_updates_stored < 0 : setting num_lbfgs_updates_stored = 10\n";
1842  cov->num_lbfgs_updates_stored_ = 10;
1843  }
1844  else if(cov->num_lbfgs_updates_stored_ < 0) {
1845  cov->num_lbfgs_updates_stored_ = uov.num_lbfgs_updates_stored_;
1846  }
1847  cov->lbfgs_auto_scaling_ = uov.lbfgs_auto_scaling_;
1848  if( cov->hessian_initialization_ == INIT_HESS_AUTO && uov.hessian_initialization_ == INIT_HESS_AUTO ) {
1849  if(trase_out)
1850  *trase_out
1851  << "\nhessian_initialization == AUTO: setting hessian_initialization = IDENTITY\n";
1852  cov->hessian_initialization_ = INIT_HESS_IDENTITY;
1853 /*
1854  if(trase_out)
1855  *trase_out
1856  << "\nhessian_initialization == AUTO: setting hessian_initialization = FINITE_DIFF_DIAGONAL_ABS\n";
1857  cov->hessian_initialization_ = INIT_HESS_FIN_DIFF_SCALE_DIAGONAL_ABS;
1858 */
1859  }
1860  else if(cov->hessian_initialization_ == INIT_HESS_AUTO) {
1861  cov->hessian_initialization_ = uov.hessian_initialization_;
1862  }
1863  if( cov->qp_solver_type_ == QP_AUTO && uov.qp_solver_type_ == QP_AUTO ) {
1864 #ifdef CONSTRAINED_OPTIMIZATION_PACK_USE_QPKWIK
1865  if(trase_out)
1866  *trase_out
1867  << "\nqp_solver_type == AUTO: setting qp_solver_type = QPKWIK\n";
1868  cov->qp_solver_type_ = QP_QPKWIK;
1869 #else
1870  if(trase_out)
1871  *trase_out
1872  << "\nqp_solver_type == AUTO: setting qp_solver_type = QPSCHUR\n";
1873  cov->qp_solver_type_ = QP_QPSCHUR;
1874 #endif
1875  }
1876  else if(cov->qp_solver_type_ == QP_AUTO) {
1877  cov->qp_solver_type_ = uov.qp_solver_type_;
1878  }
1879  cov->reinit_hessian_on_qp_fail_ = uov.reinit_hessian_on_qp_fail_;
1880  if( cov->line_search_method_ == LINE_SEARCH_AUTO && uov.line_search_method_ == LINE_SEARCH_AUTO ) {
1881  if(trase_out)
1882  *trase_out
1883  << "\nline_search_method == AUTO: setting line_search_method = FILTER\n";
1884  cov->line_search_method_ = LINE_SEARCH_FILTER;
1885  }
1886  else if(cov->line_search_method_ == LINE_SEARCH_AUTO) {
1887  cov->line_search_method_ = uov.line_search_method_;
1888  }
1889  if( cov->merit_function_type_ == MERIT_FUNC_AUTO && uov.merit_function_type_ == MERIT_FUNC_AUTO ) {
1890  if(trase_out)
1891  *trase_out
1892  << "\nmerit_function_type == AUTO: setting merit_function_type = MODIFIED_L1_INCR\n";
1893  cov->merit_function_type_ = MERIT_FUNC_MOD_L1_INCR;
1894  }
1895  else if(cov->merit_function_type_ == MERIT_FUNC_AUTO) {
1896  cov->merit_function_type_ = uov.merit_function_type_;
1897  }
1898  if( cov->l1_penalty_param_update_ == L1_PENALTY_PARAM_AUTO && uov.l1_penalty_param_update_ == L1_PENALTY_PARAM_AUTO ) {
1899  if(trase_out)
1900  *trase_out
1901  << "\nl1_penalty_param_update == AUTO: setting l1_penalty_param_update = MULT_FREE\n";
1902  cov->l1_penalty_param_update_ = L1_PENALTY_PARAM_MULT_FREE;
1903  }
1904  else if(cov->l1_penalty_param_update_ == L1_PENALTY_PARAM_AUTO) {
1905  cov->l1_penalty_param_update_ = uov.l1_penalty_param_update_;
1906  }
1907  if( cov->full_steps_after_k_ < 0 && uov.full_steps_after_k_ < 0 ) {
1908  if(trase_out)
1909  *trase_out
1910  << "\nfull_steps_after_k < 0 : the line search will never be turned off after so many iterations\n";
1911  }
1912  else {
1913  cov->full_steps_after_k_ = uov.full_steps_after_k_;
1914  }
1915  cov->max_pz_norm_ = uov.max_pz_norm_;
1916  cov->num_pz_damp_iters_ = uov.num_pz_damp_iters_;
1917  if(trase_out)
1918  *trase_out
1919  << "\n*** End setting default options\n";
1920 }
1921 
1922 } // end namespace MoochoPack
Checks for descent in the decomposed equality constraints with respect to the range space step Ypy us...
Directs the algorithm to reinitalize the reduced Hessian on the event of a QP failure.
Set options for CheckSkipBFGSUpdateStd_Step from a OptionsFromStream object.
Simply updates merit_func_nlp_k = merit_func_nlp_km1
void process_nlp_and_options(std::ostream *trase_out, NLP &nlp, NLPFirstOrder **nlp_foi, NLPSecondOrder **nlp_soi, NLPDirect **nlp_fod, bool *tailored_approach)
Process the NLP and process the options passed in from set_options(). Postconditions: ...
Checks if a BFGS update should be preformed.
virtual void max_iter(size_t max_iter)
void create_eval_new_point(std::ostream *trase_out, NLP &nlp, NLPFirstOrder *nlp_foi, NLPSecondOrder *nlp_soi, NLPDirect *nlp_fod, bool tailored_approach, const Teuchos::RCP< DecompositionSystem > &decomp_sys, Teuchos::RCP< IterationPack::AlgorithmStep > *eval_new_point_step, Teuchos::RCP< CalcFiniteDiffProd > *calc_fd_prod, Teuchos::RCP< VariableBoundsTester > *bounds_tester, Teuchos::RCP< NewDecompositionSelection_Strategy > *new_decomp_selection_strategy)
Create the EvalNewPoint step object and allocated objects.
Initializes the reduced hessian using a single finite difference along the null space of the constrai...
Set options for MeritFunc_PenaltyParamUpdate_AddedStep from a OptionsFromStream object.
Interface NLPAlgoContainer uses to access NLPAlgo.
Set options for TangentialStepWithInequStd_Step from an OptionsFromStream object. ...
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void set_options(const OptionsFromStream &options)
T_To & dyn_cast(T_From &from)
Computes the reducecd gradient of the objective rGf_k = Z_k' * Gf_k
SOptionValues & current_option_values()
Return the current option values being used.
rSQP Algorithm control class.
T * get() const
Specializes the update of the penalty parameter for a merit function as: min_mu = |(Gf_k+nu_k)'* Ypy_...
Directs the selection of a new decomposition if the line search fails.
void add_iter_quantities(std::ostream *trase_out, NLP &nlp, NLPFirstOrder *nlp_foi, NLPSecondOrder *nlp_soi, NLPDirect *nlp_fod, bool tailored_approach, const Teuchos::RCP< DecompositionSystem > &decomp_sys, const Teuchos::RCP< NLPAlgoState > &state)
Add the common iteration quantities to the state object.
Set options for CheckConvergence_Strategy from an OptionsFromStream object.
Implementation for NLPAlgo solver.
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Takes the full step x_kp1 = x_k + d_k (d_k = Ypy_k + Zpz_k).
virtual std::ostream & journal_out() const
Delegates the line search to a DirectLineSearch_Strategy object.
Reduced space SQP state encapsulation interface.
size_t size_type
Computes the bounds for the QP subproblem from the NLP bounds.
Solves the unconstrained QP subproblem: min qp_grad' * pz + (1/2) * pz' * rHL * pz.
virtual void max_run_time(double max_iter)
AlgorithmTracker & track()
Delegates the line search to a DirectLineSearch_Strategy object.
Set options for InitFinDiffReducedHessian_Step from an OptionsFromStream object.
Check if the decomposition is going singular and if it is select a new decomposition.
void config_algo_cntr(NLPAlgoContainer *algo_cntr, std::ostream *trase_out)
void create_decomp_sys(std::ostream *trase_out, NLP &nlp, NLPFirstOrder *nlp_foi, NLPSecondOrder *nlp_soi, NLPDirect *nlp_fod, bool tailored_approach, Teuchos::RCP< DecompositionSystem > *decomp_sys)
Create the decomposition system object.
Calculates the reduced gradient of the Lagrangian rGL = rGf + Z' * nu + GcUP' * lambda(equ_undecomp) ...
Implementation of CheckConvergence_Strategy interface.
options_group_t options_group(const std::string &options_group_name)
NLPAlgoState & rsqp_state()
<<std aggr>="">> members for algo_cntr
Calculates the range space step by, solving for py = -inv(R)*c(equ_decomp), then setting Ypy = Y * py...
Strategy interface which contains the guts for a dampened BFGS update.
Set options for BFGSUpdate_Strategy from an OptionsFromStream object.
void set_options(const options_ptr_t &options)
Set the OptionsFromStream object that will be used for specifying the options.
void do_step_first(Algorithm::poss_type first_step_poss)
Solves the reduced QP subproblem with bounds and/or general inequalities.
Check if the decomposition is going singular and if it is select a new decomposition.
void set_options(const options_ptr_t &options)
Set the options that will be used to configure the algorithmic objects.
#define TEUCHOS_TEST_FOR_EXCEPT(throw_exception_test)