#include "IpInexactPDTerminationTester.hpp"
#include "IpBlas.hpp"
#include <cmath>
namespace Ipopt
{
#if IPOPT_VERBOSITY > 0
static const Index dbg_verbosity = 0;
#endif
InexactPDTerminationTester::InexactPDTerminationTester()
{
DBG_START_METH("InexactPDTerminationTester::InexactPDTerminationTester", dbg_verbosity);
}
InexactPDTerminationTester::~InexactPDTerminationTester()
{
DBG_START_METH("InexactPDTerminationTester::~InexactPDTerminationTester()", dbg_verbosity);
}
void InexactPDTerminationTester::RegisterOptions(
SmartPtr<RegisteredOptions> roptions)
{
roptions->AddLowerBoundedNumberOption(
"tcc_psi",
"Psi factor in Tangential Component Condition.",
0.0, true,
1e-1);
roptions->AddLowerBoundedNumberOption(
"tcc_theta",
"theta factor in Tangential Component Condition.",
0.0, true,
1e-12);
roptions->AddLowerBoundedNumberOption(
"tcc_theta_mu_exponent",
"exponent for mu when multiplied with tcc_theta in Tangential Component Condition.",
0., false,
0.);
roptions->AddLowerBoundedNumberOption(
"tcc_zeta",
"zeta factor in Tangential Component Condition.",
0.0, true,
1e-1);
roptions->AddLowerBoundedNumberOption(
"tt_kappa1",
"kappa1 factor in Termination Test 1 and 3.",
0.0, true,
1e-3);
roptions->AddLowerBoundedNumberOption(
"tt_kappa2",
"kappa2 factor in Termination Test 2.",
0.0, true,
1e-1);
roptions->AddLowerBoundedNumberOption(
"tt_eps2",
"eps2 factor in Termination Test 2.",
0.0, true,
1.);
roptions->AddLowerBoundedNumberOption(
"tt_eps3",
"eps3 factor in Termination Test 3.",
0.0, true,
1. - 1e-1);
roptions->AddLowerBoundedNumberOption(
"inexact_desired_pd_residual",
"Desired relative residual tolerance for iterative solver during primal-dual step computation.",
0.0, true,
1e-3);
roptions->AddLowerBoundedIntegerOption(
"inexact_desired_pd_residual_iter",
"Number of iterations willing to be spent in obtaining desired primal-dual ration.",
0,
1);
}
bool InexactPDTerminationTester::InitializeImpl(
const OptionsList& options,
const std::string& prefix)
{
options.GetNumericValue("tcc_psi", tcc_psi_, prefix);
options.GetNumericValue("tcc_theta", tcc_theta_, prefix);
options.GetNumericValue("tcc_theta_mu_exponent", tcc_theta_mu_exponent_, prefix);
options.GetNumericValue("tcc_zeta", tcc_zeta_, prefix);
options.GetNumericValue("tt_kappa1", tt_kappa1_, prefix);
options.GetNumericValue("tt_kappa2", tt_kappa2_, prefix);
options.GetNumericValue("tt_eps2", tt_eps2_, prefix);
options.GetNumericValue("tt_eps3", tt_eps3_, prefix);
options.GetNumericValue("rho", rho_, prefix);
options.GetNumericValue("inexact_desired_pd_residual", inexact_desired_pd_residual_, prefix);
options.GetIntegerValue("inexact_desired_pd_residual_iter", inexact_desired_pd_residual_iter_, prefix);
std::string inexact_linear_system_scaling;
options.GetStringValue("inexact_linear_system_scaling", inexact_linear_system_scaling, prefix);
if( inexact_linear_system_scaling == "slack-based" )
{
requires_scaling_ = true;
}
else
{
requires_scaling_ = false;
}
return true;
}
bool InexactPDTerminationTester::InitializeSolve()
{
DBG_START_METH("InexactPDTerminationTester::InitializeSolve",
dbg_verbosity);
bool compute_normal = InexData().compute_normal();
c_norm_ = IpCq().curr_primal_infeasibility(NORM_2);
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: c_norm = %23.16e\n", c_norm_);
SmartPtr<const Vector> normal_x = InexData().normal_x();
SmartPtr<const Vector> normal_s = InexData().normal_s();
if( compute_normal )
{
curr_Av_c_ = InexCq().curr_jac_times_normal_c();
curr_Av_d_ = InexCq().curr_jac_times_normal_d();
SmartPtr<const Vector> curr_c = IpCq().curr_c();
SmartPtr<Vector> tmp1 = curr_c->MakeNew();
tmp1->AddTwoVectors(1, *curr_c, 1., *curr_Av_c_, 0.);
SmartPtr<const Vector> curr_d_minus_s = IpCq().curr_d_minus_s();
SmartPtr<Vector> tmp2 = curr_d_minus_s->MakeNew();
tmp2->AddTwoVectors(1, *curr_d_minus_s, 1., *curr_Av_d_, 0.);
c_plus_Av_norm_ = IpCq().CalcNormOfType(NORM_2, *tmp1, *tmp2);
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: c_plus_Av_norm_ = %23.16e\n", c_plus_Av_norm_);
v_norm_scaled_ = InexCq().slack_scaled_norm(*normal_x, *normal_s);
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: v_norm_scaled_ = %23.16e\n", v_norm_scaled_);
curr_Wv_x_ = InexCq().curr_W_times_vec_x(*normal_x);
curr_Wv_s_ = InexCq().curr_W_times_vec_s(*normal_s);
}
else
{
curr_Av_c_ = NULL;
curr_Av_d_ = NULL;
c_plus_Av_norm_ = -1.;
v_norm_scaled_ = -1.;
curr_Wv_x_ = NULL;
curr_Wv_s_ = NULL;
}
SmartPtr<const Vector> last_grad_barrier_obj_x = curr_grad_barrier_obj_x_;
SmartPtr<const Vector> last_grad_barrier_obj_s = curr_grad_barrier_obj_s_;
SmartPtr<const Matrix> last_jac_c = curr_jac_c_;
SmartPtr<const Matrix> last_jac_d = curr_jac_d_;
SmartPtr<const Vector> last_scaling_slacks = curr_scaling_slacks_;
last_Av_norm_ = curr_Av_norm_;
curr_grad_barrier_obj_x_ = IpCq().curr_grad_barrier_obj_x();
curr_grad_barrier_obj_s_ = IpCq().curr_grad_barrier_obj_s(); curr_jac_c_ = IpCq().curr_jac_c();
curr_jac_d_ = IpCq().curr_jac_d();
curr_scaling_slacks_ = InexCq().curr_scaling_slacks();
SmartPtr<const Vector> curr_jac_cT_times_curr_y_c = IpCq().curr_jac_cT_times_curr_y_c();
SmartPtr<const Vector> curr_jac_cT_times_curr_y_d = IpCq().curr_jac_dT_times_curr_y_d();
curr_nabla_phi_plus_ATy_x_ = curr_grad_barrier_obj_x_->MakeNewCopy();
curr_nabla_phi_plus_ATy_x_->AddTwoVectors(1., *curr_jac_cT_times_curr_y_c, 1., *curr_jac_cT_times_curr_y_d, 1.);
curr_nabla_phi_plus_ATy_s_ = curr_grad_barrier_obj_s_->MakeNew();
curr_nabla_phi_plus_ATy_s_->AddTwoVectors(1., *curr_grad_barrier_obj_s_, -1., *IpData().curr()->y_d(), 0.);
curr_nabla_phi_plus_ATy_s_->ElementWiseMultiply(*curr_scaling_slacks_);
curr_tt2_norm_ = IpCq().CalcNormOfType(NORM_2, *curr_nabla_phi_plus_ATy_x_, *curr_nabla_phi_plus_ATy_s_);
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: curr_tt2_norm_ = %23.16e\n", curr_tt2_norm_);
if( compute_normal )
{
curr_Av_norm_ = IpCq().CalcNormOfType(NORM_2, *curr_Av_c_, *curr_Av_d_);
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: curr_Av_norm_ = %23.16e\n", curr_Av_norm_);
curr_tt1_norm_ = std::sqrt(std::pow(curr_tt2_norm_, 2) + std::pow(curr_Av_norm_, 2));
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: curr_tt1_norm_ = %23.16e\n", curr_tt1_norm_);
}
else
{
curr_Av_norm_ = -1.;
curr_tt1_norm_ = std::sqrt(std::pow(curr_tt2_norm_, 2) + std::pow(c_norm_, 2));
}
if( compute_normal && IsValid(last_grad_barrier_obj_x) )
{
SmartPtr<Vector> last_nabla_phi_plus_ATy_x = last_grad_barrier_obj_x->MakeNewCopy();
last_jac_c->TransMultVector(1., *IpData().curr()->y_c(), 1., *last_nabla_phi_plus_ATy_x);
last_jac_d->TransMultVector(1., *IpData().curr()->y_d(), 1., *last_nabla_phi_plus_ATy_x);
SmartPtr<Vector> last_nabla_phi_plus_ATy_s = last_grad_barrier_obj_s->MakeNew();
last_nabla_phi_plus_ATy_s->AddTwoVectors(1., *last_grad_barrier_obj_s, -1., *IpData().curr()->y_d(), 0.);
last_nabla_phi_plus_ATy_s->ElementWiseMultiply(*last_scaling_slacks);
last_tt1_norm_ = IpCq().CalcNormOfType(NORM_2, *last_nabla_phi_plus_ATy_x, *last_nabla_phi_plus_ATy_s);
last_tt1_norm_ = std::sqrt(std::pow(last_tt1_norm_, 2) + std::pow(last_Av_norm_, 2));
}
else
{
last_tt1_norm_ = 1e100;
}
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: last_tt1_norm_ = %23.16e\n", last_tt1_norm_);
Number ATc_norm = InexCq().curr_scaled_Ac_norm();
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: current ATc norm = %23.16e\n", ATc_norm);
try_tt2_ = (ATc_norm <= tt_eps2_ * curr_tt2_norm_);
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: will%s try termination test 2.\n", try_tt2_ ? "" : " not");
return true;
}
InexactPDTerminationTester::ETerminationTest InexactPDTerminationTester::TestTermination(
Index ndim,
const Number* sol,
const Number* resid,
Index iter,
Number norm2_rhs
)
{
DBG_START_METH("InexactPDTerminationTester::TestTermination",
dbg_verbosity);
bool compute_normal = InexData().compute_normal();
last_iter_ = iter;
ETerminationTest retval = CONTINUE;
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"Starting PD Termination Tester for iteration %" IPOPT_INDEX_FORMAT ".\n", iter);
Number norm2_resid = IpBlasNrm2(ndim, resid, 1);
Number test_ratio = norm2_resid / norm2_rhs; Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: test ratio %e (norm2_rhs = %e norm2_resid = %e).\n",
test_ratio, norm2_rhs, norm2_resid);
if( iter < inexact_desired_pd_residual_iter_ && test_ratio > inexact_desired_pd_residual_ )
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: immediately leaving tester with test ratio %e (norm2_rhs = %e norm2_resid = %e).\n", test_ratio,
norm2_rhs, norm2_resid);
return retval;
}
SmartPtr<const Vector> sol_x;
SmartPtr<const Vector> sol_s;
SmartPtr<const Vector> sol_c;
SmartPtr<const Vector> sol_d;
GetVectors(ndim, sol, sol_x, sol_s, sol_c, sol_d);
DBG_PRINT_VECTOR(2, "sol_x", *sol_x);
DBG_PRINT_VECTOR(2, "sol_s", *sol_s);
DBG_PRINT_VECTOR(2, "sol_c", *sol_c);
DBG_PRINT_VECTOR(2, "sol_d", *sol_d);
SmartPtr<const Vector> resid_x;
SmartPtr<const Vector> resid_s;
SmartPtr<const Vector> resid_c;
SmartPtr<const Vector> resid_d;
GetVectors(ndim, resid, resid_x, resid_s, resid_c, resid_d);
if( requires_scaling_ )
{
SmartPtr<const Vector> scaling_vec = curr_scaling_slacks_;
SmartPtr<Vector> tmp = sol_s->MakeNewCopy();
tmp->ElementWiseMultiply(*scaling_vec);
sol_s = ConstPtr(tmp);
tmp = resid_s->MakeNewCopy();
tmp->ElementWiseDivide(*scaling_vec);
resid_s = ConstPtr(tmp);
}
if( !compute_normal )
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"RUNNING TERMINATION TESTS FOR INEXACT NEWTON (which means u=d)\n");
}
else
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"RUNNING TERMINATION TESTS FOR INEXACT NEWTON - TRUST REGION\n");
}
SmartPtr<const Vector> tangential_x;
SmartPtr<const Vector> tangential_s;
if( compute_normal )
{
SmartPtr<const Vector> normal_x = InexData().normal_x();
SmartPtr<Vector> tmp = sol_x->MakeNew();
tmp->AddTwoVectors(1., *sol_x, -1, *normal_x, 0.);
tangential_x = ConstPtr(tmp);
SmartPtr<const Vector> normal_s = InexData().normal_s();
tmp = sol_s->MakeNew();
tmp->AddTwoVectors(1., *sol_s, -1, *normal_s, 0.);
tangential_s = ConstPtr(tmp);
}
else
{
tangential_x = sol_x;
tangential_s = sol_s;
}
Number u_norm_scaled = InexCq().slack_scaled_norm(*tangential_x, *tangential_s);
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: u_norm_scaled = %23.16e\n", u_norm_scaled);
DBG_PRINT_VECTOR(2, "tangential_x", *tangential_x);
DBG_PRINT_VECTOR(2, "tangential_s", *tangential_s);
SmartPtr<const Vector> Wu_x = InexCq().curr_W_times_vec_x(*tangential_x);
SmartPtr<const Vector> Wu_s = InexCq().curr_W_times_vec_s(*tangential_s);
DBG_PRINT_VECTOR(2, "Wu_x", *Wu_x);
DBG_PRINT_VECTOR(2, "Wu_s", *Wu_s);
Number uWu = Wu_x->Dot(*tangential_x) + Wu_s->Dot(*tangential_s);
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: uWu = %23.16e\n", uWu);
SmartPtr<Vector> c_plus_Ad_c = IpCq().curr_c()->MakeNewCopy();
curr_jac_c_->MultVector(1., *sol_x, 1., *c_plus_Ad_c);
SmartPtr<const Vector> curr_d_minus_s = IpCq().curr_d_minus_s();
SmartPtr<Vector> c_plus_Ad_d = curr_d_minus_s->MakeNew();
c_plus_Ad_d->AddTwoVectors(1., *curr_d_minus_s, -1., *sol_s, 0.);
curr_jac_d_->MultVector(1., *sol_x, 1., *c_plus_Ad_d);
Number c_plus_Ad_norm = IpCq().CalcNormOfType(NORM_2, *c_plus_Ad_c, *c_plus_Ad_d);
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: c_plus_Ad_norm = %23.16e\n", c_plus_Ad_norm);
SmartPtr<Vector> tmp = resid_s->MakeNewCopy();
tmp->ElementWiseMultiply(*curr_scaling_slacks_);
Number rho_norm = IpCq().CalcNormOfType(NORM_2, *resid_x, *tmp);
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: rho_norm = %23.16e\n", rho_norm);
tmp = NULL;
Number Upsilon = -1.;
Number Nu = -1.;
if( !compute_normal )
{
#if 0#endif
Nu = 0; Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: Nu = ||A*u||^2/||A||^2 = %23.16e\n", Nu);
Upsilon = u_norm_scaled * u_norm_scaled - Nu;
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: Upsilon = ||u||^2 - ||A*u||^2/||A||^2 = %23.16e\n", Upsilon);
}
Number BasVal = Max(IpData().curr()->x()->Amax(), IpData().curr()->s()->Amax());
Number lhs;
Number rhs;
if( !compute_normal )
{
lhs = Upsilon;
rhs = std::pow(tcc_psi_, 2) * Nu;
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TCC1 testing Upsilon(=%23.16e) <= (tcc_psi_^2)*Nu(=%23.16e) --> ", lhs, rhs);
}
else
{
lhs = u_norm_scaled;
rhs = tcc_psi_ * v_norm_scaled_;
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TCC1 testing u_norm_scaled(=%23.16e) <= tcc_psi_*v_norm_scaled(=%23.16e) --> ", lhs, rhs);
}
bool tcc1 = Compare_le(lhs, rhs, BasVal);
if( tcc1 )
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"satisfied\n");
}
else
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"violated\n");
}
const Number mu = IpData().curr_mu();
rhs = 0.5 * uWu;
if( !compute_normal )
{
lhs = tcc_theta_ * std::pow(mu, tcc_theta_mu_exponent_) * Upsilon;
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TCC2a testing 0.5*uWu(=%23.16e) >= tcc_theta_*pow(mu,tcc_theta_mu_exponent_)*Upsilon(=%23.16e) -->", rhs,
lhs);
}
else
{
lhs = tcc_theta_ * std::pow(mu, tcc_theta_mu_exponent_) * std::pow(u_norm_scaled, 2);
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TCC2a testing 0.5*uWu(=%23.16e) >= tcc_theta_*pow(mu,tcc_theta_mu_exponent_)*u_norm^2(=%23.16e) -->", rhs,
lhs);
}
bool tcc2a = Compare_le(lhs, rhs, BasVal);
if( tcc2a )
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"satisfied\n");
}
else
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"violated\n");
}
bool tcc = tcc1;
if( !tcc && tcc2a )
{
if( !compute_normal )
{
tcc = tcc2a;
}
else
{
lhs = 0.5 * uWu + curr_grad_barrier_obj_x_->Dot(*tangential_x) + curr_grad_barrier_obj_s_->Dot(*tangential_s)
+ curr_Wv_x_->Dot(*tangential_x) + curr_Wv_s_->Dot(*tangential_s);
rhs = tcc_zeta_ * v_norm_scaled_;
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TCC2b testing (grad_barr^Tu + v^TWu + 0.5*uWu)(=%23.16e) <= tcc_zeta_*v_norm(=%23.16e) -->", lhs, rhs);
tcc = Compare_le(lhs, rhs, BasVal);
if( tcc )
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"satisfied\n");
}
else
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"violated\n");
}
}
}
if( tcc )
{
Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
"Tangential Component Condition satisfied\n");
}
else
{
Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
"Tangential Component Condition violated\n");
}
bool tt1 = tcc;
bool tt1_kappa1 = tcc;
if( !compute_normal )
{
Number resid_norm = std::sqrt(std::pow(rho_norm, 2) + std::pow(c_plus_Ad_norm, 2));
lhs = resid_norm;
rhs = tt_kappa1_ * curr_tt1_norm_;
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT1 testing resid_norm(=%23.16e) <= tt_kappa1_*curr_tt1_norm_(=%23.16e) --> ", lhs, rhs);
tt1 = Compare_le(lhs, rhs, BasVal);
}
else if( tt1 )
{
lhs = rho_norm;
rhs = tt_kappa1_ * Min(curr_tt1_norm_, last_tt1_norm_);
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT1 testing rho_norm(=%23.16e) <= kappa1*min(curr_tt1_norm_, last_tt1_norm_)(=%23.16e) -->", lhs, rhs);
tt1_kappa1 = Compare_le(lhs, rhs, BasVal);
tt1 = tt1_kappa1;
}
if( tt1 )
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"satisfied\n");
}
else
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"violated\n");
}
bool model_reduction = false;
if( !compute_normal || tt1 )
{
Number curr_nu = InexData().curr_nu();
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: curr_nu = %23.16e\n", curr_nu);
Number delta_m = -(curr_grad_barrier_obj_x_->Dot(*sol_x) + curr_grad_barrier_obj_s_->Dot(*sol_s));
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: -grad_barr^Td = %23.16e\n", delta_m);
delta_m += curr_nu * (c_norm_ - c_plus_Ad_norm);
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT: delta_m = %23.16e\n", delta_m);
rhs = delta_m;
Number sigma = rho_ * tt_eps3_;
if( !compute_normal )
{
lhs = Max(0.5 * uWu, tcc_theta_ * Upsilon) + sigma * curr_nu * Max(c_norm_, c_plus_Ad_norm - c_norm_);
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"MRC testing delta_m(=%23.16e) >= max(0.5*uWu,tcc_theta_*Upsilon) + sigma*nu*max(c_norm_, c_plus_Ad_norm - c_norm_)(=%23.16e) -->",
rhs, lhs);
model_reduction = Compare_le(lhs, rhs, BasVal);
if( model_reduction )
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"satisfied\n");
}
else
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"violated\n");
}
if( tt1 )
{
tt1 = model_reduction;
}
}
else
{
lhs = Max(0.5 * uWu, tcc_theta_ * std::pow(u_norm_scaled, 2)) + sigma * curr_nu * (c_norm_ - c_plus_Av_norm_);
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"MRC testing delta_m(=%23.16e) >= max(0.5*uWu,tcc_theta_*u_norm^2) + sigma*nu*(c_norm_ - c_plus_Av_norm_)(=%23.16e) -->",
rhs, lhs);
tt1 = Compare_le(lhs, rhs, BasVal);
if( tt1 )
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"satisfied\n");
}
else
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"violated\n");
}
}
}
if( tt1 )
{
Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
"Termination Test 1 satisfied.\n");
return TEST_1_SATISFIED;
}
else
{
Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
"Termination Test 1 not satisfied.\n");
}
bool tt3 = tcc;
if( tt3 )
{
if( !compute_normal )
{
lhs = rho_norm;
rhs = tt_kappa1_ * c_norm_;
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT3 testing rho_norm(=%23.16e) <= tt_kappa1_*c_norm_(=%23.16e) -->", lhs, rhs);
tt3 = Compare_le(lhs, rhs, BasVal);
}
else
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT3 with residual condition from TT1 -->");
tt3 = tt1_kappa1;
}
if( tt3 )
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"satisfied\n");
}
else
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"violated\n");
}
}
if( tt3 )
{
if( !compute_normal )
{
lhs = c_plus_Ad_norm;
rhs = tt_kappa1_ * c_norm_;
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT3 testing c_plus_Ad_norm(=%23.16e) <= tt_kappa1_*c_norm(=%23.16e) -->", lhs, rhs);
tt3 = Compare_le(lhs, rhs, BasVal);
}
else
{
lhs = tt_eps3_ * (c_norm_ - c_plus_Av_norm_);
rhs = c_norm_ - c_plus_Ad_norm;
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT3 testing (c_norm_-c_plus_Ad_norm)(=%23.16e) >= eps3*(c_norm_-c_plus_Av_norm_)(=%23.16e) -->", rhs, lhs);
tt3 = Compare_le(lhs, rhs, BasVal);
}
if( tt3 )
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"satisfied\n");
}
else
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"violated\n");
}
}
if( tt3 )
{
Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
"Termination Test 3 satisfied.\n");
return TEST_3_SATISFIED;
}
else
{
Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
"Termination Test 3 not satisfied.\n");
}
bool tt2 = try_tt2_;
if( tt2 )
{
DBG_PRINT_VECTOR(2, "curr_nabla_phi_plus_ATy_x_", *curr_nabla_phi_plus_ATy_x_);
DBG_PRINT_VECTOR(2, "curr_nabla_phi_plus_ATy_s_", *curr_nabla_phi_plus_ATy_s_);
DBG_PRINT_VECTOR(2, "sol_c", *sol_c);
DBG_PRINT_VECTOR(2, "sol_d", *sol_d);
SmartPtr<Vector> sol_d_scaled = sol_d->MakeNewCopy();
sol_d_scaled->ElementWiseMultiply(*curr_scaling_slacks_);
DBG_PRINT_VECTOR(2, "sol_d_scaled", *sol_d_scaled);
SmartPtr<Vector> nabla_phi_plus_ATydelta_x = curr_nabla_phi_plus_ATy_x_->MakeNewCopy();
curr_jac_c_->TransMultVector(1., *sol_c, 1., *curr_nabla_phi_plus_ATy_x_);
curr_jac_d_->TransMultVector(1., *sol_d, 1., *curr_nabla_phi_plus_ATy_x_);
SmartPtr<Vector> nabla_phi_plus_ATydelta_s = curr_nabla_phi_plus_ATy_s_->MakeNew();
nabla_phi_plus_ATydelta_s->AddTwoVectors(1., *curr_nabla_phi_plus_ATy_s_, -1., *sol_d_scaled, 0.);
Number nabla_phi_plus_ATydelta_norm = IpCq().CalcNormOfType(NORM_2, *nabla_phi_plus_ATydelta_x,
*nabla_phi_plus_ATydelta_s);
lhs = nabla_phi_plus_ATydelta_norm;
if( !compute_normal )
{
rhs = tt_kappa2_ * curr_tt2_norm_;
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT2 testing ||gamma+A^T(y+delta)||(=%23.16e) <= kappa2*curr_tt2_norm_(=%23.16e) -->", lhs, rhs);
}
else
{
rhs = tt_kappa2_ * Min(curr_tt2_norm_, last_tt1_norm_);
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"TT2 testing ||gamma+A^T(y+delta)||(=%23.16e) <= kappa2*min(curr_tt2_norm_, last_tt1_norm_)(=%23.16e) -->",
lhs, rhs);
}
tt2 = Compare_le(lhs, rhs, BasVal);
if( tt2 )
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"satisfied\n");
}
else
{
Jnlst().Printf(J_MOREDETAILED, J_LINEAR_ALGEBRA,
"violated\n");
}
}
if( tt2 )
{
Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
"Termination Test 2 satisfied.\n");
return TEST_2_SATISFIED;
}
else if( try_tt2_ )
{
Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
"Termination Test 2 not satisfied.\n");
}
if( tcc1 || tcc2a ) {
Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
"Hessian Modification not requested.\n");
}
else
{
Jnlst().Printf(J_DETAILED, J_LINEAR_ALGEBRA,
"Hessian Modification requested.\n");
return MODIFY_HESSIAN;
}
return retval;
}
void InexactPDTerminationTester::Clear()
{
DBG_START_METH("InexactPDTerminationTester::Clear",
dbg_verbosity);
curr_Av_c_ = NULL;
curr_Av_d_ = NULL;
curr_Wv_x_ = NULL;
curr_Wv_s_ = NULL;
curr_nabla_phi_plus_ATy_x_ = NULL;
curr_nabla_phi_plus_ATy_s_ = NULL;
}
}