void MultiVectorMatrix::LRMultVector(Number alpha, const Vector &x, Number beta, Vector &y) const { DBG_START_METH("MultiVectorMatrix::LRMultVector(", dbg_verbosity); DBG_ASSERT(NRows()==x.Dim()); DBG_ASSERT(NRows()==y.Dim()); DBG_PRINT((1, "alpha = %e beta = %e\n", alpha, beta)); DBG_PRINT_VECTOR(2, "x", x); if ( beta!=0.0 ) { y.Scal(beta); } else { y.Set(0.0); } DBG_PRINT_VECTOR(2, "beta*y", y); for (Index i=0; i<NCols(); i++) { DBG_PRINT_VECTOR(2, "ConstVec(i)", *ConstVec(i)); y.AddOneVector(alpha*ConstVec(i)->Dot(x), *ConstVec(i), 1.); DBG_PRINT_VECTOR(2, "y mid", y); } }
void InexactLSAcceptor::ResetSlacks() { DBG_START_METH("InexactLSAcceptor::ResetSlacks", dbg_verbosity); DBG_PRINT_VECTOR(1, "sorig", *IpData().trial()->s()); DBG_PRINT_VECTOR(1, "dtrial", *IpCq().trial_d()); SmartPtr<Vector> new_s = IpData().trial()->s()->MakeNew(); SmartPtr<Vector> tmp_d = IpNLP().d_L()->MakeNew(); IpNLP().Pd_L()->TransMultVector(1., *IpCq().trial_d(), 0., *tmp_d); SmartPtr<Vector> tmp_s = IpNLP().d_L()->MakeNew(); IpNLP().Pd_L()->TransMultVector(1., *IpData().trial()->s(), 0., *tmp_s); tmp_s->ElementWiseMax(*tmp_d); IpNLP().Pd_L()->MultVector(1., *tmp_s, 0., *new_s); tmp_d = IpNLP().d_U()->MakeNew(); IpNLP().Pd_U()->TransMultVector(1., *IpCq().trial_d(), 0., *tmp_d); tmp_s = IpNLP().d_U()->MakeNew(); IpNLP().Pd_U()->TransMultVector(1., *IpData().trial()->s(), 0., *tmp_s); tmp_s->ElementWiseMin(*tmp_d); IpNLP().Pd_U()->MultVector(1., *tmp_s, 1., *new_s); SmartPtr<IteratesVector> trial = IpData().trial()->MakeNewContainer(); trial->Set_s(*new_s); IpData().set_trial(trial); DBG_PRINT_VECTOR(1, "new_s", *IpData().trial()->s()); }
void IpoptAlgorithm::calc_number_of_bounds( const Vector& x, const Vector& x_L, const Vector& x_U, const Matrix& Px_L, const Matrix& Px_U, Index& n_tot, Index& n_only_lower, Index& n_both, Index& n_only_upper) { DBG_START_METH("IpoptAlgorithm::calc_number_of_bounds", dbg_verbosity); n_tot = x.Dim(); SmartPtr<Vector> tmpx = x.MakeNew(); SmartPtr<Vector> tmpxL = x_L.MakeNew(); SmartPtr<Vector> tmpxU = x_U.MakeNew(); tmpxL->Set(-1.); tmpxU->Set(2.); Px_L.MultVector(1.0, *tmpxL, 0.0, *tmpx); Px_U.MultVector(1.0, *tmpxU, 1.0, *tmpx); // Now, x has elements // -1 : if component has only lower bound // 0 : if component has no bound // 1 : if component has both lower and upper bound // 2 : if component has only upper bound DBG_PRINT_VECTOR(2, "x-indicator", *tmpx); SmartPtr<Vector> tmpx0 = x.MakeNew(); tmpx0->Set(0.); SmartPtr<Vector> tmpx2 = x.MakeNew(); tmpx2->Set(-1.0); tmpx2->Axpy(1.0, *tmpx); tmpx2->ElementWiseMax(*tmpx0); // tmpx2 is now 1 in those // components with only upper bounds n_only_upper = (Index)tmpx2->Asum(); tmpx->Axpy(-2., *tmpx2); // now make all those entries for // only upper bounds zero in tmpx tmpx2->Copy(*tmpx); tmpx2->ElementWiseMax(*tmpx0); // tmpx2 is now 1 in those // components with both bounds n_both = (Index)tmpx2->Asum(); tmpx->Axpy(-1., *tmpx2); tmpx->ElementWiseMin(*tmpx); // tmpx is now -1 in those with only // lower bounds n_only_lower = (Index)tmpx->Asum(); }
PointPerturber::PointPerturber(const Vector& x0, Number random_pert_radius, const Matrix& Px_L, const Vector& x_L, const Matrix& Px_U, const Vector& x_U) { DBG_START_METH("PointPerturber::PointPerturber", dbg_verbosity); const Number very_large = 1e300; // First we compute full-space lower and upper bounds SmartPtr<Vector> full_x_L = x0.MakeNew(); full_x_L->Set(-very_large); SmartPtr<Vector> tmp = x_L.MakeNew(); tmp->Set(very_large); Px_L.MultVector(1., *tmp, 1., *full_x_L); DBG_PRINT_VECTOR(1,"full_x_L1", *full_x_L); Px_L.MultVector(1., x_L, 1., *full_x_L); DBG_PRINT_VECTOR(1,"full_x_L2", *full_x_L); SmartPtr<Vector> full_x_U = x0.MakeNew(); full_x_U->Set(very_large); tmp = x_U.MakeNew(); tmp->Set(-very_large); Px_U.MultVector(1., *tmp, 1., *full_x_U); DBG_PRINT_VECTOR(1,"full_x_U1", *full_x_U); Px_U.MultVector(1., x_U, 1., *full_x_U); DBG_PRINT_VECTOR(1,"full_x_U2", *full_x_U); pert_dir_ = full_x_U->MakeNew(); pert_dir_->AddTwoVectors(.5, *full_x_U, -.5, *full_x_L, 0.); tmp = full_x_U->MakeNew(); tmp->Set(random_pert_radius); pert_dir_->ElementWiseMin(*tmp); DBG_PRINT_VECTOR(1,"pert_dir", *pert_dir_); ref_point_ = x0.MakeNewCopy(); DBG_PRINT_VECTOR(1,"ref_point1", *ref_point_); full_x_U->AddOneVector(-1., *pert_dir_, 1.); ref_point_->ElementWiseMin(*full_x_U); DBG_PRINT_VECTOR(1,"ref_point2", *ref_point_); full_x_L->AddOneVector(1., *pert_dir_, 1.); ref_point_->ElementWiseMax(*full_x_L); DBG_PRINT_VECTOR(1,"ref_point3", *ref_point_); }
SmartPtr<const Vector> AugRestoSystemSolver::D_x_plus_wr_d( const SmartPtr<const Vector>& CD_x0, Number factor, const Vector& wr_d) { DBG_START_METH("AugRestoSystemSolver::D_x_plus_wr_d",dbg_verbosity); SmartPtr<Vector> retVec; std::vector<const TaggedObject*> deps(2); deps[0] = &wr_d; if (IsValid(CD_x0)) { deps[1] = GetRawPtr(CD_x0); } else { deps[1] = NULL; } std::vector<Number> scalar_deps(1); scalar_deps[0] = factor; if (!d_x_plus_wr_d_cache_.GetCachedResult(retVec, deps, scalar_deps)) { DBG_PRINT((1,"Not found in cache\n")); retVec = wr_d.MakeNew(); Number fact; SmartPtr<const Vector> v; if (IsValid(CD_x0)) { fact = 1.; v = CD_x0; } else { fact = 0.; v = &wr_d; } retVec->AddTwoVectors(factor, wr_d, fact, *v, 0.); d_x_plus_wr_d_cache_.AddCachedResult(retVec, deps, scalar_deps); } DBG_PRINT_VECTOR(2, "retVec", *retVec); return ConstPtr(retVec); }
Number RestoIpoptNLP::f( const Vector& x, Number mu ) { DBG_START_METH("RestoIpoptNLP::f", dbg_verbosity); Number ret = 0.0; // rho*(pcTe + ncTe + pdT*e + ndT*e) + eta/2*||Dr*(x-xr)||_2^2 const CompoundVector* c_vec = static_cast<const CompoundVector*>(&x); DBG_ASSERT(c_vec); SmartPtr<const Vector> x_only = c_vec->GetComp(0); ret = x.Sum() - x_only->Sum(); DBG_PRINT((1, "xdiff sum = %e\n", ret)); ret = rho_ * ret; DBG_PRINT((1, "rho_ = %e\n", rho_)); SmartPtr<Vector> x_diff = x_only->MakeNew(); x_diff->Copy(*x_only); x_diff->Axpy(-1.0, *x_ref_); DBG_PRINT_VECTOR(2, "x_ref", *x_ref_); x_diff->ElementWiseMultiply(*dr_x_); Number ret2 = x_diff->Nrm2(); DBG_PRINT((1, "Eta = %e\n", Eta(mu))); ret2 = Eta(mu) / 2.0 * ret2 * ret2; ret += ret2; // We evaluate also the objective function for the original // problem here. This might be wasteful, but it will detect if // the original objective function cannot be evaluated at the // trial point in the restoration phase if( evaluate_orig_obj_at_resto_trial_ ) { /* Number orig_f = */orig_ip_nlp_->f(*x_only); } return ret; }
bool RestoIterateInitializer::SetInitialIterates() { DBG_START_METH("RestoIterateInitializer::SetInitialIterates", dbg_verbosity); // Get a grip on the restoration phase NLP and obtain the pointers // to the original NLP data SmartPtr<RestoIpoptNLP> resto_ip_nlp = static_cast<RestoIpoptNLP*> (&IpNLP()); SmartPtr<IpoptNLP> orig_ip_nlp = static_cast<IpoptNLP*> (&resto_ip_nlp->OrigIpNLP()); SmartPtr<IpoptData> orig_ip_data = static_cast<IpoptData*> (&resto_ip_nlp->OrigIpData()); SmartPtr<IpoptCalculatedQuantities> orig_ip_cq = static_cast<IpoptCalculatedQuantities*> (&resto_ip_nlp->OrigIpCq()); // Set the value of the barrier parameter Number resto_mu; resto_mu = Max(orig_ip_data->curr_mu(), orig_ip_cq->curr_c()->Amax(), orig_ip_cq->curr_d_minus_s()->Amax()); IpData().Set_mu(resto_mu); Jnlst().Printf(J_DETAILED, J_INITIALIZATION, "Initial barrier parameter resto_mu = %e\n", resto_mu); ///////////////////////////////////////////////////////////////////// // Initialize primal varialbes // ///////////////////////////////////////////////////////////////////// // initialize the data structures in the restoration phase NLP IpData().InitializeDataStructures(IpNLP(), false, false, false, false, false); SmartPtr<Vector> new_x = IpData().curr()->x()->MakeNew(); SmartPtr<CompoundVector> Cnew_x = static_cast<CompoundVector*> (GetRawPtr(new_x)); // Set the trial x variables from the original NLP Cnew_x->GetCompNonConst(0)->Copy(*orig_ip_data->curr()->x()); // Compute the initial values for the n and p variables for the // equality constraints Number rho = resto_ip_nlp->Rho(); DBG_PRINT((1,"rho = %e\n", rho)); SmartPtr<Vector> nc = Cnew_x->GetCompNonConst(1); SmartPtr<Vector> pc = Cnew_x->GetCompNonConst(2); SmartPtr<const Vector> cvec = orig_ip_cq->curr_c(); DBG_PRINT_VECTOR(2, "cvec", *cvec); SmartPtr<Vector> a = nc->MakeNew(); SmartPtr<Vector> b = nc->MakeNew(); a->Set(resto_mu/(2.*rho)); a->Axpy(-0.5, *cvec); b->Copy(*cvec); b->Scal(resto_mu/(2.*rho)); DBG_PRINT_VECTOR(2, "a", *a); DBG_PRINT_VECTOR(2, "b", *b); solve_quadratic(*a, *b, *nc); pc->Copy(*cvec); pc->Axpy(1., *nc); DBG_PRINT_VECTOR(2, "nc", *nc); DBG_PRINT_VECTOR(2, "pc", *pc); // initial values for the n and p variables for the inequality // constraints SmartPtr<Vector> nd = Cnew_x->GetCompNonConst(3); SmartPtr<Vector> pd = Cnew_x->GetCompNonConst(4); cvec = orig_ip_cq->curr_d_minus_s(); a = nd->MakeNew(); b = nd->MakeNew(); a->Set(resto_mu/(2.*rho)); a->Axpy(-0.5, *cvec); b->Copy(*cvec); b->Scal(resto_mu/(2.*rho)); solve_quadratic(*a, *b, *nd); pd->Copy(*cvec); pd->Axpy(1., *nd); DBG_PRINT_VECTOR(2, "nd", *nd); DBG_PRINT_VECTOR(2, "pd", *pd); // Leave the slacks unchanged SmartPtr<const Vector> new_s = orig_ip_data->curr()->s(); // Now set the primal trial variables DBG_PRINT_VECTOR(2,"new_s",*new_s); DBG_PRINT_VECTOR(2,"new_x",*new_x); SmartPtr<IteratesVector> trial = IpData().curr()->MakeNewContainer(); trial->Set_primal(*new_x, *new_s); IpData().set_trial(trial); DBG_PRINT_VECTOR(2, "resto_c", *IpCq().trial_c()); DBG_PRINT_VECTOR(2, "resto_d_minus_s", *IpCq().trial_d_minus_s()); ///////////////////////////////////////////////////////////////////// // Initialize bound multipliers // ///////////////////////////////////////////////////////////////////// SmartPtr<Vector> new_z_L = IpData().curr()->z_L()->MakeNew(); SmartPtr<CompoundVector> Cnew_z_L = static_cast<CompoundVector*> (GetRawPtr(new_z_L)); DBG_ASSERT(IsValid(Cnew_z_L)); SmartPtr<Vector> new_z_U = IpData().curr()->z_U()->MakeNew(); SmartPtr<Vector> new_v_L = IpData().curr()->v_L()->MakeNew(); SmartPtr<Vector> new_v_U = IpData().curr()->v_U()->MakeNew(); // multipliers for the original bounds are SmartPtr<const Vector> orig_z_L = orig_ip_data->curr()->z_L(); SmartPtr<const Vector> orig_z_U = orig_ip_data->curr()->z_U(); SmartPtr<const Vector> orig_v_L = orig_ip_data->curr()->v_L(); SmartPtr<const Vector> orig_v_U = orig_ip_data->curr()->v_U(); // Set the new multipliers to the min of the penalty parameter Rho // and their current value SmartPtr<Vector> Cnew_z_L0 = Cnew_z_L->GetCompNonConst(0); Cnew_z_L0->Set(rho); Cnew_z_L0->ElementWiseMin(*orig_z_L); new_z_U->Set(rho); new_z_U->ElementWiseMin(*orig_z_U); new_v_L->Set(rho); new_v_L->ElementWiseMin(*orig_v_L); new_v_U->Set(rho); new_v_U->ElementWiseMin(*orig_v_U); // Set the multipliers for the p and n bounds to the "primal" multipliers SmartPtr<Vector> Cnew_z_L1 = Cnew_z_L->GetCompNonConst(1); Cnew_z_L1->Set(resto_mu); Cnew_z_L1->ElementWiseDivide(*nc); SmartPtr<Vector> Cnew_z_L2 = Cnew_z_L->GetCompNonConst(2); Cnew_z_L2->Set(resto_mu); Cnew_z_L2->ElementWiseDivide(*pc); SmartPtr<Vector> Cnew_z_L3 = Cnew_z_L->GetCompNonConst(3); Cnew_z_L3->Set(resto_mu); Cnew_z_L3->ElementWiseDivide(*nd); SmartPtr<Vector> Cnew_z_L4 = Cnew_z_L->GetCompNonConst(4); Cnew_z_L4->Set(resto_mu); Cnew_z_L4->ElementWiseDivide(*pd); // Set those initial values to be the trial values in Data trial = IpData().trial()->MakeNewContainer(); trial->Set_bound_mult(*new_z_L, *new_z_U, *new_v_L, *new_v_U); IpData().set_trial(trial); ///////////////////////////////////////////////////////////////////// // Initialize equality constraint multipliers // ///////////////////////////////////////////////////////////////////// DefaultIterateInitializer::least_square_mults( Jnlst(), IpNLP(), IpData(), IpCq(), resto_eq_mult_calculator_, constr_mult_init_max_); // upgrade the trial to the current point IpData().AcceptTrialPoint(); DBG_PRINT_VECTOR(2, "y_c", *IpData().curr()->y_c()); DBG_PRINT_VECTOR(2, "y_d", *IpData().curr()->y_d()); DBG_PRINT_VECTOR(2, "z_L", *IpData().curr()->z_L()); DBG_PRINT_VECTOR(2, "z_U", *IpData().curr()->z_U()); DBG_PRINT_VECTOR(2, "v_L", *IpData().curr()->v_L()); DBG_PRINT_VECTOR(2, "v_U", *IpData().curr()->v_U()); return true; }
ESymSolverStatus AugRestoSystemSolver::Solve(const SymMatrix* W, double W_factor, const Vector* D_x, double delta_x, const Vector* D_s, double delta_s, const Matrix* J_c, const Vector* D_c, double delta_c, const Matrix* J_d, const Vector* D_d, double delta_d, const Vector& rhs_x, const Vector& rhs_s, const Vector& rhs_c, const Vector& rhs_d, Vector& sol_x, Vector& sol_s, Vector& sol_c, Vector& sol_d, bool check_NegEVals, Index numberOfNegEVals) { DBG_START_METH("AugRestoSystemSolver::Solve",dbg_verbosity); DBG_ASSERT(J_c && J_d); // should pass these by ref // I think the comment below is incorrect // Remember, W and the D's may be NULL! // ToDo: I don't think the W's can ever be NULL (we always need the structure) DBG_ASSERT(W); SmartPtr<const CompoundSymMatrix> CW = static_cast<const CompoundSymMatrix*>(W); SmartPtr<const CompoundVector> CD_x = static_cast<const CompoundVector*>(D_x); SmartPtr<const CompoundMatrix> CJ_c = static_cast<const CompoundMatrix*>(J_c); DBG_ASSERT(IsValid(CJ_c)); SmartPtr<const CompoundMatrix> CJ_d = static_cast<const CompoundMatrix*>(J_d); DBG_ASSERT(IsValid(CJ_d)); SmartPtr<const CompoundVector> Crhs_x = static_cast<const CompoundVector*>(&rhs_x); DBG_ASSERT(IsValid(Crhs_x)); SmartPtr<CompoundVector> Csol_x = static_cast<CompoundVector*>(&sol_x); DBG_ASSERT(IsValid(Csol_x)); // Get the Sigma inverses SmartPtr<const Vector> sigma_n_c; SmartPtr<const Vector> sigma_p_c; SmartPtr<const Vector> sigma_n_d; SmartPtr<const Vector> sigma_p_d; if (IsValid(CD_x)) { sigma_n_c = CD_x->GetComp(1); sigma_p_c = CD_x->GetComp(2); sigma_n_d = CD_x->GetComp(3); sigma_p_d = CD_x->GetComp(4); } SmartPtr<const Vector> sigma_tilde_n_c_inv = Sigma_tilde_n_c_inv(sigma_n_c, delta_x, *Crhs_x->GetComp(1)); SmartPtr<const Vector> sigma_tilde_p_c_inv = Sigma_tilde_p_c_inv(sigma_p_c, delta_x, *Crhs_x->GetComp(2)); SmartPtr<const Vector> sigma_tilde_n_d_inv = Sigma_tilde_n_d_inv(sigma_n_d, delta_x, *Crhs_x->GetComp(3)); SmartPtr<const Vector> sigma_tilde_p_d_inv = Sigma_tilde_p_d_inv(sigma_p_d, delta_x, *Crhs_x->GetComp(4)); // Pull out the expansion matrices for d SmartPtr<const Matrix> pd_l = CJ_d->GetComp(0,3); SmartPtr<const Matrix> neg_pd_u = CJ_d->GetComp(0,4); // Now map the correct entries into the Solve method // pull out the parts of the hessian h_orig + diag DBG_PRINT_MATRIX(2, "CW", *CW); SmartPtr<const SymMatrix> h_orig; SmartPtr<const Vector> D_xR; SmartPtr<const SumSymMatrix> WR_sum = dynamic_cast<const SumSymMatrix*>(GetRawPtr(CW->GetComp(0,0))); Number orig_W_factor = W_factor; if (IsValid(WR_sum)) { // We seem to be in the regular situation with exact second // derivatives double temp_factor; WR_sum->GetTerm(0, temp_factor, h_orig); DBG_ASSERT(temp_factor == 1. || temp_factor == 0.); orig_W_factor = temp_factor * W_factor; SmartPtr<const SymMatrix> eta_DR; double factor; WR_sum->GetTerm(1, factor, eta_DR); SmartPtr<const Vector> wr_d = static_cast<const DiagMatrix*>(GetRawPtr(eta_DR))->GetDiag(); if (IsValid(CD_x)) { D_xR = D_x_plus_wr_d(CD_x->GetComp(0), factor, *wr_d); } else { D_xR = D_x_plus_wr_d(NULL, factor, *wr_d); } } else { // Looks like limited memory quasi-Newton stuff const LowRankUpdateSymMatrix* LR_W = static_cast<const LowRankUpdateSymMatrix*>(GetRawPtr(CW->GetComp(0,0))); DBG_ASSERT(LR_W); h_orig = LR_W; if (IsValid(CD_x)) { D_xR = CD_x->GetComp(0); } else { D_xR = NULL; } } Number delta_xR = delta_x; SmartPtr<const Vector> D_sR = D_s; Number delta_sR = delta_s; SmartPtr<const Matrix> J_cR = CJ_c->GetComp(0,0); SmartPtr<const Vector> D_cR = Neg_Omega_c_plus_D_c(sigma_tilde_n_c_inv, sigma_tilde_p_c_inv, D_c, rhs_c); DBG_PRINT((1,"D_cR tag = %d\n",D_cR->GetTag())); Number delta_cR = delta_c; SmartPtr<const Matrix> J_dR = CJ_d->GetComp(0,0); SmartPtr<const Vector> D_dR = Neg_Omega_d_plus_D_d(*pd_l, sigma_tilde_n_d_inv, *neg_pd_u, sigma_tilde_p_d_inv, D_d, rhs_d); Number delta_dR = delta_d; SmartPtr<const Vector> rhs_xR = Crhs_x->GetComp(0); SmartPtr<const Vector> rhs_sR = &rhs_s; SmartPtr<const Vector> rhs_cR = Rhs_cR(rhs_c, sigma_tilde_n_c_inv, *Crhs_x->GetComp(1), sigma_tilde_p_c_inv, *Crhs_x->GetComp(2)); SmartPtr<const Vector> rhs_dR = Rhs_dR(rhs_d, sigma_tilde_n_d_inv, *Crhs_x->GetComp(3), *pd_l, sigma_tilde_p_d_inv, *Crhs_x->GetComp(4), *neg_pd_u); SmartPtr<Vector> sol_xR = Csol_x->GetCompNonConst(0); Vector& sol_sR = sol_s; Vector& sol_cR = sol_c; Vector& sol_dR = sol_d; ESymSolverStatus status = orig_aug_solver_->Solve(GetRawPtr(h_orig), orig_W_factor, GetRawPtr(D_xR), delta_xR, GetRawPtr(D_sR), delta_sR, GetRawPtr(J_cR), GetRawPtr(D_cR), delta_cR, GetRawPtr(J_dR), GetRawPtr(D_dR), delta_dR, *rhs_xR, *rhs_sR, *rhs_cR, *rhs_dR, *sol_xR, sol_sR, sol_cR, sol_dR, check_NegEVals, numberOfNegEVals); if (status == SYMSOLVER_SUCCESS) { // Now back out the solutions for the n and p variables SmartPtr<Vector> sol_n_c = Csol_x->GetCompNonConst(1); sol_n_c->Set(0.0); if (IsValid(sigma_tilde_n_c_inv)) { sol_n_c->AddTwoVectors(1., *Crhs_x->GetComp(1), -1.0, sol_cR, 0.); sol_n_c->ElementWiseMultiply(*sigma_tilde_n_c_inv); } SmartPtr<Vector> sol_p_c = Csol_x->GetCompNonConst(2); sol_p_c->Set(0.0); if (IsValid(sigma_tilde_p_c_inv)) { DBG_PRINT_VECTOR(2, "rhs_pc", *Crhs_x->GetComp(2)); DBG_PRINT_VECTOR(2, "delta_y_c", sol_cR); DBG_PRINT_VECTOR(2, "Sig~_{p_c}^{-1}", *sigma_tilde_p_c_inv); sol_p_c->AddTwoVectors(1., *Crhs_x->GetComp(2), 1.0, sol_cR, 0.); sol_p_c->ElementWiseMultiply(*sigma_tilde_p_c_inv); } SmartPtr<Vector> sol_n_d = Csol_x->GetCompNonConst(3); sol_n_d->Set(0.0); if (IsValid(sigma_tilde_n_d_inv)) { pd_l->TransMultVector(-1.0, sol_dR, 0.0, *sol_n_d); sol_n_d->Axpy(1.0, *Crhs_x->GetComp(3)); sol_n_d->ElementWiseMultiply(*sigma_tilde_n_d_inv); } SmartPtr<Vector> sol_p_d = Csol_x->GetCompNonConst(4); sol_p_d->Set(0.0); if (IsValid(sigma_tilde_p_d_inv)) { neg_pd_u->TransMultVector(-1.0, sol_dR, 0.0, *sol_p_d); sol_p_d->Axpy(1.0, *Crhs_x->GetComp(4)); sol_p_d->ElementWiseMultiply(*sigma_tilde_p_d_inv); } } return status; }
void PDFullSpaceSolver::ComputeResiduals( const SymMatrix& W, const Matrix& J_c, const Matrix& J_d, const Matrix& Px_L, const Matrix& Px_U, const Matrix& Pd_L, const Matrix& Pd_U, const Vector& z_L, const Vector& z_U, const Vector& v_L, const Vector& v_U, const Vector& slack_x_L, const Vector& slack_x_U, const Vector& slack_s_L, const Vector& slack_s_U, const Vector& sigma_x, const Vector& sigma_s, Number alpha, Number beta, const IteratesVector& rhs, const IteratesVector& res, IteratesVector& resid) { DBG_START_METH("PDFullSpaceSolver::ComputeResiduals", dbg_verbosity); DBG_PRINT_VECTOR(2, "res", res); IpData().TimingStats().ComputeResiduals().Start(); // Get the current sizes of the perturbation factors Number delta_x; Number delta_s; Number delta_c; Number delta_d; perturbHandler_->CurrentPerturbation(delta_x, delta_s, delta_c, delta_d); SmartPtr<Vector> tmp; // x W.MultVector(1., *res.x(), 0., *resid.x_NonConst()); J_c.TransMultVector(1., *res.y_c(), 1., *resid.x_NonConst()); J_d.TransMultVector(1., *res.y_d(), 1., *resid.x_NonConst()); Px_L.MultVector(-1., *res.z_L(), 1., *resid.x_NonConst()); Px_U.MultVector(1., *res.z_U(), 1., *resid.x_NonConst()); resid.x_NonConst()->AddTwoVectors(delta_x, *res.x(), -1., *rhs.x(), 1.); // s Pd_U.MultVector(1., *res.v_U(), 0., *resid.s_NonConst()); Pd_L.MultVector(-1., *res.v_L(), 1., *resid.s_NonConst()); resid.s_NonConst()->AddTwoVectors(-1., *res.y_d(), -1., *rhs.s(), 1.); if (delta_s!=0.) { resid.s_NonConst()->Axpy(delta_s, *res.s()); } // c J_c.MultVector(1., *res.x(), 0., *resid.y_c_NonConst()); resid.y_c_NonConst()->AddTwoVectors(-delta_c, *res.y_c(), -1., *rhs.y_c(), 1.); // d J_d.MultVector(1., *res.x(), 0., *resid.y_d_NonConst()); resid.y_d_NonConst()->AddTwoVectors(-1., *res.s(), -1., *rhs.y_d(), 1.); if (delta_d!=0.) { resid.y_d_NonConst()->Axpy(-delta_d, *res.y_d()); } // zL resid.z_L_NonConst()->Copy(*res.z_L()); resid.z_L_NonConst()->ElementWiseMultiply(slack_x_L); tmp = z_L.MakeNew(); Px_L.TransMultVector(1., *res.x(), 0., *tmp); tmp->ElementWiseMultiply(z_L); resid.z_L_NonConst()->AddTwoVectors(1., *tmp, -1., *rhs.z_L(), 1.); // zU resid.z_U_NonConst()->Copy(*res.z_U()); resid.z_U_NonConst()->ElementWiseMultiply(slack_x_U); tmp = z_U.MakeNew(); Px_U.TransMultVector(1., *res.x(), 0., *tmp); tmp->ElementWiseMultiply(z_U); resid.z_U_NonConst()->AddTwoVectors(-1., *tmp, -1., *rhs.z_U(), 1.); // vL resid.v_L_NonConst()->Copy(*res.v_L()); resid.v_L_NonConst()->ElementWiseMultiply(slack_s_L); tmp = v_L.MakeNew(); Pd_L.TransMultVector(1., *res.s(), 0., *tmp); tmp->ElementWiseMultiply(v_L); resid.v_L_NonConst()->AddTwoVectors(1., *tmp, -1., *rhs.v_L(), 1.); // vU resid.v_U_NonConst()->Copy(*res.v_U()); resid.v_U_NonConst()->ElementWiseMultiply(slack_s_U); tmp = v_U.MakeNew(); Pd_U.TransMultVector(1., *res.s(), 0., *tmp); tmp->ElementWiseMultiply(v_U); resid.v_U_NonConst()->AddTwoVectors(-1., *tmp, -1., *rhs.v_U(), 1.); DBG_PRINT_VECTOR(2, "resid", resid); if (Jnlst().ProduceOutput(J_MOREVECTOR, J_LINEAR_ALGEBRA)) { resid.Print(Jnlst(), J_MOREVECTOR, J_LINEAR_ALGEBRA, "resid"); } if (Jnlst().ProduceOutput(J_MOREDETAILED, J_LINEAR_ALGEBRA)) { Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_x %e\n", resid.x()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_s %e\n", resid.s()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_c %e\n", resid.y_c()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_d %e\n", resid.y_d()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_zL %e\n", resid.z_L()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_zU %e\n", resid.z_U()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_vL %e\n", resid.v_L()->Amax()); Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA, "max-norm resid_vU %e\n", resid.v_U()->Amax()); } IpData().TimingStats().ComputeResiduals().End(); }
bool PDFullSpaceSolver::Solve(Number alpha, Number beta, const IteratesVector& rhs, IteratesVector& res, bool allow_inexact, bool improve_solution /* = false */) { DBG_START_METH("PDFullSpaceSolver::Solve",dbg_verbosity); DBG_ASSERT(!allow_inexact || !improve_solution); DBG_ASSERT(!improve_solution || beta==0.); // Timing of PDSystem solver starts here IpData().TimingStats().PDSystemSolverTotal().Start(); DBG_PRINT_VECTOR(2, "rhs_x", *rhs.x()); DBG_PRINT_VECTOR(2, "rhs_s", *rhs.s()); DBG_PRINT_VECTOR(2, "rhs_c", *rhs.y_c()); DBG_PRINT_VECTOR(2, "rhs_d", *rhs.y_d()); DBG_PRINT_VECTOR(2, "rhs_zL", *rhs.z_L()); DBG_PRINT_VECTOR(2, "rhs_zU", *rhs.z_U()); DBG_PRINT_VECTOR(2, "rhs_vL", *rhs.v_L()); DBG_PRINT_VECTOR(2, "rhs_vU", *rhs.v_U()); DBG_PRINT_VECTOR(2, "res_x in", *res.x()); DBG_PRINT_VECTOR(2, "res_s in", *res.s()); DBG_PRINT_VECTOR(2, "res_c in", *res.y_c()); DBG_PRINT_VECTOR(2, "res_d in", *res.y_d()); DBG_PRINT_VECTOR(2, "res_zL in", *res.z_L()); DBG_PRINT_VECTOR(2, "res_zU in", *res.z_U()); DBG_PRINT_VECTOR(2, "res_vL in", *res.v_L()); DBG_PRINT_VECTOR(2, "res_vU in", *res.v_U()); // if beta is nonzero, keep a copy of the incoming values in res_ */ SmartPtr<IteratesVector> copy_res; if (beta != 0.) { copy_res = res.MakeNewIteratesVectorCopy(); } // Receive data about matrix SmartPtr<const Vector> x = IpData().curr()->x(); SmartPtr<const Vector> s = IpData().curr()->s(); SmartPtr<const SymMatrix> W = IpData().W(); SmartPtr<const Matrix> J_c = IpCq().curr_jac_c(); SmartPtr<const Matrix> J_d = IpCq().curr_jac_d(); SmartPtr<const Matrix> Px_L = IpNLP().Px_L(); SmartPtr<const Matrix> Px_U = IpNLP().Px_U(); SmartPtr<const Matrix> Pd_L = IpNLP().Pd_L(); SmartPtr<const Matrix> Pd_U = IpNLP().Pd_U(); SmartPtr<const Vector> z_L = IpData().curr()->z_L(); SmartPtr<const Vector> z_U = IpData().curr()->z_U(); SmartPtr<const Vector> v_L = IpData().curr()->v_L(); SmartPtr<const Vector> v_U = IpData().curr()->v_U(); SmartPtr<const Vector> slack_x_L = IpCq().curr_slack_x_L(); SmartPtr<const Vector> slack_x_U = IpCq().curr_slack_x_U(); SmartPtr<const Vector> slack_s_L = IpCq().curr_slack_s_L(); SmartPtr<const Vector> slack_s_U = IpCq().curr_slack_s_U(); SmartPtr<const Vector> sigma_x = IpCq().curr_sigma_x(); SmartPtr<const Vector> sigma_s = IpCq().curr_sigma_s(); DBG_PRINT_VECTOR(2, "Sigma_x", *sigma_x); DBG_PRINT_VECTOR(2, "Sigma_s", *sigma_s); bool done = false; // The following flag is set to true, if we asked the linear // solver to improve the quality of the solution in // the next solve bool resolve_with_better_quality = false; // the following flag is set to true, if iterative refinement // failed and we want to try if a modified system is able to // remedy that problem by pretending the matrix is singular bool pretend_singular = false; bool pretend_singular_last_time = false; // Beginning of loop for solving the system (including all // modifications for the linear system to ensure good solution // quality) while (!done) { // if improve_solution is true, we are given already a solution // from the calling function, so we can skip the first solve bool solve_retval = true; if (!improve_solution) { solve_retval = SolveOnce(resolve_with_better_quality, pretend_singular, *W, *J_c, *J_d, *Px_L, *Px_U, *Pd_L, *Pd_U, *z_L, *z_U, *v_L, *v_U, *slack_x_L, *slack_x_U, *slack_s_L, *slack_s_U, *sigma_x, *sigma_s, 1., 0., rhs, res); resolve_with_better_quality = false; pretend_singular = false; } improve_solution = false; if (!solve_retval) { // If system seems not to be solvable, we return with false // and let the calling routine deal with it. IpData().TimingStats().PDSystemSolverTotal().End(); return false; } if (allow_inexact) { // no safety checks required if (Jnlst().ProduceOutput(J_MOREDETAILED, J_LINEAR_ALGEBRA)) { SmartPtr<IteratesVector> resid = res.MakeNewIteratesVector(true); ComputeResiduals(*W, *J_c, *J_d, *Px_L, *Px_U, *Pd_L, *Pd_U, *z_L, *z_U, *v_L, *v_U, *slack_x_L, *slack_x_U, *slack_s_L, *slack_s_U, *sigma_x, *sigma_s, alpha, beta, rhs, res, *resid); } break; } // Get space for the residual SmartPtr<IteratesVector> resid = res.MakeNewIteratesVector(true); // ToDo don't to that after max refinement? ComputeResiduals(*W, *J_c, *J_d, *Px_L, *Px_U, *Pd_L, *Pd_U, *z_L, *z_U, *v_L, *v_U, *slack_x_L, *slack_x_U, *slack_s_L, *slack_s_U, *sigma_x, *sigma_s, alpha, beta, rhs, res, *resid); Number residual_ratio = ComputeResidualRatio(rhs, res, *resid); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "residual_ratio = %e\n", residual_ratio); Number residual_ratio_old = residual_ratio; // Beginning of loop for iterative refinement Index num_iter_ref = 0; bool quit_refinement = false; while (!allow_inexact && !quit_refinement && (num_iter_ref < min_refinement_steps_ || residual_ratio > residual_ratio_max_) ) { // To the next back solve solve_retval = SolveOnce(resolve_with_better_quality, false, *W, *J_c, *J_d, *Px_L, *Px_U, *Pd_L, *Pd_U, *z_L, *z_U, *v_L, *v_U, *slack_x_L, *slack_x_U, *slack_s_L, *slack_s_U, *sigma_x, *sigma_s, -1., 1., *resid, res); ASSERT_EXCEPTION(solve_retval, INTERNAL_ABORT, "SolveOnce returns false during iterative refinement."); ComputeResiduals(*W, *J_c, *J_d, *Px_L, *Px_U, *Pd_L, *Pd_U, *z_L, *z_U, *v_L, *v_U, *slack_x_L, *slack_x_U, *slack_s_L, *slack_s_U, *sigma_x, *sigma_s, alpha, beta, rhs, res, *resid); residual_ratio = ComputeResidualRatio(rhs, res, *resid); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "residual_ratio = %e\n", residual_ratio); num_iter_ref++; // Check if we have to give up on iterative refinement if (residual_ratio > residual_ratio_max_ && num_iter_ref>min_refinement_steps_ && (num_iter_ref>max_refinement_steps_ || residual_ratio>residual_improvement_factor_*residual_ratio_old)) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Iterative refinement failed with residual_ratio = %e\n", residual_ratio); quit_refinement = true; // Pretend singularity only once - if it didn't help, we // have to live with what we got so far resolve_with_better_quality = false; DBG_PRINT((1, "pretend_singular = %d\n", pretend_singular)); if (!pretend_singular_last_time) { // First try if we can ask the augmented system solver to // improve the quality of the solution (only if that hasn't // been done before for this linear system) if (!augsys_improved_) { Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Asking augmented system solver to improve quality of its solutions.\n"); augsys_improved_ = augSysSolver_->IncreaseQuality(); if (augsys_improved_) { IpData().Append_info_string("q"); resolve_with_better_quality = true; } else { // solver said it cannot improve quality, so let // possibly conclude that the current modification is // singular pretend_singular = true; } } else { // we had already asked the solver before to improve the // quality of the solution, so let's now pretend that the // modification is possibly singular pretend_singular = true; } pretend_singular_last_time = pretend_singular; if (pretend_singular) { // let's only conclude that the current linear system // including modifications is singular, if the residual is // quite bad if (residual_ratio < residual_ratio_singular_) { pretend_singular = false; IpData().Append_info_string("S"); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Just accept current solution.\n"); } else { IpData().Append_info_string("s"); Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA, "Pretend that the current system (including modifications) is singular.\n"); } } } else { pretend_singular = false; DBG_PRINT((1,"Resetting pretend_singular to false.\n")); } } residual_ratio_old = residual_ratio; } // End of loop for iterative refinement done = !(resolve_with_better_quality) && !(pretend_singular); } // End of loop for solving the linear system (incl. modifications) // Finally let's assemble the res result vectors if (alpha != 0.) { res.Scal(alpha); } if (beta != 0.) { res.Axpy(beta, *copy_res); } DBG_PRINT_VECTOR(2, "res_x", *res.x()); DBG_PRINT_VECTOR(2, "res_s", *res.s()); DBG_PRINT_VECTOR(2, "res_c", *res.y_c()); DBG_PRINT_VECTOR(2, "res_d", *res.y_d()); DBG_PRINT_VECTOR(2, "res_zL", *res.z_L()); DBG_PRINT_VECTOR(2, "res_zU", *res.z_U()); DBG_PRINT_VECTOR(2, "res_vL", *res.v_L()); DBG_PRINT_VECTOR(2, "res_vU", *res.v_U()); IpData().TimingStats().PDSystemSolverTotal().End(); return true; }
bool PDSearchDirCalculator::ComputeSearchDirection() { DBG_START_METH("PDSearchDirCalculator::ComputeSearchDirection", dbg_verbosity); bool improve_solution = false; if (IpData().HaveDeltas()) { improve_solution = true; } bool retval; if (improve_solution && fast_step_computation_) { retval = true; } else { SmartPtr<IteratesVector> rhs = IpData().curr()->MakeNewContainer(); rhs->Set_x(*IpCq().curr_grad_lag_with_damping_x()); rhs->Set_s(*IpCq().curr_grad_lag_with_damping_s()); rhs->Set_y_c(*IpCq().curr_c()); rhs->Set_y_d(*IpCq().curr_d_minus_s()); Index nbounds = IpNLP().x_L()->Dim()+ IpNLP().x_U()->Dim() + IpNLP().d_L()->Dim()+ IpNLP().d_U()->Dim(); if (nbounds>0 && mehrotra_algorithm_) { // set up the right hand side a la Mehrotra DBG_ASSERT(IpData().HaveAffineDeltas()); DBG_ASSERT(!IpData().HaveDeltas()); const SmartPtr<const IteratesVector> delta_aff = IpData().delta_aff(); SmartPtr<Vector> tmpvec = delta_aff->z_L()->MakeNew(); IpNLP().Px_L()->TransMultVector(1., *delta_aff->x(), 0., *tmpvec); tmpvec->ElementWiseMultiply(*delta_aff->z_L()); tmpvec->Axpy(1., *IpCq().curr_relaxed_compl_x_L()); rhs->Set_z_L(*tmpvec); tmpvec = delta_aff->z_U()->MakeNew(); IpNLP().Px_U()->TransMultVector(-1., *delta_aff->x(), 0., *tmpvec); tmpvec->ElementWiseMultiply(*delta_aff->z_U()); tmpvec->Axpy(1., *IpCq().curr_relaxed_compl_x_U()); rhs->Set_z_U(*tmpvec); tmpvec = delta_aff->v_L()->MakeNew(); IpNLP().Pd_L()->TransMultVector(1., *delta_aff->s(), 0., *tmpvec); tmpvec->ElementWiseMultiply(*delta_aff->v_L()); tmpvec->Axpy(1., *IpCq().curr_relaxed_compl_s_L()); rhs->Set_v_L(*tmpvec); tmpvec = delta_aff->v_U()->MakeNew(); IpNLP().Pd_U()->TransMultVector(-1., *delta_aff->s(), 0., *tmpvec); tmpvec->ElementWiseMultiply(*delta_aff->v_U()); tmpvec->Axpy(1., *IpCq().curr_relaxed_compl_s_U()); rhs->Set_v_U(*tmpvec); } else { rhs->Set_z_L(*IpCq().curr_relaxed_compl_x_L()); rhs->Set_z_U(*IpCq().curr_relaxed_compl_x_U()); rhs->Set_v_L(*IpCq().curr_relaxed_compl_s_L()); rhs->Set_v_U(*IpCq().curr_relaxed_compl_s_U()); } DBG_PRINT_VECTOR(2, "rhs", *rhs); // Get space for the search direction SmartPtr<IteratesVector> delta = IpData().curr()->MakeNewIteratesVector(true); if (improve_solution) { // We can probably avoid copying and scaling... delta->AddOneVector(-1., *IpData().delta(), 0.); } bool& allow_inexact = fast_step_computation_; retval = pd_solver_->Solve(-1.0, 0.0, *rhs, *delta, allow_inexact, improve_solution); if (retval) { // Store the search directions in the IpData object IpData().set_delta(delta); } } return retval; }
bool ProbingMuOracle::CalculateMu( Number mu_min, Number mu_max, Number& new_mu ) { DBG_START_METH("ProbingMuOracle::CalculateMu", dbg_verbosity); ///////////////////////////////////// // Compute the affine scaling step // ///////////////////////////////////// Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE, "Solving the Primal Dual System for the affine step\n"); // First get the right hand side SmartPtr<IteratesVector> rhs = IpData().curr()->MakeNewContainer(); rhs->Set_x(*IpCq().curr_grad_lag_x()); rhs->Set_s(*IpCq().curr_grad_lag_s()); rhs->Set_y_c(*IpCq().curr_c()); rhs->Set_y_d(*IpCq().curr_d_minus_s()); rhs->Set_z_L(*IpCq().curr_compl_x_L()); rhs->Set_z_U(*IpCq().curr_compl_x_U()); rhs->Set_v_L(*IpCq().curr_compl_s_L()); rhs->Set_v_U(*IpCq().curr_compl_s_U()); // Get space for the affine scaling step SmartPtr<IteratesVector> step = rhs->MakeNewIteratesVector(true); // Now solve the primal-dual system to get the affine step. We // allow a somewhat inexact solution here bool allow_inexact = true; bool retval = pd_solver_->Solve(-1.0, 0.0, *rhs, *step, allow_inexact); if( !retval ) { Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE, "The linear system could not be solved for the affine step!\n"); return false; } DBG_PRINT_VECTOR(2, "step", *step); ///////////////////////////////////////////////////////////// // Use Mehrotra's formula to compute the barrier parameter // ///////////////////////////////////////////////////////////// // First compute the fraction-to-the-boundary step sizes Number alpha_primal_aff = IpCq().primal_frac_to_the_bound(1.0, *step->x(), *step->s()); Number alpha_dual_aff = IpCq().dual_frac_to_the_bound(1.0, *step->z_L(), *step->z_U(), *step->v_L(), *step->v_U()); Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE, " The affine maximal step sizes are\n" " alpha_primal_aff = %23.16e\n" " alpha_dual_aff = %23.16e\n", alpha_primal_aff, alpha_dual_aff); // now compute the average complementarity at the affine step // ToDo shoot for mu_min instead of 0? Number mu_aff = CalculateAffineMu(alpha_primal_aff, alpha_dual_aff, *step); Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE, " The average complementariy at the affine step is %23.16e\n", mu_aff); // get the current average complementarity Number mu_curr = IpCq().curr_avrg_compl(); Jnlst().Printf(J_DETAILED, J_BARRIER_UPDATE, " The average complementariy at the current point is %23.16e\n", mu_curr); DBG_ASSERT(mu_curr > 0.); // Apply Mehrotra's rule Number sigma = pow((mu_aff / mu_curr), 3); // Make sure, sigma is not too large sigma = Min(sigma, sigma_max_); Number mu = sigma * mu_curr; // Store the affine search direction (in case it is needed in the // line search for a corrector step) IpData().set_delta_aff(step); IpData().SetHaveAffineDeltas(true); char ssigma[40]; sprintf(ssigma, " sigma=%8.2e", sigma); IpData().Append_info_string(ssigma); //sprintf(ssigma, " xi=%8.2e ", IpCq().curr_centrality_measure()); //IpData().Append_info_string(ssigma); new_mu = Max(Min(mu, mu_max), mu_min); return true; }
ESymSolverStatus LowRankAugSystemSolver::UpdateFactorization( const SymMatrix* W, double W_factor, const Vector* D_x, double delta_x, const Vector* D_s, double delta_s, const Matrix& J_c, const Vector* D_c, double delta_c, const Matrix& J_d, const Vector* D_d, double delta_d, const Vector& proto_rhs_x, const Vector& proto_rhs_s, const Vector& proto_rhs_c, const Vector& proto_rhs_d, bool check_NegEVals, Index numberOfNegEVals ) { DBG_START_METH("LowRankAugSystemSolver::UpdateFactorization", dbg_verbosity); DBG_ASSERT(W_factor == 0.0 || W_factor == 1.0); ESymSolverStatus retval = SYMSOLVER_SUCCESS; // Get the low update information out of W const LowRankUpdateSymMatrix* LR_W = static_cast<const LowRankUpdateSymMatrix*>(W); DBG_ASSERT(LR_W); DBG_PRINT_MATRIX(2, "LR_W", *LR_W); SmartPtr<const Vector> B0; SmartPtr<const MultiVectorMatrix> V; SmartPtr<const MultiVectorMatrix> U; if( W_factor == 1.0 ) { V = LR_W->GetV(); U = LR_W->GetU(); B0 = LR_W->GetDiag(); } SmartPtr<const Matrix> P_LM = LR_W->P_LowRank(); SmartPtr<const VectorSpace> LR_VecSpace = LR_W->LowRankVectorSpace(); if( IsNull(B0) ) { SmartPtr<Vector> zero_B0 = (IsValid(P_LM)) ? LR_VecSpace->MakeNew() : proto_rhs_x.MakeNew(); zero_B0->Set(0.0); B0 = GetRawPtr(zero_B0); } // set up the Hessian for the underlying augmented system solver // without the low-rank update if( IsValid(P_LM) && LR_W->ReducedDiag() ) { DBG_ASSERT(IsValid(B0)); SmartPtr<Vector> fullx = proto_rhs_x.MakeNew(); P_LM->MultVector(1., *B0, 0., *fullx); Wdiag_->SetDiag(*fullx); } else { Wdiag_->SetDiag(*B0); DBG_PRINT_VECTOR(2, "B0", *B0); } SmartPtr<MultiVectorMatrix> Vtilde1_x; if( IsValid(V) ) { SmartPtr<MultiVectorMatrix> V_x; Index nV = V->NCols(); //DBG_PRINT((1, "delta_x = %e\n", delta_x)); //DBG_PRINT_MATRIX(2, "V", *V); retval = SolveMultiVector(D_x, delta_x, D_s, delta_s, J_c, D_c, delta_c, J_d, D_d, delta_d, proto_rhs_x, proto_rhs_s, proto_rhs_c, proto_rhs_d, *V, P_LM, V_x, Vtilde1_, Vtilde1_x, check_NegEVals, numberOfNegEVals); if( retval != SYMSOLVER_SUCCESS ) { Jnlst().Printf(J_DETAILED, J_SOLVE_PD_SYSTEM, "LowRankAugSystemSolver: SolveMultiVector returned retval = %d for V.\n", retval); return retval; } //DBG_PRINT_MATRIX(2, "Vtilde1_x", *Vtilde1_x); SmartPtr<DenseSymMatrixSpace> M1space = new DenseSymMatrixSpace(nV); SmartPtr<DenseSymMatrix> M1 = M1space->MakeNewDenseSymMatrix(); M1->FillIdentity(); M1->HighRankUpdateTranspose(1., *Vtilde1_x, *V_x, 1.); //DBG_PRINT_MATRIX(2, "M1", *M1); SmartPtr<DenseGenMatrixSpace> J1space = new DenseGenMatrixSpace(nV, nV); J1_ = J1space->MakeNewDenseGenMatrix(); bool retchol = J1_->ComputeCholeskyFactor(*M1); // M1 must be positive definite! //DBG_ASSERT(retchol); if( !retchol ) { Jnlst().Printf(J_DETAILED, J_SOLVE_PD_SYSTEM, "LowRankAugSystemSolver: Cholesky for M1 returned error!\n"); retval = SYMSOLVER_WRONG_INERTIA; num_neg_evals_++; return retval; } } else { Vtilde1_ = NULL; J1_ = NULL; } if( IsValid(U) ) { Index nU = U->NCols(); SmartPtr<MultiVectorMatrix> U_x; SmartPtr<MultiVectorMatrix> Utilde1; SmartPtr<MultiVectorMatrix> Utilde1_x; SmartPtr<MultiVectorMatrix> Utilde2_x; retval = SolveMultiVector(D_x, delta_x, D_s, delta_s, J_c, D_c, delta_c, J_d, D_d, delta_d, proto_rhs_x, proto_rhs_s, proto_rhs_c, proto_rhs_d, *U, P_LM, U_x, Utilde1, Utilde1_x, check_NegEVals, numberOfNegEVals); if( retval != SYMSOLVER_SUCCESS ) { Jnlst().Printf(J_DETAILED, J_SOLVE_PD_SYSTEM, "LowRankAugSystemSolver: SolveMultiVector returned retval = %d for U.\n", retval); return retval; } if( IsNull(Vtilde1_) ) { Utilde2_ = Utilde1; Utilde2_x = Utilde1_x; } else { Index nV = Vtilde1_->NCols(); SmartPtr<DenseGenMatrixSpace> Cspace = new DenseGenMatrixSpace(nV, nU); SmartPtr<DenseGenMatrix> C = Cspace->MakeNewDenseGenMatrix(); C->HighRankUpdateTranspose(1., *Vtilde1_x, *U_x, 0.); J1_->CholeskySolveMatrix(*C); Utilde2_ = Utilde1; Utilde2_->AddRightMultMatrix(-1, *Vtilde1_, *C, 1.); Utilde2_x = Utilde1_x->MakeNewMultiVectorMatrix(); for( Index i = 0; i < Utilde1_x->NCols(); i++ ) { const CompoundVector* cvec = static_cast<const CompoundVector*>(GetRawPtr(Utilde2_->GetVector(i))); DBG_ASSERT(cvec); Utilde2_x->SetVector(i, *cvec->GetComp(0)); } } SmartPtr<DenseSymMatrixSpace> M2space = new DenseSymMatrixSpace(nU); SmartPtr<DenseSymMatrix> M2 = M2space->MakeNewDenseSymMatrix(); M2->FillIdentity(); M2->HighRankUpdateTranspose(-1., *Utilde2_x, *U_x, 1.); SmartPtr<DenseGenMatrixSpace> J2space = new DenseGenMatrixSpace(nU, nU); J2_ = J2space->MakeNewDenseGenMatrix(); //DBG_PRINT_MATRIX(2, "M2", *M2); bool retchol = J2_->ComputeCholeskyFactor(*M2); if( !retchol ) { Jnlst().Printf(J_DETAILED, J_SOLVE_PD_SYSTEM, "LowRankAugSystemSolver: Cholesky for M2 returned error.\n"); retval = SYMSOLVER_WRONG_INERTIA; num_neg_evals_++; return retval; } } else { J2_ = NULL; Utilde2_ = NULL; } return retval; }
bool RestoIpoptNLP::InitializeStructures( SmartPtr<Vector>& x, bool init_x, SmartPtr<Vector>& y_c, bool init_y_c, SmartPtr<Vector>& y_d, bool init_y_d, SmartPtr<Vector>& z_L, bool init_z_L, SmartPtr<Vector>& z_U, bool init_z_U, SmartPtr<Vector>& v_L, SmartPtr<Vector>& v_U) { DBG_START_METH("RestoIpoptNLP::InitializeStructures", 0); DBG_ASSERT(initialized_); /////////////////////////////////////////////////////////// // Get the vector/matrix spaces for the original problem // /////////////////////////////////////////////////////////// SmartPtr<const VectorSpace> orig_x_space; SmartPtr<const VectorSpace> orig_c_space; SmartPtr<const VectorSpace> orig_d_space; SmartPtr<const VectorSpace> orig_x_l_space; SmartPtr<const MatrixSpace> orig_px_l_space; SmartPtr<const VectorSpace> orig_x_u_space; SmartPtr<const MatrixSpace> orig_px_u_space; SmartPtr<const VectorSpace> orig_d_l_space; SmartPtr<const MatrixSpace> orig_pd_l_space; SmartPtr<const VectorSpace> orig_d_u_space; SmartPtr<const MatrixSpace> orig_pd_u_space; SmartPtr<const MatrixSpace> orig_jac_c_space; SmartPtr<const MatrixSpace> orig_jac_d_space; SmartPtr<const SymMatrixSpace> orig_h_space; orig_ip_nlp_->GetSpaces(orig_x_space, orig_c_space, orig_d_space, orig_x_l_space, orig_px_l_space, orig_x_u_space, orig_px_u_space, orig_d_l_space, orig_pd_l_space, orig_d_u_space, orig_pd_u_space, orig_jac_c_space, orig_jac_d_space, orig_h_space); // Create the restoration phase problem vector/matrix spaces, based // on the original spaces (pretty inconvenient with all the // matrix spaces, isn't it?!?) DBG_PRINT((1, "Creating the x_space_\n")); // vector x Index total_dim = orig_x_space->Dim() + 2 * orig_c_space->Dim() + 2 * orig_d_space->Dim(); x_space_ = new CompoundVectorSpace(5, total_dim); x_space_->SetCompSpace(0, *orig_x_space); x_space_->SetCompSpace(1, *orig_c_space); // n_c x_space_->SetCompSpace(2, *orig_c_space); // p_c x_space_->SetCompSpace(3, *orig_d_space); // n_d x_space_->SetCompSpace(4, *orig_d_space); // p_d DBG_PRINT((1, "Setting the c_space_\n")); // vector c //c_space_ = orig_c_space; c_space_ = new CompoundVectorSpace(1, orig_c_space->Dim()); c_space_->SetCompSpace(0, *orig_c_space); DBG_PRINT((1, "Setting the d_space_\n")); // vector d //d_space_ = orig_d_space; d_space_ = new CompoundVectorSpace(1, orig_d_space->Dim()); d_space_->SetCompSpace(0, *orig_d_space); DBG_PRINT((1, "Creating the x_l_space_\n")); // vector x_L total_dim = orig_x_l_space->Dim() + 2 * orig_c_space->Dim() + 2 * orig_d_space->Dim(); x_l_space_ = new CompoundVectorSpace(5, total_dim); x_l_space_->SetCompSpace(0, *orig_x_l_space); x_l_space_->SetCompSpace(1, *orig_c_space); // n_c >=0 x_l_space_->SetCompSpace(2, *orig_c_space); // p_c >=0 x_l_space_->SetCompSpace(3, *orig_d_space); // n_d >=0 x_l_space_->SetCompSpace(4, *orig_d_space); // p_d >=0 DBG_PRINT((1, "Setting the x_u_space_\n")); // vector x_U x_u_space_ = new CompoundVectorSpace(1, orig_x_u_space->Dim()); x_u_space_->SetCompSpace(0, *orig_x_u_space); DBG_PRINT((1, "Creating the px_l_space_\n")); // matrix px_l Index total_rows = orig_x_space->Dim() + 2 * orig_c_space->Dim() + 2 * orig_d_space->Dim(); Index total_cols = orig_x_l_space->Dim() + 2 * orig_c_space->Dim() + 2 * orig_d_space->Dim(); px_l_space_ = new CompoundMatrixSpace(5, 5, total_rows, total_cols); px_l_space_->SetBlockRows(0, orig_x_space->Dim()); px_l_space_->SetBlockRows(1, orig_c_space->Dim()); px_l_space_->SetBlockRows(2, orig_c_space->Dim()); px_l_space_->SetBlockRows(3, orig_d_space->Dim()); px_l_space_->SetBlockRows(4, orig_d_space->Dim()); px_l_space_->SetBlockCols(0, orig_x_l_space->Dim()); px_l_space_->SetBlockCols(1, orig_c_space->Dim()); px_l_space_->SetBlockCols(2, orig_c_space->Dim()); px_l_space_->SetBlockCols(3, orig_d_space->Dim()); px_l_space_->SetBlockCols(4, orig_d_space->Dim()); px_l_space_->SetCompSpace(0, 0, *orig_px_l_space); // now setup the identity matrix // This could be changed to be something like... // px_l_space_->SetBlockToIdentity(1,1,1.0); // px_l_space_->SetBlockToIdentity(2,2,other_factor); // ... etc with some simple changes to the CompoundMatrixSpace // to allow this (space should auto create the matrices) // // for now, we use the new feature and set the true flag for this block // to say that the matrices should be auto_allocated SmartPtr<const MatrixSpace> identity_mat_space_nc = new IdentityMatrixSpace(orig_c_space->Dim()); px_l_space_->SetCompSpace(1, 1, *identity_mat_space_nc, true); px_l_space_->SetCompSpace(2, 2, *identity_mat_space_nc, true); SmartPtr<const MatrixSpace> identity_mat_space_nd = new IdentityMatrixSpace(orig_d_space->Dim()); px_l_space_->SetCompSpace(3, 3, *identity_mat_space_nd, true); px_l_space_->SetCompSpace(4, 4, *identity_mat_space_nd, true); DBG_PRINT((1, "Creating the px_u_space_\n")); // matrix px_u total_rows = orig_x_space->Dim() + 2 * orig_c_space->Dim() + 2 * orig_d_space->Dim(); total_cols = orig_x_u_space->Dim(); DBG_PRINT((1, "total_rows = %d, total_cols = %d\n", total_rows, total_cols)); px_u_space_ = new CompoundMatrixSpace(5, 1, total_rows, total_cols); px_u_space_->SetBlockRows(0, orig_x_space->Dim()); px_u_space_->SetBlockRows(1, orig_c_space->Dim()); px_u_space_->SetBlockRows(2, orig_c_space->Dim()); px_u_space_->SetBlockRows(3, orig_d_space->Dim()); px_u_space_->SetBlockRows(4, orig_d_space->Dim()); px_u_space_->SetBlockCols(0, orig_x_u_space->Dim()); px_u_space_->SetCompSpace(0, 0, *orig_px_u_space); // other matrices are zero'ed out // vector d_L //d_l_space_ = orig_d_l_space; d_l_space_ = new CompoundVectorSpace(1, orig_d_l_space->Dim()); d_l_space_->SetCompSpace(0, *orig_d_l_space); // vector d_U //d_u_space_ = orig_d_u_space; d_u_space_ = new CompoundVectorSpace(1, orig_d_u_space->Dim()); d_u_space_->SetCompSpace(0, *orig_d_u_space); // matrix pd_L //pd_l_space_ = orig_pd_l_space; pd_l_space_ = new CompoundMatrixSpace(1, 1, orig_pd_l_space->NRows(), orig_pd_l_space->NCols()); pd_l_space_->SetBlockRows(0, orig_pd_l_space->NRows()); pd_l_space_->SetBlockCols(0, orig_pd_l_space->NCols()); pd_l_space_->SetCompSpace(0, 0, *orig_pd_l_space); // matrix pd_U //pd_u_space_ = orig_pd_u_space; pd_u_space_ = new CompoundMatrixSpace(1, 1, orig_pd_u_space->NRows(), orig_pd_u_space->NCols()); pd_u_space_->SetBlockRows(0, orig_pd_u_space->NRows()); pd_u_space_->SetBlockCols(0, orig_pd_u_space->NCols()); pd_u_space_->SetCompSpace(0, 0, *orig_pd_u_space); DBG_PRINT((1, "Creating the jac_c_space_\n")); // matrix jac_c total_rows = orig_c_space->Dim(); total_cols = orig_x_space->Dim() + 2 * orig_c_space->Dim() + 2 * orig_d_space->Dim(); jac_c_space_ = new CompoundMatrixSpace(1, 5, total_rows, total_cols); jac_c_space_->SetBlockRows(0, orig_c_space->Dim()); jac_c_space_->SetBlockCols(0, orig_x_space->Dim()); jac_c_space_->SetBlockCols(1, orig_c_space->Dim()); jac_c_space_->SetBlockCols(2, orig_c_space->Dim()); jac_c_space_->SetBlockCols(3, orig_d_space->Dim()); jac_c_space_->SetBlockCols(4, orig_d_space->Dim()); jac_c_space_->SetCompSpace(0, 0, *orig_jac_c_space); // **NOTE: By placing "flat" identity matrices here, we are creating // potential issues for linalg operations that arise when the original // NLP has a "compound" c_space. To avoid problems like this, // we place all unmodified component spaces in trivial (size 1) // "compound" spaces. jac_c_space_->SetCompSpace(0, 1, *identity_mat_space_nc, true); jac_c_space_->SetCompSpace(0, 2, *identity_mat_space_nc, true); // remaining blocks are zero'ed DBG_PRINT((1, "Creating the jac_d_space_\n")); // matrix jac_d total_rows = orig_d_space->Dim(); total_cols = orig_x_space->Dim() + 2 * orig_c_space->Dim() + 2 * orig_d_space->Dim(); jac_d_space_ = new CompoundMatrixSpace(1, 5, total_rows, total_cols); jac_d_space_->SetBlockRows(0, orig_d_space->Dim()); jac_d_space_->SetBlockCols(0, orig_x_space->Dim()); jac_d_space_->SetBlockCols(1, orig_c_space->Dim()); jac_d_space_->SetBlockCols(2, orig_c_space->Dim()); jac_d_space_->SetBlockCols(3, orig_d_space->Dim()); jac_d_space_->SetBlockCols(4, orig_d_space->Dim()); jac_d_space_->SetCompSpace(0, 0, *orig_jac_d_space); DBG_PRINT((1, "orig_jac_d_space = %x\n", GetRawPtr(orig_jac_d_space))) // Blocks (0,1) and (0,2) are zero'ed out // **NOTE: By placing "flat" identity matrices here, we are creating // potential issues for linalg operations that arise when the original // NLP has a "compound" d_space. To avoid problems like this, // we place all unmodified component spaces in trivial (size 1) // "compound" spaces. jac_d_space_->SetCompSpace(0, 3, *identity_mat_space_nd, true); jac_d_space_->SetCompSpace(0, 4, *identity_mat_space_nd, true); DBG_PRINT((1, "Creating the h_space_\n")); // matrix h total_dim = orig_x_space->Dim() + 2 * orig_c_space->Dim() + 2 * orig_d_space->Dim(); h_space_ = new CompoundSymMatrixSpace(5, total_dim); h_space_->SetBlockDim(0, orig_x_space->Dim()); h_space_->SetBlockDim(1, orig_c_space->Dim()); h_space_->SetBlockDim(2, orig_c_space->Dim()); h_space_->SetBlockDim(3, orig_d_space->Dim()); h_space_->SetBlockDim(4, orig_d_space->Dim()); SmartPtr<DiagMatrixSpace> DR_x_space = new DiagMatrixSpace(orig_x_space->Dim()); if( hessian_approximation_ == LIMITED_MEMORY ) { const LowRankUpdateSymMatrixSpace* LR_h_space = static_cast<const LowRankUpdateSymMatrixSpace*>(GetRawPtr( orig_h_space)); DBG_ASSERT(LR_h_space); SmartPtr<LowRankUpdateSymMatrixSpace> new_orig_h_space = new LowRankUpdateSymMatrixSpace(LR_h_space->Dim(), NULL, orig_x_space, false); h_space_->SetCompSpace(0, 0, *new_orig_h_space, true); } else { SmartPtr<SumSymMatrixSpace> sumsym_mat_space = new SumSymMatrixSpace(orig_x_space->Dim(), 2); sumsym_mat_space->SetTermSpace(0, *orig_h_space); sumsym_mat_space->SetTermSpace(1, *DR_x_space); h_space_->SetCompSpace(0, 0, *sumsym_mat_space, true); // All remaining blocks are zero'ed out } /////////////////////////// // Create the bound data // /////////////////////////// // x_L x_L_ = x_l_space_->MakeNewCompoundVector(); x_L_->SetComp(0, *orig_ip_nlp_->x_L()); // x >= x_L x_L_->GetCompNonConst(1)->Set(0.0); // n_c >= 0 x_L_->GetCompNonConst(2)->Set(0.0); // p_c >= 0 x_L_->GetCompNonConst(3)->Set(0.0); // n_d >= 0 x_L_->GetCompNonConst(4)->Set(0.0); // p_d >= 0 DBG_PRINT_VECTOR(2, "resto_x_L", *x_L_); // x_U x_U_ = x_u_space_->MakeNewCompoundVector(); x_U_->SetComp(0, *orig_ip_nlp_->x_U()); // d_L d_L_ = d_l_space_->MakeNewCompoundVector(); d_L_->SetComp(0, *orig_ip_nlp_->d_L()); // d_U d_U_ = d_u_space_->MakeNewCompoundVector(); d_U_->SetComp(0, *orig_ip_nlp_->d_U()); // Px_L Px_L_ = px_l_space_->MakeNewCompoundMatrix(); Px_L_->SetComp(0, 0, *orig_ip_nlp_->Px_L()); // Identities are auto-created (true flag passed into SetCompSpace) // Px_U Px_U_ = px_u_space_->MakeNewCompoundMatrix(); Px_U_->SetComp(0, 0, *orig_ip_nlp_->Px_U()); // Remaining matrices will be zero'ed out // Pd_L //Pd_L_ = orig_ip_nlp_->Pd_L(); Pd_L_ = pd_l_space_->MakeNewCompoundMatrix(); Pd_L_->SetComp(0, 0, *orig_ip_nlp_->Pd_L()); // Pd_U //Pd_U_ = orig_ip_nlp_->Pd_U(); Pd_U_ = pd_u_space_->MakeNewCompoundMatrix(); Pd_U_->SetComp(0, 0, *orig_ip_nlp_->Pd_U()); // Getting the NLP scaling SmartPtr<const MatrixSpace> scaled_jac_c_space; SmartPtr<const MatrixSpace> scaled_jac_d_space; SmartPtr<const SymMatrixSpace> scaled_h_space; NLP_scaling()->DetermineScaling(GetRawPtr(x_space_), c_space_, d_space_, GetRawPtr(jac_c_space_), GetRawPtr(jac_d_space_), GetRawPtr(h_space_), scaled_jac_c_space, scaled_jac_d_space, scaled_h_space, *Px_L_, *x_L_, *Px_U_, *x_U_); // For now we assume that no scaling is done inside the NLP_Scaling DBG_ASSERT(scaled_jac_c_space == jac_c_space_); DBG_ASSERT(scaled_jac_d_space == jac_d_space_); DBG_ASSERT(scaled_h_space == h_space_); ///////////////////////////////////////////////////////////////////////// // Create and initialize the vectors for the restoration phase problem // ///////////////////////////////////////////////////////////////////////// // Vector x SmartPtr<CompoundVector> comp_x = x_space_->MakeNewCompoundVector(); if( init_x ) { comp_x->GetCompNonConst(0)->Copy(*orig_ip_data_->curr()->x()); comp_x->GetCompNonConst(1)->Set(1.0); comp_x->GetCompNonConst(2)->Set(1.0); comp_x->GetCompNonConst(3)->Set(1.0); comp_x->GetCompNonConst(4)->Set(1.0); } x = GetRawPtr(comp_x); // Vector y_c y_c = c_space_->MakeNew(); if( init_y_c ) { y_c->Set(0.0); // ToDo } // Vector y_d y_d = d_space_->MakeNew(); if( init_y_d ) { y_d->Set(0.0); } // Vector z_L z_L = x_l_space_->MakeNew(); if( init_z_L ) { z_L->Set(1.0); } // Vector z_U z_U = x_u_space_->MakeNew(); if( init_z_U ) { z_U->Set(1.0); } // Vector v_L v_L = d_l_space_->MakeNew(); // Vector v_U v_U = d_u_space_->MakeNew(); // Initialize other data needed by the restoration nlp. x_ref is // the point to reference to which we based the regularization // term x_ref_ = orig_x_space->MakeNew(); x_ref_->Copy(*orig_ip_data_->curr()->x()); dr_x_ = orig_x_space->MakeNew(); dr_x_->Set(1.0); SmartPtr<Vector> tmp = dr_x_->MakeNew(); tmp->Copy(*x_ref_); dr_x_->ElementWiseMax(*tmp); tmp->Scal(-1.); dr_x_->ElementWiseMax(*tmp); dr_x_->ElementWiseReciprocal(); DBG_PRINT_VECTOR(2, "dr_x_", *dr_x_); DR_x_ = DR_x_space->MakeNewDiagMatrix(); DR_x_->SetDiag(*dr_x_); return true; }
Number IpoptAlgorithm::correct_bound_multiplier( const Vector& trial_z, const Vector& trial_slack, const Vector& trial_compl, SmartPtr<const Vector>& new_trial_z) { DBG_START_METH("IpoptAlgorithm::CorrectBoundMultiplier", dbg_verbosity); if (kappa_sigma_<1. || trial_z.Dim()==0) { new_trial_z = &trial_z; return 0.; } // We choose as barrier parameter to be used either the current // algorithmic barrier parameter (if we are not in the free mode), // or the average complementarity (at the trial point) Number mu; if (IpData().FreeMuMode()) { mu = IpCq().trial_avrg_compl(); mu = Min(mu, 1e3); } else { mu = IpData().curr_mu(); } DBG_PRINT((1,"mu = %8.2e\n", mu)); DBG_PRINT_VECTOR(2, "trial_z", trial_z); // First check quickly if anything need to be corrected, using the // trial complementarity directly. Here, Amax is the same as Max // (and we use Amax because that can be used later) if (trial_compl.Amax() <= kappa_sigma_*mu && trial_compl.Min() >= 1./kappa_sigma_*mu) { new_trial_z = &trial_z; return 0.; } SmartPtr<Vector> one_over_s = trial_z.MakeNew(); one_over_s->Copy(trial_slack); one_over_s->ElementWiseReciprocal(); SmartPtr<Vector> step_z = trial_z.MakeNew(); step_z->AddTwoVectors(kappa_sigma_*mu, *one_over_s, -1., trial_z, 0.); DBG_PRINT_VECTOR(2, "step_z", *step_z); Number max_correction_up = Max(0., -step_z->Min()); if (max_correction_up>0.) { SmartPtr<Vector> tmp = trial_z.MakeNew(); tmp->Set(0.); step_z->ElementWiseMin(*tmp); tmp->AddTwoVectors(1., trial_z, 1., *step_z, 0.); new_trial_z = GetRawPtr(tmp); } else { new_trial_z = &trial_z; } step_z->AddTwoVectors(1./kappa_sigma_*mu, *one_over_s, -1., *new_trial_z, 0.); Number max_correction_low = Max(0., step_z->Max()); if (max_correction_low>0.) { SmartPtr<Vector> tmp = trial_z.MakeNew(); tmp->Set(0.); step_z->ElementWiseMax(*tmp); tmp->AddTwoVectors(1., *new_trial_z, 1., *step_z, 0.); new_trial_z = GetRawPtr(tmp); } DBG_PRINT_VECTOR(2, "new_trial_z", *new_trial_z); return Max(max_correction_up, max_correction_low); }
bool RestoRestorationPhase::PerformRestoration() { DBG_START_METH("RestoRestorationPhase::PerformRestoration", dbg_verbosity); Jnlst().Printf(J_DETAILED, J_MAIN, "Performing second level restoration phase for current constriant violation %8.2e\n", IpCq().curr_constraint_violation()); DBG_ASSERT(IpCq().curr_constraint_violation()>0.); // Get a grip on the restoration phase NLP and obtain the pointers // to the original NLP data SmartPtr<RestoIpoptNLP> resto_ip_nlp = static_cast<RestoIpoptNLP*> (&IpNLP()); DBG_ASSERT(dynamic_cast<RestoIpoptNLP*> (&IpNLP())); SmartPtr<IpoptNLP> orig_ip_nlp = static_cast<IpoptNLP*> (&resto_ip_nlp->OrigIpNLP()); DBG_ASSERT(dynamic_cast<IpoptNLP*> (&resto_ip_nlp->OrigIpNLP())); // Get the current point and create a new vector for the result SmartPtr<const CompoundVector> Ccurr_x = static_cast<const CompoundVector*> (GetRawPtr(IpData().curr()->x())); SmartPtr<Vector> new_x = IpData().curr()->x()->MakeNew(); SmartPtr<CompoundVector> Cnew_x = static_cast<CompoundVector*> (GetRawPtr(new_x)); // The x values remain unchanged SmartPtr<Vector> x = Cnew_x->GetCompNonConst(0); x->Copy(*Ccurr_x->GetComp(0)); // ToDo in free mu mode - what to do here? Number mu = IpData().curr_mu(); // Compute the initial values for the n and p variables for the // equality constraints Number rho = resto_ip_nlp->Rho(); SmartPtr<Vector> nc = Cnew_x->GetCompNonConst(1); SmartPtr<Vector> pc = Cnew_x->GetCompNonConst(2); SmartPtr<const Vector> cvec = orig_ip_nlp->c(*Ccurr_x->GetComp(0)); SmartPtr<Vector> a = nc->MakeNew(); SmartPtr<Vector> b = nc->MakeNew(); a->Set(mu/(2.*rho)); a->Axpy(-0.5, *cvec); b->Copy(*cvec); b->Scal(mu/(2.*rho)); solve_quadratic(*a, *b, *nc); pc->Copy(*cvec); pc->Axpy(1., *nc); DBG_PRINT_VECTOR(2, "nc", *nc); DBG_PRINT_VECTOR(2, "pc", *pc); // initial values for the n and p variables for the inequality // constraints SmartPtr<Vector> nd = Cnew_x->GetCompNonConst(3); SmartPtr<Vector> pd = Cnew_x->GetCompNonConst(4); SmartPtr<Vector> dvec = pd->MakeNew(); dvec->Copy(*orig_ip_nlp->d(*Ccurr_x->GetComp(0))); dvec->Axpy(-1., *IpData().curr()->s()); a = nd->MakeNew(); b = nd->MakeNew(); a->Set(mu/(2.*rho)); a->Axpy(-0.5, *dvec); b->Copy(*dvec); b->Scal(mu/(2.*rho)); solve_quadratic(*a, *b, *nd); pd->Copy(*dvec); pd->Axpy(1., *nd); DBG_PRINT_VECTOR(2, "nd", *nd); DBG_PRINT_VECTOR(2, "pd", *pd); // Now set the trial point to the solution of the restoration phase // s and all multipliers remain unchanged SmartPtr<IteratesVector> new_trial = IpData().curr()->MakeNewContainer(); new_trial->Set_x(*new_x); IpData().set_trial(new_trial); IpData().Append_info_string("R"); return true; }
bool MinC_1NrmRestorationPhase::PerformRestoration() { DBG_START_METH("MinC_1NrmRestorationPhase::PerformRestoration", dbg_verbosity); // Increase counter for restoration phase calls count_restorations_++; Jnlst().Printf(J_DETAILED, J_MAIN, "Starting Restoration Phase for the %d. time\n", count_restorations_); DBG_ASSERT(IpCq().curr_constraint_violation()>0.); // ToDo set those up during initialize? // Create the restoration phase NLP etc objects SmartPtr<IpoptData> resto_ip_data = new IpoptData(); SmartPtr<IpoptNLP> resto_ip_nlp = new RestoIpoptNLP(IpNLP(), IpData(), IpCq()); SmartPtr<IpoptCalculatedQuantities> resto_ip_cq = new IpoptCalculatedQuantities(resto_ip_nlp, resto_ip_data); // Determine if this is a square problem bool square_problem = IpCq().IsSquareProblem(); // Decide if we want to use the original option or want to make // some changes SmartPtr<OptionsList> actual_resto_options = resto_options_; if(square_problem) { actual_resto_options = new OptionsList(*resto_options_); // If this is a square problem, the want the restoration phase // never to be left until the problem is converged actual_resto_options->SetNumericValue("resto.required_infeasibility_reduction", 0.); } else if (expect_infeasible_problem_ && count_restorations_==1) { if (IpCq().curr_constraint_violation()>1e-3) { actual_resto_options = new OptionsList(*resto_options_); // Ask for significant reduction of infeasibility, in the hope // that we do not return from the restoration phase is the // problem is infeasible actual_resto_options->SetNumericValue("resto.required_infeasibility_reduction", 1e-3); } } // Initialize the restoration phase algorithm resto_alg_->Initialize(Jnlst(), *resto_ip_nlp, *resto_ip_data, *resto_ip_cq, *actual_resto_options, "resto."); // Set iteration counter and info field for the restoration phase resto_ip_data->Set_iter_count(IpData().iter_count()+1); resto_ip_data->Set_info_regu_x(IpData().info_regu_x()); resto_ip_data->Set_info_alpha_primal(IpData().info_alpha_primal()); resto_ip_data->Set_info_alpha_primal_char(IpData().info_alpha_primal_char()); resto_ip_data->Set_info_alpha_dual(IpData().info_alpha_dual()); resto_ip_data->Set_info_ls_count(IpData().info_ls_count()); // Call the optimization algorithm to solve the restoration phase // problem SolverReturn resto_status = resto_alg_->Optimize(); int retval=-1; if (resto_status == SUCCESS) { if (Jnlst().ProduceOutput(J_DETAILED, J_LINE_SEARCH)) { Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "\nRESTORATION PHASE RESULTS\n"); Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "\n\nOptimal solution found! \n"); Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "Optimal Objective Value = %.16E\n", resto_ip_cq->curr_f()); Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "Number of Iterations = %d\n", resto_ip_data->iter_count()); } if (Jnlst().ProduceOutput(J_VECTOR, J_LINE_SEARCH)) { resto_ip_data->curr()->Print(Jnlst(), J_VECTOR, J_LINE_SEARCH, "curr"); } retval = 0; } else if (resto_status == STOP_AT_TINY_STEP || resto_status == STOP_AT_ACCEPTABLE_POINT) { Number orig_primal_inf = IpCq().curr_primal_infeasibility(NORM_MAX); // ToDo make the factor in following line an option if (orig_primal_inf <= 1e2*IpData().tol()) { Jnlst().Printf(J_WARNING, J_LINE_SEARCH, "Restoration phase converged to a point with small primal infeasibility.\n"); THROW_EXCEPTION(RESTORATION_CONVERGED_TO_FEASIBLE_POINT, "Restoration phase converged to a point with small primal infeasibility"); } else { THROW_EXCEPTION(LOCALLY_INFEASIBLE, "Restoration phase converged to a point of local infeasibility"); } } else if (resto_status == MAXITER_EXCEEDED) { THROW_EXCEPTION(RESTORATION_MAXITER_EXCEEDED, "Maximal number of iterations exceeded in restoration phase."); } else if (resto_status == LOCAL_INFEASIBILITY) { // converged to locally infeasible point - pass this on to the outer algorithm... THROW_EXCEPTION(LOCALLY_INFEASIBLE, "Restoration phase converged to a point of local infeasibility"); } else if (resto_status == RESTORATION_FAILURE) { Jnlst().Printf(J_WARNING, J_LINE_SEARCH, "Restoration phase in the restoration phase failed.\n"); THROW_EXCEPTION(RESTORATION_FAILED, "Restoration phase in the restoration phase failed."); } else if (resto_status == USER_REQUESTED_STOP) { // Use requested stop during restoration phase - rethrow exception THROW_EXCEPTION(RESTORATION_USER_STOP, "User requested stop during restoration phase"); } else { Jnlst().Printf(J_ERROR, J_MAIN, "Sorry, things failed ?!?!\n"); retval = 1; } if (retval == 0) { // Copy the results into the trial fields;. They will be // accepted later in the full algorithm SmartPtr<const CompoundVector> cx = dynamic_cast<const CompoundVector*>(GetRawPtr(resto_ip_data->curr()->x())); DBG_ASSERT(IsValid(cx)); SmartPtr<IteratesVector> trial = IpData().trial()->MakeNewContainer(); trial->Set_primal(*cx->GetComp(0), *resto_ip_data->curr()->s()); IpData().set_trial(trial); // If this is a square problem, we are done because a // sufficiently feasible point has been found if (square_problem) { Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "Recursive restoration phase algorithm termined successfully for square problem.\n"); IpData().AcceptTrialPoint(); THROW_EXCEPTION(FEASIBILITY_PROBLEM_SOLVED, "Restoration phase converged to sufficiently feasible point of original square problem."); } // Update the bound multiplers, pretending that the entire // progress in x and s in the restoration phase has been one // [rimal-dual Newton step (and therefore the result of solving // an augmented system) SmartPtr<IteratesVector> delta = IpData().curr()->MakeNewIteratesVector(true); delta->Set(0.0); ComputeBoundMultiplierStep(*delta->z_L_NonConst(), *IpData().curr()->z_L(), *IpCq().curr_slack_x_L(), *IpCq().trial_slack_x_L()); ComputeBoundMultiplierStep(*delta->z_U_NonConst(), *IpData().curr()->z_U(), *IpCq().curr_slack_x_U(), *IpCq().trial_slack_x_U()); ComputeBoundMultiplierStep(*delta->v_L_NonConst(), *IpData().curr()->v_L(), *IpCq().curr_slack_s_L(), *IpCq().trial_slack_s_L()); ComputeBoundMultiplierStep(*delta->v_U_NonConst(), *IpData().curr()->v_U(), *IpCq().curr_slack_s_U(), *IpCq().trial_slack_s_U()); DBG_PRINT_VECTOR(1, "delta_z_L", *delta->z_L()); DBG_PRINT_VECTOR(1, "delta_z_U", *delta->z_U()); DBG_PRINT_VECTOR(1, "delta_v_L", *delta->v_L()); DBG_PRINT_VECTOR(1, "delta_v_U", *delta->v_U()); Number alpha_dual = IpCq().dual_frac_to_the_bound(IpData().curr_tau(), *delta->z_L_NonConst(), *delta->z_U_NonConst(), *delta->v_L_NonConst(), *delta->v_U_NonConst()); Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "Step size for bound multipliers: %8.2e\n", alpha_dual); IpData().SetTrialBoundMultipliersFromStep(alpha_dual, *delta->z_L(), *delta->z_U(), *delta->v_L(), *delta->v_U() ); // ToDo: Check what to do here: Number bound_mult_max = Max(IpData().trial()->z_L()->Amax(), IpData().trial()->z_U()->Amax(), IpData().trial()->v_L()->Amax(), IpData().trial()->v_U()->Amax()); if (bound_mult_max > bound_mult_reset_threshold_) { trial = IpData().trial()->MakeNewContainer(); Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "Bound multipliers after restoration phase too large (max=%8.2e). Set all to 1.\n", bound_mult_max); trial->create_new_z_L(); trial->create_new_z_U(); trial->create_new_v_L(); trial->create_new_v_U(); trial->z_L_NonConst()->Set(1.0); trial->z_U_NonConst()->Set(1.0); trial->v_L_NonConst()->Set(1.0); trial->v_U_NonConst()->Set(1.0); IpData().set_trial(trial); } DefaultIterateInitializer::least_square_mults( Jnlst(), IpNLP(), IpData(), IpCq(), eq_mult_calculator_, constr_mult_reset_threshold_); DBG_PRINT_VECTOR(2, "y_c", *IpData().curr()->y_c()); DBG_PRINT_VECTOR(2, "y_d", *IpData().curr()->y_d()); IpData().Set_iter_count(resto_ip_data->iter_count()-1); // Skip the next line, because it would just replicate the first // on during the restoration phase. IpData().Set_info_skip_output(true); } return (retval == 0); }