source: branches/dev/Algorithm/IpAlgBuilder.cpp @ 542

Last change on this file since 542 was 542, checked in by andreasw, 14 years ago
  • cleaned up line search to allow for alternative globalization scheme
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.7 KB
Line 
1// Copyright (C) 2004, 2005 International Business Machines and others.
2// All Rights Reserved.
3// This code is published under the Common Public License.
4//
5// $Id: IpAlgBuilder.cpp 542 2005-10-13 22:43:08Z andreasw $
6//
7// Authors:  Carl Laird, Andreas Waechter     IBM    2004-09-29
8
9#include "IpAlgBuilder.hpp"
10
11#include "IpStdAugSystemSolver.hpp"
12#include "IpAugRestoSystemSolver.hpp"
13#include "IpPDFullSpaceSolver.hpp"
14#include "IpPDPerturbationHandler.hpp"
15#include "IpOptErrorConvCheck.hpp"
16#include "IpBacktrackingLineSearch.hpp"
17#include "IpFilterLSAcceptor.hpp"
18#include "IpMonotoneMuUpdate.hpp"
19#include "IpAdaptiveMuUpdate.hpp"
20#include "IpLoqoMuOracle.hpp"
21#include "IpProbingMuOracle.hpp"
22#include "IpQualityFunctionMuOracle.hpp"
23#include "IpRestoMinC_1Nrm.hpp"
24#include "IpLeastSquareMults.hpp"
25#include "IpDefaultIterateInitializer.hpp"
26#include "IpWarmStartIterateInitializer.hpp"
27#include "IpOrigIterationOutput.hpp"
28#include "IpRestoIterationOutput.hpp"
29#include "IpRestoFilterConvCheck.hpp"
30#include "IpRestoIterateInitializer.hpp"
31#include "IpRestoRestoPhase.hpp"
32#include "IpTSymLinearSolver.hpp"
33
34#ifdef HAVE_MA27
35# include "IpMa27TSolverInterface.hpp"
36#endif
37#ifdef HAVE_MC19
38# include "IpMc19TSymScalingMethod.hpp"
39#endif
40#ifdef HAVE_PARDISO
41# include "IpPardisoSolverInterface.hpp"
42#endif
43#ifdef HAVE_TAUCS
44# include "IpTAUCSSolverInterface.hpp"
45#endif
46
47namespace Ipopt
48{
49#ifdef IP_DEBUG
50  static const Index dbg_verbosity = 0;
51#endif
52
53  void AlgorithmBuilder::RegisterOptions(SmartPtr<RegisteredOptions> roptions)
54  {
55    roptions->SetRegisteringCategory("Undocumented");
56    roptions->AddStringOption3(
57      "linear_solver",
58      "Linear solver used for step computations.",
59      "ma27",
60      "ma27", "use the Harwell routine MA27",
61      "pardiso", "use the Pardiso package",
62      "taucs", "use TAUCS package",
63      "Determines which linear algebra package is to be used for the "
64      "solution of the augmented linear system (for obtaining the search "
65      "directions). "
66      "Note that depending on your Ipopt installation, not all "
67      "options may be available.");
68    roptions->SetRegisteringCategory("Linear Solver");
69    roptions->AddStringOption2(
70      "linear_system_scaling",
71      "Method for scaling the linear system.",
72      "none",
73      "none", "no scaling will be performed",
74      "mc19", "use the Harwell routine mc19",
75      "Determines the method used to compute symmetric scaling "
76      "factors for the augmented system. This scaling will be done "
77      "in addition to any NLP problem scaling.");
78
79    roptions->SetRegisteringCategory("Mu Update");
80    roptions->AddStringOption2(
81      "mu_strategy",
82      "Update strategy for barrier parameter.",
83      "monotone",
84      "monotone", "use the monotone (Fiacco-McCormick) strategy",
85      "adaptive", "use the adaptive update strategy",
86      "Determines which barrier parameter update strategy is to be used.");
87    roptions->AddStringOption3(
88      "mu_oracle",
89      "Oracle for a new barrier parameter in the adaptive strategy.",
90      "probing",
91      "probing", "Mehrotra's probing heuristic",
92      "loqo", "LOQO's centrality rule",
93      "quality_function", "minimize a quality function",
94      "Determines how a new barrier parameter is computed in each "
95      "\"free-mode\" iteration of the adaptive barrier parameter "
96      "strategy. (Only considered if \"adaptive\" is selected for "
97      "option \"mu_strategy\").");
98    roptions->AddStringOption4(
99      "fixed_mu_oracle",
100      "Oracle for the barrier parameter when switching to fixed mode.",
101      "average_compl",
102      "probing", "Mehrotra's probing heuristic",
103      "loqo", "LOQO's centrality rule",
104      "quality_function", "minimize a quality function",
105      "average_compl", "base on current average complementarity",
106      "Determines how the first value of the barrier parameter should be "
107      "computed when switching to the \"monotone mode\" in the adaptive "
108      "strategy. (Only considered if \"adaptive\" is selected for option "
109      "\"mu_strategy\".)");
110  }
111
112  SmartPtr<IpoptAlgorithm>
113  AlgorithmBuilder::BuildBasicAlgorithm(const Journalist& jnlst,
114                                        const OptionsList& options,
115                                        const std::string& prefix)
116  {
117    DBG_START_FUN("AlgorithmBuilder::BuildBasicAlgorithm",
118                  dbg_verbosity);
119    // Create the convergence check
120    SmartPtr<ConvergenceCheck> convCheck =
121      new OptimalityErrorConvergenceCheck();
122
123    // Create the solvers that will be used by the main algorithm
124    SmartPtr<TSymScalingMethod> ScalingMethod;
125    std::string linear_system_scaling;
126    options.GetStringValue("linear_system_scaling",
127                           linear_system_scaling, prefix);
128    if (linear_system_scaling=="mc19") {
129#ifdef HAVE_MC19
130      ScalingMethod = new Mc19TSymScalingMethod();
131#else
132
133      THROW_EXCEPTION(OPTION_INVALID,
134                      "Selected linear system scaling method MC19 not available.");
135#endif
136
137    }
138
139    SmartPtr<SparseSymLinearSolverInterface> SolverInterface;
140    std::string linear_solver;
141    options.GetStringValue("linear_solver", linear_solver, prefix);
142    if (linear_solver=="ma27") {
143#ifdef HAVE_MA27
144      SolverInterface = new Ma27TSolverInterface();
145#else
146
147      THROW_EXCEPTION(OPTION_INVALID,
148                      "Selected linear solver MA27 not available.");
149#endif
150
151    }
152    else if (linear_solver=="pardiso") {
153#ifdef HAVE_PARDISO
154      SolverInterface = new PardisoSolverInterface();
155#else
156
157      THROW_EXCEPTION(OPTION_INVALID,
158                      "Selected linear solver Pardiso not available.");
159#endif
160
161    }
162    else if (linear_solver=="taucs") {
163#ifdef HAVE_TAUCS
164      SolverInterface = new TAUCSSolverInterface();
165#else
166
167      THROW_EXCEPTION(OPTION_INVALID,
168                      "Selected linear solver TAUCS not available.");
169#endif
170
171    }
172
173    SmartPtr<SymLinearSolver> ScaledSolver =
174      new TSymLinearSolver(SolverInterface, ScalingMethod);
175
176    SmartPtr<AugSystemSolver> AugSolver =
177      //        = new AugTSystemSolver(*Ma27Solver);
178      new StdAugSystemSolver(*ScaledSolver);
179    SmartPtr<PDPerturbationHandler> pertHandler =
180      new PDPerturbationHandler();
181    SmartPtr<PDSystemSolver> PDSolver =
182      new PDFullSpaceSolver(*AugSolver, *pertHandler);
183
184    // Create the object for initializing the iterates Initialization
185    // object.  We include both the warm start and the defaut
186    // initializer, so that the warm start options can be activated
187    // without having to rebuild the algorithm
188    SmartPtr<EqMultiplierCalculator> EqMultCalculator =
189      new LeastSquareMultipliers(*AugSolver);
190    SmartPtr<IterateInitializer> WarmStartInitializer =
191      new WarmStartIterateInitializer();
192    SmartPtr<IterateInitializer> IterInitializer =
193      new DefaultIterateInitializer(EqMultCalculator, WarmStartInitializer);
194
195    // Solver for the restoration phase
196    SmartPtr<AugSystemSolver> resto_AugSolver =
197      new AugRestoSystemSolver(*AugSolver);
198    SmartPtr<PDPerturbationHandler> resto_pertHandler =
199      new PDPerturbationHandler();
200    SmartPtr<PDSystemSolver> resto_PDSolver =
201      new PDFullSpaceSolver(*resto_AugSolver, *resto_pertHandler);
202
203    // Convergence check in the restoration phase
204    SmartPtr<RestoFilterConvergenceCheck> resto_convCheck =
205      new RestoFilterConvergenceCheck();
206
207    // Line search method for the restoration phase
208    SmartPtr<RestoRestorationPhase> resto_resto =
209      new RestoRestorationPhase();
210    SmartPtr<FilterLSAcceptor> resto_filterLSacceptor =
211      new FilterLSAcceptor(GetRawPtr(resto_PDSolver));
212    SmartPtr<LineSearch> resto_LineSearch =
213      new BacktrackingLineSearch(GetRawPtr(resto_filterLSacceptor),
214                                 GetRawPtr(resto_resto), GetRawPtr(resto_convCheck));
215
216    // Create the mu update that will be used by the restoration phase
217    // algorithm
218    SmartPtr<MuUpdate> resto_MuUpdate;
219    std::string resto_smuupdate;
220    options.GetStringValue("mu_strategy", resto_smuupdate, "resto."+prefix);
221
222    std::string resto_smuoracle;
223    std::string resto_sfixmuoracle;
224    if (resto_smuupdate=="adaptive" ) {
225      options.GetStringValue("mu_oracle", resto_smuoracle, "resto."+prefix);
226      options.GetStringValue("fixed_mu_oracle", resto_sfixmuoracle, "resto."+prefix);
227    }
228
229    if (resto_smuupdate=="monotone" ) {
230      resto_MuUpdate = new MonotoneMuUpdate(GetRawPtr(resto_LineSearch));
231    }
232    else if (resto_smuupdate=="adaptive") {
233      SmartPtr<MuOracle> resto_MuOracle;
234      if (resto_smuoracle=="loqo") {
235        resto_MuOracle = new LoqoMuOracle();
236      }
237      else if (resto_smuoracle=="probing") {
238        resto_MuOracle = new ProbingMuOracle(resto_PDSolver);
239      }
240      else if (resto_smuoracle=="quality_function") {
241        resto_MuOracle = new QualityFunctionMuOracle(resto_PDSolver);
242      }
243      SmartPtr<MuOracle> resto_FixMuOracle;
244      if (resto_sfixmuoracle=="loqo") {
245        resto_FixMuOracle = new LoqoMuOracle();
246      }
247      else if (resto_sfixmuoracle=="probing") {
248        resto_FixMuOracle = new ProbingMuOracle(resto_PDSolver);
249      }
250      else if (resto_sfixmuoracle=="quality_function") {
251        resto_FixMuOracle = new QualityFunctionMuOracle(resto_PDSolver);
252      }
253      else {
254        resto_FixMuOracle = NULL;
255      }
256      resto_MuUpdate =
257        new AdaptiveMuUpdate(GetRawPtr(resto_LineSearch),
258                             resto_MuOracle, resto_FixMuOracle);
259    }
260
261    // Initialization of the iterates for the restoration phase
262    SmartPtr<EqMultiplierCalculator> resto_EqMultCalculator =
263      new LeastSquareMultipliers(*resto_AugSolver);
264    SmartPtr<IterateInitializer> resto_IterInitializer =
265      new RestoIterateInitializer(resto_EqMultCalculator);
266
267    // Create the object for the iteration output during restoration
268    SmartPtr<OrigIterationOutput> resto_OrigIterOutput = NULL;
269    //   new OrigIterationOutput();
270    SmartPtr<IterationOutput> resto_IterOutput =
271      new RestoIterationOutput(resto_OrigIterOutput);
272
273    // Put together the overall restoration phase IP algorithm
274    SmartPtr<IpoptAlgorithm> resto_alg =
275      new IpoptAlgorithm(resto_PDSolver,
276                         GetRawPtr(resto_LineSearch),
277                         GetRawPtr(resto_MuUpdate),
278                         GetRawPtr(resto_convCheck),
279                         resto_IterInitializer,
280                         resto_IterOutput);
281
282    // Set the restoration phase
283    SmartPtr<RestorationPhase> resto_phase =
284      new MinC_1NrmRestorationPhase(*resto_alg, EqMultCalculator);
285
286    // Create the line search to be used by the main algorithm
287    SmartPtr<FilterLSAcceptor> filterLSacceptor =
288      new FilterLSAcceptor(GetRawPtr(PDSolver));
289    SmartPtr<LineSearch> lineSearch =
290      new BacktrackingLineSearch(GetRawPtr(filterLSacceptor),
291                                 GetRawPtr(resto_phase), convCheck);
292
293    // The following cross reference is not good: We have to store a
294    // pointer to the lineSearch object in resto_convCheck as a
295    // non-SmartPtr to make sure that things are properly deleted when
296    // the IpoptAlgorithm return by the Builder is destructed.
297    resto_convCheck->SetOrigFilterLSAcceptor(*filterLSacceptor);
298
299    // Create the mu update that will be used by the main algorithm
300    SmartPtr<MuUpdate> MuUpdate;
301    std::string smuupdate;
302    options.GetStringValue("mu_strategy", smuupdate, prefix);
303    std::string smuoracle;
304    std::string sfixmuoracle;
305    if (smuupdate=="adaptive" ) {
306      options.GetStringValue("mu_oracle", smuoracle, prefix);
307      options.GetStringValue("fixed_mu_oracle", sfixmuoracle, prefix);
308    }
309
310    if (smuupdate=="monotone" ) {
311      MuUpdate = new MonotoneMuUpdate(GetRawPtr(lineSearch));
312    }
313    else if (smuupdate=="adaptive") {
314      SmartPtr<MuOracle> muOracle;
315      if (smuoracle=="loqo") {
316        muOracle = new LoqoMuOracle();
317      }
318      else if (smuoracle=="probing") {
319        muOracle = new ProbingMuOracle(PDSolver);
320      }
321      else if (smuoracle=="quality_function") {
322        muOracle = new QualityFunctionMuOracle(PDSolver);
323      }
324      SmartPtr<MuOracle> FixMuOracle;
325      if (sfixmuoracle=="loqo") {
326        FixMuOracle = new LoqoMuOracle();
327      }
328      else if (sfixmuoracle=="probing") {
329        FixMuOracle = new ProbingMuOracle(PDSolver);
330      }
331      else if (sfixmuoracle=="quality_function") {
332        FixMuOracle = new QualityFunctionMuOracle(PDSolver);
333      }
334      else {
335        FixMuOracle = NULL;
336      }
337      MuUpdate = new AdaptiveMuUpdate(GetRawPtr(lineSearch),
338                                      muOracle, FixMuOracle);
339    }
340
341    // Create the object for the iteration output
342    SmartPtr<IterationOutput> IterOutput =
343      new OrigIterationOutput();
344
345    // Create the main algorithm
346    SmartPtr<IpoptAlgorithm> alg =
347      new IpoptAlgorithm(PDSolver,
348                         GetRawPtr(lineSearch), MuUpdate,
349                         convCheck, IterInitializer, IterOutput);
350
351    return alg;
352  }
353
354} // namespace
Note: See TracBrowser for help on using the repository browser.