MOOCHO (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MoochoPack_PostEvalNewPointBarrier_Step.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 <ostream>
43 #include <typeinfo>
44 #include <iostream>
45 
53 #include "MoochoPack_IpState.hpp"
56 
58 
59 #include "Teuchos_dyn_cast.hpp"
60 
61 namespace MoochoPack {
62 
64  Algorithm& _algo, poss_type step_poss, IterationPack::EDoStepType type
65  ,poss_type assoc_step_poss
66  )
67  {
68  using Teuchos::dyn_cast;
74 
75  NLPAlgo &algo = dyn_cast<NLPAlgo>(_algo);
76  IpState &s = dyn_cast<IpState>(_algo.state());
77  NLP &nlp = algo.nlp();
78 
79  EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level();
80  std::ostream& out = algo.track().journal_out();
81 
82  if(!nlp.is_initialized())
83  nlp.initialize(algo.algo_cntr().check_results());
84 
85  // print step header.
86  if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) )
87  {
89  print_algorithm_step( _algo, step_poss, type, assoc_step_poss, out );
90  }
91 
92  IterQuantityAccess<VectorMutable> &x_iq = s.x();
93  IterQuantityAccess<MatrixSymDiagStd> &Vl_iq = s.Vl();
94  IterQuantityAccess<MatrixSymDiagStd> &Vu_iq = s.Vu();
95 
97  // Calculate invXl = diag(1/(x-xl))
98  // and invXu = diag(1/(xu-x)) matrices
100 
101  // get references to x, invXl, and invXu
102  VectorMutable& x = x_iq.get_k(0);
103  MatrixSymDiagStd& invXu = s.invXu().set_k(0);
104  MatrixSymDiagStd& invXl = s.invXl().set_k(0);
105 
106  //std::cout << "xu=\n";
107  //nlp.xu().output(std::cout);
108 
109  inv_of_difference(1.0, nlp.xu(), x, &invXu.diag());
110  inv_of_difference(1.0, x, nlp.xl(), &invXl.diag());
111 
112  //std::cout << "invXu=\v";
113  //invXu.output(std::cout);
114 
115  //std::cout << "\ninvXl=\v";
116  //invXl.output(std::cout);
117 
118  // Check for divide by zeros -
120  assert_print_nan_inf(invXu.diag(), "invXu", true, &out);
121  assert_print_nan_inf(invXl.diag(), "invXl", true, &out);
122  // These should never go negative either - could be a useful check
123 
124  // Initialize Vu and Vl if necessary
125  if ( Vu_iq.last_updated() == IterQuantity::NONE_UPDATED )
126  {
127  VectorMutable& vu = Vu_iq.set_k(0).diag();
128  vu = 0;
129  Vp_StV(&vu, s.barrier_parameter().get_k(-1), invXu.diag());
130 
131  if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) )
132  {
133  out << "\nInitialize Vu with barrier_parameter * invXu ...\n";
134  }
135  }
136 
137 if ( Vl_iq.last_updated() == IterQuantity::NONE_UPDATED )
138  {
139  VectorMutable& vl = Vl_iq.set_k(0).diag();
140  vl = 0;
141  Vp_StV(&vl, s.barrier_parameter().get_k(-1), invXl.diag());
142 
143  if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) )
144  {
145  out << "\nInitialize Vl with barrier_parameter * invXl ...\n";
146  }
147  }
148 
149  if (s.num_basis().updated_k(0))
150  {
151  // Basis changed, reorder Vl and Vu
152  if (Vu_iq.updated_k(-1))
153  { Vu_iq.set_k(0,-1); }
154  if (Vl_iq.updated_k(-1))
155  { Vl_iq.set_k(0,-1); }
156 
157  VectorMutable& vu = Vu_iq.set_k(0).diag();
158  VectorMutable& vl = Vl_iq.set_k(0).diag();
159 
160  s.P_var_last().permute( BLAS_Cpp::trans, &vu ); // Permute back to original order
161  s.P_var_last().permute( BLAS_Cpp::trans, &vl ); // Permute back to original order
162 
163  if( (int)olevel >= (int)PRINT_VECTORS )
164  {
165  out << "\nx resorted vl and vu to the original order\n" << x;
166  }
167 
168  s.P_var_current().permute( BLAS_Cpp::no_trans, &vu ); // Permute to new (current) order
169  s.P_var_current().permute( BLAS_Cpp::no_trans, &vl ); // Permute to new (current) order
170 
171  if( (int)olevel >= (int)PRINT_VECTORS )
172  {
173  out << "\nx resorted to new basis \n" << x;
174  }
175  }
176 
177  correct_upper_bound_multipliers(nlp.xu(), +NLP::infinite_bound(), &Vu_iq.get_k(0).diag());
178  correct_lower_bound_multipliers(nlp.xl(), -NLP::infinite_bound(), &Vl_iq.get_k(0).diag());
179 
180  if( (int)olevel >= (int)PRINT_VECTORS )
181  {
182  out << "x=\n" << s.x().get_k(0);
183  out << "xl=\n" << nlp.xl();
184  out << "vl=\n" << s.Vl().get_k(0).diag();
185  out << "xu=\n" << nlp.xu();
186  out << "vu=\n" << s.Vu().get_k(0).diag();
187  }
188 
189  // Update general algorithm bound multipliers
190  VectorMutable& v = s.nu().set_k(0);
191  v = Vu_iq.get_k(0).diag();
192  Vp_StV(&v,-1.0,Vl_iq.get_k(0).diag());
193 
194  // Print vector information
195  if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) )
196  {
197  out << "invXu_k.diag()=\n" << invXu.diag();
198  out << "invXl_k.diag()=\n" << invXl.diag();
199  out << "Vu_k.diag()=\n" << Vu_iq.get_k(0).diag();
200  out << "Vl_k.diag()=\n" << Vl_iq.get_k(0).diag();
201  out << "nu_k=\n" << s.nu().get_k(0);
202  }
203 
204  return true;
205  }
206 
207 
209  const Algorithm& _algo, poss_type step_poss, IterationPack::EDoStepType type
210  ,poss_type assoc_step_poss, std::ostream& out, const std::string& L
211  ) const
212  {
213  //const NLPAlgo &algo = rsqp_algo(_algo);
214  //const NLPAlgoState &s = algo.rsqp_state();
215  out << L << "# Evaluate information specific to primal / dual barrier algorithms (Post EvalNewPoint)\n"
216  << L << "invXl_k = diag(i, 1/(x(i)-xl))"
217  << L << "invXu_k = diag(i, 1/(xu-x(i)))\n"
218  << L << "if (Vu_k not updated) then\n"
219  << L << " Vu_k = mu_k*invXu_k\n"
220  << L << "end\n"
221  << L << "if (Vl_k not updated) then\n"
222  << L << " Vl_k = mu_k*invXl_k\n"
223  << L << "end\n"
224  << L << "nu_k_k = Vu_k.diag() - Vl_k.diag()\n";
225  }
226 
227 } // end namespace MoochoPack
void inv_of_difference(const value_type alpha, const Vector &v0, const Vector &v1, VectorMutable *z)
Computes the inverse of the difference between two vectors.
void Vp_StV(VectorMutable *v_lhs, const value_type &alpha, const Vector &v_rhs)
v_lhs = alpha * v_rhs + v_lhs
rSQP Algorithm control class.
Transposed.
Not transposed.
virtual std::ostream & journal_out() const
Return a reference to a std::ostream to be used to output debug information and the like...
EJournalOutputLevel
enum for journal output.
T_To & dyn_cast(T_From &from)
std::ostream * out
void print_algorithm_step(const Algorithm &algo, Algorithm::poss_type step_poss, EDoStepType type, Algorithm::poss_type assoc_step_poss, std::ostream &out)
Prints to 'out' the algorithm step.
bool do_step(Algorithm &algo, poss_type step_poss, IterationPack::EDoStepType type, poss_type assoc_step_poss)
AlgorithmTracker & track()
bool assert_print_nan_inf(const value_type &val, const char name[], bool throw_excpt, std::ostream *out)
This function asserts if a value_type scalare is a NaN or Inf and optionally prints out these entires...
Acts as the central hub for an iterative algorithm.
void correct_lower_bound_multipliers(const Vector &xl, const value_type inf_bound_limit, VectorMutable *vl)
Corrects the lower bound multipliers with infinite bounds.
void print_step(const IterationPack::Algorithm &algo, poss_type step_poss, IterationPack::EDoStepType type, poss_type assoc_step_poss, std::ostream &out, const std::string &leading_str) const
Called by Algorithm::print_algorithm() to print out what this step does in Matlab like format...
void correct_upper_bound_multipliers(const Vector &xu, const value_type inf_bound_limit, VectorMutable *vu)
Corrects the upper bound multipliers with infinite bounds.