MoochoPack : Framework for Large-Scale Optimization Algorithms  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
MoochoPack_CheckDecompositionFromRPy_Step.cpp
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 <typeinfo>
43 
44 #include "MoochoPack_CheckDecompositionFromRPy_Step.hpp"
45 #include "MoochoPack_moocho_algo_conversion.hpp"
46 #include "IterationPack_print_algorithm_step.hpp"
47 #include "AbstractLinAlgPack_MatrixOpNonsing.hpp"
48 #include "AbstractLinAlgPack_Vector.hpp"
49 #include "AbstractLinAlgPack_LinAlgOpPack.hpp"
50 
51 namespace MoochoPack {
52 
53 CheckDecompositionFromRPy_Step::CheckDecompositionFromRPy_Step(
54  const new_decomp_strategy_ptr_t &new_decomp_strategy
55  ,value_type max_decomposition_cond_change_frac
56  )
57  :new_decomp_strategy_(new_decomp_strategy)
58  ,max_decomposition_cond_change_frac_(max_decomposition_cond_change_frac)
59 {
60  reset();
61 }
62 
64  beta_min_ = std::numeric_limits<value_type>::max();
65 }
66 
67 // Overridden
68 
70  , IterationPack::EDoStepType type, poss_type assoc_step_poss )
71 {
72  NLPAlgo &algo = rsqp_algo(_algo);
73  NLPAlgoState &s = algo.rsqp_state();
74  const Range1D equ_decomp = s.equ_decomp();
75  EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level();
76  std::ostream &out = algo.track().journal_out();
77 
78  // print step header.
79  if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
80  using IterationPack::print_algorithm_step;
81  print_algorithm_step( algo, step_poss, type, assoc_step_poss, out );
82  }
83 
84  bool select_new_decomposition = false;
85 
86  // Compute: resid = (Gc(decomp)'*Y) * py + c(decomp)
87  const Vector &py_k = s.py().get_k(0);
88  const Vector &c_k = s.c().get_k(0);
89  Vector::vec_ptr_t c_decomp_k = c_k.sub_view(equ_decomp);
90  VectorMutable::vec_mut_ptr_t resid = c_decomp_k->space().create_member();
91 
92  // resid = R*py + c(equ_decomp)
93  LinAlgOpPack::V_MtV( resid.get(), s.R().get_k(0), BLAS_Cpp::no_trans, py_k );
94  LinAlgOpPack::Vp_V( resid.get(), *c_decomp_k );
95 
96  const value_type
97  small_num = std::numeric_limits<value_type>::min(),
98  epsilon = std::numeric_limits<value_type>::epsilon(),
99  nrm_resid = resid->norm_inf(),
100  nrm_c_decomp = c_decomp_k->norm_inf(),
101  beta = nrm_resid / (nrm_c_decomp+small_num);
102 
103  if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) {
104  out << "\nbeta = ||R*py_k + c_k(decomp)||inf / (||c_k(decomp)||inf + small_number)"
105  << "\n = "<<nrm_resid<<" / ("<<nrm_c_decomp<<" + "<<small_num<<")"
106  << "\n = " << beta << std::endl;
107  }
108 
109  // Check to see if a new basis was selected or not
110  IterQuantityAccess<index_type>
111  &num_basis_iq = s.num_basis();
112  if( num_basis_iq.updated_k(0) ) {
113  if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS )
114  out << "\nnum_basis_k was updated so the basis changed so we will skip this check\n"
115  << " reset min ||R*py+c||/||c|| to current value + epsilon(" << epsilon << ")\n";
116  beta_min_ = beta + epsilon;
117  return true;
118  }
119 
120  if( beta != 0.0 ) {
121  if( beta < beta_min_ ) {
122  beta_min_ = beta;
123  }
124  else {
125  if( beta / beta_min_ > max_decomposition_cond_change_frac() ) {
126  if( (int)olevel >= (int)PRINT_BASIC_ALGORITHM_INFO ) {
127  out
128  << "\nbeta_change = ( ||R*py+c||/||c|| = " << beta
129  << " ) / ( min ||R*py+c||/||c|| = " << beta_min_ << " )\n"
130  << " = " << (beta/beta_min_) << " > max_decomposition_cond_change_frac = "
131  << max_decomposition_cond_change_frac()
132  << "\n\nSelecting a new decomposition"
133  << " (k = " << algo.state().k() << ") ...\n";
134  }
135  select_new_decomposition = true;
136  }
137  }
138  if(select_new_decomposition) {
139  reset();
140  return new_decomp_strategy().new_decomposition(algo,step_poss,type,assoc_step_poss);
141  }
142  }
143  return true;
144 }
145 
147  , IterationPack::EDoStepType type, poss_type assoc_step_poss
148  , std::ostream& out, const std::string& L ) const
149 {
150  out
151  << L << "*** Try to detect when the decomposition is becomming illconditioned\n"
152  << L << "default: beta_min = inf\n"
153  << L << " max_decomposition_cond_change_frac = " << max_decomposition_cond_change_frac() << std::endl
154  << L << "beta = norm_inf(R*py_k + c_k(decomp)) / (norm_inf(c_k(decomp))+small_number)\n"
155  << L << "select_new_decomposition = false\n"
156  << L << "if num_basis_k is updated then\n"
157  << L << " beta_min = beta\n"
158  << L << "end\n"
159  << L << "if beta < beta_min then\n"
160  << L << " beta_min = beta\n"
161  << L << "else\n"
162  << L << " if beta/ beta_min > max_decomposition_cond_change_frac then\n"
163  << L << " select_new_decomposition = true\n"
164  << L << " end\n"
165  << L << "end\n"
166  << L << "if select_new_decomposition == true then\n"
167  << L << " new decomposition selection : " << typeName(new_decomp_strategy()) << std::endl
168  ;
169  new_decomp_strategy().print_new_decomposition(
170  rsqp_algo(algo),step_poss,type,assoc_step_poss,out, L + " " );
171  out
172  << L << " end new decomposition selection\n"
173  << L << "end\n"
174  ;
175 }
176 
177 } // end namespace MoochoPack
rSQP Algorithm control class.
virtual std::ostream & journal_out() const
void reset()
Call the reset initialization of all defaults.
Reduced space SQP state encapsulation interface.
AlgorithmTracker & track()
AlgorithmState & state()
bool do_step(Algorithm &algo, poss_type step_poss, IterationPack::EDoStepType type, poss_type assoc_step_poss)
NLPAlgoState & rsqp_state()
<<std aggr>="">> members for algo_cntr
void print_step(const Algorithm &algo, poss_type step_poss, IterationPack::EDoStepType type, poss_type assoc_step_poss, std::ostream &out, const std::string &leading_str) const
std::string typeName(const T &t)
void Vp_V(VectorMutable *v_lhs, const V &V_rhs)