bool MoochoPack::CrossTermExactStd_Step::do_step(Algorithm& _algo , poss_type step_poss, IterationPack::EDoStepType type, poss_type assoc_step_poss) { using LinAlgOpPack::V_MtV; using DenseLinAlgPack::norm_inf; NLPAlgo &algo = rsqp_algo(_algo); NLPAlgoState &s = algo.rsqp_state(); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); std::ostream& out = algo.track().journal_out(); // print step header. if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { using IterationPack::print_algorithm_step; print_algorithm_step( _algo, step_poss, type, assoc_step_poss, out ); } // tmp = HL * Ypy DVector tmp; V_MtV( &tmp, s.HL().get_k(0), BLAS_Cpp::no_trans, s.Ypy().get_k(0)() ); // w = Z' * tmp V_MtV( &s.w().set_k(0).v(), s.Z().get_k(0), BLAS_Cpp::trans, tmp() ); if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\n||w||inf = " << s.w().get_k(0).norm_inf() << std::endl; } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "\nw_k =\n" << s.w().get_k(0)(); } return true; }
bool CalcDFromYPY_Step::do_step( Algorithm& _algo, poss_type step_poss, IterationPack::EDoStepType type, poss_type assoc_step_poss ) { NLPAlgo &algo = rsqp_algo(_algo); NLPAlgoState &s = algo.rsqp_state(); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); std::ostream& out = algo.track().journal_out(); // print step header. if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { using IterationPack::print_algorithm_step; print_algorithm_step( algo, step_poss, type, assoc_step_poss, out ); } // d = Ypy VectorMutable &d_k = s.d().set_k(0) = s.Ypy().get_k(0); if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\n||d||inf = " << d_k.norm_inf() << std::endl; } if( (int)olevel >= (int)PRINT_VECTORS ) { out << "\nd_k = \n" << d_k; } return true; }
bool SetDBoundsStd_AddedStep::do_step( Algorithm& _algo, poss_type step_poss, IterationPack::EDoStepType type ,poss_type assoc_step_poss ) { NLPAlgo &algo = rsqp_algo(_algo); NLPAlgoState &s = algo.rsqp_state(); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); EJournalOutputLevel ns_olevel = algo.algo_cntr().null_space_journal_output_level(); std::ostream &out = algo.track().journal_out(); // print step header. if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { using IterationPack::print_algorithm_step; print_algorithm_step( algo, step_poss, type, assoc_step_poss, out ); } const Range1D var_dep = s.var_dep(), var_indep = s.var_indep(); const Vector &x_k = s.x().get_k(0), &xl = algo.nlp().xl(), &xu = algo.nlp().xu(); VectorMutable &dl = dl_iq_(s).set_k(0), &du = du_iq_(s).set_k(0); // dl = xl - x_k LinAlgOpPack::V_VmV( &dl, xl, x_k ); // du = xu - x_k LinAlgOpPack::V_VmV( &du, xu, x_k ); if( static_cast<int>(ns_olevel) >= static_cast<int>(PRINT_VECTORS) ) { if(var_indep.size()) { out << "\ndl(var_indep)_k = \n" << *dl.sub_view(var_indep); out << "\ndu(var_indep)_k = \n" << *du.sub_view(var_indep); } } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { if(var_dep.size()) { out << "\ndl(var_dep)_k = \n" << *dl.sub_view(var_dep); out << "\ndu(var_dep)_k = \n" << *du.sub_view(var_dep); } out << "\ndl_k = \n" << dl; out << "\ndu_k = \n" << du; } return true; }
bool CheckDescentQuasiNormalStep_Step::do_step( Algorithm& _algo, poss_type step_poss, IterationPack::EDoStepType type ,poss_type assoc_step_poss ) { using BLAS_Cpp::no_trans; using AbstractLinAlgPack::dot; using LinAlgOpPack::V_MtV; NLPAlgo &algo = rsqp_algo(_algo); NLPAlgoState &s = algo.rsqp_state(); NLP &nlp = algo.nlp(); const Range1D equ_decomp = s.equ_decomp(); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); std::ostream& out = algo.track().journal_out(); // print step header. if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { using IterationPack::print_algorithm_step; print_algorithm_step( algo, step_poss, type, assoc_step_poss, out ); } const size_type nb = nlp.num_bounded_x(); // Get iteration quantities IterQuantityAccess<VectorMutable> &c_iq = s.c(), &Ypy_iq = s.Ypy(); const Vector::vec_ptr_t cd_k = c_iq.get_k(0).sub_view(equ_decomp); const Vector &Ypy_k = Ypy_iq.get_k(0); value_type descent_c = -1.0; if( s.get_iter_quant_id( Gc_name ) != AlgorithmState::DOES_NOT_EXIST ) { if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nGc_k exists; compute descent_c = c_k(equ_decomp)'*Gc_k(:,equ_decomp)'*Ypy_k ...\n"; } const MatrixOp::mat_ptr_t Gcd_k = s.Gc().get_k(0).sub_view(Range1D(),equ_decomp); VectorSpace::vec_mut_ptr_t t = cd_k->space().create_member(); V_MtV( t.get(), *Gcd_k, BLAS_Cpp::trans, Ypy_k ); if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "\nGc_k(:,equ_decomp)'*Ypy_k =\n" << *t; } descent_c = dot( *cd_k, *t ); } else { if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nGc_k does not exist; compute descent_c = c_k(equ_decomp)'*FDGc_k(:,equ_decomp)'*Ypy_k " << "using finite differences ...\n"; } VectorSpace::vec_mut_ptr_t t = nlp.space_c()->create_member(); calc_fd_prod().calc_deriv_product( s.x().get_k(0),nb?&nlp.xl():NULL,nb?&nlp.xu():NULL ,Ypy_k,NULL,&c_iq.get_k(0),true,&nlp ,NULL,t.get() ,static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ? &out : NULL ); if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "\nFDGc_k(:,equ_decomp)'*Ypy_k =\n" << *t->sub_view(equ_decomp); } descent_c = dot( *cd_k, *t->sub_view(equ_decomp) ); } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\ndescent_c = " << descent_c << std::endl; } if( descent_c > 0.0 ) { // ToDo: add some allowance for > 0.0 for finite difference errors! if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nError, descent_c > 0.0; this is not a descent direction\n" << "Throw TestFailed and terminate the algorithm ...\n"; } TEST_FOR_EXCEPTION( true, TestFailed ,"CheckDescentQuasiNormalStep_Step::do_step(...) : Error, descent for the decomposed constraints " "with respect to the quasi-normal step c_k(equ_decomp)'*FDGc_k(:,equ_decomp)'*Ypy_k = " << descent_c << " > 0.0; This is not a descent direction!\n" ); } return true; }
bool TangentialStepIP_Step::do_step( Algorithm& _algo, poss_type step_poss, IterationPack::EDoStepType type ,poss_type assoc_step_poss ) { using BLAS_Cpp::no_trans; using Teuchos::dyn_cast; using AbstractLinAlgPack::assert_print_nan_inf; using LinAlgOpPack::Vt_S; using LinAlgOpPack::Vp_StV; using LinAlgOpPack::V_StV; using LinAlgOpPack::V_MtV; using LinAlgOpPack::V_InvMtV; using LinAlgOpPack::M_StM; using LinAlgOpPack::Mp_StM; using LinAlgOpPack::assign; NLPAlgo &algo = rsqp_algo(_algo); IpState &s = dyn_cast<IpState>(_algo.state()); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); std::ostream& out = algo.track().journal_out(); // print step header. if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { using IterationPack::print_algorithm_step; print_algorithm_step( algo, step_poss, type, assoc_step_poss, out ); } // Compute qp_grad which is an approximation to rGf + Z'*(mu*(invXu*e-invXl*e) + no_cross_term // minimize round off error by calc'ing Z'*(Gf + mu*(invXu*e-invXl*e)) // qp_grad_k = Z'*(Gf + mu*(invXu*e-invXl*e)) const MatrixSymDiagStd &invXu = s.invXu().get_k(0); const MatrixSymDiagStd &invXl = s.invXl().get_k(0); const value_type &mu = s.barrier_parameter().get_k(0); const MatrixOp &Z_k = s.Z().get_k(0); Teuchos::RCP<VectorMutable> rhs = s.Gf().get_k(0).clone(); Vp_StV( rhs.get(), mu, invXu.diag() ); Vp_StV( rhs.get(), -1.0*mu, invXl.diag() ); if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\n||Gf_k + mu_k*(invXu_k-invXl_k)||inf = " << rhs->norm_inf() << std::endl; } if( (int)olevel >= (int)PRINT_VECTORS) { out << "\nGf_k + mu_k*(invXu_k-invXl_k) =\n" << *rhs; } VectorMutable &qp_grad_k = s.qp_grad().set_k(0); V_MtV(&qp_grad_k, Z_k, BLAS_Cpp::trans, *rhs); if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\n||Z_k'*(Gf_k + mu_k*(invXu_k-invXl_k))||inf = " << qp_grad_k.norm_inf() << std::endl; } if( (int)olevel >= (int)PRINT_VECTORS ) { out << "\nZ_k'*(Gf_k + mu_k*(invXu_k-invXl_k)) =\n" << qp_grad_k; } // error check for cross term value_type &zeta = s.zeta().set_k(0); const Vector &w_sigma = s.w_sigma().get_k(0); // need code to calculate damping parameter zeta = 1.0; Vp_StV(&qp_grad_k, zeta, w_sigma); if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\n||qp_grad_k||inf = " << qp_grad_k.norm_inf() << std::endl; } if( (int)olevel >= (int)PRINT_VECTORS ) { out << "\nqp_grad_k =\n" << qp_grad_k; } // build the "Hessian" term B = rHL + rHB // should this be MatrixSymOpNonsing const MatrixSymOp &rHL_k = s.rHL().get_k(0); const MatrixSymOp &rHB_k = s.rHB().get_k(0); MatrixSymOpNonsing &B_k = dyn_cast<MatrixSymOpNonsing>(s.B().set_k(0)); if (B_k.cols() != Z_k.cols()) { // Initialize space in rHB dyn_cast<MatrixSymInitDiag>(B_k).init_identity(Z_k.space_rows(), 0.0); } // M_StM(&B_k, 1.0, rHL_k, no_trans); assign(&B_k, rHL_k, BLAS_Cpp::no_trans); if( (int)olevel >= (int)PRINT_VECTORS ) { out << "\nB_k = rHL_k =\n" << B_k; } Mp_StM(&B_k, 1.0, rHB_k, BLAS_Cpp::no_trans); if( (int)olevel >= (int)PRINT_VECTORS ) { out << "\nB_k = rHL_k + rHB_k =\n" << B_k; } // Solve the system pz = - inv(rHL) * qp_grad VectorMutable &pz_k = s.pz().set_k(0); V_InvMtV( &pz_k, B_k, no_trans, qp_grad_k ); Vt_S( &pz_k, -1.0 ); // Zpz = Z * pz V_MtV( &s.Zpz().set_k(0), s.Z().get_k(0), no_trans, pz_k ); if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\n||pz||inf = " << s.pz().get_k(0).norm_inf() << "\nsum(Zpz) = " << AbstractLinAlgPack::sum(s.Zpz().get_k(0)) << std::endl; } if( (int)olevel >= (int)PRINT_VECTORS ) { out << "\npz_k = \n" << s.pz().get_k(0); out << "\nnu_k = \n" << s.nu().get_k(0); out << "\nZpz_k = \n" << s.Zpz().get_k(0); out << std::endl; } if(algo.algo_cntr().check_results()) { assert_print_nan_inf(s.pz().get_k(0), "pz_k",true,&out); assert_print_nan_inf(s.Zpz().get_k(0), "Zpz_k",true,&out); } return true; }
bool MoochoPack::CalcDFromYPYZPZ_Step::do_step(Algorithm& _algo , poss_type step_poss, IterationPack::EDoStepType type, poss_type assoc_step_poss) { using Teuchos::implicit_cast; using AbstractLinAlgPack::dot; using LinAlgOpPack::V_VpV; NLPAlgo &algo = rsqp_algo(_algo); NLPAlgoState &s = algo.rsqp_state(); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); EJournalOutputLevel ns_olevel = algo.algo_cntr().null_space_journal_output_level(); std::ostream& out = algo.track().journal_out(); // print step header. if( implicit_cast<int>(olevel) >= implicit_cast<int>(PRINT_ALGORITHM_STEPS) ) { using IterationPack::print_algorithm_step; print_algorithm_step( algo, step_poss, type, assoc_step_poss, out ); } // d = Ypy + Zpz VectorMutable &d_k = s.d().set_k(0); const Vector &Ypy_k = s.Ypy().get_k(0); const Vector &Zpz_k = s.Zpz().get_k(0); V_VpV( &d_k, Ypy_k, Zpz_k ); Range1D var_dep = s.var_dep(), var_indep = s.var_indep(); if( implicit_cast<int>(olevel) >= implicit_cast<int>(PRINT_ALGORITHM_STEPS) ) { const value_type very_small = std::numeric_limits<value_type>::min(); out << "\n(Ypy_k'*Zpz_k)/(||Ypy_k||2 * ||Zpz_k||2 + eps)\n" << " = ("<<dot(Ypy_k,Zpz_k)<<")/("<<Ypy_k.norm_2()<<" * "<<Zpz_k.norm_2()<<" + "<<very_small<<")\n" << " = " << dot(Ypy_k,Zpz_k) / ( Ypy_k.norm_2() * Zpz_k.norm_2() + very_small ) << "\n"; /* ConstrainedOptPack::print_vector_change_stats( s.x().get_k(0), "x", s.d().get_k(0), "d", out ); */ // ToDo: Replace the above with a reduction operator! } if( implicit_cast<int>(olevel) >= implicit_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\n||d_k||inf = " << d_k.norm_inf(); if( var_dep.size() ) out << "\n||d(var_dep)_k||inf = " << d_k.sub_view(var_dep)->norm_inf(); if( var_indep.size() ) out << "\n||d(var_indep)_k||inf = " << d_k.sub_view(var_indep)->norm_inf(); out << std::endl; } if( implicit_cast<int>(olevel) >= implicit_cast<int>(PRINT_VECTORS) ) { out << "\nd_k = \n" << d_k; if( var_dep.size() ) out << "\nd(var_dep)_k = \n" << *d_k.sub_view(var_dep); } if( implicit_cast<int>(ns_olevel) >= implicit_cast<int>(PRINT_VECTORS) ) { if( var_indep.size() ) out << "\nd(var_indep)_k = \n" << *d_k.sub_view(var_indep); } return true; }
bool ReducedHessianExactStd_Step::do_step( Algorithm& _algo, poss_type step_poss, IterationPack::EDoStepType type , poss_type assoc_step_poss) { using Teuchos::dyn_cast; using DenseLinAlgPack::nonconst_sym; using AbstractLinAlgPack::Mp_StMtMtM; typedef AbstractLinAlgPack::MatrixSymDenseInitialize MatrixSymDenseInitialize; typedef AbstractLinAlgPack::MatrixSymOp MatrixSymOp; using ConstrainedOptPack::NLPSecondOrder; NLPAlgo &algo = rsqp_algo(_algo); NLPAlgoState &s = algo.rsqp_state(); NLPSecondOrder #ifdef _WINDOWS &nlp = dynamic_cast<NLPSecondOrder&>(algo.nlp()); #else &nlp = dyn_cast<NLPSecondOrder>(algo.nlp()); #endif MatrixSymOp *HL_sym_op = dynamic_cast<MatrixSymOp*>(&s.HL().get_k(0)); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); std::ostream& out = algo.track().journal_out(); // print step header. if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { using IterationPack::print_algorithm_step; print_algorithm_step( algo, step_poss, type, assoc_step_poss, out ); } // problem size size_type n = nlp.n(), r = nlp.r(), nind = n - r; // Compute HL first (You may want to move this into its own step later?) if( !s.lambda().updated_k(-1) ) { if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "Initializing lambda_km1 = nlp.get_lambda_init ... \n"; } nlp.get_init_lagrange_mult( &s.lambda().set_k(-1).v(), NULL ); if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "||lambda_km1||inf = " << s.lambda().get_k(-1).norm_inf() << std::endl; } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "lambda_km1 = \n" << s.lambda().get_k(-1)(); } } nlp.set_HL( HL_sym_op ); nlp.calc_HL( s.x().get_k(0)(), s.lambda().get_k(-1)(), false ); if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ITERATION_QUANTITIES) ) { s.HL().get_k(0).output( out << "\nHL_k = \n" ); } // If rHL has already been updated for this iteration then just leave it. if( !s.rHL().updated_k(0) ) { if( !HL_sym_op ) { std::ostringstream omsg; omsg << "ReducedHessianExactStd_Step::do_step(...) : Error, " << "The matrix HL with the concrete type " << typeName(s.HL().get_k(0)) << " does not support the " << "MatrixSymOp iterface"; throw std::logic_error( omsg.str() ); } MatrixSymDenseInitialize *rHL_sym_init = dynamic_cast<MatrixSymDenseInitialize*>(&s.rHL().set_k(0)); if( !rHL_sym_init ) { std::ostringstream omsg; omsg << "ReducedHessianExactStd_Step::do_step(...) : Error, " << "The matrix rHL with the concrete type " << typeName(s.rHL().get_k(0)) << " does not support the " << "MatrixSymDenseInitialize iterface"; throw std::logic_error( omsg.str() ); } // Compute the dense reduced Hessian DMatrix rHL_sym_store(nind,nind); DMatrixSliceSym rHL_sym(rHL_sym_store(),BLAS_Cpp::lower); Mp_StMtMtM( &rHL_sym, 1.0, MatrixSymOp::DUMMY_ARG, *HL_sym_op , s.Z().get_k(0), BLAS_Cpp::no_trans, 0.0 ); if( (int)olevel >= (int)PRINT_ITERATION_QUANTITIES ) { out << "\nLower triangular partion of dense reduced Hessian (ignore nonzeros above diagonal):\nrHL_dense = \n" << rHL_sym_store(); } // Set the reduced Hessain rHL_sym_init->initialize( rHL_sym ); if( (int)olevel >= (int)PRINT_ITERATION_QUANTITIES ) { s.rHL().get_k(0).output( out << "\nrHL_k = \n" ); } } return true; }
bool TangentialStepWithInequStd_Step::do_step( Algorithm& _algo, poss_type step_poss, IterationPack::EDoStepType type ,poss_type assoc_step_poss ) { using Teuchos::RCP; using Teuchos::dyn_cast; using ::fabs; using LinAlgOpPack::Vt_S; using LinAlgOpPack::V_VpV; using LinAlgOpPack::V_VmV; using LinAlgOpPack::Vp_StV; using LinAlgOpPack::Vp_V; using LinAlgOpPack::V_StV; using LinAlgOpPack::V_MtV; // using ConstrainedOptPack::min_abs; using AbstractLinAlgPack::max_near_feas_step; typedef VectorMutable::vec_mut_ptr_t vec_mut_ptr_t; NLPAlgo &algo = rsqp_algo(_algo); NLPAlgoState &s = algo.rsqp_state(); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); EJournalOutputLevel ns_olevel = algo.algo_cntr().null_space_journal_output_level(); std::ostream &out = algo.track().journal_out(); //const bool check_results = algo.algo_cntr().check_results(); // print step header. if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { using IterationPack::print_algorithm_step; print_algorithm_step( algo, step_poss, type, assoc_step_poss, out ); } // problem dimensions const size_type //n = algo.nlp().n(), m = algo.nlp().m(), r = s.equ_decomp().size(); // Get the iteration quantity container objects IterQuantityAccess<value_type> &alpha_iq = s.alpha(), &zeta_iq = s.zeta(), &eta_iq = s.eta(); IterQuantityAccess<VectorMutable> &dl_iq = dl_iq_(s), &du_iq = du_iq_(s), &nu_iq = s.nu(), *c_iq = m > 0 ? &s.c() : NULL, *lambda_iq = m > 0 ? &s.lambda() : NULL, &rGf_iq = s.rGf(), &w_iq = s.w(), &qp_grad_iq = s.qp_grad(), &py_iq = s.py(), &pz_iq = s.pz(), &Ypy_iq = s.Ypy(), &Zpz_iq = s.Zpz(); IterQuantityAccess<MatrixOp> &Z_iq = s.Z(), //*Uz_iq = (m > r) ? &s.Uz() : NULL, *Uy_iq = (m > r) ? &s.Uy() : NULL; IterQuantityAccess<MatrixSymOp> &rHL_iq = s.rHL(); IterQuantityAccess<ActSetStats> &act_set_stats_iq = act_set_stats_(s); // Accessed/modified/updated (just some) VectorMutable *Ypy_k = (m ? &Ypy_iq.get_k(0) : NULL); const MatrixOp &Z_k = Z_iq.get_k(0); VectorMutable &pz_k = pz_iq.set_k(0); VectorMutable &Zpz_k = Zpz_iq.set_k(0); // Comupte qp_grad which is an approximation to rGf + Z'*HL*Y*py // qp_grad = rGf VectorMutable &qp_grad_k = ( qp_grad_iq.set_k(0) = rGf_iq.get_k(0) ); // qp_grad += zeta * w if( w_iq.updated_k(0) ) { if(zeta_iq.updated_k(0)) Vp_StV( &qp_grad_k, zeta_iq.get_k(0), w_iq.get_k(0) ); else Vp_V( &qp_grad_k, w_iq.get_k(0) ); } // // Set the bounds for: // // dl <= Z*pz + Y*py <= du -> dl - Ypy <= Z*pz <= du - Ypz vec_mut_ptr_t bl = s.space_x().create_member(), bu = s.space_x().create_member(); if(m) { // bl = dl_k - Ypy_k V_VmV( bl.get(), dl_iq.get_k(0), *Ypy_k ); // bu = du_k - Ypy_k V_VmV( bu.get(), du_iq.get_k(0), *Ypy_k ); } else { *bl = dl_iq.get_k(0); *bu = du_iq.get_k(0); } // Print out the QP bounds for the constraints if( static_cast<int>(ns_olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "\nqp_grad_k = \n" << qp_grad_k; } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "\nbl = \n" << *bl; out << "\nbu = \n" << *bu; } // // Determine if we should perform a warm start or not. // bool do_warm_start = false; if( act_set_stats_iq.updated_k(-1) ) { if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nDetermining if the QP should use a warm start ...\n"; } // We need to see if we should preform a warm start for the next iteration ActSetStats &stats = act_set_stats_iq.get_k(-1); const size_type num_active = stats.num_active(), num_adds = stats.num_adds(), num_drops = stats.num_drops(); const value_type frac_same = ( num_adds == ActSetStats::NOT_KNOWN || num_active == 0 ? 0.0 : my_max(((double)(num_active)-num_adds-num_drops) / num_active, 0.0 ) ); do_warm_start = ( num_active > 0 && frac_same >= warm_start_frac() ); if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nnum_active = " << num_active; if( num_active ) { out << "\nmax(num_active-num_adds-num_drops,0)/(num_active) = " << "max("<<num_active<<"-"<<num_adds<<"-"<<num_drops<<",0)/("<<num_active<<") = " << frac_same; if( do_warm_start ) out << " >= "; else out << " < "; out << "warm_start_frac = " << warm_start_frac(); } if( do_warm_start ) out << "\nUse a warm start this time!\n"; else out << "\nDon't use a warm start this time!\n"; } } // Use active set from last iteration as an estimate for current active set // if we are to use a warm start. // // ToDo: If the selection of dependent and independent variables changes // then you will have to adjust this or not perform a warm start at all! if( do_warm_start ) { nu_iq.set_k(0,-1); } else { nu_iq.set_k(0) = 0.0; // No guess of the active set } VectorMutable &nu_k = nu_iq.get_k(0); // // Setup the reduced QP subproblem // // The call to the QP is setup for the more flexible call to the QPSolverRelaxed // interface to deal with the three independent variabilities: using simple // bounds for pz or not, general inequalities included or not, and extra equality // constraints included or not. // If this method of calling the QP solver were not used then 4 separate // calls to solve_qp(...) would have to be included to handle the four possible // QP formulations. // // The numeric arguments for the QP solver (in the nomenclatrue of QPSolverRelaxed) const value_type qp_bnd_inf = NLP::infinite_bound(); const Vector &qp_g = qp_grad_k; const MatrixSymOp &qp_G = rHL_iq.get_k(0); const value_type qp_etaL = 0.0; vec_mut_ptr_t qp_dL = Teuchos::null; vec_mut_ptr_t qp_dU = Teuchos::null; Teuchos::RCP<const MatrixOp> qp_E = Teuchos::null; BLAS_Cpp::Transp qp_trans_E = BLAS_Cpp::no_trans; vec_mut_ptr_t qp_b = Teuchos::null; vec_mut_ptr_t qp_eL = Teuchos::null; vec_mut_ptr_t qp_eU = Teuchos::null; Teuchos::RCP<const MatrixOp> qp_F = Teuchos::null; BLAS_Cpp::Transp qp_trans_F = BLAS_Cpp::no_trans; vec_mut_ptr_t qp_f = Teuchos::null; value_type qp_eta = 0.0; VectorMutable &qp_d = pz_k; // pz_k will be updated directly! vec_mut_ptr_t qp_nu = Teuchos::null; vec_mut_ptr_t qp_mu = Teuchos::null; vec_mut_ptr_t qp_Ed = Teuchos::null; vec_mut_ptr_t qp_lambda = Teuchos::null; // // Determine if we can use simple bounds on pz. // // If we have a variable-reduction null-space matrix // (with any choice for Y) then: // // d = Z*pz + (1-eta) * Y*py // // [ d(var_dep) ] = [ D ] * pz + (1-eta) * [ Ypy(var_dep) ] // [ d(var_indep) ] [ I ] [ Ypy(var_indep) ] // // For a cooridinate decomposition (Y = [ I ; 0 ]) then Ypy(var_indep) == // 0.0 and in this case the bounds on d(var_indep) become simple bounds on // pz even with the relaxation. Also, if dl(var_dep) and du(var_dep) are // unbounded, then we can also use simple bounds since we don't need the // relaxation and we can set eta=0. In this case we just have to subtract // from the upper and lower bounds on pz! // // Otherwise, we can not use simple variable bounds and implement the // relaxation properly. // const MatrixIdentConcat *Zvr = dynamic_cast<const MatrixIdentConcat*>( &Z_k ); const Range1D var_dep = Zvr ? Zvr->D_rng() : Range1D::Invalid, var_indep = Zvr ? Zvr->I_rng() : Range1D(); RCP<Vector> Ypy_indep; const value_type Ypy_indep_norm_inf = ( m ? (Ypy_indep=Ypy_k->sub_view(var_indep))->norm_inf() : 0.0); if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) out << "\nDetermine if we can use simple bounds on pz ...\n" << " m = " << m << std::endl << " dynamic_cast<const MatrixIdentConcat*>(&Z_k) = " << Zvr << std::endl << " ||Ypy_k(var_indep)||inf = " << Ypy_indep_norm_inf << std::endl; const bool bounded_var_dep = ( m > 0 && num_bounded( *bl->sub_view(var_dep), *bu->sub_view(var_dep), qp_bnd_inf ) ); const bool use_simple_pz_bounds = ( m == 0 || ( Zvr != NULL && ( Ypy_indep_norm_inf == 0.0 || bounded_var_dep == 0 ) ) ); if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) out << (use_simple_pz_bounds ? "\nUsing simple bounds on pz ...\n" : "\nUsing bounds on full Z*pz ...\n") << (bounded_var_dep ? "\nThere are finite bounds on dependent variables. Adding extra inequality constrints for D*pz ...\n" : "\nThere are no finite bounds on dependent variables. There will be no extra inequality constraints added on D*pz ...\n" ) ; if( use_simple_pz_bounds ) { // Set simple bound constraints on pz qp_dL = bl->sub_view(var_indep); qp_dU = bu->sub_view(var_indep); qp_nu = nu_k.sub_view(var_indep); // nu_k(var_indep) will be updated directly! if( m && bounded_var_dep ) { // Set general inequality constraints for D*pz qp_E = Teuchos::rcp(&Zvr->D(),false); qp_b = Ypy_k->sub_view(var_dep); qp_eL = bl->sub_view(var_dep); qp_eU = bu->sub_view(var_dep); qp_mu = nu_k.sub_view(var_dep); // nu_k(var_dep) will be updated directly! qp_Ed = Zpz_k.sub_view(var_dep); // Zpz_k(var_dep) will be updated directly! } else { // Leave these as NULL since there is no extra general inequality constraints } } else if( !use_simple_pz_bounds ) { // ToDo: Leave out parts for unbounded dependent variables! // There are no simple bounds! (leave qp_dL, qp_dU and qp_nu as null) // Set general inequality constraints for Z*pz qp_E = Teuchos::rcp(&Z_k,false); qp_b = Teuchos::rcp(Ypy_k,false); qp_eL = bl; qp_eU = bu; qp_mu = Teuchos::rcp(&nu_k,false); qp_Ed = Teuchos::rcp(&Zpz_k,false); // Zpz_k will be updated directly! } else { TEST_FOR_EXCEPT(true); } // Set the general equality constriants (if they exist) Range1D equ_undecomp = s.equ_undecomp(); if( m > r && m > 0 ) { // qp_f = Uy_k * py_k + c_k(equ_undecomp) qp_f = s.space_c().sub_space(equ_undecomp)->create_member(); V_MtV( qp_f.get(), Uy_iq->get_k(0), BLAS_Cpp::no_trans, py_iq.get_k(0) ); Vp_V( qp_f.get(), *c_iq->get_k(0).sub_view(equ_undecomp) ); // Must resize for the undecomposed constriants if it has not already been qp_F = Teuchos::rcp(&Uy_iq->get_k(0),false); qp_lambda = lambda_iq->set_k(0).sub_view(equ_undecomp); // lambda_k(equ_undecomp), will be updated directly! } // Setup the rest of the arguments QPSolverRelaxed::EOutputLevel qp_olevel; switch( olevel ) { case PRINT_NOTHING: qp_olevel = QPSolverRelaxed::PRINT_NONE; break; case PRINT_BASIC_ALGORITHM_INFO: qp_olevel = QPSolverRelaxed::PRINT_NONE; break; case PRINT_ALGORITHM_STEPS: qp_olevel = QPSolverRelaxed::PRINT_BASIC_INFO; break; case PRINT_ACTIVE_SET: qp_olevel = QPSolverRelaxed::PRINT_ITER_SUMMARY; break; case PRINT_VECTORS: qp_olevel = QPSolverRelaxed::PRINT_ITER_VECTORS; break; case PRINT_ITERATION_QUANTITIES: qp_olevel = QPSolverRelaxed::PRINT_EVERY_THING; break; default: TEST_FOR_EXCEPT(true); } // ToDo: Set print options so that only vectors matrices etc // are only printed in the null space // // Solve the QP // qp_solver().infinite_bound(qp_bnd_inf); const QPSolverStats::ESolutionType solution_type = qp_solver().solve_qp( int(olevel) == int(PRINT_NOTHING) ? NULL : &out ,qp_olevel ,( algo.algo_cntr().check_results() ? QPSolverRelaxed::RUN_TESTS : QPSolverRelaxed::NO_TESTS ) ,qp_g, qp_G, qp_etaL, qp_dL.get(), qp_dU.get() ,qp_E.get(), qp_trans_E, qp_E.get() ? qp_b.get() : NULL ,qp_E.get() ? qp_eL.get() : NULL, qp_E.get() ? qp_eU.get() : NULL ,qp_F.get(), qp_trans_F, qp_F.get() ? qp_f.get() : NULL ,NULL // obj_d ,&qp_eta, &qp_d ,qp_nu.get() ,qp_mu.get(), qp_E.get() ? qp_Ed.get() : NULL ,qp_F.get() ? qp_lambda.get() : NULL ,NULL // qp_Fd ); // // Check the optimality conditions for the QP // std::ostringstream omsg; bool throw_qp_failure = false; if( qp_testing() == QP_TEST || ( qp_testing() == QP_TEST_DEFAULT && algo.algo_cntr().check_results() ) ) { if( int(olevel) >= int(PRINT_ALGORITHM_STEPS) ) { out << "\nChecking the optimality conditions of the reduced QP subproblem ...\n"; } if(!qp_tester().check_optimality_conditions( solution_type,qp_solver().infinite_bound() ,int(olevel) == int(PRINT_NOTHING) ? NULL : &out ,int(olevel) >= int(PRINT_VECTORS) ? true : false ,int(olevel) >= int(PRINT_ITERATION_QUANTITIES) ? true : false ,qp_g, qp_G, qp_etaL, qp_dL.get(), qp_dU.get() ,qp_E.get(), qp_trans_E, qp_E.get() ? qp_b.get() : NULL ,qp_E.get() ? qp_eL.get() : NULL, qp_E.get() ? qp_eU.get() : NULL ,qp_F.get(), qp_trans_F, qp_F.get() ? qp_f.get() : NULL ,NULL // obj_d ,&qp_eta, &qp_d ,qp_nu.get() ,qp_mu.get(), qp_E.get() ? qp_Ed.get() : NULL ,qp_F.get() ? qp_lambda.get() : NULL ,NULL // qp_Fd )) { omsg << "\n*** Alert! at least one of the QP optimality conditions did not check out.\n"; if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << omsg.str(); } throw_qp_failure = true; } } // // Set the solution // if( !use_simple_pz_bounds ) { // Everything is already updated! } else if( use_simple_pz_bounds ) { // Just have to set Zpz_k(var_indep) = pz_k *Zpz_k.sub_view(var_indep) = pz_k; if( m && !bounded_var_dep ) { // Must compute Zpz_k(var_dep) = D*pz LinAlgOpPack::V_MtV( &*Zpz_k.sub_view(var_dep), Zvr->D(), BLAS_Cpp::no_trans, pz_k ); // ToDo: Remove the compuation of Zpz here unless you must } } else { TEST_FOR_EXCEPT(true); } // Set the solution statistics qp_solver_stats_(s).set_k(0) = qp_solver().get_qp_stats(); // Cut back Ypy_k = (1-eta) * Ypy_k const value_type eps = std::numeric_limits<value_type>::epsilon(); if( fabs(qp_eta - 0.0) > eps ) { if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\n*** Alert! the QP was infeasible (eta = "<<qp_eta<<"). Cutting back Ypy_k = (1.0 - eta)*Ypy_k ...\n"; } Vt_S( Ypy_k, 1.0 - qp_eta ); } // eta_k eta_iq.set_k(0) = qp_eta; // // Modify the solution if we have to! // switch(solution_type) { case QPSolverStats::OPTIMAL_SOLUTION: break; // we are good! case QPSolverStats::PRIMAL_FEASIBLE_POINT: { omsg << "\n*** Alert! the returned QP solution is PRIMAL_FEASIBLE_POINT but not optimal!\n"; if( primal_feasible_point_error() ) omsg << "\n*** primal_feasible_point_error == true, this is an error!\n"; if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << omsg.str(); } throw_qp_failure = primal_feasible_point_error(); break; } case QPSolverStats::DUAL_FEASIBLE_POINT: { omsg << "\n*** Alert! the returned QP solution is DUAL_FEASIBLE_POINT" << "\n*** but not optimal so we cut back the step ...\n"; if( dual_feasible_point_error() ) omsg << "\n*** dual_feasible_point_error == true, this is an error!\n"; if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << omsg.str(); } // Cut back the step to fit in the bounds // // dl <= u*(Ypy_k+Zpz_k) <= du // vec_mut_ptr_t zero = s.space_x().create_member(0.0), d_tmp = s.space_x().create_member(); V_VpV( d_tmp.get(), *Ypy_k, Zpz_k ); const std::pair<value_type,value_type> u_steps = max_near_feas_step( *zero, *d_tmp, dl_iq.get_k(0), du_iq.get_k(0), 0.0 ); const value_type u = my_min( u_steps.first, 1.0 ); // largest positive step size alpha_iq.set_k(0) = u; if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nFinding u s.t. dl <= u*(Ypy_k+Zpz_k) <= du\n" << "max step length u = " << u << std::endl << "alpha_k = u = " << alpha_iq.get_k(0) << std::endl; } throw_qp_failure = dual_feasible_point_error(); break; } case QPSolverStats::SUBOPTIMAL_POINT: { omsg << "\n*** Alert!, the returned QP solution is SUBOPTIMAL_POINT!\n"; if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << omsg.str(); } throw_qp_failure = true; break; } default: TEST_FOR_EXCEPT(true); // should not happen! } // // Output the final solution! // if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\n||pz_k||inf = " << s.pz().get_k(0).norm_inf() << "\nnu_k.nz() = " << s.nu().get_k(0).nz() << "\nmax(|nu_k(i)|) = " << s.nu().get_k(0).norm_inf() // << "\nmin(|nu_k(i)|) = " << min_abs( s.nu().get_k(0)() ) ; if( m > r ) out << "\n||lambda_k(undecomp)||inf = " << s.lambda().get_k(0).norm_inf(); out << "\n||Zpz_k||2 = " << s.Zpz().get_k(0).norm_2() ; if(qp_eta > 0.0) out << "\n||Ypy||2 = " << s.Ypy().get_k(0).norm_2(); out << std::endl; } if( static_cast<int>(ns_olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "\npz_k = \n" << s.pz().get_k(0); if(var_indep.size()) out << "\nnu_k(var_indep) = \n" << *s.nu().get_k(0).sub_view(var_indep); } if( static_cast<int>(ns_olevel) >= static_cast<int>(PRINT_VECTORS) ) { if(var_indep.size()) out << "\nZpz(var_indep)_k = \n" << *s.Zpz().get_k(0).sub_view(var_indep); out << std::endl; } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { if(var_dep.size()) out << "\nZpz(var_dep)_k = \n" << *s.Zpz().get_k(0).sub_view(var_dep); out << "\nZpz_k = \n" << s.Zpz().get_k(0); out << std::endl; } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "\nnu_k = \n" << s.nu().get_k(0); if(var_dep.size()) out << "\nnu_k(var_dep) = \n" << *s.nu().get_k(0).sub_view(var_dep); if( m > r ) out << "\nlambda_k(equ_undecomp) = \n" << *s.lambda().get_k(0).sub_view(equ_undecomp); if(qp_eta > 0.0) out << "\nYpy = \n" << s.Ypy().get_k(0); } if( qp_eta == 1.0 ) { omsg << "TangentialStepWithInequStd_Step::do_step(...) : Error, a QP relaxation parameter\n" << "of eta = " << qp_eta << " was calculated and therefore it must be assumed\n" << "that the NLP's constraints are infeasible\n" << "Throwing an InfeasibleConstraints exception!\n"; if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << omsg.str(); } throw InfeasibleConstraints(omsg.str()); } if( throw_qp_failure ) throw QPFailure( omsg.str(), qp_solver().get_qp_stats() ); return true; }
bool LineSearchFullStep_Step::do_step(Algorithm& _algo , poss_type step_poss, IterationPack::EDoStepType type, poss_type assoc_step_poss) { using AbstractLinAlgPack::Vp_StV; using AbstractLinAlgPack::assert_print_nan_inf; using LinAlgOpPack::V_VpV; NLPAlgo &algo = rsqp_algo(_algo); NLPAlgoState &s = algo.rsqp_state(); NLP &nlp = algo.nlp(); const size_type m = nlp.m(); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); std::ostream& out = algo.track().journal_out(); // print step header. if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { using IterationPack::print_algorithm_step; print_algorithm_step( algo, step_poss, type, assoc_step_poss, out ); } // alpha_k = 1.0 IterQuantityAccess<value_type> &alpha_iq = s.alpha(); if( !alpha_iq.updated_k(0) ) alpha_iq.set_k(0) = 1.0; if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nf_k = " << s.f().get_k(0); if(m) out << "\n||c_k||inf = " << s.c().get_k(0).norm_inf(); out << "\nalpha_k = " << alpha_iq.get_k(0) << std::endl; } // x_kp1 = x_k + d_k IterQuantityAccess<VectorMutable> &x_iq = s.x(); const Vector &x_k = x_iq.get_k(0); VectorMutable &x_kp1 = x_iq.set_k(+1); x_kp1 = x_k; Vp_StV( &x_kp1, alpha_iq.get_k(0), s.d().get_k(0) ); if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\n||x_kp1||inf = " << s.x().get_k(+1).norm_inf() << std::endl; } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "\nx_kp1 =\n" << s.x().get_k(+1); } if(algo.algo_cntr().check_results()) { assert_print_nan_inf( x_kp1, "x_kp1",true ,int(olevel) >= int(PRINT_ALGORITHM_STEPS) ? &out : NULL ); if( nlp.num_bounded_x() ) { if(!bounds_tester().check_in_bounds( int(olevel) >= int(PRINT_ALGORITHM_STEPS) ? &out : NULL , int(olevel) >= int(PRINT_VECTORS) // print_all_warnings , int(olevel) >= int(PRINT_ITERATION_QUANTITIES) // print_vectors , nlp.xl(), "xl" , nlp.xu(), "xu" , x_kp1, "x_kp1" )) { TEST_FOR_EXCEPTION( true, TestFailed ,"LineSearchFullStep_Step::do_step(...) : Error, " "the variables bounds xl <= x_k(+1) <= xu where violated!" ); } } } // Calcuate f and c at the new point. nlp.unset_quantities(); nlp.set_f( &s.f().set_k(+1) ); if(m) nlp.set_c( &s.c().set_k(+1) ); nlp.calc_f(x_kp1); if(m) nlp.calc_c( x_kp1, false ); nlp.unset_quantities(); if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nf_kp1 = " << s.f().get_k(+1); if(m) out << "\n||c_kp1||inf = " << s.c().get_k(+1).norm_inf(); out << std::endl; } if( m && static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "\nc_kp1 =\n" << s.c().get_k(+1); } if(algo.algo_cntr().check_results()) { assert_print_nan_inf( s.f().get_k(+1), "f(x_kp1)", true, &out ); if(m) assert_print_nan_inf( s.c().get_k(+1), "c(x_kp1)", true, &out ); } return true; }
bool MoochoPack::LineSearchWatchDog_Step::do_step(Algorithm& _algo , poss_type step_poss, IterationPack::EDoStepType type, poss_type assoc_step_poss) { using DenseLinAlgPack::norm_inf; using DenseLinAlgPack::V_VpV; using DenseLinAlgPack::Vp_StV; using DenseLinAlgPack::Vt_S; using LinAlgOpPack::Vp_V; using LinAlgOpPack::V_MtV; using ConstrainedOptPack::print_vector_change_stats; NLPAlgo &algo = rsqp_algo(_algo); NLPAlgoState &s = algo.rsqp_state(); NLP &nlp = algo.nlp(); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); std::ostream& out = algo.track().journal_out(); out << std::boolalpha; // print step header. if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { using IterationPack::print_algorithm_step; print_algorithm_step( algo, step_poss, type, assoc_step_poss, out ); } // ///////////////////////////////////////// // Set references to iteration quantities // // Set k+1 first then go back to get k to ensure // we have backward storage. DVector &x_kp1 = s.x().set_k(+1).v(); value_type &f_kp1 = s.f().set_k(+1); DVector &c_kp1 = s.c().set_k(+1).v(); const value_type &f_k = s.f().get_k(0); const DVector &c_k = s.c().get_k(0).v(); const DVector &x_k = s.x().get_k(0).v(); const DVector &d_k = s.d().get_k(0).v(); value_type &alpha_k = s.alpha().get_k(0); // ///////////////////////////////////// // Compute Dphi_k, phi_kp1 and phi_k // Dphi_k const value_type Dphi_k = merit_func().deriv(); if( Dphi_k >= 0 ) { throw LineSearchFailure( "LineSearch2ndOrderCorrect_Step::do_step(...) : " "Error, d_k is not a descent direction for the merit function " ); } // ph_kp1 value_type &phi_kp1 = s.phi().set_k(+1) = merit_func().value( f_kp1, c_kp1 ); // Must compute phi(x) at the base point x_k since the penalty parameter may have changed. const value_type &phi_k = s.phi().set_k(0) = merit_func().value( f_k, c_k ); // ////////////////////////////////////// // Setup the calculation merit function // Here f_kp1, and c_kp1 are updated at the same time the // line search is being performed. nlp.set_f( &f_kp1 ); nlp.set_c( &c_kp1 ); MeritFuncCalcNLP phi_calc( &merit_func(), &nlp ); // //////////////////////////////// // Use Watchdog near the solution if( watch_k_ == NORMAL_LINE_SEARCH ) { const value_type opt_kkt_err_k = s.opt_kkt_err().get_k(0), feas_kkt_err_k = s.feas_kkt_err().get_k(0); if( opt_kkt_err_k <= opt_kkt_err_threshold() && feas_kkt_err_k <= feas_kkt_err_threshold() ) { if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nopt_kkt_err_k = " << opt_kkt_err_k << " <= opt_kkt_err_threshold = " << opt_kkt_err_threshold() << std::endl << "\nfeas_kkt_err_k = " << feas_kkt_err_k << " <= feas_kkt_err_threshold = " << feas_kkt_err_threshold() << std::endl << "\nSwitching to watchdog linesearch ...\n"; } watch_k_ = 0; } } if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nTrial point:\n" << "phi_k = " << phi_k << std::endl << "Dphi_k = " << Dphi_k << std::endl << "phi_kp1 = " << phi_kp1 << std::endl; } bool ls_success = true, step_return = true; switch( watch_k_ ) { case 0: { // Take a full step const value_type phi_cord = phi_k + eta() * Dphi_k; const bool accept_step = phi_kp1 <= phi_cord; if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\n*** Zeroth watchdog iteration:\n" << "\nphi_kp1 = " << phi_kp1 << ( accept_step ? " <= " : " > " ) << "phi_k + eta * Dphi_k = " << phi_cord << std::endl; } if( phi_kp1 > phi_cord ) { if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nAccept this increase for now but watch out next iteration!\n"; } // Save this initial point xo_ = x_k; fo_ = f_k; nrm_co_ = norm_inf( c_k ); do_ = d_k; phio_ = phi_k; Dphio_ = Dphi_k; phiop1_ = phi_kp1; // Slip the update of the penalty parameter const value_type mu_k = s.mu().get_k(0); s.mu().set_k(+1) = mu_k; // Move on to the next step in the watchdog procedure watch_k_ = 1; } else { if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nAll is good!\n"; } // watch_k_ stays 0 } step_return = true; break; } case 1: { if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\n*** First watchdog iteration:\n" << "\nDo a line search to determine x_kp1 = x_k + alpha_k * d_k ...\n"; } // Now do a line search but and we require some type of reduction const DVectorSlice xd[2] = { x_k(), d_k() }; MeritFuncCalc1DQuadratic phi_calc_1d( phi_calc, 1, xd, &x_kp1() ); ls_success = direct_line_search().do_line_search( phi_calc_1d, phi_k , &alpha_k, &phi_kp1 , (int)olevel >= (int)PRINT_ALGORITHM_STEPS ? &out : static_cast<std::ostream*>(0) ); // If the linesearch failed then the rest of the tests will catch this. value_type phi_cord = 0; bool test1, test2; if( ( test1 = ( phi_k <= phio_ ) ) || ( test2 = phi_kp1 <= ( phi_cord = phio_ + eta() * Dphio_ ) ) ) { // We will accept this step and and move on. if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nphi_k = " << phi_k << ( test1 ? " <= " : " > " ) << "phi_km1 = " << phio_ << std::endl << "phi_kp1 = " << phi_kp1 << ( test2 ? " <= " : " > " ) << "phi_km1 + eta * Dphi_km1 = " << phi_cord << std::endl << "This is a sufficent reduction so reset watchdog.\n"; } watch_k_ = 0; step_return = true; } else if ( ! ( test1 = ( phi_kp1 <= phio_ ) ) ) { // Even this reduction is no good! // Go back to original point and do a linesearch from there. if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nphi_kp1 = " << phi_kp1 << " > phi_km1 = " << phio_ << std::endl << "This is not good reduction in phi so do linesearch from x_km1\n" << "\n* Go back to x_km1: x_kp1 = x_k - alpha_k * d_k ...\n"; } // Go back from x_k to x_km1 for iteration k: // // x_kp1 = x_km1 // x_kp1 = x_k - alpha_km1 * d_km1 // // A negative sign for alpha is an indication that we are backtracking. // s.alpha().set_k(0) = -1.0; s.d().set_k(0).v() = do_; s.f().set_k(+1) = fo_; if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "Output iteration k ...\n" << "k = k+1\n"; } // Output these iteration quantities algo.track().output_iteration( algo ); // k // Transition to iteration k+1 s.next_iteration(); // Take the step from x_k = x_km2 to x_kp1 for iteration k (k+1): // // x_kp1 = x_km2 + alpha_n * d_km2 // x_kp1 = x_k + alpha_n * d_km1 // x_kp1 = x_n // if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\n* Take the step from x_k = x_km2 to x_kp1 for iteration k (k+1)\n" << "Find: x_kp1 = x_k + alpha_k * d_k = x_km2 + alpha_k * d_km2\n ...\n"; } // alpha_k = 1.0 value_type &alpha_k = s.alpha().set_k(0) = 1.0; // ///////////////////////////////////// // Compute Dphi_k and phi_k // x_k const DVector &x_k = xo_; // d_k const DVector &d_k = s.d().set_k(0).v() = do_; // Dphi_k const value_type &Dphi_k = Dphio_; // phi_k const value_type &phi_k = s.phi().set_k(0) = phio_; // Here f_kp1, and c_kp1 are updated at the same time the // line search is being performed. algo.nlp().set_f( &s.f().set_k(+1) ); algo.nlp().set_c( &s.c().set_k(+1).v() ); phi_calc.set_nlp( algo.get_nlp() ); // //////////////////////////////////////// // Compute x_xp1 and ph_kp1 for full step // x_kp1 = x_k + alpha_k * d_k DVector &x_kp1 = s.x().set_k(+1).v(); V_VpV( &x_kp1, x_k, d_k ); // phi_kp1 value_type &phi_kp1 = s.phi().set_k(+1) = phiop1_; const DVectorSlice xd[2] = { x_k(), d_k() }; MeritFuncCalc1DQuadratic phi_calc_1d( phi_calc, 1, xd, &x_kp1() ); ls_success = direct_line_search().do_line_search( phi_calc_1d, phi_k , &alpha_k, &phi_kp1 , (int)olevel >= (int)PRINT_ALGORITHM_STEPS ? &out : static_cast<std::ostream*>(0) ); if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nOutput iteration k (k+1) ...\n" << "k = k+1 (k+2)\n" << "Reinitialize watchdog algorithm\n"; } // Output these iteration quantities algo.track().output_iteration( algo ); // (k+1) // Transition to iteration k+1 (k+2) s.next_iteration(); watch_k_ = 0; // Reinitialize the watchdog // Any update for k (k+2) should use the last updated value // which was for k-2 (k) since there is not much info for k-1 (k+1). // Be careful here and make sure this is square with other steps. algo.do_step_next( EvalNewPoint_name ); step_return = false; // Redirect control } else { if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "phi_kp1 = " << phi_kp1 << " <= phi_km1 = " << phio_ << std::endl << "\nAccept this step but do a linesearch next iteration!\n"; } // Slip the update of the penalty parameter const value_type mu_k = s.mu().get_k(0); s.mu().set_k(+1) = mu_k; // Do the last stage of the watchdog procedure next iteration. watch_k_ = 2; step_return = true; } break; } case NORMAL_LINE_SEARCH: case 2: { if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { if( watch_k_ == 2 ) { out << "\n*** Second watchdog iteration:\n" << "Do a line search to determine x_kp1 = x_k + alpha_k * d_k ...\n"; } else { out << "\n*** Normal linesearch:\n" << "Do a line search to determine x_kp1 = x_k + alpha_k * d_k ...\n"; } } const DVectorSlice xd[2] = { x_k(), d_k() }; MeritFuncCalc1DQuadratic phi_calc_1d( phi_calc, 1, xd, &x_kp1() ); ls_success = direct_line_search().do_line_search( phi_calc_1d, phi_k , &alpha_k, &phi_kp1 , (int)olevel >= (int)PRINT_ALGORITHM_STEPS ? &out : static_cast<std::ostream*>(0) ); if( watch_k_ == 2 ) watch_k_ = 0; step_return = true; break; } default: TEST_FOR_EXCEPT(true); // Only local programming error } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nalpha = " << s.alpha().get_k(0) << "\n"; out << "\nphi_kp1 = " << s.phi().get_k(+1) << "\n"; } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "\nd_k = \n" << s.d().get_k(0)(); out << "\nx_kp1 = \n" << s.x().get_k(+1)(); } if( !ls_success ) throw LineSearchFailure("LineSearchWatchDog_Step::do_step(): Line search failure"); return step_return; }
bool CalcReducedGradLagrangianStd_AddedStep::do_step( Algorithm& _algo, poss_type step_poss, IterationPack::EDoStepType type ,poss_type assoc_step_poss ) { using BLAS_Cpp::trans; using LinAlgOpPack::V_VpV; using LinAlgOpPack::V_MtV; using LinAlgOpPack::Vp_V; using LinAlgOpPack::Vp_MtV; NLPAlgo &algo = rsqp_algo(_algo); NLPAlgoState &s = algo.rsqp_state(); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); EJournalOutputLevel ns_olevel = algo.algo_cntr().null_space_journal_output_level(); std::ostream& out = algo.track().journal_out(); // print step header. if( static_cast<int>(ns_olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { using IterationPack::print_algorithm_step; print_algorithm_step( algo, step_poss, type, assoc_step_poss, out ); } // Calculate: rGL = rGf + Z' * nu + Uz' * lambda(equ_undecomp) IterQuantityAccess<VectorMutable> &rGL_iq = s.rGL(), &nu_iq = s.nu(), &Gf_iq = s.Gf(); VectorMutable &rGL_k = rGL_iq.set_k(0); if( nu_iq.updated_k(0) && nu_iq.get_k(0).nz() > 0 ) { // Compute rGL = Z'*(Gf + nu) to reduce the effect of roundoff in this // catastropic cancelation const Vector &nu_k = nu_iq.get_k(0); VectorSpace::vec_mut_ptr_t tmp = nu_k.space().create_member(); if( (int)olevel >= (int)PRINT_VECTORS ) out << "\nnu_k = \n" << nu_k; V_VpV( tmp.get(), Gf_iq.get_k(0), nu_k ); if( (int)olevel >= (int)PRINT_VECTORS ) out << "\nGf_k+nu_k = \n" << *tmp; V_MtV( &rGL_k, s.Z().get_k(0), trans, *tmp ); if( (int)ns_olevel >= (int)PRINT_VECTORS ) out << "\nrGL_k = \n" << rGL_k; } else { rGL_k = s.rGf().get_k(0); } // ToDo: Add terms for undecomposed equalities and inequalities! // + Uz' * lambda(equ_undecomp) if( static_cast<int>(ns_olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\n||rGL_k||inf = " << rGL_k.norm_inf() << "\n"; } if( static_cast<int>(ns_olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "\nrGL_k = \n" << rGL_k; } return true; }
bool ReducedHessianSerialization_Step::do_step( Algorithm& _algo, poss_type step_poss, IterationPack::EDoStepType type ,poss_type assoc_step_poss ) { using Teuchos::dyn_cast; using SerializationPack::Serializable; NLPAlgo &algo = rsqp_algo(_algo); NLPAlgoState &s = algo.rsqp_state(); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); EJournalOutputLevel ns_olevel = algo.algo_cntr().null_space_journal_output_level(); std::ostream& out = algo.track().journal_out(); // print step header. if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { using IterationPack::print_algorithm_step; print_algorithm_step( _algo, step_poss, type, assoc_step_poss, out ); } IterQuantityAccess<MatrixSymOp> &rHL_iq = s.rHL(); if( !rHL_iq.updated_k(0) && reduced_hessian_input_file_name().length() ) { int k_last_offset = rHL_iq.last_updated(); if( k_last_offset == IterQuantity::NONE_UPDATED ) { if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nNo previous matrix rHL was found!\n" << "\nReading in the matrix rHL_k from the file \""<<reduced_hessian_input_file_name()<<"\" ...\n"; } MatrixSymOp &rHL_k = rHL_iq.set_k(0); Serializable &rHL_serializable = dyn_cast<Serializable>(rHL_k); std::ifstream reduced_hessian_input_file(reduced_hessian_input_file_name().c_str()); TEST_FOR_EXCEPTION( !reduced_hessian_input_file, std::logic_error ,"ReducedHessianSerialization_Step::do_step(...): Error, the file \""<<reduced_hessian_input_file_name()<<"\"" " could not be opened or contains no input!" ); rHL_serializable.unserialize(reduced_hessian_input_file); if( (int)ns_olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nrHL_k.rows() = " << rHL_k.rows() << std::endl; out << "\nrHL_k.cols() = " << rHL_k.cols() << std::endl; if(algo.algo_cntr().calc_matrix_norms()) out << "\n||rHL_k||inf = " << rHL_k.calc_norm(MatrixOp::MAT_NORM_INF).value << std::endl; if(algo.algo_cntr().calc_conditioning()) { const MatrixSymOpNonsing *rHL_ns_k = dynamic_cast<const MatrixSymOpNonsing*>(&rHL_k); if(rHL_ns_k) out << "\ncond_inf(rHL_k) = " << rHL_ns_k->calc_cond_num(MatrixOp::MAT_NORM_INF).value << std::endl; } } if( (int)ns_olevel >= (int)PRINT_ITERATION_QUANTITIES ) out << "\nrHL_k = \n" << rHL_k; // Validate the space const MatrixOp &Z_k = s.Z().get_k(0); const VectorSpace &null_space = Z_k.space_rows(); TEST_FOR_EXCEPTION( !null_space.is_compatible(rHL_k.space_cols()) || !null_space.is_compatible(rHL_k.space_rows()) ,std::runtime_error ,"ReducedHessianSerialization_Step::do_step(...): Error, the read-in reduced Hessian of dimension " << rHL_k.rows() << " x " << rHL_k.cols() << " is not compatible with the null space of dimension " "Z_k.cols() = " << Z_k.cols() << "!" ); } } return true; }
bool MeritFunc_PenaltyParamsUpdateWithMult_AddedStep::do_step(Algorithm& _algo , poss_type step_poss, IterationPack::EDoStepType type , poss_type assoc_step_poss) { using DenseLinAlgPack::norm_inf; NLPAlgo &algo = rsqp_algo(_algo); NLPAlgoState &s = algo.rsqp_state(); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); std::ostream& out = algo.track().journal_out(); // print step header. if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { using IterationPack::print_algorithm_step; print_algorithm_step( algo, step_poss, type, assoc_step_poss, out ); } MeritFuncPenaltyParams *params = dynamic_cast<MeritFuncPenaltyParams*>(&merit_func()); if( !params ) { std::ostringstream omsg; omsg << "MeritFunc_PenaltyParamsUpdateWithMult_AddedStep::do_step(...), Error " << "The class " << typeName(&merit_func()) << " does not support the " << "MeritFuncPenaltyParams iterface\n"; out << omsg.str(); throw std::logic_error( omsg.str() ); } MeritFuncNLPDirecDeriv *direc_deriv = dynamic_cast<MeritFuncNLPDirecDeriv*>(&merit_func()); if( !direc_deriv ) { std::ostringstream omsg; omsg << "MeritFunc_PenaltyParamsUpdateWithMult_AddedStep::do_step(...), Error " << "The class " << typeName(&merit_func()) << " does not support the " << "MeritFuncNLPDirecDeriv iterface\n"; out << omsg.str(); throw std::logic_error( omsg.str() ); } bool perform_update = true; if( s.mu().updated_k(0) ) { if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nmu_k is already updated by someone else?\n"; } const value_type mu_k = s.mu().get_k(0); if( mu_k == norm_inf_mu_last_ ) { if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nmu_k " << mu_k << " == norm_inf_mu_last = " << norm_inf_mu_last_ << "\nso we will take this as a signal to skip the update.\n"; } perform_update = false; } else { if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nmu_k " << mu_k << " != norm_inf_mu_last = " << norm_inf_mu_last_ << "\nso we will ignore this and perform the update anyway.\n"; } } } if(perform_update) { if ( s.lambda().updated_k(0) ) { if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nUpdate the penalty parameter...\n"; } const DVector &lambda_k = s.lambda().get_k(0).cv(); if( params->mu().size() != lambda_k.size() ) params->resize( lambda_k.size() ); DVectorSlice mu = params->mu(); const value_type max_lambda = norm_inf( lambda_k() ), mult_fact = (1.0 + mult_factor_); if(near_solution_) { if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nNear solution, forcing mu(j) >= mu_old(j)...\n"; } DVector::const_iterator lb_itr = lambda_k.begin(); DVectorSlice::iterator mu_itr = mu.begin(); for( ; lb_itr != lambda_k.end(); ++mu_itr, ++ lb_itr ) *mu_itr = max( max( *mu_itr, mult_fact * ::fabs(*lb_itr) ), small_mu_ ); } else { if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nNot near solution, allowing reduction in mu(j) ...\n"; } DVector::const_iterator lb_itr = lambda_k.begin(); DVectorSlice::iterator mu_itr = mu.begin(); for( ; lb_itr != lambda_k.end(); ++mu_itr, ++ lb_itr ) { const value_type lb_j = ::fabs(*lb_itr); *mu_itr = max( (3.0 * (*mu_itr) + lb_j) / 4.0 , max( mult_fact * lb_j, small_mu_ ) ); } value_type kkt_error = s.opt_kkt_err().get_k(0) + s.feas_kkt_err().get_k(0); if(kkt_error <= kkt_near_sol_) { if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nkkt_error = " << kkt_error << " <= kkt_near_sol = " << kkt_near_sol_ << std::endl << "Switching to forcing mu_k >= mu_km1 in the future\n"; } near_solution_ = true; } } // Force the ratio const value_type max_mu = norm_inf( mu() ), min_mu = min_mu_ratio_ * max_mu; for(DVectorSlice::iterator mu_itr = mu.begin(); mu_itr != mu.end(); ++mu_itr) *mu_itr = max( (*mu_itr), min_mu ); s.mu().set_k(0) = norm_inf_mu_last_ = max_mu; if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nmax(|mu(j)|) = " << (*std::max_element( mu.begin(), mu.end() )) << "\nmin(|mu(j)|) = " << (*std::min_element( mu.begin(), mu.end() )) << std::endl; } if( (int)olevel >= (int)PRINT_VECTORS ) { out << "\nmu = \n" << mu; } } else { if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nDon't have the info to update penalty parameter so just use the last updated...\n"; } } } // In addition also compute the directional derivative direc_deriv->calc_deriv( s.Gf().get_k(0)(), s.c().get_k(0)(), s.d().get_k(0)() ); if( (int)olevel >= (int)PRINT_ALGORITHM_STEPS ) { out << "\nmu_k = " << s.mu().get_k(0) << "\n"; } return true; }
bool PostEvalNewPointBarrier_Step::do_step( Algorithm& _algo, poss_type step_poss, IterationPack::EDoStepType type ,poss_type assoc_step_poss ) { using Teuchos::dyn_cast; using IterationPack::print_algorithm_step; using AbstractLinAlgPack::inv_of_difference; using AbstractLinAlgPack::correct_upper_bound_multipliers; using AbstractLinAlgPack::correct_lower_bound_multipliers; using LinAlgOpPack::Vp_StV; NLPAlgo &algo = dyn_cast<NLPAlgo>(_algo); IpState &s = dyn_cast<IpState>(_algo.state()); NLP &nlp = algo.nlp(); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); std::ostream& out = algo.track().journal_out(); if(!nlp.is_initialized()) nlp.initialize(algo.algo_cntr().check_results()); // print step header. if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { using IterationPack::print_algorithm_step; print_algorithm_step( _algo, step_poss, type, assoc_step_poss, out ); } IterQuantityAccess<VectorMutable> &x_iq = s.x(); IterQuantityAccess<MatrixSymDiagStd> &Vl_iq = s.Vl(); IterQuantityAccess<MatrixSymDiagStd> &Vu_iq = s.Vu(); ///*********************************************************** // Calculate invXl = diag(1/(x-xl)) // and invXu = diag(1/(xu-x)) matrices ///*********************************************************** // get references to x, invXl, and invXu VectorMutable& x = x_iq.get_k(0); MatrixSymDiagStd& invXu = s.invXu().set_k(0); MatrixSymDiagStd& invXl = s.invXl().set_k(0); //std::cout << "xu=\n"; //nlp.xu().output(std::cout); inv_of_difference(1.0, nlp.xu(), x, &invXu.diag()); inv_of_difference(1.0, x, nlp.xl(), &invXl.diag()); //std::cout << "invXu=\v"; //invXu.output(std::cout); //std::cout << "\ninvXl=\v"; //invXl.output(std::cout); // Check for divide by zeros - using AbstractLinAlgPack::assert_print_nan_inf; assert_print_nan_inf(invXu.diag(), "invXu", true, &out); assert_print_nan_inf(invXl.diag(), "invXl", true, &out); // These should never go negative either - could be a useful check // Initialize Vu and Vl if necessary if ( /*!Vu_iq.updated_k(0) */ Vu_iq.last_updated() == IterQuantity::NONE_UPDATED ) { VectorMutable& vu = Vu_iq.set_k(0).diag(); vu = 0; Vp_StV(&vu, s.barrier_parameter().get_k(-1), invXu.diag()); if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nInitialize Vu with barrier_parameter * invXu ...\n"; } } if ( /*!Vl_iq.updated_k(0) */ Vl_iq.last_updated() == IterQuantity::NONE_UPDATED ) { VectorMutable& vl = Vl_iq.set_k(0).diag(); vl = 0; Vp_StV(&vl, s.barrier_parameter().get_k(-1), invXl.diag()); if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nInitialize Vl with barrier_parameter * invXl ...\n"; } } if (s.num_basis().updated_k(0)) { // Basis changed, reorder Vl and Vu if (Vu_iq.updated_k(-1)) { Vu_iq.set_k(0,-1); } if (Vl_iq.updated_k(-1)) { Vl_iq.set_k(0,-1); } VectorMutable& vu = Vu_iq.set_k(0).diag(); VectorMutable& vl = Vl_iq.set_k(0).diag(); s.P_var_last().permute( BLAS_Cpp::trans, &vu ); // Permute back to original order s.P_var_last().permute( BLAS_Cpp::trans, &vl ); // Permute back to original order if( (int)olevel >= (int)PRINT_VECTORS ) { out << "\nx resorted vl and vu to the original order\n" << x; } s.P_var_current().permute( BLAS_Cpp::no_trans, &vu ); // Permute to new (current) order s.P_var_current().permute( BLAS_Cpp::no_trans, &vl ); // Permute to new (current) order if( (int)olevel >= (int)PRINT_VECTORS ) { out << "\nx resorted to new basis \n" << x; } } correct_upper_bound_multipliers(nlp.xu(), +NLP::infinite_bound(), &Vu_iq.get_k(0).diag()); correct_lower_bound_multipliers(nlp.xl(), -NLP::infinite_bound(), &Vl_iq.get_k(0).diag()); if( (int)olevel >= (int)PRINT_VECTORS ) { out << "x=\n" << s.x().get_k(0); out << "xl=\n" << nlp.xl(); out << "vl=\n" << s.Vl().get_k(0).diag(); out << "xu=\n" << nlp.xu(); out << "vu=\n" << s.Vu().get_k(0).diag(); } // Update general algorithm bound multipliers VectorMutable& v = s.nu().set_k(0); v = Vu_iq.get_k(0).diag(); Vp_StV(&v,-1.0,Vl_iq.get_k(0).diag()); // Print vector information if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "invXu_k.diag()=\n" << invXu.diag(); out << "invXl_k.diag()=\n" << invXl.diag(); out << "Vu_k.diag()=\n" << Vu_iq.get_k(0).diag(); out << "Vl_k.diag()=\n" << Vl_iq.get_k(0).diag(); out << "nu_k=\n" << s.nu().get_k(0); } return true; }
bool EvalNewPointStd_Step::do_step( Algorithm& _algo, poss_type step_poss, IterationPack::EDoStepType type ,poss_type assoc_step_poss ) { using Teuchos::rcp; using Teuchos::dyn_cast; using AbstractLinAlgPack::assert_print_nan_inf; using IterationPack::print_algorithm_step; using NLPInterfacePack::NLPFirstOrder; NLPAlgo &algo = rsqp_algo(_algo); NLPAlgoState &s = algo.rsqp_state(); NLPFirstOrder &nlp = dyn_cast<NLPFirstOrder>(algo.nlp()); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); EJournalOutputLevel ns_olevel = algo.algo_cntr().null_space_journal_output_level(); std::ostream& out = algo.track().journal_out(); // print step header. if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { using IterationPack::print_algorithm_step; print_algorithm_step( algo, step_poss, type, assoc_step_poss, out ); } if(!nlp.is_initialized()) nlp.initialize(algo.algo_cntr().check_results()); Teuchos::VerboseObjectTempState<NLP> nlpOutputTempState(rcp(&nlp,false),Teuchos::getFancyOStream(rcp(&out,false)),convertToVerbLevel(olevel)); const size_type n = nlp.n(), nb = nlp.num_bounded_x(), m = nlp.m(); size_type r = 0; // Get the iteration quantity container objects IterQuantityAccess<value_type> &f_iq = s.f(); IterQuantityAccess<VectorMutable> &x_iq = s.x(), *c_iq = m > 0 ? &s.c() : NULL, &Gf_iq = s.Gf(); IterQuantityAccess<MatrixOp> *Gc_iq = m > 0 ? &s.Gc() : NULL, *Z_iq = NULL, *Y_iq = NULL, *Uz_iq = NULL, *Uy_iq = NULL; IterQuantityAccess<MatrixOpNonsing> *R_iq = NULL; MatrixOp::EMatNormType mat_nrm_inf = MatrixOp::MAT_NORM_INF; const bool calc_matrix_norms = algo.algo_cntr().calc_matrix_norms(); const bool calc_matrix_info_null_space_only = algo.algo_cntr().calc_matrix_info_null_space_only(); if( x_iq.last_updated() == IterQuantity::NONE_UPDATED ) { if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nx is not updated for any k so set x_k = nlp.xinit() ...\n"; } x_iq.set_k(0) = nlp.xinit(); } // Validate x if( nb && algo.algo_cntr().check_results() ) { assert_print_nan_inf( x_iq.get_k(0), "x_k", true , int(olevel) >= int(PRINT_ALGORITHM_STEPS) ? &out : NULL ); if( nlp.num_bounded_x() > 0 ) { if(!bounds_tester().check_in_bounds( int(olevel) >= int(PRINT_ALGORITHM_STEPS) ? &out : NULL ,int(olevel) >= int(PRINT_VECTORS) // print_all_warnings ,int(olevel) >= int(PRINT_ITERATION_QUANTITIES) // print_vectors ,nlp.xl(), "xl" ,nlp.xu(), "xu" ,x_iq.get_k(0), "x_k" )) { TEUCHOS_TEST_FOR_EXCEPTION( true, TestFailed ,"EvalNewPointStd_Step::do_step(...) : Error, " "the variables bounds xl <= x_k <= xu where violated!" ); } } } Vector &x = x_iq.get_k(0); Range1D var_dep(Range1D::INVALID), var_indep(Range1D::INVALID); if( s.get_decomp_sys().get() ) { const ConstrainedOptPack::DecompositionSystemVarReduct *decomp_sys_vr = dynamic_cast<ConstrainedOptPack::DecompositionSystemVarReduct*>(&s.decomp_sys()); if(decomp_sys_vr) { var_dep = decomp_sys_vr->var_dep(); var_indep = decomp_sys_vr->var_indep(); } s.var_dep(var_dep); s.var_indep(var_indep); } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\n||x_k||inf = " << x.norm_inf(); if( var_dep.size() ) out << "\n||x(var_dep)_k||inf = " << x.sub_view(var_dep)->norm_inf(); if( var_indep.size() ) out << "\n||x(var_indep)_k||inf = " << x.sub_view(var_indep)->norm_inf(); out << std::endl; } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "\nx_k = \n" << x; if( var_dep.size() ) out << "\nx(var_dep)_k = \n" << *x.sub_view(var_dep); } if( static_cast<int>(ns_olevel) >= static_cast<int>(PRINT_VECTORS) ) { if( var_indep.size() ) out << "\nx(var_indep)_k = \n" << *x.sub_view(var_indep); } // Set the references to the current point's quantities to be updated const bool f_k_updated = f_iq.updated_k(0); const bool Gf_k_updated = Gf_iq.updated_k(0); const bool c_k_updated = m > 0 ? c_iq->updated_k(0) : false; const bool Gc_k_updated = m > 0 ? Gc_iq->updated_k(0) : false; nlp.unset_quantities(); if(!f_k_updated) nlp.set_f( &f_iq.set_k(0) ); if(!Gf_k_updated) nlp.set_Gf( &Gf_iq.set_k(0) ); if( m > 0 ) { if(!c_k_updated) nlp.set_c( &c_iq->set_k(0) ); if(!Gc_k_updated) nlp.set_Gc( &Gc_iq->set_k(0) ); } // Calculate Gc at x_k bool new_point = true; if(m > 0) { if(!Gc_k_updated) nlp.calc_Gc( x, new_point ); new_point = false; } // // Update (or select a new) range/null decomposition // bool new_decomp_selected = false; if( m > 0 ) { // Update the range/null decomposition decomp_sys_handler().update_decomposition( algo, s, nlp, decomp_sys_testing(), decomp_sys_testing_print_level() ,&new_decomp_selected ); r = s.equ_decomp().size(); Z_iq = ( n > m && r > 0 ) ? &s.Z() : NULL; Y_iq = ( r > 0 ) ? &s.Y() : NULL; Uz_iq = ( m > 0 && m > r ) ? &s.Uz() : NULL; Uy_iq = ( m > 0 && m > r ) ? &s.Uy() : NULL; R_iq = ( m > 0 ) ? &s.R() : NULL; // Determine if we will test the decomp_sys or not const DecompositionSystem::ERunTests ds_test_what = ( ( decomp_sys_testing() == DecompositionSystemHandler_Strategy::DST_TEST || ( decomp_sys_testing() == DecompositionSystemHandler_Strategy::DST_DEFAULT && algo.algo_cntr().check_results() ) ) ? DecompositionSystem::RUN_TESTS : DecompositionSystem::NO_TESTS ); // Determine the output level for decomp_sys DecompositionSystem::EOutputLevel ds_olevel; switch(olevel) { case PRINT_NOTHING: case PRINT_BASIC_ALGORITHM_INFO: ds_olevel = DecompositionSystem::PRINT_NONE; break; case PRINT_ALGORITHM_STEPS: case PRINT_ACTIVE_SET: ds_olevel = DecompositionSystem::PRINT_BASIC_INFO; break; case PRINT_VECTORS: ds_olevel = DecompositionSystem::PRINT_VECTORS; break; case PRINT_ITERATION_QUANTITIES: ds_olevel = DecompositionSystem::PRINT_EVERY_THING; break; default: TEUCHOS_TEST_FOR_EXCEPT(true); // Should not get here! }; // Test the decomposition system if( ds_test_what == DecompositionSystem::RUN_TESTS ) { // Set the output level if( decomp_sys_tester().print_tests() == DecompositionSystemTester::PRINT_NOT_SELECTED ) { DecompositionSystemTester::EPrintTestLevel ds_olevel; switch(olevel) { case PRINT_NOTHING: case PRINT_BASIC_ALGORITHM_INFO: ds_olevel = DecompositionSystemTester::PRINT_NONE; break; case PRINT_ALGORITHM_STEPS: case PRINT_ACTIVE_SET: ds_olevel = DecompositionSystemTester::PRINT_BASIC; break; case PRINT_VECTORS: ds_olevel = DecompositionSystemTester::PRINT_MORE; break; case PRINT_ITERATION_QUANTITIES: ds_olevel = DecompositionSystemTester::PRINT_ALL; break; default: TEUCHOS_TEST_FOR_EXCEPT(true); // Should not get here! } decomp_sys_tester().print_tests(ds_olevel); decomp_sys_tester().dump_all( olevel == PRINT_ITERATION_QUANTITIES ); } // Run the tests if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nTesting the range/null decompostion ...\n"; } const bool decomp_sys_passed = decomp_sys_tester().test_decomp_system( s.decomp_sys() ,Gc_iq->get_k(0) // Gc ,Z_iq ? &Z_iq->get_k(0) : NULL // Z ,&Y_iq->get_k(0) // Y ,&R_iq->get_k(0) // R ,m > r ? &Uz_iq->get_k(0) : NULL // Uz ,m > r ? &Uy_iq->get_k(0) : NULL // Uy ,( olevel >= PRINT_ALGORITHM_STEPS ) ? &out : NULL ); TEUCHOS_TEST_FOR_EXCEPTION( !decomp_sys_passed, TestFailed ,"EvalNewPointStd_Step::do_step(...) : Error, " "the tests of the decomposition system failed!" ); } } else { // Unconstrained problem Z_iq = &s.Z(); dyn_cast<MatrixSymIdent>(Z_iq->set_k(0)).initialize( nlp.space_x() ); s.equ_decomp(Range1D::Invalid); s.equ_undecomp(Range1D::Invalid); } // Calculate the rest of the quantities. If decomp_sys is a variable // reduction decomposition system object, then nlp will be hip to the // basis selection and will permute these quantities to that basis. // Note that x will already be permuted to the current basis. if(!Gf_k_updated) { nlp.calc_Gf( x, new_point ); new_point = false; } if( m && (!c_k_updated || new_decomp_selected ) ) { if(c_k_updated) nlp.set_c( &c_iq->set_k(0) ); // This was not set earlier! nlp.calc_c( x, false); } if(!f_k_updated) { nlp.calc_f( x, false); } nlp.unset_quantities(); // Check for NaN and Inf assert_print_nan_inf(f_iq.get_k(0),"f_k",true,&out); if(m) assert_print_nan_inf(c_iq->get_k(0),"c_k",true,&out); assert_print_nan_inf(Gf_iq.get_k(0),"Gf_k",true,&out); // Print the iteration quantities before we test the derivatives for debugging // Update the selection of dependent and independent variables if( s.get_decomp_sys().get() ) { const ConstrainedOptPack::DecompositionSystemVarReduct *decomp_sys_vr = dynamic_cast<ConstrainedOptPack::DecompositionSystemVarReduct*>(&s.decomp_sys()); if(decomp_sys_vr) { var_dep = decomp_sys_vr->var_dep(); var_indep = decomp_sys_vr->var_indep(); } } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nPrinting the updated iteration quantities ...\n"; } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nf_k = " << f_iq.get_k(0); out << "\n||Gf_k||inf = " << Gf_iq.get_k(0).norm_inf(); if( var_dep.size() ) out << "\n||Gf_k(var_dep)_k||inf = " << Gf_iq.get_k(0).sub_view(var_dep)->norm_inf(); if( var_indep.size() ) out << "\n||Gf_k(var_indep)_k||inf = " << Gf_iq.get_k(0).sub_view(var_indep)->norm_inf(); if(m) { out << "\n||c_k||inf = " << c_iq->get_k(0).norm_inf(); if( calc_matrix_norms && !calc_matrix_info_null_space_only ) out << "\n||Gc_k||inf = " << Gc_iq->get_k(0).calc_norm(mat_nrm_inf).value; if( n > r && calc_matrix_norms && !calc_matrix_info_null_space_only ) out << "\n||Z||inf = " << Z_iq->get_k(0).calc_norm(mat_nrm_inf).value; if( r && calc_matrix_norms && !calc_matrix_info_null_space_only ) out << "\n||Y||inf = " << Y_iq->get_k(0).calc_norm(mat_nrm_inf).value; if( r && calc_matrix_norms && !calc_matrix_info_null_space_only ) out << "\n||R||inf = " << R_iq->get_k(0).calc_norm(mat_nrm_inf).value; if( algo.algo_cntr().calc_conditioning() && !calc_matrix_info_null_space_only ) { out << "\ncond_inf(R) = " << R_iq->get_k(0).calc_cond_num(mat_nrm_inf).value; } if( m > r && calc_matrix_norms && !calc_matrix_info_null_space_only ) { out << "\n||Uz_k||inf = " << Uz_iq->get_k(0).calc_norm(mat_nrm_inf).value; out << "\n||Uy_k||inf = " << Uy_iq->get_k(0).calc_norm(mat_nrm_inf).value; } } out << std::endl; } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ITERATION_QUANTITIES) ) { if(m) out << "\nGc_k =\n" << Gc_iq->get_k(0); if( n > r ) out << "\nZ_k =\n" << Z_iq->get_k(0); if(r) { out << "\nY_k =\n" << Y_iq->get_k(0); out << "\nR_k =\n" << R_iq->get_k(0); } if( m > r ) { out << "\nUz_k =\n" << Uz_iq->get_k(0); out << "\nUy_k =\n" << Uy_iq->get_k(0); } } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "\nGf_k =\n" << Gf_iq.get_k(0); if( var_dep.size() ) out << "\nGf(var_dep)_k =\n " << *Gf_iq.get_k(0).sub_view(var_dep); } if( static_cast<int>(ns_olevel) >= static_cast<int>(PRINT_VECTORS) ) { if( var_indep.size() ) out << "\nGf(var_indep)_k =\n" << *Gf_iq.get_k(0).sub_view(var_indep); } if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { if(m) out << "\nc_k = \n" << c_iq->get_k(0); } // Check the derivatives if we are checking the results if( fd_deriv_testing() == FD_TEST || ( fd_deriv_testing() == FD_DEFAULT && algo.algo_cntr().check_results() ) ) { if( olevel >= PRINT_ALGORITHM_STEPS ) { out << "\n*** Checking derivatives by finite differences\n"; } const bool nlp_passed = deriv_tester().finite_diff_check( &nlp ,x ,nb ? &nlp.xl() : NULL ,nb ? &nlp.xu() : NULL ,m ? &Gc_iq->get_k(0) : NULL ,&Gf_iq.get_k(0) ,olevel >= PRINT_VECTORS ,( olevel >= PRINT_ALGORITHM_STEPS ) ? &out : NULL ); TEUCHOS_TEST_FOR_EXCEPTION( !nlp_passed, TestFailed ,"EvalNewPointStd_Step::do_step(...) : Error, " "the tests of the nlp derivatives failed!" ); } return true; }
bool PreEvalNewPointBarrier_Step::do_step( Algorithm& _algo, poss_type step_poss, IterationPack::EDoStepType type ,poss_type assoc_step_poss ) { using Teuchos::dyn_cast; using IterationPack::print_algorithm_step; using AbstractLinAlgPack::force_in_bounds_buffer; NLPAlgo &algo = dyn_cast<NLPAlgo>(_algo); IpState &s = dyn_cast<IpState>(_algo.state()); NLP &nlp = algo.nlp(); NLPFirstOrder *nlp_foi = dynamic_cast<NLPFirstOrder*>(&nlp); EJournalOutputLevel olevel = algo.algo_cntr().journal_output_level(); std::ostream& out = algo.track().journal_out(); if(!nlp.is_initialized()) nlp.initialize(algo.algo_cntr().check_results()); // print step header. if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { using IterationPack::print_algorithm_step; print_algorithm_step( _algo, step_poss, type, assoc_step_poss, out ); } IterQuantityAccess<value_type> &barrier_parameter_iq = s.barrier_parameter(); IterQuantityAccess<VectorMutable> &x_iq = s.x(); if( x_iq.last_updated() == IterQuantity::NONE_UPDATED ) { if( static_cast<int>(olevel) >= static_cast<int>(PRINT_ALGORITHM_STEPS) ) { out << "\nInitialize x with x_k = nlp.xinit() ...\n" << " and push x_k within bounds.\n"; } VectorMutable& x_k = x_iq.set_k(0) = nlp.xinit(); // apply transformation operator to push x sufficiently within bounds force_in_bounds_buffer(relative_bound_push_, absolute_bound_push_, nlp.xl(), nlp.xu(), &x_k); // evaluate the func and constraints IterQuantityAccess<value_type> &f_iq = s.f(); IterQuantityAccess<VectorMutable> &Gf_iq = s.Gf(), *c_iq = nlp.m() > 0 ? &s.c() : NULL; IterQuantityAccess<MatrixOp> *Gc_iq = nlp_foi ? &s.Gc() : NULL; using AbstractLinAlgPack::assert_print_nan_inf; assert_print_nan_inf(x_k, "x", true, NULL); // With throw exception if Inf or NaN! // Wipe out storage for computed iteration quantities (just in case?) : RAB: 7/29/2002 if(f_iq.updated_k(0)) f_iq.set_not_updated_k(0); if(Gf_iq.updated_k(0)) Gf_iq.set_not_updated_k(0); if (c_iq) { if(c_iq->updated_k(0)) c_iq->set_not_updated_k(0); } if (nlp_foi) { if(Gc_iq->updated_k(0)) Gc_iq->set_not_updated_k(0); } } if (barrier_parameter_iq.last_updated() == IterQuantity::NONE_UPDATED) { barrier_parameter_iq.set_k(-1) = 0.1; // RAB: 7/29/2002: This should be parameterized! (allow user to set this!) } // Print vector information if( static_cast<int>(olevel) >= static_cast<int>(PRINT_VECTORS) ) { out << "x_k =\n" << x_iq.get_k(0); } return true; }