MOOCHO (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MoochoPack_CheckConvergenceIP_Strategy.cpp
Go to the documentation of this file.
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 <ostream>
45 //#include <limits>
46 //#include <sstream>
47 
49 #include "MoochoPack_IpState.hpp"
55 #include "Teuchos_dyn_cast.hpp"
56 
57 namespace MoochoPack {
58 
60  EOptErrorCheck opt_error_check
61  ,EScaleKKTErrorBy scale_opt_error_by
62  ,EScaleKKTErrorBy scale_feas_error_by
63  ,EScaleKKTErrorBy scale_comp_error_by
64  ,bool scale_opt_error_by_Gf
65  )
66  :
68  opt_error_check,
69  scale_opt_error_by,
70  scale_feas_error_by,
71  scale_comp_error_by,
72  scale_opt_error_by_Gf
73  )
74  {}
75 
77  Algorithm& _algo
78  )
79  {
80  using Teuchos::dyn_cast;
83 
84  // Calculate kkt errors and check for overall convergence
85  //bool found_solution = CheckConvergenceStd_Strategy::Converged(_algo);
86  bool found_solution = false;
87 
88  // Recalculate the complementarity error including mu
89 
90  // Get the iteration quantities
91  IpState &s = dyn_cast<IpState>(*_algo.get_state());
92  NLPAlgo& algo = rsqp_algo(_algo);
93  NLP& nlp = algo.nlp();
94 
95  EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level();
96  std::ostream& out = algo.track().journal_out();
97 
98  // Get necessary iteration quantities
99  const value_type &mu_km1 = s.barrier_parameter().get_k(-1);
100  const Vector& x_k = s.x().get_k(0);
101  const VectorMutable& Gf_k = s.Gf().get_k(0);
102  const Vector& rGL_k = s.rGL().get_k(0);
103  const Vector& c_k = s.c().get_k(0);
104  const Vector& vl_k = s.Vl().get_k(0).diag();
105  const Vector& vu_k = s.Vu().get_k(0).diag();
106 
107  // Calculate the errors with Andreas' scaling
108  value_type& opt_err = s.opt_kkt_err().set_k(0);
109  value_type& feas_err = s.feas_kkt_err().set_k(0);
110  value_type& comp_err = s.comp_kkt_err().set_k(0);
111  value_type& comp_err_mu = s.comp_err_mu().set_k(0);
112 
113  // scaling
114  value_type scale_1 = 1 + x_k.norm_1()/x_k.dim();
115 
116  Teuchos::RCP<VectorMutable> temp = Gf_k.clone();
117  temp->axpy(-1.0, vl_k);
118  temp->axpy(1.0, vu_k);
119  value_type scale_2 = temp->norm_1();
120  scale_2 += vl_k.norm_1() + vu_k.norm_1();
121 
122  *temp = nlp.infinite_bound();
123  const size_type nlb = num_bounded(nlp.xl(), *temp, nlp.infinite_bound());
124  *temp = -nlp.infinite_bound();
125  const size_type nub = num_bounded(*temp, nlp.xu(), nlp.infinite_bound());
126  scale_2 = 1 + scale_2/(1+nlp.m()+nlb+nub);
127 
128  // Calculate the opt_err
129  opt_err = rGL_k.norm_inf() / scale_2;
130 
131  // Calculate the feas_err
132  feas_err = c_k.norm_inf() / scale_1;
133 
134  // Calculate the comp_err
135  if( (int)olevel >= (int)PRINT_VECTORS )
136  {
137  out << "\nx =\n" << s.x().get_k(0);
138  out << "\nxl =\n" << nlp.xl();
139  out << "\nvl =\n" << s.Vl().get_k(0).diag();
140  out << "\nxu =\n" << nlp.xu();
141  out << "\nvu =\n" << s.Vu().get_k(0).diag();
142  }
143 
144  comp_err = IP_comp_err_with_mu(
145  0.0, nlp.infinite_bound(), s.x().get_k(0), nlp.xl(), nlp.xu()
146  ,s.Vl().get_k(0).diag(), s.Vu().get_k(0).diag());
147 
148  comp_err_mu = IP_comp_err_with_mu(
149  mu_km1, nlp.infinite_bound(), s.x().get_k(0), nlp.xl(), nlp.xu()
150  ,s.Vl().get_k(0).diag(), s.Vu().get_k(0).diag());
151 
152  comp_err = comp_err / scale_2;
153  comp_err_mu = comp_err_mu / scale_2;
154 
155  // check for convergence
156 
157  const value_type opt_tol = algo.algo_cntr().opt_tol();
158  const value_type feas_tol = algo.algo_cntr().feas_tol();
159  const value_type comp_tol = algo.algo_cntr().comp_tol();
160 
161  if (opt_err < opt_tol && feas_err < feas_tol && comp_err < comp_tol)
162  {
163  found_solution = true;
164  }
165 
166  if( int(olevel) >= int(PRINT_ALGORITHM_STEPS) || (int(olevel) >= int(PRINT_BASIC_ALGORITHM_INFO) && found_solution) )
167  {
168  out
169  << "\nopt_kkt_err_k = " << opt_err << ( opt_err < opt_tol ? " < " : " > " )
170  << "opt_tol = " << opt_tol
171  << "\nfeas_kkt_err_k = " << feas_err << ( feas_err < feas_tol ? " < " : " > " )
172  << "feas_tol = " << feas_tol
173  << "\ncomp_kkt_err_k = " << comp_err << ( comp_err < comp_tol ? " < " : " > " )
174  << "comp_tol = " << comp_tol
175  << "\ncomp_err_mu = " << comp_err_mu
176  << "\nbarrier_parameter_k (mu_km1) = " << mu_km1
177  << "comp_tol = " << comp_tol
178  << std::endl;
179  }
180 
181  return found_solution;
182  }
183 
184 void CheckConvergenceIP_Strategy::print_step( const Algorithm& _algo, std::ostream& out, const std::string& L ) const
185  {
186  out
187  << L << "CheckConvergenceIP_Strategy\n"
188  << L << " IP_found_solution = CheckConvergedStd_Strategy::Converged(_algo, reportFinalSolution)\n";
189 
190  CheckConvergenceStd_Strategy::print_step(_algo, out, L+" ");
191 
192  out
193  << L << "*** recalculate comp_err\n"
194  << L << "comp_err_k = 0.0"
195  << L << "for all i = 1 to n\n"
196  << L << " comp_err_k = max( comp_err_k, vl_k(i)*(x_k(i)-xl_k(i))-mu_km1, vu_k(i)*(xu_k(i)-x_k(i))-mu_k )\n"
197  << L << "next i\n"
198  << L << "if IP_found_solution then\n"
199  << L << " IP_found_solution = false\n"
200  << L << " if (comp_err_k < comp_tol && mu_k < comp_tol) then\n"
201  << L << " IP_found_solution = true\n"
202  << L << " end\n"
203  << L << "end\n"
204  << L << "return IP_found_solution\n";
205  }
206 
207 } // end namespace MoochoPack
208 
AbstractLinAlgPack::size_type size_type
CheckConvergenceIP_Strategy(EOptErrorCheck opt_error_check=OPT_ERROR_REDUCED_GRADIENT_LAGR, EScaleKKTErrorBy scale_opt_error_by=SCALE_BY_ONE, EScaleKKTErrorBy scale_feas_error_by=SCALE_BY_ONE, EScaleKKTErrorBy scale_comp_error_by=SCALE_BY_ONE, bool scale_opt_error_by_Gf=true)
value_type IP_comp_err_with_mu(const value_type mu, const value_type inf_bound, const Vector &x, const Vector &xl, const Vector &xu, const Vector &vl, const Vector &vu)
Computes the complementarity error for a primal/dual interior point algorithm using inf norm...
rSQP Algorithm control class.
virtual void print_step(const Algorithm &_algo, std::ostream &out, const std::string &L) const
virtual void print_step(const Algorithm &_algo, std::ostream &out, const std::string &L) const
EJournalOutputLevel
enum for journal output.
T_To & dyn_cast(T_From &from)
std::ostream * out
size_type num_bounded(const Vector &xl, const Vector &xu, value_type inf_bound)
Count the number of finitly bounded elements in xl <= x <= xu.
Implementation of CheckConvergence_Strategy interface.
AbstractLinAlgPack::value_type value_type
Acts as the central hub for an iterative algorithm.
NLPAlgo & rsqp_algo(Algorithm &algo)
Convert from a Algorithm to a NLPAlgo.