source: branches/dev/Algorithm/IpMonotoneMuUpdate.cpp @ 416

Last change on this file since 416 was 416, checked in by andreasw, 14 years ago
  • revised handling of "acceptable level of accuracy" (now in ConvCheck?)
  • fixed uncaught evaluation error exceptions
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.5 KB
Line 
1// Copyright (C) 2004, International Business Machines and others.
2// All Rights Reserved.
3// This code is published under the Common Public License.
4//
5// $Id: IpMonotoneMuUpdate.cpp 416 2005-07-29 19:11:41Z andreasw $
6//
7// Authors:  Carl Laird, Andreas Waechter     IBM    2004-08-13
8
9#include "IpMonotoneMuUpdate.hpp"
10#include "IpJournalist.hpp"
11
12#ifdef OLD_C_HEADERS
13# include <math.h>
14#else
15# include <cmath>
16#endif
17
18namespace Ipopt
19{
20
21  DBG_SET_VERBOSITY(0);
22
23  DefineIpoptType(MonotoneMuUpdate);
24
25  MonotoneMuUpdate::MonotoneMuUpdate(const SmartPtr<LineSearch>& linesearch)
26      :
27      MuUpdate(),
28      linesearch_(linesearch),
29      initialized_(false)
30  {
31    DBG_START_METH("MonotoneMuUpdate::MonotoneMuUpdate",
32                   dbg_verbosity);
33    DBG_ASSERT(IsValid(linesearch_));
34  }
35
36  MonotoneMuUpdate::~MonotoneMuUpdate()
37  {
38    DBG_START_METH("MonotoneMuUpdate::~MonotoneMuUpdate",
39                   dbg_verbosity);
40  }
41
42  void MonotoneMuUpdate::RegisterOptions(SmartPtr<RegisteredOptions> roptions)
43  {
44    roptions->AddLowerBoundedNumberOption(
45      "mu_init", "Initial value for the barrier parameter.",
46      0.0, true,
47      0.1,
48      "This option determines the initial value for the barrier parameter "
49      "(mu).  It is only relevant in the monotone, Fiacco-McCormick "
50      "version of the algorithm., i.e., if \"mu_strategy\" is chosen "
51      "as \"monotone\"");
52    roptions->AddLowerBoundedNumberOption(
53      "barrier_tol_factor",
54      "Factor for mu in barrier stop test.",
55      0.0, true,
56      10.0,
57      "The convergence tolerance for each barrier problem in the montone mode "
58      "is the value of the barrier parameter times this value. This option is "
59      "also used in class \"AdaptiveMuUpdate\" during the monotone mode. "
60      "(This is kappa_epsilon in implementation paper).");
61    roptions->AddBoundedNumberOption(
62      "mu_linear_decrease_factor",
63      "Determines linear decrease rate of barrier parameter.",
64      0.0, true, 1.0, true,
65      0.2,
66      "For the Fiacco-McCormick update procedure the new barrier parameter mu "
67      "is obtained by taking the minimum of mu*\"mu_linear_decrease_factor\" "
68      "and mu^\"superlinear_decrease_power\".  (This is kappa_mu in "
69      "implementation paper.) [This option is also used in "
70      "AdaptiveMuUpdate]");
71    roptions->AddBoundedNumberOption(
72      "mu_superlinear_decrease_power",
73      "Determines superlinear decrease rate of barrier parameter.",
74      1.0, true, 2.0, true,
75      1.5,
76      "For the Fiacco-McCormick update procedure the new barrier parameter mu "
77      "is obtained by taking the minimum of mu*\"mu_linear_decrease_factor\" "
78      "and mu^\"superlinear_decrease_power\".  (This is theta_mu in "
79      "implementation paper.) [This option is also used in "
80      "AdaptiveMuUpdate]");
81    roptions->AddBoundedNumberOption(
82      "tau_min",
83      "Lower bound on fraction-to-the-boundary parameter tau.",
84      0.0, true, 1.0, true,
85      0.99,
86      "(This is tau_min in implementation paper.) [This option is also "
87      "used in AdaptiveMuUpdate]");
88  }
89
90  bool MonotoneMuUpdate::InitializeImpl(const OptionsList& options,
91                                        const std::string& prefix)
92  {
93    options.GetNumericValue("mu_init", mu_init_, prefix);
94    options.GetNumericValue("barrier_tol_factor", barrier_tol_factor_, prefix);
95    options.GetNumericValue("mu_linear_decrease_factor", mu_linear_decrease_factor_, prefix);
96    options.GetNumericValue("mu_superlinear_decrease_power", mu_superlinear_decrease_power_, prefix);
97    options.GetNumericValue("tau_min", tau_min_, prefix);
98    options.GetNumericValue("compl_inf_tol", compl_inf_tol_, prefix);
99
100    IpData().Set_mu(mu_init_);
101    Number tau = Max(tau_min_, 1.0 - mu_init_);
102    IpData().Set_tau(tau);
103
104    initialized_ = false;
105
106    //TODO we need to clean up the mu-update for the restoration phase
107    if (prefix=="resto.") {
108      first_iter_resto_ = true;
109    }
110    else {
111      first_iter_resto_ = false;
112    }
113
114    return true;
115  }
116
117  void MonotoneMuUpdate::UpdateBarrierParameter()
118  {
119    Number mu = IpData().curr_mu();
120    Number tau = IpData().curr_tau();
121
122    Number sub_problem_error = IpCq().curr_barrier_error();
123
124    Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE,
125                   "Optimality Error for Barrier Sub-problem = %e\n",
126                   sub_problem_error);
127    Number kappa_eps_mu = barrier_tol_factor_ * mu;
128
129    bool done = false;
130    bool tiny_step_flag = IpData().tiny_step_flag();
131    while ((sub_problem_error <= kappa_eps_mu || tiny_step_flag)
132           && !done && !first_iter_resto_) {
133      Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE,
134                     "  sub_problem_error < kappa_eps * mu (%e)\n", kappa_eps_mu);
135
136      // Compute the new values for mu and tau
137      Number new_mu;
138      Number new_tau;
139      Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE,
140                     "Updating mu=%e and tau=%e to ", mu, tau);
141      CalcNewMuAndTau(new_mu, new_tau);
142      Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE,
143                     "new_mu=%e and new_tau=%e\n", new_mu, new_tau);
144      bool mu_changed = (mu != new_mu);
145      if (!mu_changed && tiny_step_flag) {
146        THROW_EXCEPTION(TINY_STEP_DETECTED,
147                        "Problem solved to best possible numerical accuracy");
148      }
149
150      // Set the new values for mu and tau
151      IpData().Set_mu(new_mu);
152      IpData().Set_tau(new_tau);
153      mu = new_mu;
154      tau = new_tau;
155
156      // If this is the first iteration, we want to check if we can
157      // decrease mu even more
158      if (initialized_) {
159        done = true;
160      }
161      else {
162        sub_problem_error = IpCq().curr_barrier_error();
163        kappa_eps_mu = barrier_tol_factor_ * mu;
164        done = (sub_problem_error > kappa_eps_mu);
165      }
166
167      // Reset the line search
168      if (done && mu_changed) {
169        linesearch_->Reset();
170      }
171
172      tiny_step_flag = false;
173    }
174
175    first_iter_resto_ = false;
176    initialized_ = true;
177  }
178
179  void MonotoneMuUpdate::CalcNewMuAndTau(Number &new_mu,
180                                         Number &new_tau)
181  {
182    // update the barrier parameter
183    Number mu = IpData().curr_mu();
184    Number tol = IpData().tol();
185
186    // Here we need the complementarity tolerance that is posed to the
187    // scaled problem
188    Number compl_inf_tol =
189      IpNLP().NLP_scaling()->apply_obj_scaling(compl_inf_tol_);
190
191    new_mu = Min( mu_linear_decrease_factor_*mu,
192                  pow(mu, mu_superlinear_decrease_power_) );
193    new_mu = Max(new_mu, Min(tol, compl_inf_tol)/(barrier_tol_factor_+1.));
194
195    // update the fraction to the boundary parameter
196    new_tau = Max(tau_min_, 1.-new_mu);
197  }
198
199} // namespace Ipopt
Note: See TracBrowser for help on using the repository browser.