#include "IpRestoIpoptNLP.hpp"
#include "IpIdentityMatrix.hpp"
#include "IpSumSymMatrix.hpp"
#include "IpSumMatrix.hpp"
#include "IpNLPScaling.hpp"
#include "IpLowRankUpdateSymMatrix.hpp"
#include "IpIpoptData.hpp"
#include "IpIpoptCalculatedQuantities.hpp"
#include <cmath>
#include <cassert>
namespace Ipopt
{
#if IPOPT_VERBOSITY > 0
static const Index dbg_verbosity = 0;
#endif
RestoIpoptNLP::RestoIpoptNLP(
IpoptNLP& orig_ip_nlp,
IpoptData& orig_ip_data,
IpoptCalculatedQuantities& orig_ip_cq
)
: IpoptNLP(new NoNLPScalingObject()),
orig_ip_nlp_(&orig_ip_nlp),
orig_ip_data_(&orig_ip_data),
orig_ip_cq_(&orig_ip_cq),
eta_mu_exponent_(0.5)
{ }
RestoIpoptNLP::~RestoIpoptNLP()
{ }
void RestoIpoptNLP::RegisterOptions(
SmartPtr<RegisteredOptions> roptions
)
{
roptions->AddBoolOption(
"evaluate_orig_obj_at_resto_trial",
"Determines if the original objective function should be evaluated at restoration phase trial points.",
true,
"Enabling this option makes the restoration phase algorithm evaluate the objective function "
"of the original problem at every trial point encountered during the restoration phase, "
"even if this value is not required. "
"In this way, it is guaranteed that the original objective function can be evaluated without error "
"at all accepted iterates; "
"otherwise the algorithm might fail at a point where the restoration phase accepts an iterate that is good "
"for the restoration phase problem, but not the original problem. "
"On the other hand, if the evaluation of the original objective is expensive, this might be costly.");
roptions->AddLowerBoundedNumberOption(
"resto_penalty_parameter",
"Penalty parameter in the restoration phase objective function.",
0., true,
1e3,
"This is the parameter rho in equation (31a) in the Ipopt implementation paper.",
true);
roptions->AddLowerBoundedNumberOption(
"resto_proximity_weight",
"Weighting factor for the proximity term in restoration phase objective.",
0., false,
1.,
"This determines how the parameter zeta in equation (29a) in the implementation paper is computed. "
"zeta here is resto_proximity_weight*sqrt(mu), where mu is the current barrier parameter.",
true);
}
bool RestoIpoptNLP::Initialize(
const Journalist& jnlst,
const OptionsList& options,
const std::string& prefix
)
{
options.GetBoolValue("evaluate_orig_obj_at_resto_trial", evaluate_orig_obj_at_resto_trial_, prefix);
options.GetNumericValue("resto_penalty_parameter", rho_, prefix);
Index enum_int;
options.GetEnumValue("hessian_approximation", enum_int, prefix);
hessian_approximation_ = HessianApproximationType(enum_int);
options.GetNumericValue("resto_proximity_weight", eta_factor_, prefix);
initialized_ = true;
return IpoptNLP::Initialize(jnlst, options, prefix);
}
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_);
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);
DBG_PRINT((1, "Creating the x_space_\n"));
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); x_space_->SetCompSpace(2, *orig_c_space); x_space_->SetCompSpace(3, *orig_d_space); x_space_->SetCompSpace(4, *orig_d_space);
DBG_PRINT((1, "Setting the c_space_\n"));
c_space_ = new CompoundVectorSpace(1, orig_c_space->Dim());
c_space_->SetCompSpace(0, *orig_c_space);
DBG_PRINT((1, "Setting the d_space_\n"));
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"));
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); x_l_space_->SetCompSpace(2, *orig_c_space); x_l_space_->SetCompSpace(3, *orig_d_space); x_l_space_->SetCompSpace(4, *orig_d_space);
DBG_PRINT((1, "Setting the x_u_space_\n"));
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"));
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);
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"));
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 = %" IPOPT_INDEX_FORMAT ", total_cols = %" IPOPT_INDEX_FORMAT "\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);
d_l_space_ = new CompoundVectorSpace(1, orig_d_l_space->Dim());
d_l_space_->SetCompSpace(0, *orig_d_l_space);
d_u_space_ = new CompoundVectorSpace(1, orig_d_u_space->Dim());
d_u_space_->SetCompSpace(0, *orig_d_u_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);
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"));
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);
jac_c_space_->SetCompSpace(0, 1, *identity_mat_space_nc, true);
jac_c_space_->SetCompSpace(0, 2, *identity_mat_space_nc, true);
DBG_PRINT((1, "Creating the jac_d_space_\n"));
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 = %p\n", GetRawPtr(orig_jac_d_space)))
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"));
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> DR2_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, *DR2_x_space);
h_space_->SetCompSpace(0, 0, *sumsym_mat_space, true);
}
x_L_ = x_l_space_->MakeNewCompoundVector();
x_L_->SetComp(0, *orig_ip_nlp_->x_L()); x_L_->GetCompNonConst(1)->Set(0.0); x_L_->GetCompNonConst(2)->Set(0.0); x_L_->GetCompNonConst(3)->Set(0.0); x_L_->GetCompNonConst(4)->Set(0.0); DBG_PRINT_VECTOR(2, "resto_x_L", *x_L_);
x_U_ = x_u_space_->MakeNewCompoundVector();
x_U_->SetComp(0, *orig_ip_nlp_->x_U());
d_L_ = d_l_space_->MakeNewCompoundVector();
d_L_->SetComp(0, *orig_ip_nlp_->d_L());
d_U_ = d_u_space_->MakeNewCompoundVector();
d_U_->SetComp(0, *orig_ip_nlp_->d_U());
Px_L_ = px_l_space_->MakeNewCompoundMatrix();
Px_L_->SetComp(0, 0, *orig_ip_nlp_->Px_L());
Px_U_ = px_u_space_->MakeNewCompoundMatrix();
Px_U_->SetComp(0, 0, *orig_ip_nlp_->Px_U());
Pd_L_ = pd_l_space_->MakeNewCompoundMatrix();
Pd_L_->SetComp(0, 0, *orig_ip_nlp_->Pd_L());
Pd_U_ = pd_u_space_->MakeNewCompoundMatrix();
Pd_U_->SetComp(0, 0, *orig_ip_nlp_->Pd_U());
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_);
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_);
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);
y_c = c_space_->MakeNew();
if( init_y_c )
{
y_c->Set(0.0); }
y_d = d_space_->MakeNew();
if( init_y_d )
{
y_d->Set(0.0);
}
z_L = x_l_space_->MakeNew();
if( init_z_L )
{
z_L->Set(1.0);
}
z_U = x_u_space_->MakeNew();
if( init_z_U )
{
z_U->Set(1.0);
}
v_L = d_l_space_->MakeNew();
v_U = d_u_space_->MakeNew();
SmartPtr<Vector> x_ref = orig_x_space->MakeNew();
x_ref->Copy(*orig_ip_data_->curr()->x());
x_ref_ = x_ref;
SmartPtr<Vector> 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();
dr_x_ = dr_x;
DBG_PRINT_VECTOR(2, "dr_x_", *dr_x_);
SmartPtr<Vector> dr2_x = dr_x->MakeNewCopy();
dr2_x->ElementWiseMultiply(*dr_x_);
dr2_x_ = dr2_x;
SmartPtr<DiagMatrix> DR2_x = DR2_x_space->MakeNewDiagMatrix();
DR2_x->SetDiag(*dr2_x_);
DR2_x_ = DR2_x;
return true;
}
Number RestoIpoptNLP::f(
const Vector&
)
{
THROW_EXCEPTION(INTERNAL_ABORT, "ERROR: In RestoIpoptNLP f() is called without mu!");
return 0.;
}
Number RestoIpoptNLP::f(
const Vector& x,
Number mu
)
{
DBG_START_METH("RestoIpoptNLP::f",
dbg_verbosity);
Number ret = 0.0;
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;
if( evaluate_orig_obj_at_resto_trial_ )
{
orig_ip_nlp_->f(*x_only);
}
return ret;
}
SmartPtr<const Vector> RestoIpoptNLP::grad_f(
const Vector& x,
Number mu
)
{
SmartPtr<Vector> retPtr = x.MakeNew();
retPtr->Set(rho_);
const CompoundVector* c_vec_in = static_cast<const CompoundVector*>(&x);
SmartPtr<const Vector> x_only_in = c_vec_in->GetComp(0);
CompoundVector* c_vec = static_cast<CompoundVector*>(GetRawPtr(retPtr));
DBG_ASSERT(c_vec);
SmartPtr<Vector> x_only = c_vec->GetCompNonConst(0);
x_only->Copy(*x_only_in);
x_only->Axpy(-1.0, *x_ref_);
x_only->ElementWiseMultiply(*dr2_x_);
x_only->Scal(Eta(mu));
return ConstPtr(retPtr);
}
SmartPtr<const Vector> RestoIpoptNLP::c(
const Vector& x
)
{
const CompoundVector* c_vec = static_cast<const CompoundVector*>(&x);
SmartPtr<const Vector> x_only = c_vec->GetComp(0);
SmartPtr<const Vector> nc_only = c_vec->GetComp(1);
SmartPtr<const Vector> pc_only = c_vec->GetComp(2);
SmartPtr<const Vector> orig_c = orig_ip_nlp_->c(*x_only);
SmartPtr<Vector> retPtr = c_space_->MakeNew();
SmartPtr<CompoundVector> CretPtr = static_cast<CompoundVector*>(GetRawPtr(retPtr));
DBG_ASSERT(dynamic_cast<CompoundVector*> (GetRawPtr(retPtr)));
SmartPtr<Vector> CretPtr0 = CretPtr->GetCompNonConst(0);
CretPtr0->Copy(*orig_c);
CretPtr0->Axpy(1.0, *nc_only);
CretPtr0->Axpy(-1.0, *pc_only);
return GetRawPtr(retPtr);
}
SmartPtr<const Vector> RestoIpoptNLP::grad_f(
const Vector&
)
{
THROW_EXCEPTION(INTERNAL_ABORT, "ERROR: In RestoIpoptNLP grad_f() is called without mu!");
}
SmartPtr<const Vector> RestoIpoptNLP::d(
const Vector& x
)
{
const CompoundVector* c_vec = static_cast<const CompoundVector*>(&x);
SmartPtr<const Vector> x_only = c_vec->GetComp(0);
SmartPtr<const Vector> nd_only = c_vec->GetComp(3);
SmartPtr<const Vector> pd_only = c_vec->GetComp(4);
SmartPtr<const Vector> orig_d = orig_ip_nlp_->d(*x_only);
SmartPtr<Vector> retPtr = d_space_->MakeNew();
SmartPtr<CompoundVector> CretPtr = static_cast<CompoundVector*>(GetRawPtr(retPtr));
DBG_ASSERT(dynamic_cast<CompoundVector*> (GetRawPtr(retPtr)));
SmartPtr<Vector> CretPtr0 = CretPtr->GetCompNonConst(0);
CretPtr0->Copy(*orig_d);
CretPtr0->Axpy(1., *nd_only);
CretPtr0->Axpy(-1., *pd_only);
return GetRawPtr(retPtr);
}
SmartPtr<const Matrix> RestoIpoptNLP::jac_c(
const Vector& x
)
{
const CompoundVector* c_vec = static_cast<const CompoundVector*>(&x);
DBG_ASSERT(c_vec);
SmartPtr<const Vector> x_only = c_vec->GetComp(0);
SmartPtr<const Matrix> jac_c_only = orig_ip_nlp_->jac_c(*x_only);
SmartPtr<CompoundMatrix> retPtr = jac_c_space_->MakeNewCompoundMatrix();
retPtr->SetComp(0, 0, *jac_c_only);
SmartPtr<Matrix> jac_c_pc_mat = retPtr->GetCompNonConst(0, 2);
IdentityMatrix* jac_c_pc = static_cast<IdentityMatrix*>(GetRawPtr(jac_c_pc_mat));
DBG_ASSERT(jac_c_pc);
jac_c_pc->SetFactor(-1.0);
return GetRawPtr(retPtr);
}
SmartPtr<const Matrix> RestoIpoptNLP::jac_d(
const Vector& x
)
{
DBG_START_METH("RestoIpoptNLP::jac_d", dbg_verbosity);
const CompoundVector* c_vec = static_cast<const CompoundVector*>(&x);
DBG_ASSERT(c_vec);
SmartPtr<const Vector> x_only = c_vec->GetComp(0);
SmartPtr<const Matrix> jac_d_only = orig_ip_nlp_->jac_d(*x_only);
SmartPtr<CompoundMatrix> retPtr = jac_d_space_->MakeNewCompoundMatrix();
DBG_PRINT((1, "jac_d_space_ = %p\n", GetRawPtr(jac_d_space_)))
retPtr->SetComp(0, 0, *jac_d_only);
SmartPtr<Matrix> jac_d_pd_mat = retPtr->GetCompNonConst(0, 4);
IdentityMatrix* jac_d_pd = static_cast<IdentityMatrix*>(GetRawPtr(jac_d_pd_mat));
DBG_ASSERT(jac_d_pd);
jac_d_pd->SetFactor(-1.0);
return GetRawPtr(retPtr);
}
SmartPtr<const SymMatrix> RestoIpoptNLP::h(
const Vector& ,
Number ,
const Vector& ,
const Vector&
)
{
assert(false && "ERROR: In RestoIpoptNLP h() is called without mu!");
return NULL;
}
SmartPtr<const SymMatrix> RestoIpoptNLP::h(
const Vector& x,
Number obj_factor,
const Vector& yc,
const Vector& yd,
Number mu
)
{
const CompoundVector* c_vec = static_cast<const CompoundVector*>(&x);
DBG_ASSERT(dynamic_cast<const CompoundVector*>(&x));
SmartPtr<const Vector> x_only = c_vec->GetComp(0);
const CompoundVector* Cyc = static_cast<const CompoundVector*>(&yc);
DBG_ASSERT(dynamic_cast<const CompoundVector*>(&yc));
DBG_ASSERT(Cyc->NComps() == 1);
SmartPtr<const Vector> Cyc0 = Cyc->GetComp(0);
const CompoundVector* Cyd = static_cast<const CompoundVector*>(&yd);
DBG_ASSERT(dynamic_cast<const CompoundVector*>(&yd));
DBG_ASSERT(Cyd->NComps() == 1);
SmartPtr<const Vector> Cyd0 = Cyd->GetComp(0);
SmartPtr<const SymMatrix> h_con_orig = orig_ip_nlp_->h(*x_only, 0.0, *Cyc0, *Cyd0);
SmartPtr<CompoundSymMatrix> retPtr = h_space_->MakeNewCompoundSymMatrix();
SmartPtr<Matrix> h_sum_mat = retPtr->GetCompNonConst(0, 0);
SmartPtr<SumSymMatrix> h_sum = static_cast<SumSymMatrix*>(GetRawPtr(h_sum_mat));
h_sum->SetTerm(0, 1.0, *h_con_orig);
h_sum->SetTerm(1, obj_factor * Eta(mu), *DR2_x_);
return GetRawPtr(retPtr);
}
SmartPtr<const SymMatrix> RestoIpoptNLP::uninitialized_h()
{
SmartPtr<CompoundSymMatrix> retPtr;
if( hessian_approximation_ == LIMITED_MEMORY )
{
retPtr = h_space_->MakeNewCompoundSymMatrix();
}
else
{
SmartPtr<const SymMatrix> h_con_orig = orig_ip_nlp_->uninitialized_h();
retPtr = h_space_->MakeNewCompoundSymMatrix();
SmartPtr<Matrix> h_sum_mat = retPtr->GetCompNonConst(0, 0);
SmartPtr<SumSymMatrix> h_sum = static_cast<SumSymMatrix*>(GetRawPtr(h_sum_mat));
h_sum->SetTerm(0, 1.0, *h_con_orig);
h_sum->SetTerm(1, 1.0, *DR2_x_);
}
return GetRawPtr(retPtr);
}
void RestoIpoptNLP::GetSpaces(
SmartPtr<const VectorSpace>& x_space,
SmartPtr<const VectorSpace>& c_space,
SmartPtr<const VectorSpace>& d_space,
SmartPtr<const VectorSpace>& x_l_space,
SmartPtr<const MatrixSpace>& px_l_space,
SmartPtr<const VectorSpace>& x_u_space,
SmartPtr<const MatrixSpace>& px_u_space,
SmartPtr<const VectorSpace>& d_l_space,
SmartPtr<const MatrixSpace>& pd_l_space,
SmartPtr<const VectorSpace>& d_u_space,
SmartPtr<const MatrixSpace>& pd_u_space,
SmartPtr<const MatrixSpace>& Jac_c_space,
SmartPtr<const MatrixSpace>& Jac_d_space,
SmartPtr<const SymMatrixSpace>& Hess_lagrangian_space
)
{
x_space = GetRawPtr(x_space_);
c_space = GetRawPtr(c_space_);
d_space = GetRawPtr(d_space_);
x_l_space = GetRawPtr(x_l_space_);
px_l_space = GetRawPtr(px_l_space_);
x_u_space = GetRawPtr(x_u_space_);
px_u_space = GetRawPtr(px_u_space_);
d_l_space = GetRawPtr(d_l_space_);
pd_l_space = GetRawPtr(pd_l_space_);
d_u_space = GetRawPtr(d_u_space_);
pd_u_space = GetRawPtr(pd_u_space_);
Jac_c_space = GetRawPtr(jac_c_space_);
Jac_d_space = GetRawPtr(jac_d_space_);
Hess_lagrangian_space = GetRawPtr(h_space_);
}
Number RestoIpoptNLP::Eta(
Number mu
) const
{
return eta_factor_ * std::pow(mu, eta_mu_exponent_);
}
void RestoIpoptNLP::AdjustVariableBounds(
const Vector& new_x_L,
const Vector& new_x_U,
const Vector& new_d_L,
const Vector& new_d_U
)
{
const CompoundVector* comp_new_x_L = static_cast<const CompoundVector*>(&new_x_L);
DBG_ASSERT(dynamic_cast<const CompoundVector*>(&new_x_L));
SmartPtr<const Vector> new_orig_x_L = comp_new_x_L->GetComp(0);
const CompoundVector* comp_new_x_U = static_cast<const CompoundVector*>(&new_x_U);
DBG_ASSERT(dynamic_cast<const CompoundVector*>(&new_x_U));
SmartPtr<const Vector> new_orig_x_U = comp_new_x_U->GetComp(0);
const CompoundVector* comp_new_d_L = static_cast<const CompoundVector*>(&new_d_L);
DBG_ASSERT(dynamic_cast<const CompoundVector*>(&new_d_L));
SmartPtr<const Vector> new_orig_d_L = comp_new_d_L->GetComp(0);
const CompoundVector* comp_new_d_U = static_cast<const CompoundVector*>(&new_d_U);
DBG_ASSERT(dynamic_cast<const CompoundVector*>(&new_d_U));
SmartPtr<const Vector> new_orig_d_U = comp_new_d_U->GetComp(0);
orig_ip_nlp_->AdjustVariableBounds(*new_orig_x_L, *new_orig_x_U, *new_orig_d_L, *new_orig_d_U);
SmartPtr<const Vector> new_nc_L = comp_new_x_L->GetComp(1);
SmartPtr<const Vector> new_pc_L = comp_new_x_L->GetComp(2);
SmartPtr<const Vector> new_nd_L = comp_new_x_L->GetComp(3);
SmartPtr<const Vector> new_pd_L = comp_new_x_L->GetComp(4);
x_L_->GetCompNonConst(1)->Copy(*new_nc_L);
x_L_->GetCompNonConst(2)->Copy(*new_pc_L);
x_L_->GetCompNonConst(3)->Copy(*new_nd_L);
x_L_->GetCompNonConst(4)->Copy(*new_pd_L);
}
bool RestoIpoptNLP::IntermediateCallBack(
AlgorithmMode mode,
Index iter,
Number obj_value,
Number inf_pr,
Number inf_du,
Number mu,
Number d_norm,
Number regularization_size,
Number alpha_du,
Number alpha_pr,
Index ls_trials,
SmartPtr<const IpoptData> ip_data,
SmartPtr<IpoptCalculatedQuantities> ip_cq
)
{
return orig_ip_nlp_->IntermediateCallBack(mode, iter, obj_value, inf_pr, inf_du, mu, d_norm, regularization_size,
alpha_du, alpha_pr, ls_trials, ip_data, ip_cq);
}
}