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

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

renamed NonmonotoneMuUpdate? to AdaptiveMuUpdate?

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.3 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 378 2005-07-18 18:50:53Z 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
99    IpData().Set_mu(mu_init_);
100    Number tau = Max(tau_min_, 1.0 - mu_init_);
101    IpData().Set_tau(tau);
102
103    initialized_ = false;
104
105    //TODO we need to clean up the mu-update for the restoration phase
106    if (prefix=="resto.") {
107      first_iter_resto_ = true;
108    }
109    else {
110      first_iter_resto_ = false;
111    }
112
113    return true;
114  }
115
116  void MonotoneMuUpdate::UpdateBarrierParameter()
117  {
118    Number mu = IpData().curr_mu();
119    Number tau = IpData().curr_tau();
120
121    Number sub_problem_error = IpCq().curr_barrier_error();
122
123    Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE,
124                   "Optimality Error for Barrier Sub-problem = %e\n",
125                   sub_problem_error);
126    Number kappa_eps_mu = barrier_tol_factor_ * mu;
127
128    bool done = false;
129    bool tiny_step_flag = IpData().tiny_step_flag();
130    while ((sub_problem_error <= kappa_eps_mu || tiny_step_flag)
131           && !done && !first_iter_resto_) {
132      Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE,
133                     "  sub_problem_error < kappa_eps * mu (%e)\n", kappa_eps_mu);
134
135      // Compute the new values for mu and tau
136      Number new_mu;
137      Number new_tau;
138      Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE,
139                     "Updating mu=%e and tau=%e to ", mu, tau);
140      CalcNewMuAndTau(new_mu, new_tau);
141      Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE,
142                     "new_mu=%e and new_tau=%e\n", new_mu, new_tau);
143      bool mu_changed = (mu != new_mu);
144      if (!mu_changed && tiny_step_flag) {
145        THROW_EXCEPTION(TINY_STEP_DETECTED,
146                        "Problem solved to best possible numerical accuracy");
147      }
148
149      // Set the new values for mu and tau
150      IpData().Set_mu(new_mu);
151      IpData().Set_tau(new_tau);
152      mu = new_mu;
153      tau = new_tau;
154
155      // If this is the first iteration, we want to check if we can
156      // decrease mu even more
157      if (initialized_) {
158        done = true;
159      }
160      else {
161        sub_problem_error = IpCq().curr_barrier_error();
162        kappa_eps_mu = barrier_tol_factor_ * mu;
163        done = (sub_problem_error > kappa_eps_mu);
164      }
165
166      // Reset the line search
167      if (done && mu_changed) {
168        linesearch_->Reset();
169      }
170
171      tiny_step_flag = false;
172    }
173
174    first_iter_resto_ = false;
175    initialized_ = true;
176  }
177
178  void MonotoneMuUpdate::CalcNewMuAndTau(Number &new_mu,
179                                         Number &new_tau)
180  {
181    // update the barrier parameter
182    Number mu = IpData().curr_mu();
183    Number tol = IpData().tol();
184    Number compl_inf_tol = IpData().compl_inf_tol();
185
186    new_mu = Min( mu_linear_decrease_factor_*mu,
187                  pow(mu, mu_superlinear_decrease_power_) );
188    new_mu = Max(new_mu, Min(tol, compl_inf_tol)/10.);
189
190    // update the fraction to the boundary parameter
191    new_tau = Max(tau_min_, 1.-new_mu);
192  }
193
194} // namespace Ipopt
Note: See TracBrowser for help on using the repository browser.