#include "IpoptConfig.h"
#include "IpTNLP.hpp"
#include "IpIpoptData.hpp"
#include "IpIpoptCalculatedQuantities.hpp"
#include "IpOrigIpoptNLP.hpp"
#include "IpRestoIpoptNLP.hpp"
#include "IpTNLPAdapter.hpp"
#include "IpDenseVector.hpp"
#include "IpBlas.hpp"
namespace Ipopt
{
static
SmartPtr<const DenseVector> curr_x(
const IpoptData* ip_data,
IpoptCalculatedQuantities* ,
OrigIpoptNLP* orignlp,
RestoIpoptNLP* restonlp,
bool scaled
)
{
SmartPtr<const Vector> x;
if( restonlp == NULL )
{
x = ip_data->curr()->x();
}
else
{
DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->x())) != NULL);
const CompoundVector* c_vec = static_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->x()));
x = c_vec->GetComp(0);
}
DBG_ASSERT(IsValid(x));
if( !scaled && orignlp->NLP_scaling()->have_x_scaling() )
{
x = orignlp->NLP_scaling()->unapply_vector_scaling_x(x);
}
DBG_ASSERT(dynamic_cast<const DenseVector*>(GetRawPtr(x)) != NULL);
return static_cast<const DenseVector*>(GetRawPtr(x));
}
static
SmartPtr<const DenseVector> curr_z_L(
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq,
OrigIpoptNLP* orignlp,
RestoIpoptNLP* restonlp,
bool scaled
)
{
SmartPtr<const Vector> z_L;
if( restonlp == NULL )
{
z_L = ip_data->curr()->z_L();
}
else
{
DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->z_L())) != NULL);
const CompoundVector* c_vec = static_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->z_L()));
z_L = c_vec->GetComp(0);
}
DBG_ASSERT(IsValid(z_L));
if( !scaled )
{
Number obj_unscale_factor = orignlp->NLP_scaling()->unapply_obj_scaling(1.);
if( orignlp->NLP_scaling()->have_x_scaling() )
{
Index x_dim = curr_x(ip_data, ip_cq, orignlp, restonlp, true)->Dim();
SmartPtr<Vector> tmp = orignlp->NLP_scaling()->apply_vector_scaling_x_LU_NonConst(*orignlp->Px_L(), z_L, *new DenseVectorSpace(x_dim));
tmp->Scal(obj_unscale_factor);
z_L = ConstPtr(tmp);
}
else if( obj_unscale_factor != 1. )
{
SmartPtr<Vector> tmp = z_L->MakeNewCopy();
tmp->Scal(obj_unscale_factor);
z_L = ConstPtr(tmp);
}
}
DBG_ASSERT(dynamic_cast<const DenseVector*>(GetRawPtr(z_L)) != NULL);
return static_cast<const DenseVector*>(GetRawPtr(z_L));
}
static
SmartPtr<const DenseVector> curr_z_U(
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq,
OrigIpoptNLP* orignlp,
RestoIpoptNLP* restonlp,
bool scaled
)
{
SmartPtr<const Vector> z_U;
if( restonlp == NULL )
{
z_U = ip_data->curr()->z_U();
}
else
{
DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->z_U())) != NULL);
const CompoundVector* c_vec = static_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->z_U()));
z_U = c_vec->GetComp(0);
}
DBG_ASSERT(IsValid(z_U));
if( !scaled )
{
Number obj_unscale_factor = orignlp->NLP_scaling()->unapply_obj_scaling(1.);
if( orignlp->NLP_scaling()->have_x_scaling() )
{
Index x_dim = curr_x(ip_data, ip_cq, orignlp, restonlp, true)->Dim();
SmartPtr<Vector> tmp = orignlp->NLP_scaling()->apply_vector_scaling_x_LU_NonConst(*orignlp->Px_U(), z_U, *new DenseVectorSpace(x_dim));
tmp->Scal(obj_unscale_factor);
z_U = ConstPtr(tmp);
}
else if( obj_unscale_factor != 1. )
{
SmartPtr<Vector> tmp = z_U->MakeNewCopy();
tmp->Scal(obj_unscale_factor);
z_U = ConstPtr(tmp);
}
}
DBG_ASSERT(dynamic_cast<const DenseVector*>(GetRawPtr(z_U)) != NULL);
return static_cast<const DenseVector*>(GetRawPtr(z_U));
}
static
SmartPtr<const DenseVector> curr_c(
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq,
OrigIpoptNLP* orignlp,
RestoIpoptNLP* restonlp,
bool scaled
)
{
SmartPtr<const Vector> c;
if( restonlp == NULL )
{
c = ip_cq->curr_c();
}
else
{
DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->x())) != NULL);
const CompoundVector* c_vec = static_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->x()));
SmartPtr<const Vector> nc_only = c_vec->GetComp(1);
SmartPtr<const Vector> pc_only = c_vec->GetComp(2);
DBG_ASSERT(IsValid(nc_only));
DBG_ASSERT(IsValid(pc_only));
c_vec = static_cast<const CompoundVector*>(GetRawPtr(ip_cq->curr_c()));
DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(ip_cq->curr_c())) != NULL);
SmartPtr<Vector> c_resto = c_vec->GetComp(0)->MakeNewCopy();
c_resto->Axpy(-1.0, *nc_only);
c_resto->Axpy(1.0, *pc_only);
c = c_resto;
}
DBG_ASSERT(IsValid(c));
if( !scaled )
{
c = orignlp->NLP_scaling()->unapply_vector_scaling_c(c);
}
DBG_ASSERT(dynamic_cast<const DenseVector*>(GetRawPtr(c)) != NULL);
return static_cast<const DenseVector*>(GetRawPtr(c));
}
static
SmartPtr<const DenseVector> curr_y_c(
const IpoptData* ip_data,
IpoptCalculatedQuantities* ,
OrigIpoptNLP* orignlp,
RestoIpoptNLP* restonlp,
bool scaled
)
{
SmartPtr<const Vector> y_c;
if( restonlp == NULL )
{
y_c = ip_data->curr()->y_c();
}
else
{
DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->y_c())) != NULL);
const CompoundVector* c_vec = static_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->y_c()));
DBG_ASSERT(c_vec->NComps() == 1);
y_c = c_vec->GetComp(0);
}
DBG_ASSERT(IsValid(y_c));
if( !scaled )
{
Number obj_unscale_factor = orignlp->NLP_scaling()->unapply_obj_scaling(1.);
if( orignlp->NLP_scaling()->have_c_scaling() )
{
SmartPtr<Vector> tmp = orignlp->NLP_scaling()->apply_vector_scaling_c_NonConst(y_c);
tmp->Scal(obj_unscale_factor);
y_c = ConstPtr(tmp);
}
else if( obj_unscale_factor != 1. )
{
SmartPtr<Vector> tmp = y_c->MakeNewCopy();
tmp->Scal(obj_unscale_factor);
y_c = ConstPtr(tmp);
}
}
DBG_ASSERT(dynamic_cast<const DenseVector*>(GetRawPtr(y_c)) != NULL);
return static_cast<const DenseVector*>(GetRawPtr(y_c));
}
static
SmartPtr<const DenseVector> curr_d(
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq,
OrigIpoptNLP* orignlp,
RestoIpoptNLP* restonlp,
bool scaled
)
{
SmartPtr<const Vector> d;
if( restonlp == NULL )
{
d = ip_cq->curr_d();
}
else
{
DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->x())) != NULL);
const CompoundVector* c_vec = static_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->x()));
SmartPtr<const Vector> nd_only = c_vec->GetComp(3);
SmartPtr<const Vector> pd_only = c_vec->GetComp(4);
DBG_ASSERT(IsValid(nd_only));
DBG_ASSERT(IsValid(pd_only));
c_vec = static_cast<const CompoundVector*>(GetRawPtr(ip_cq->curr_d()));
DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(ip_cq->curr_d())) != NULL);
SmartPtr<Vector> d_resto = c_vec->GetComp(0)->MakeNewCopy();
d_resto->Axpy(-1.0, *nd_only);
d_resto->Axpy(1.0, *pd_only);
d = d_resto;
}
DBG_ASSERT(IsValid(d));
if( !scaled )
{
d = orignlp->NLP_scaling()->unapply_vector_scaling_d(d);
}
DBG_ASSERT(dynamic_cast<const DenseVector*>(GetRawPtr(d)) != NULL);
return static_cast<const DenseVector*>(GetRawPtr(d));
}
static
SmartPtr<const DenseVector> curr_y_d(
const IpoptData* ip_data,
IpoptCalculatedQuantities* ,
OrigIpoptNLP* orignlp,
RestoIpoptNLP* restonlp,
bool scaled
)
{
SmartPtr<const Vector> y_d;
if( restonlp == NULL )
{
y_d = ip_data->curr()->y_d();
}
else
{
DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->y_d())) != NULL);
const CompoundVector* c_vec = static_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->y_d()));
DBG_ASSERT(c_vec->NComps() == 1);
y_d = c_vec->GetComp(0);
}
DBG_ASSERT(IsValid(y_d));
if( !scaled )
{
Number obj_unscale_factor = orignlp->NLP_scaling()->unapply_obj_scaling(1.);
if( orignlp->NLP_scaling()->have_d_scaling() )
{
SmartPtr<Vector> tmp = orignlp->NLP_scaling()->apply_vector_scaling_d_NonConst(y_d);
tmp->Scal(obj_unscale_factor);
y_d = ConstPtr(tmp);
}
else if( obj_unscale_factor != 1. )
{
SmartPtr<Vector> tmp = y_d->MakeNewCopy();
tmp->Scal(obj_unscale_factor);
y_d = ConstPtr(tmp);
}
}
DBG_ASSERT(dynamic_cast<const DenseVector*>(GetRawPtr(y_d)) != NULL);
return static_cast<const DenseVector*>(GetRawPtr(y_d));
}
static
SmartPtr<const DenseVector> curr_x_L_viol(
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq,
OrigIpoptNLP* orignlp,
RestoIpoptNLP* restonlp,
bool scaled
)
{
SmartPtr<const Vector> x_L_viol;
if( restonlp == NULL )
{
if( scaled )
{
x_L_viol = ip_cq->curr_orig_x_L_violation();
}
else
{
x_L_viol = ip_cq->unscaled_curr_orig_x_L_violation();
}
}
else
{
DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->x())) != NULL);
const CompoundVector* c_vec = static_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->x()));
SmartPtr<const Vector> x = c_vec->GetComp(0);
if( scaled )
{
x_L_viol = restonlp->OrigIpCq().orig_x_L_violation(*x);
}
else
{
x = orignlp->NLP_scaling()->unapply_vector_scaling_x(x);
x_L_viol = restonlp->OrigIpCq().unscaled_orig_x_L_violation(*x);
}
}
DBG_ASSERT(IsValid(x_L_viol));
DBG_ASSERT(dynamic_cast<const DenseVector*>(GetRawPtr(x_L_viol)) != NULL);
return static_cast<const DenseVector*>(GetRawPtr(x_L_viol));
}
static
SmartPtr<const DenseVector> curr_x_U_viol(
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq,
OrigIpoptNLP* orignlp,
RestoIpoptNLP* restonlp,
bool scaled
)
{
SmartPtr<const Vector> x_U_viol;
if( restonlp == NULL )
{
if( scaled )
{
x_U_viol = ip_cq->curr_orig_x_U_violation();
}
else
{
x_U_viol = ip_cq->unscaled_curr_orig_x_U_violation();
}
}
else
{
DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->x())) != NULL);
const CompoundVector* c_vec = static_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->x()));
SmartPtr<const Vector> x = c_vec->GetComp(0);
if( scaled )
{
x_U_viol = restonlp->OrigIpCq().orig_x_U_violation(*x);
}
else
{
x = orignlp->NLP_scaling()->unapply_vector_scaling_x(x);
x_U_viol = restonlp->OrigIpCq().unscaled_orig_x_U_violation(*x);
}
}
DBG_ASSERT(IsValid(x_U_viol));
DBG_ASSERT(dynamic_cast<const DenseVector*>(GetRawPtr(x_U_viol)) != NULL);
return static_cast<const DenseVector*>(GetRawPtr(x_U_viol));
}
static
SmartPtr<const DenseVector> curr_compl_x_L(
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq,
OrigIpoptNLP* orignlp,
RestoIpoptNLP* restonlp,
bool scaled
)
{
SmartPtr<const Vector> compl_x_L;
Number obj_unscal = scaled ? 1.0 : orignlp->NLP_scaling()->unapply_obj_scaling(1.0);
if( restonlp == NULL )
{
compl_x_L = ip_cq->curr_compl_x_L();
if( obj_unscal != 1.0 )
{
SmartPtr<Vector> tmp = compl_x_L->MakeNewCopy();
tmp->Scal(obj_unscal);
compl_x_L = tmp;
}
}
else
{
DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->z_L())) != NULL);
const CompoundVector* c_vec = static_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->z_L()));
SmartPtr<const Vector> z_L_only = c_vec->GetComp(0);
DBG_ASSERT(IsValid(z_L_only));
c_vec = static_cast<const CompoundVector*>(GetRawPtr(ip_cq->curr_slack_x_L()));
DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(ip_cq->curr_slack_x_L())) != NULL);
SmartPtr<const Vector> slack_x_L = c_vec->GetComp(0);
DBG_ASSERT(IsValid(slack_x_L));
SmartPtr<Vector> compl_x_L_v = slack_x_L->MakeNewCopy();
compl_x_L_v->ElementWiseMultiply(*z_L_only);
compl_x_L_v->Scal(obj_unscal);
compl_x_L = compl_x_L_v;
}
DBG_ASSERT(IsValid(compl_x_L));
DBG_ASSERT(dynamic_cast<const DenseVector*>(GetRawPtr(compl_x_L)) != NULL);
return static_cast<const DenseVector*>(GetRawPtr(compl_x_L));
}
static
SmartPtr<const DenseVector> curr_compl_x_U(
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq,
OrigIpoptNLP* orignlp,
RestoIpoptNLP* restonlp,
bool scaled
)
{
SmartPtr<const Vector> compl_x_U;
Number obj_unscal = scaled ? 1.0 : orignlp->NLP_scaling()->unapply_obj_scaling(1.0);
if( restonlp == NULL )
{
compl_x_U = ip_cq->curr_compl_x_U();
if( obj_unscal != 1.0 )
{
SmartPtr<Vector> tmp = compl_x_U->MakeNewCopy();
tmp->Scal(obj_unscal);
compl_x_U = tmp;
}
}
else
{
const CompoundVector* c_vec = static_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->z_U()));
DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(ip_data->curr()->z_U())) != NULL);
SmartPtr<const Vector> z_U_only = c_vec->GetComp(0);
DBG_ASSERT(IsValid(z_U_only));
c_vec = static_cast<const CompoundVector*>(GetRawPtr(ip_cq->curr_slack_x_U()));
DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(ip_cq->curr_slack_x_U())) != NULL);
SmartPtr<const Vector> slack_x_U = c_vec->GetComp(0);
DBG_ASSERT(IsValid(slack_x_U));
SmartPtr<Vector> compl_x_U_v = slack_x_U->MakeNewCopy();
compl_x_U_v->ElementWiseMultiply(*z_U_only);
compl_x_U_v->Scal(obj_unscal);
compl_x_U = compl_x_U_v;
}
DBG_ASSERT(IsValid(compl_x_U));
DBG_ASSERT(dynamic_cast<const DenseVector*>(GetRawPtr(compl_x_U)) != NULL);
return static_cast<const DenseVector*>(GetRawPtr(compl_x_U));
}
static
SmartPtr<const DenseVector> curr_grad_lag_x(
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq,
OrigIpoptNLP* orignlp,
RestoIpoptNLP* restonlp,
bool scaled
)
{
SmartPtr<const Vector> grad;
if( restonlp == NULL )
{
grad = ip_cq->curr_grad_lag_x();
}
else
{
SmartPtr<Vector> tmp = orignlp->grad_f(*curr_x(ip_data, ip_cq, orignlp, restonlp, true))->MakeNewCopy();
SmartPtr<const Vector> resto_c_part = ip_cq->curr_jac_cT_times_curr_y_c();
DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(resto_c_part)) != NULL);
const CompoundVector* c_vec = static_cast<const CompoundVector*>(GetRawPtr(resto_c_part));
tmp->Axpy(1.0, *c_vec->GetComp(0));
SmartPtr<const Vector> resto_d_part = ip_cq->curr_jac_dT_times_curr_y_d();
DBG_ASSERT(dynamic_cast<const CompoundVector*>(GetRawPtr(resto_d_part)) != NULL);
c_vec = static_cast<const CompoundVector*>(GetRawPtr(resto_d_part));
tmp->Axpy(1.0, *c_vec->GetComp(0));
SmartPtr<const DenseVector> z_L = curr_z_L(ip_data, ip_cq, orignlp, restonlp, true);
orignlp->Px_L()->MultVector(-1., *z_L, 1., *tmp);
SmartPtr<const DenseVector> z_U = curr_z_U(ip_data, ip_cq, orignlp, restonlp, true);
orignlp->Px_U()->MultVector(1., *z_U, 1., *tmp);
grad = ConstPtr(tmp);
}
DBG_ASSERT(IsValid(grad));
if( !scaled )
{
grad = orignlp->NLP_scaling()->unapply_grad_obj_scaling(grad);
}
DBG_ASSERT(dynamic_cast<const DenseVector*>(GetRawPtr(grad)) != NULL);
return static_cast<const DenseVector*>(GetRawPtr(grad));
}
bool TNLP::get_curr_iterate(
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq,
bool scaled,
Index n,
Number* x,
Number* z_L,
Number* z_U,
Index m,
Number* g,
Number* lambda
) const
{
if( ip_data == NULL || !IsValid(ip_data->curr()) )
{
return false;
}
if( ip_cq == NULL )
{
return false;
}
Ipopt::OrigIpoptNLP* orignlp;
Ipopt::RestoIpoptNLP* restonlp = NULL;
TNLPAdapter* tnlp_adapter;
Index n_full;
Index m_full;
orignlp = dynamic_cast<OrigIpoptNLP*>(GetRawPtr(ip_cq->GetIpoptNLP()));
if( orignlp == NULL )
{
restonlp = dynamic_cast<RestoIpoptNLP*>(GetRawPtr(ip_cq->GetIpoptNLP()));
if( restonlp == NULL )
{
return false;
}
if( (orignlp = dynamic_cast<OrigIpoptNLP*>(&restonlp->OrigIpNLP())) == NULL )
{
return false;
}
}
tnlp_adapter = dynamic_cast<TNLPAdapter*>(GetRawPtr(orignlp->nlp()));
if( tnlp_adapter == NULL )
{
return false;
}
tnlp_adapter->GetFullDimensions(n_full, m_full);
if( n != n_full && (x != NULL || (z_L != NULL && z_U != NULL)) )
{
THROW_EXCEPTION(IpoptException, "Incorrect dimension of x given to TNLP::get_curr_iterate().\n");
}
if( m != m_full && (lambda != NULL || g != NULL) )
{
THROW_EXCEPTION(IpoptException, "Incorrect dimension of g(x) given to TNLP::get_curr_iterate().\n");
}
SmartPtr<const DenseVector> intern_x;
SmartPtr<const DenseVector> intern_y_c;
SmartPtr<const DenseVector> intern_y_d;
if( x != NULL || (z_L != NULL && z_U != NULL) )
{
intern_x = curr_x(ip_data, ip_cq, orignlp, restonlp, scaled);
}
if( (z_L != NULL && z_U != NULL) || lambda != NULL )
{
intern_y_c = curr_y_c(ip_data, ip_cq, orignlp, restonlp, scaled);
intern_y_d = curr_y_d(ip_data, ip_cq, orignlp, restonlp, scaled);
}
if( x != NULL )
{
tnlp_adapter->ResortX(*intern_x, x);
}
if( z_L != NULL && z_U != NULL )
{
Index n_x_fixed;
Index* x_fixed_map;
TNLPAdapter::FixedVariableTreatmentEnum fixed_variable_treatment;
tnlp_adapter->GetFixedVariables(n_x_fixed, x_fixed_map, fixed_variable_treatment);
if( !scaled || n_x_fixed == 0 || fixed_variable_treatment != TNLPAdapter::MAKE_PARAMETER )
tnlp_adapter->ResortBoundMultipliers(
*intern_x, *intern_y_c, *intern_y_d,
*curr_z_L(ip_data, ip_cq, orignlp, restonlp, scaled), z_L,
*curr_z_U(ip_data, ip_cq, orignlp, restonlp, scaled), z_U);
else
{
tnlp_adapter->ResortBoundMultipliers(
*curr_x(ip_data, ip_cq, orignlp, restonlp, false),
*curr_y_c(ip_data, ip_cq, orignlp, restonlp, false),
*curr_y_d(ip_data, ip_cq, orignlp, restonlp, false),
*curr_z_L(ip_data, ip_cq, orignlp, restonlp, true), z_L,
*curr_z_U(ip_data, ip_cq, orignlp, restonlp, true), z_U);
Number obj_scal = orignlp->NLP_scaling()->apply_obj_scaling(1.0);
if( obj_scal != 1.0 )
for( Index i = 0; i < n_x_fixed; ++i )
{
if( obj_scal > 0.0 )
{
z_L[x_fixed_map[i]] *= obj_scal;
z_U[x_fixed_map[i]] *= obj_scal;
}
else
{
Number tmp = -z_L[x_fixed_map[i]] * obj_scal;
z_L[x_fixed_map[i]] = -z_U[x_fixed_map[i]] * obj_scal;
z_U[x_fixed_map[i]] = tmp;
}
}
}
}
if( g != NULL )
{
if( !scaled || !orignlp->NLP_scaling()->have_c_scaling() )
{
tnlp_adapter->ResortG(*curr_c(ip_data, ip_cq, orignlp, restonlp, scaled), *curr_d(ip_data, ip_cq, orignlp, restonlp, scaled), g, true);
}
else
{
SmartPtr<const DenseVector> c_scaled = curr_c(ip_data, ip_cq, orignlp, restonlp, true);
SmartPtr<DenseVector> c_rhs = new DenseVector(new DenseVectorSpace(c_scaled->Dim()));
c_rhs->SetValues(tnlp_adapter->GetC_Rhs());
SmartPtr<Vector> c_rhs_scaled = orignlp->NLP_scaling()->apply_vector_scaling_c_NonConst(c_rhs);
c_rhs_scaled->Axpy(1.0, *c_scaled);
tnlp_adapter->ResortG(*c_rhs_scaled, *curr_d(ip_data, ip_cq, orignlp, restonlp, scaled), g);
}
}
if( lambda != NULL )
{
tnlp_adapter->ResortG(*intern_y_c, *intern_y_d, lambda);
}
return true;
}
bool TNLP::get_curr_violations(
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq,
bool scaled,
Index n,
Number* x_L_violation,
Number* x_U_violation,
Number* compl_x_L,
Number* compl_x_U,
Number* grad_lag_x,
Index m,
Number* nlp_constraint_violation,
Number* compl_g
) const
{
if( ip_data == NULL || !IsValid(ip_data->curr()) )
{
return false;
}
if( ip_cq == NULL )
{
return false;
}
Ipopt::OrigIpoptNLP* orignlp;
Ipopt::RestoIpoptNLP* restonlp = NULL;
TNLPAdapter* tnlp_adapter;
Index n_full;
Index m_full;
orignlp = dynamic_cast<OrigIpoptNLP*>(GetRawPtr(ip_cq->GetIpoptNLP()));
if( orignlp == NULL )
{
restonlp = dynamic_cast<RestoIpoptNLP*>(GetRawPtr(ip_cq->GetIpoptNLP()));
if( restonlp == NULL )
{
return false;
}
if( (orignlp = dynamic_cast<OrigIpoptNLP*>(&restonlp->OrigIpNLP())) == NULL )
{
return false;
}
}
tnlp_adapter = dynamic_cast<TNLPAdapter*>(GetRawPtr(orignlp->nlp()));
if( tnlp_adapter == NULL )
{
return false;
}
tnlp_adapter->GetFullDimensions(n_full, m_full);
if( n != n_full && (x_L_violation != NULL || x_U_violation != NULL || compl_x_L != NULL || compl_x_U != NULL || grad_lag_x != NULL) )
{
THROW_EXCEPTION(IpoptException, "Incorrect dimension of x given to TNLP::get_curr_violations().\n");
}
if( m != m_full && (nlp_constraint_violation != NULL || compl_g != NULL) )
{
THROW_EXCEPTION(IpoptException, "Incorrect dimension of g(x) given to TNLP::get_curr_violations().\n");
}
Index n_x_fixed;
Index* x_fixed_map;
TNLPAdapter::FixedVariableTreatmentEnum fixed_variable_treatment;
tnlp_adapter->GetFixedVariables(n_x_fixed, x_fixed_map, fixed_variable_treatment);
if( x_L_violation != NULL || x_U_violation != NULL )
{
tnlp_adapter->ResortBounds(*curr_x_L_viol(ip_data, ip_cq, orignlp, restonlp, scaled), x_L_violation,
*curr_x_U_viol(ip_data, ip_cq, orignlp, restonlp, scaled), x_U_violation);
if( n_x_fixed > 0 && fixed_variable_treatment == TNLPAdapter::MAKE_CONSTRAINT )
{
SmartPtr<const DenseVector> c = curr_c(ip_data, ip_cq, orignlp, restonlp, scaled);
for( Index i = 0; i < n_x_fixed; ++i )
{
Number viol;
if( c->IsHomogeneous() )
{
viol = c->Scalar();
}
else
{
viol = c->Values()[c->Dim() - n_x_fixed + i];
}
if( x_L_violation != NULL )
{
x_L_violation[x_fixed_map[i]] = Max(Number(0.), -viol); }
if( x_U_violation != NULL )
{
x_U_violation[x_fixed_map[i]] = Max(Number(0.), viol); }
}
}
}
if( compl_x_L != NULL || compl_x_U != NULL )
{
tnlp_adapter->ResortBounds(*curr_compl_x_L(ip_data, ip_cq, orignlp, restonlp, scaled), compl_x_L,
*curr_compl_x_U(ip_data, ip_cq, orignlp, restonlp, scaled), compl_x_U);
if( n_x_fixed > 0 && fixed_variable_treatment == TNLPAdapter::MAKE_CONSTRAINT )
{
SmartPtr<const Vector> y_c = curr_y_c(ip_data, ip_cq, orignlp, restonlp, scaled);
SmartPtr<Vector> yc_pos = y_c->MakeNewCopy();
SmartPtr<Vector> yc_neg = y_c->MakeNewCopy();
SmartPtr<Vector> zero = yc_pos->MakeNew();
zero->Set(0.);
yc_pos->ElementWiseMax(*zero); yc_neg->ElementWiseMin(*zero);
SmartPtr<const Vector> c = curr_c(ip_data, ip_cq, orignlp, restonlp, scaled);
yc_pos->ElementWiseMultiply(*c); yc_neg->ElementWiseMultiply(*c);
DBG_ASSERT(dynamic_cast<DenseVector*>(GetRawPtr(yc_pos)) != NULL);
DBG_ASSERT(dynamic_cast<DenseVector*>(GetRawPtr(yc_neg)) != NULL);
Number* yc_pos_val = static_cast<DenseVector*>(GetRawPtr(yc_pos))->ExpandedValues();
Number* yc_neg_val = static_cast<DenseVector*>(GetRawPtr(yc_neg))->ExpandedValues();
for( Index i = 0; i < n_x_fixed; ++i )
{
if( compl_x_L != NULL )
{
compl_x_L[x_fixed_map[i]] = -yc_neg_val[yc_neg->Dim() - n_x_fixed + i];
}
if( compl_x_U != NULL )
{
compl_x_U[x_fixed_map[i]] = -yc_pos_val[yc_pos->Dim() - n_x_fixed + i];
}
}
}
}
if( grad_lag_x != NULL )
{
tnlp_adapter->ResortX(*curr_grad_lag_x(ip_data, ip_cq, orignlp, restonlp, scaled), grad_lag_x, false);
if( n_x_fixed > 0 && fixed_variable_treatment == TNLPAdapter::MAKE_CONSTRAINT )
{
SmartPtr<const DenseVector> y_c = curr_y_c(ip_data, ip_cq, orignlp, restonlp, scaled);
const Number* c_rhs = tnlp_adapter->GetC_Rhs();
DBG_ASSERT(y_c->Dim() >= n_x_fixed);
if( y_c->IsHomogeneous() )
for( Index i = 0; i < n_x_fixed; ++i )
{
grad_lag_x[x_fixed_map[i]] += y_c->Scalar() * (1.0 - c_rhs[y_c->Dim() - n_x_fixed + i]);
}
else
for( Index i = 0; i < n_x_fixed; ++i )
{
grad_lag_x[x_fixed_map[i]] += y_c->Values()[y_c->Dim() - n_x_fixed + i] * (1.0 - c_rhs[y_c->Dim() - n_x_fixed + i]);
}
}
}
if( nlp_constraint_violation != NULL || compl_g != NULL )
{
SmartPtr<const DenseVector> c = curr_c(ip_data, ip_cq, orignlp, restonlp, scaled);
SmartPtr<const DenseVector> d = curr_d(ip_data, ip_cq, orignlp, restonlp, true);
SmartPtr<Vector> d_viol_L;
SmartPtr<const Vector> d_L;
d_L = orignlp->orig_d_L();
if( IsValid(d_L) )
{
if( orignlp->NLP_scaling()->have_d_scaling() )
{
d_L = orignlp->NLP_scaling()->apply_vector_scaling_d_NonConst(d_L);
}
}
else {
d_L = orignlp->d_L();
}
if( d_L->Dim() > 0 )
{
SmartPtr<Vector> tmp = d_L->MakeNewCopy();
d_viol_L = d->MakeNew();
d_viol_L->Set(0.);
orignlp->Pd_L()->TransMultVector(-1., *d, 1., *tmp); orignlp->Pd_L()->MultVector(1., *tmp, 0., *d_viol_L); if( !scaled && orignlp->NLP_scaling()->have_d_scaling() )
{
d_viol_L = orignlp->NLP_scaling()->unapply_vector_scaling_d_NonConst(ConstPtr(d_viol_L));
}
}
else
{
d_viol_L = d->MakeNew();
d_viol_L->Set(0.);
}
SmartPtr<Vector> d_viol_U;
SmartPtr<const Vector> d_U;
d_U = orignlp->orig_d_U();
if( IsValid(d_U) )
{
if( orignlp->NLP_scaling()->have_d_scaling() )
{
d_U = orignlp->NLP_scaling()->apply_vector_scaling_d_NonConst(d_U);
}
}
else {
d_U = orignlp->d_U();
}
if( d_U->Dim() > 0 )
{
SmartPtr<Vector> tmp = d_U->MakeNewCopy();
d_viol_U = d->MakeNew();
d_viol_U->Set(0.);
orignlp->Pd_U()->TransMultVector(1., *d, -1., *tmp); orignlp->Pd_U()->MultVector(1., *tmp, 0., *d_viol_U); if( !scaled && orignlp->NLP_scaling()->have_d_scaling() )
{
d_viol_U = orignlp->NLP_scaling()->unapply_vector_scaling_d_NonConst(ConstPtr(d_viol_U));
}
}
else
{
d_viol_U = d->MakeNew();
d_viol_U->Set(0.);
}
if( compl_g != NULL )
{
SmartPtr<const DenseVector> y_d = curr_y_d(ip_data, ip_cq, orignlp, restonlp, scaled);
SmartPtr<Vector> yd_pos = y_d->MakeNewCopy();
SmartPtr<Vector> yd_neg = y_d->MakeNewCopy();
SmartPtr<Vector> zero = yd_pos->MakeNew();
zero->Set(0.);
yd_pos->ElementWiseMax(*zero);
yd_neg->ElementWiseMin(*zero);
yd_pos->ElementWiseMultiply(*d_viol_U); yd_neg->ElementWiseMultiply(*d_viol_L);
yd_neg->Axpy(-1.0, *yd_pos);
SmartPtr<const DenseVector> y_c = curr_y_c(ip_data, ip_cq, orignlp, restonlp, scaled);
SmartPtr<Vector> c_compl = c->MakeNewCopy();
c_compl->ElementWiseMultiply(*y_c); c_compl->Scal(-1.0);
tnlp_adapter->ResortG(*c_compl, *yd_neg, compl_g);
}
if( nlp_constraint_violation != NULL )
{
SmartPtr<Vector> c_viol = c->MakeNewCopy();
c_viol->ElementWiseAbs();
d_viol_L->ElementWiseMax(*d_viol_U);
SmartPtr<Vector> tmp = d_viol_L->MakeNew();
tmp->Set(0.);
d_viol_L->ElementWiseMax(*tmp);
tnlp_adapter->ResortG(*c_viol, *d_viol_L, nlp_constraint_violation);
}
}
return true;
}
}