45 #include "MoochoPack_MeritFunc_PenaltyParamUpdateGuts_AddedStep.hpp"
46 #include "MoochoPack_moocho_algo_conversion.hpp"
47 #include "IterationPack_print_algorithm_step.hpp"
48 #include "ConstrainedOptPack_MeritFuncNLP.hpp"
49 #include "ConstrainedOptPack_MeritFuncPenaltyParam.hpp"
50 #include "ConstrainedOptPack_MeritFuncNLPDirecDeriv.hpp"
51 #include "AbstractLinAlgPack_Vector.hpp"
52 #include "AbstractLinAlgPack_VectorStdOps.hpp"
57 T my_max(
const T& v1,
const T& v2 ) {
return v1 > v2 ? v1 : v2; }
60 namespace MoochoPack {
64 ,value_type mult_factor
65 ,value_type kkt_near_sol
67 :near_solution_(false)
69 ,mult_factor_(mult_factor)
70 ,kkt_near_sol_(kkt_near_sol)
78 NLPAlgo &algo = rsqp_algo(_algo);
80 NLP &nlp = algo.nlp();
82 EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level();
86 if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) {
87 using IterationPack::print_algorithm_step;
88 print_algorithm_step( algo, step_poss, type, assoc_step_poss, out );
94 IterQuantityAccess<MeritFuncNLP>
95 &merit_func_nlp_iq = s.merit_func_nlp();
97 if( !merit_func_nlp_iq.updated_k(0) ) {
98 const int merit_func_k_last_updated = merit_func_nlp_iq.last_updated();
99 if( merit_func_k_last_updated != IterQuantity::NONE_UPDATED ) {
101 &merit_func_nlp_k_last = merit_func_nlp_iq.get_k(merit_func_k_last_updated);
102 merit_func_nlp_iq.set_k(0) = merit_func_nlp_k_last;
105 merit_func_nlp_iq.set_k(0);
108 &merit_func_nlp_k = merit_func_nlp_iq.get_k(0);
109 MeritFuncPenaltyParam
110 *param =
dynamic_cast<MeritFuncPenaltyParam*
>(&merit_func_nlp_k);
112 !param, std::logic_error
113 ,
"MeritFunc_PenaltyParamUpdateGuts_AddedStep::do_step(...), Error "
114 <<
"The class " <<
typeName(merit_func_nlp_k) <<
" does not support the "
115 <<
"MeritFuncPenaltyParam iterface" );
116 MeritFuncNLPDirecDeriv
117 *direc_deriv =
dynamic_cast<MeritFuncNLPDirecDeriv*
>(&merit_func_nlp_k);
119 !direc_deriv, std::logic_error
120 ,
"MeritFunc_PenaltyParamUpdateGuts_AddedStep::do_step(...), Error "
121 <<
"The class " <<
typeName(merit_func_nlp_k) <<
" does not support the "
122 <<
"MeritFuncNLPDirecDeriv iterface" );
123 value_type new_mu = 0.0;
125 if ( this->
min_mu(s,&min_mu) ) {
127 if( (
int)olevel >= (
int)PRINT_ALGORITHM_STEPS ) {
128 out <<
"\nUpdate the penalty parameter...\n";
131 mu_km1 = param->mu(),
132 mult_fact = (1.0 + mult_factor_);
134 if( (
int)olevel >= (int)PRINT_ALGORITHM_STEPS ) {
135 out <<
"\nNear solution, forcing mu_k >= mu_km1...\n";
137 new_mu = my_max( my_max( mu_km1, mult_fact * min_mu ), small_mu_ );
140 if( (
int)olevel >= (
int)PRINT_ALGORITHM_STEPS ) {
141 out <<
"\nNot near solution, allowing reduction in mu ...\n";
144 (3.0 * mu_km1 + min_mu) / 4.0
145 , my_max( mult_fact * min_mu, small_mu_ )
148 kkt_error = s.opt_kkt_err().get_k(0) + s.feas_kkt_err().get_k(0);
149 if(kkt_error <= kkt_near_sol_) {
150 if( (
int)olevel >= (
int)PRINT_ALGORITHM_STEPS ) {
151 out <<
"\nkkt_error = " << kkt_error <<
" <= kkt_near_sol = "
152 << kkt_near_sol_ << std::endl
153 <<
"Switching to forcing mu_k >= mu_km1 in the future\n";
155 near_solution_ =
true;
160 if( (
int)olevel >= (
int)PRINT_ALGORITHM_STEPS ) {
161 out <<
"\nDon't have the info to update penalty parameter so just use the last updated...\n";
163 new_mu = param->mu();
168 direc_deriv->calc_deriv(
170 ,m ? &s.c().get_k(0) : NULL
177 if( (
int)olevel >= (int)PRINT_ALGORITHM_STEPS ) {
178 out <<
"\nmu = " << new_mu <<
"\n";
186 , std::ostream& out,
const std::string& L )
const
189 << L <<
"*** Update the penalty parameter for the merit function to ensure\n"
190 << L <<
"*** a descent direction a directional derivatieve.\n"
191 << L <<
"*** phi is a merit function object that uses the penalty parameter mu.\n"
192 << L <<
"default: near_solution = false\n"
193 << L <<
" small_mu = " << small_mu_ << std::endl
194 << L <<
" mult_factor = " << mult_factor_ << std::endl
195 << L <<
" kkt_near_sol = " << kkt_near_sol_ << std::endl
196 << L <<
"if merit_func_nlp_k is not already updated then\n"
197 << L <<
" if some merit_func_nlp_k(?) has been udpated then\n"
198 << L <<
" merit_func_nlp_k = merit_func_nlp_k(last_udpated)\n"
200 << L <<
" merit_func_nlp_k = default construction\n"
202 << L <<
" if merit_func_nlp_k does not support MeritFuncPenaltyParam throw excpetion\n"
203 << L <<
" if merit_func_nlp_k does not support MeritFuncNLPDirecDeriv throw excpetion\n"
207 << L <<
" mu_new = merit_func_nlp_k.mu()\n"
208 << L <<
" if update_mu == true then\n"
209 << L <<
" mu_last = merit_func_nlp_k.mu()\n"
210 << L <<
" mult_fact = 1.0 + mult_factor\n"
211 << L <<
" if near_solution == true\n"
212 << L <<
" mu_new = max( max( mu_last, mult_fact*min_mu ), small_mu )\n"
214 << L <<
" mu_new = max( ( 3.0 * mu_last + min_mu ) / 4.0\n"
215 << L <<
" , max( mult_fact * min_mu , small_mu ) )\n"
216 << L <<
" kkt_error = opt_kkt_err_k + feas_kkt_err_k\n"
217 << L <<
" if kkt_error <= kkt_near_sol then\n"
218 << L <<
" near_solution = true\n"
222 << L <<
" mu_new = merit_func_nlp_k.mu()\n"
224 << L <<
" merit_func_nlp_k..mu(mu_new)\n"
225 << L <<
" merit_func_nlp_k.calc_deriv(Gf_k,c_k,h_k,hl,hu,d_k)\n"
259 return kkt_near_sol_;
MeritFunc_PenaltyParamUpdateGuts_AddedStep(value_type small_mu, value_type mult_factor, value_type kkt_near_sol)
virtual void print_min_mu_step(std::ostream &out, const std::string &leading_str) const =0
Override to print how min_mu calculated.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
virtual bool min_mu(NLPAlgoState &s, value_type *min_mu) const =0
Override to determine the mininum value of mu the penalty parameter can take on.
rSQP Algorithm control class.
value_type small_mu() const
bool do_step(Algorithm &algo, poss_type step_poss, IterationPack::EDoStepType type, poss_type assoc_step_poss)
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
virtual std::ostream & journal_out() const
value_type mult_factor() const
Reduced space SQP state encapsulation interface.
AlgorithmTracker & track()
value_type kkt_near_sol() const
NLPAlgoState & rsqp_state()
<<std aggr>="">> members for algo_cntr
std::string typeName(const T &t)