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); }