Number CGPenaltyCq::dT_times_barH_times_d() { DBG_START_METH("IpoptCalculatedQuantities::dT_times_barH_times_d()", dbg_verbosity); Number result; SmartPtr<const Vector> d_x = CGPenData().delta_cgfast()->x(); SmartPtr<const Vector> d_s = CGPenData().delta_cgfast()->s(); SmartPtr<const Vector> y_c = ip_data_->curr()->y_c(); SmartPtr<const Vector> y_d = ip_data_->curr()->y_d(); SmartPtr<const Vector> dy_c = CGPenData().delta_cgfast()->y_c(); SmartPtr<const Vector> dy_d = CGPenData().delta_cgfast()->y_d(); SmartPtr<const Vector> c = ip_cq_->curr_c(); SmartPtr<const Vector> d_minus_s = ip_cq_->curr_d_minus_s(); Number deriv_barrier_dx = ip_cq_->curr_grad_barrier_obj_x()->Dot(*d_x); Number deriv_barrier_dx_ds = deriv_barrier_dx + ip_cq_->curr_grad_barrier_obj_s()->Dot(*d_s); Number penalty = CGPenData().curr_penalty(); result = -y_c->Dot(*dy_c); result -= y_d->Dot(*dy_d); result *= curr_cg_pert_fact(); result -= deriv_barrier_dx_ds; result += c->Dot(*y_c); result += d_minus_s->Dot(*y_d); result -= c->Dot(*dy_c); result -= d_minus_s->Dot(*dy_d); result += penalty*ip_cq_->curr_primal_infeasibility(NORM_2); return result; }
Number CGPenaltyCq::curr_direct_deriv_penalty_function() { DBG_START_METH("CGPenaltyCq::curr_direct_deriv_penalty_function()", dbg_verbosity); Number result; SmartPtr<const Vector> x = ip_data_->curr()->x(); SmartPtr<const Vector> s = ip_data_->curr()->s(); SmartPtr<const Vector> y_c = ip_data_->curr()->y_c(); SmartPtr<const Vector> y_d = ip_data_->curr()->y_d(); SmartPtr<const Vector> dy_c = CGPenData().delta_cgpen()->y_c(); SmartPtr<const Vector> dy_d = CGPenData().delta_cgpen()->y_d(); SmartPtr<const Vector> dx = CGPenData().delta_cgpen()->x(); SmartPtr<const Vector> ds = CGPenData().delta_cgpen()->s(); std::vector<const TaggedObject*> tdeps(8); tdeps[0] = GetRawPtr(x); tdeps[1] = GetRawPtr(s); tdeps[2] = GetRawPtr(y_c); tdeps[3] = GetRawPtr(y_d); tdeps[4] = GetRawPtr(dy_c); tdeps[5] = GetRawPtr(dy_d); tdeps[6] = GetRawPtr(dx); tdeps[7] = GetRawPtr(ds); Number mu = ip_data_->curr_mu(); Number penalty = CGPenData().curr_penalty(); std::vector<Number> sdeps(2); sdeps[0] = mu; sdeps[1] = penalty; if (!curr_direct_deriv_penalty_function_cache_.GetCachedResult(result, tdeps, sdeps)) { result = ip_cq_->curr_grad_barrier_obj_x()->Dot(*dx) + ip_cq_->curr_grad_barrier_obj_s()->Dot(*ds); Number curr_inf = ip_cq_->curr_primal_infeasibility(NORM_2); result -= penalty*curr_inf; if (curr_inf != 0.) { Number fac = penalty*CGPenData().CurrPenaltyPert()/curr_inf; SmartPtr<const Vector> c = ip_cq_->curr_c(); SmartPtr<const Vector> d_minus_s = ip_cq_->curr_d_minus_s(); Number result1 = c->Dot(*y_c); result1 += c->Dot(*dy_c); result1 += d_minus_s->Dot(*y_d); result1 += d_minus_s->Dot(*dy_d); result1 *= fac; result += result1; } curr_direct_deriv_penalty_function_cache_.AddCachedResult(result, tdeps, sdeps); } return result; }
Number CGPenaltyCq::compute_curr_cg_penalty(const Number pen_des_fact ) { DBG_START_METH("CGPenaltyCq::compute_curr_cg_penalty()", dbg_verbosity); SmartPtr<const Vector> d_x = ip_data_->delta()->x(); SmartPtr<const Vector> d_s = ip_data_->delta()->s(); SmartPtr<const Vector> y_c = ip_data_->curr()->y_c(); SmartPtr<const Vector> y_d = ip_data_->curr()->y_d(); SmartPtr<const Vector> dy_c = ip_data_->delta()->y_c(); SmartPtr<const Vector> dy_d = ip_data_->delta()->y_d(); // Compute delta barrier times (delta x, delta s) Number deriv_barrier_dx = ip_cq_->curr_grad_barrier_obj_x()->Dot(*d_x); Number deriv_barrier_dx_ds = deriv_barrier_dx + ip_cq_->curr_grad_barrier_obj_s()->Dot(*d_s); // Compute delta x times the damped Hessian times delta x SmartPtr<const Vector> tem_jac_cT_times_y_c = ip_cq_->curr_jac_cT_times_vec(*y_c); SmartPtr<const Vector> tem_jac_cT_times_dy_c = ip_cq_->curr_jac_cT_times_vec(*dy_c); SmartPtr<Vector> tem_jac_cT_times_y_c_plus_dy_c = tem_jac_cT_times_y_c->MakeNew(); tem_jac_cT_times_y_c_plus_dy_c->AddTwoVectors(1.,*tem_jac_cT_times_y_c, 1., *tem_jac_cT_times_dy_c, 0.); SmartPtr<const Vector> tem_jac_dT_times_y_d = ip_cq_->curr_jac_dT_times_vec(*y_d); SmartPtr<const Vector> tem_jac_dT_times_dy_d = ip_cq_->curr_jac_cT_times_vec(*dy_c); SmartPtr<Vector> tem_jac_dT_times_y_d_plus_dy_d = tem_jac_cT_times_y_c->MakeNew(); tem_jac_dT_times_y_d_plus_dy_d->AddTwoVectors(1.,*tem_jac_dT_times_y_d, 1., *tem_jac_dT_times_dy_d, 0.); Number d_xs_times_damped_Hessian_times_d_xs = -deriv_barrier_dx_ds; d_xs_times_damped_Hessian_times_d_xs += -(tem_jac_cT_times_y_c_plus_dy_c->Dot(*d_x) +tem_jac_dT_times_y_d_plus_dy_d->Dot(*d_x) -y_d->Dot(*d_s) -dy_d->Dot(*d_s)); Number dxs_nrm = pow(d_x->Nrm2(), 2.) + pow(d_s->Nrm2(), 2.); d_xs_times_damped_Hessian_times_d_xs = Max(1e-8*dxs_nrm, d_xs_times_damped_Hessian_times_d_xs); Number infeasibility = ip_cq_->curr_primal_infeasibility(NORM_2); Number penalty = 0.; if (infeasibility > 0.) { Number deriv_inf = 0.; Number fac = CGPenData().CurrPenaltyPert()/infeasibility; SmartPtr<const Vector> c = ip_cq_->curr_c(); SmartPtr<const Vector> d_minus_s = ip_cq_->curr_d_minus_s(); if (CGPenData().HaveCgFastDeltas()) { SmartPtr<const Vector> fast_dy_c = CGPenData().delta_cgfast()->y_c(); SmartPtr<const Vector> fast_dy_d = CGPenData().delta_cgfast()->y_d(); deriv_inf += c->Dot(*fast_dy_c); deriv_inf += d_minus_s->Dot(*fast_dy_d); deriv_inf *= fac; deriv_inf -= infeasibility; } else { SmartPtr<const Vector> cgpen_dy_c = CGPenData().delta_cgpen()->y_c(); SmartPtr<const Vector> cgpen_dy_d = CGPenData().delta_cgpen()->y_d(); deriv_inf += c->Dot(*cgpen_dy_c); deriv_inf += c->Dot(*y_c); deriv_inf += d_minus_s->Dot(*cgpen_dy_d); deriv_inf += d_minus_s->Dot(*y_d); deriv_inf *= fac; deriv_inf -= infeasibility; } penalty = -(deriv_barrier_dx_ds + pen_des_fact* d_xs_times_damped_Hessian_times_d_xs)/ (deriv_inf + pen_des_fact*infeasibility); } return penalty; }
Number InexactLSAcceptor::ComputeAlphaForY( Number alpha_primal, Number alpha_dual, SmartPtr<IteratesVector>& delta ) { DBG_START_METH("InexactLSAcceptor::ComputeAlphaForY", dbg_verbosity); // Here, we choose as stepsize for y either alpha_primal, if the // conditions from the ineqaxt paper is satisfied for it, or we // compute the step size closest to alpha_primal but great than // it, that does give the same progress as the full step would // give. Number alpha_y = alpha_primal; SmartPtr<Vector> gx = IpCq().curr_grad_barrier_obj_x()->MakeNewCopy(); gx->AddTwoVectors(1., *IpCq().curr_jac_cT_times_curr_y_c(), 1., *IpCq().curr_jac_dT_times_curr_y_d(), 1.); SmartPtr<Vector> Jxy = gx->MakeNew(); IpCq().curr_jac_c()->TransMultVector(1., *delta->y_c(), 0., *Jxy); IpCq().curr_jac_d()->TransMultVector(1., *delta->y_d(), 1., *Jxy); SmartPtr<const Vector> curr_scaling_slacks = InexCq().curr_scaling_slacks(); SmartPtr<Vector> gs = curr_scaling_slacks->MakeNew(); gs->AddTwoVectors(1., *IpCq().curr_grad_barrier_obj_s(), -1., *IpData().curr()->y_d(), 0.); gs->ElementWiseMultiply(*curr_scaling_slacks); SmartPtr<Vector> Sdy = delta->y_d()->MakeNewCopy(); Sdy->ElementWiseMultiply(*curr_scaling_slacks); // using the magic formula in my notebook Number a = pow(Jxy->Nrm2(), 2) + pow(Sdy->Nrm2(), 2); Number b = 2 * (gx->Dot(*Jxy) - gs->Dot(*Sdy)); Number c = pow(gx->Nrm2(), 2) + pow(gs->Nrm2(), 2); // First we check if the primal step size is good enough: Number val_ap = alpha_primal * alpha_primal * a + alpha_primal * b + c; Number val_1 = a + b + c; if( val_ap <= val_1 ) { Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, " Step size for y: using alpha_primal\n."); } else { Number alpha_2 = -b / a - 1.; Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, " Step size for y candidate: %8.2e - ", alpha_2); if( alpha_2 > alpha_primal && alpha_2 < 1. ) { alpha_y = alpha_2; Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "using that one\n."); } else { alpha_y = 1.; Jnlst().Printf(J_DETAILED, J_LINE_SEARCH, "using 1 instead\n"); } } return alpha_y; }