Commit b291d649 authored by Martin Marinov's avatar Martin Marinov
Browse files

Merge remote-tracking branch 'VCI/master' into marinom/merge-from-VCI

parents 27f5b51a fba5e448
......@@ -76,6 +76,8 @@ solve(NProblemInterface* _problem,
// move to next constraint
++n_constraints;
} else {
std::cerr << "Warning: COMISOSolver received a problem with non-equality constraints!!!" << std::endl;
}
// resize matrix to final number of constraints
......
......@@ -80,7 +80,7 @@ private:
} // namespace COMISO
//=============================================================================
// support std vectors
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(COMISO::ConeConstraint);
EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(COMISO::ConeConstraint)
//=============================================================================
#endif // ACG_CONECONSTRAINT_HH defined
//=============================================================================
......
......@@ -19,7 +19,7 @@
#include <iostream>
#include <vector>
#include <gmm/gmm.h>
#include <CoMISo/Utils/gmm.hh>
#include <CoMISo/Config/CoMISoDefines.hh>
#include <CoMISo/NSolver/NConstraintInterface.hh>
......
......@@ -182,6 +182,7 @@ public:
for(unsigned int j=0; j<NV; ++j)
x_[j] = _x[instances_.index(i,j)];
triplets_.clear();
element_.eval_hessian(x_, instances_.c(i), triplets_);
for(unsigned int j=0; j<triplets_.size(); ++j)
......
This diff is collapsed.
......@@ -46,7 +46,9 @@ public:
bool solve(NProblemInterface* _problem, // problem instance
const std::vector<NConstraintInterface*>& _constraints, // linear constraints
const std::vector<PairIndexVtype>& _discrete_constraints, // discrete constraints
const double _time_limit = 60 ); // time limit in seconds
const double _time_limit = 60, // time limit in seconds
const double _gap = 0.0); // stops when solution with optimality gap
// lower than _gab is reached
bool solve(NProblemInterface* _problem, // problem instance
const std::vector<NConstraintInterface*>& _constraints, // linear constraints
......@@ -89,6 +91,14 @@ public:
const double _time_limit = 60,
const bool _silent = false);
bool solve( NProblemInterface* _problem,
const std::vector<NConstraintInterface*>& _constraints,
const std::vector<NConstraintInterface*>& _lazy_constraints,
const std::vector<PairIndexVtype>& _discrete_constraints, // discrete constraints
const double _time_limit = 60,
const double _gap = 0.0,
const int _lazy_level = 0); // lazy level between 0 and 3
// same as above with additional lazy constraints that are only added iteratively to the problem if not satisfied
bool solve(NProblemInterface* _problem,
......@@ -104,24 +114,19 @@ public:
}
void set_problem_output_path ( const std::string &_problem_output_path);
void set_problem_env_output_path( const std::string &_problem_env_output_path);
void set_solution_input_path ( const std::string &_solution_input_path);
void set_problem_output_path ( const std::string &_problem_output_path);
void set_start_solution_output_path( const std::string &_start_solution_output_path);
void set_problem_env_output_path ( const std::string &_problem_env_output_path);
void set_solution_input_path ( const std::string &_solution_input_path);
protected:
double* P(std::vector<double>& _v)
{
if( !_v.empty())
return ((double*)&_v[0]);
else
return 0;
}
private:
// filenames for exporting/importing gurobi solutions
// if string is empty nothing is imported or exported
std::string problem_output_path_;
std::string start_solution_output_path_;
std::string problem_env_output_path_;
std::string solution_input_path_;
};
......
//=============================================================================
//
// STRUCT IPOPTCallbackParameters
//
//=============================================================================
#ifndef COMISO_IPOPTCALLBACKPARAMETERS_HH
#define COMISO_IPOPTCALLBACKPARAMETERS_HH
#include <IpTNLP.hpp>
//== TYPE DEFINITION CALLBACK PARAMETERS ======================================
namespace COMISO {
struct IPOPTCallbackParameters {
Ipopt::AlgorithmMode mode;
Ipopt::Index iter;
Ipopt::Number obj_value;
Ipopt::Number inf_pr;
Ipopt::Number inf_du;
Ipopt::Number mu;
Ipopt::Number d_norm;
Ipopt::Number regularization_size;
Ipopt::Number alpha_du;
Ipopt::Number alpha_pr;
Ipopt::Index ls_trials;
const Ipopt::IpoptData* ip_data;
Ipopt::IpoptCalculatedQuantities* ip_cq;
};
}
#endif
......@@ -11,21 +11,18 @@
#if COMISO_IPOPT_AVAILABLE
//=============================================================================
#include "CoMISo/Utils/CoMISoError.hh"
#include <CoMISo/Utils/gmm.hh>
#include <Base/Debug/DebTime.hh>
#include "NProblemIPOPT.hh"
#include "NProblemGmmInterface.hh"
#include "NProblemInterface.hh"
#include "NConstraintInterface.hh"
#include "BoundConstraint.hh"
#include "CoMISo/Utils/CoMISoError.hh"
#include <Base/Debug/DebTime.hh>
#include "IPOPTCallbackParameters.hh"
#include <gmm/gmm.h>
#include <IpTNLP.hpp>
#include <IpIpoptApplication.hpp>
#include <IpSolveStatistics.hpp>
#include "IPOPTProblemInstance.hh"
//== NAMESPACES ===============================================================
......@@ -33,11 +30,10 @@ namespace COMISO {
//== IMPLEMENTATION PROBLEM INSTANCE==========================================================
//== IMPLEMENTATION PROBLEM INSTANCE===========================================
void
NProblemIPOPT::
IPOPTProblemInstance::
split_constraints(const std::vector<NConstraintInterface*>& _constraints)
{
DEB_enter_func;
......@@ -61,7 +57,7 @@ split_constraints(const std::vector<NConstraintInterface*>& _constraints)
void
NProblemIPOPT::
IPOPTProblemInstance::
analyze_special_properties(const NProblemInterface* _problem, const std::vector<NConstraintInterface*>& _constraints)
{
hessian_constant_ = true;
......@@ -98,7 +94,7 @@ analyze_special_properties(const NProblemInterface* _problem, const std::vector<
//-----------------------------------------------------------------------------
bool NProblemIPOPT::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
bool IPOPTProblemInstance::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
Index& nnz_h_lag, IndexStyleEnum& index_style)
{
DEB_enter_func;
......@@ -137,7 +133,7 @@ bool NProblemIPOPT::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
{
constraints_[i]->eval_gradient(P(x),g);
nnz_jac_g += g.nonZeros();
nnz_jac_g += static_cast<Index>(g.nonZeros());
if(!hessian_approximation_)
{
......@@ -161,7 +157,7 @@ bool NProblemIPOPT::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
//-----------------------------------------------------------------------------
bool NProblemIPOPT::get_bounds_info(Index n, Number* x_l, Number* x_u,
bool IPOPTProblemInstance::get_bounds_info(Index n, Number* x_l, Number* x_u,
Index m, Number* g_l, Number* g_u)
{
DEB_enter_func;
......@@ -230,7 +226,7 @@ bool NProblemIPOPT::get_bounds_info(Index n, Number* x_l, Number* x_u,
//-----------------------------------------------------------------------------
bool NProblemIPOPT::get_starting_point(Index n, bool init_x, Number* x,
bool IPOPTProblemInstance::get_starting_point(Index n, bool init_x, Number* x,
bool init_z, Number* z_L, Number* z_U,
Index m, bool init_lambda,
Number* lambda)
......@@ -246,7 +242,7 @@ bool NProblemIPOPT::get_starting_point(Index n, bool init_x, Number* x,
//-----------------------------------------------------------------------------
bool NProblemIPOPT::eval_f(Index n, const Number* x, bool new_x, Number& obj_value)
bool IPOPTProblemInstance::eval_f(Index n, const Number* x, bool new_x, Number& obj_value)
{
DEB_enter_func;
// return the value of the objective function
......@@ -258,7 +254,7 @@ bool NProblemIPOPT::eval_f(Index n, const Number* x, bool new_x, Number& obj_val
//-----------------------------------------------------------------------------
bool NProblemIPOPT::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f)
bool IPOPTProblemInstance::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f)
{
DEB_enter_func;
problem_->eval_gradient(x, grad_f);
......@@ -270,7 +266,7 @@ bool NProblemIPOPT::eval_grad_f(Index n, const Number* x, bool new_x, Number* gr
//-----------------------------------------------------------------------------
bool NProblemIPOPT::eval_g(Index n, const Number* x, bool new_x, Index m, Number* g)
bool IPOPTProblemInstance::eval_g(Index n, const Number* x, bool new_x, Index m, Number* g)
{
DEB_enter_func;
// evaluate all constraint functions
......@@ -284,7 +280,7 @@ bool NProblemIPOPT::eval_g(Index n, const Number* x, bool new_x, Index m, Number
//-----------------------------------------------------------------------------
bool NProblemIPOPT::eval_jac_g(Index n, const Number* x, bool new_x,
bool IPOPTProblemInstance::eval_jac_g(Index n, const Number* x, bool new_x,
Index m, Index nele_jac, Index* iRow, Index *jCol,
Number* values)
{
......@@ -342,7 +338,7 @@ bool NProblemIPOPT::eval_jac_g(Index n, const Number* x, bool new_x,
//-----------------------------------------------------------------------------
bool NProblemIPOPT::eval_h(Index n, const Number* x, bool new_x,
bool IPOPTProblemInstance::eval_h(Index n, const Number* x, bool new_x,
Number obj_factor, Index m, const Number* lambda,
bool new_lambda, Index nele_hess, Index* iRow,
Index* jCol, Number* values)
......@@ -368,8 +364,8 @@ bool NProblemIPOPT::eval_h(Index n, const Number* x, bool new_x,
if(it.row() >= it.col())
{
// it.value();
iRow[gi] = it.row();
jCol[gi] = it.col();
iRow[gi] = static_cast<Index>(it.row());
jCol[gi] = static_cast<Index>(it.col());
++gi;
}
}
......@@ -476,7 +472,7 @@ bool NProblemIPOPT::eval_h(Index n, const Number* x, bool new_x,
double _QNT(const double x) { return x; }
void NProblemIPOPT::finalize_solution(SolverReturn status,
void IPOPTProblemInstance::finalize_solution(SolverReturn status,
Index n, const Number* x, const Number* z_L, const Number* z_U,
Index m, const Number* g, const Number* lambda,
Number obj_value,
......@@ -516,21 +512,44 @@ void NProblemIPOPT::finalize_solution(SolverReturn status,
//-----------------------------------------------------------------------------
void
IPOPTProblemInstance::
set_callback_function
(std::function<bool(const IPOPTCallbackParameters &)> func)
{
intermediate_callback_ = func;
}
bool NProblemIPOPT::intermediate_callback(
Ipopt::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*/,
const IpoptData* /*ip_data*/,
IpoptCalculatedQuantities* /*ip_cq*/
)
bool IPOPTProblemInstance::intermediate_callback(
Ipopt::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,
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq
)
{
PROGRESS_TICK;
if(intermediate_callback_) {
IPOPTCallbackParameters callbackParameters {
mode,
iter, obj_value,
inf_pr, inf_du,
mu, d_norm,
regularization_size,
alpha_du, alpha_pr,
ls_trials,
ip_data,
ip_cq
};
return intermediate_callback_(callbackParameters);
}
return true;
}
......@@ -538,7 +557,7 @@ bool NProblemIPOPT::intermediate_callback(
//-----------------------------------------------------------------------------
bool NProblemIPOPT::hessian_constant() const
bool IPOPTProblemInstance::hessian_constant() const
{
return hessian_constant_;
}
......@@ -547,7 +566,7 @@ bool NProblemIPOPT::hessian_constant() const
//-----------------------------------------------------------------------------
bool NProblemIPOPT::jac_c_constant() const
bool IPOPTProblemInstance::jac_c_constant() const
{
return jac_c_constant_;
}
......@@ -556,7 +575,7 @@ bool NProblemIPOPT::jac_c_constant() const
//-----------------------------------------------------------------------------
bool NProblemIPOPT::jac_d_constant() const
bool IPOPTProblemInstance::jac_d_constant() const
{
return jac_d_constant_;
}
......@@ -565,7 +584,7 @@ bool NProblemIPOPT::jac_d_constant() const
//== IMPLEMENTATION PROBLEM INSTANCE==========================================================
bool NProblemGmmIPOPT::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
bool IPOPTProblemInstanceGmm::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
Index& nnz_h_lag, IndexStyleEnum& index_style)
{
DEB_enter_func;
......@@ -657,7 +676,7 @@ bool NProblemGmmIPOPT::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
//-----------------------------------------------------------------------------
bool NProblemGmmIPOPT::get_bounds_info(Index n, Number* x_l, Number* x_u,
bool IPOPTProblemInstanceGmm::get_bounds_info(Index n, Number* x_l, Number* x_u,
Index m, Number* g_l, Number* g_u)
{
DEB_enter_func;
......@@ -691,7 +710,7 @@ bool NProblemGmmIPOPT::get_bounds_info(Index n, Number* x_l, Number* x_u,
//-----------------------------------------------------------------------------
bool NProblemGmmIPOPT::get_starting_point(Index n, bool init_x, Number* x,
bool IPOPTProblemInstanceGmm::get_starting_point(Index n, bool init_x, Number* x,
bool init_z, Number* z_L, Number* z_U,
Index m, bool init_lambda,
Number* lambda)
......@@ -707,7 +726,7 @@ bool NProblemGmmIPOPT::get_starting_point(Index n, bool init_x, Number* x,
//-----------------------------------------------------------------------------
bool NProblemGmmIPOPT::eval_f(Index n, const Number* x, bool new_x, Number& obj_value)
bool IPOPTProblemInstanceGmm::eval_f(Index n, const Number* x, bool new_x, Number& obj_value)
{
DEB_enter_func;
// return the value of the objective function
......@@ -719,7 +738,7 @@ bool NProblemGmmIPOPT::eval_f(Index n, const Number* x, bool new_x, Number& obj_
//-----------------------------------------------------------------------------
bool NProblemGmmIPOPT::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f)
bool IPOPTProblemInstanceGmm::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f)
{
DEB_enter_func;
problem_->eval_gradient(x, grad_f);
......@@ -731,7 +750,7 @@ bool NProblemGmmIPOPT::eval_grad_f(Index n, const Number* x, bool new_x, Number*
//-----------------------------------------------------------------------------
bool NProblemGmmIPOPT::eval_g(Index n, const Number* x, bool new_x, Index m, Number* g)
bool IPOPTProblemInstanceGmm::eval_g(Index n, const Number* x, bool new_x, Index m, Number* g)
{
DEB_enter_func;
// evaluate all constraint functions
......@@ -745,7 +764,7 @@ bool NProblemGmmIPOPT::eval_g(Index n, const Number* x, bool new_x, Index m, Num
//-----------------------------------------------------------------------------
bool NProblemGmmIPOPT::eval_jac_g(Index n, const Number* x, bool new_x,
bool IPOPTProblemInstanceGmm::eval_jac_g(Index n, const Number* x, bool new_x,
Index m, Index nele_jac, Index* iRow, Index *jCol,
Number* values)
{
......@@ -791,7 +810,7 @@ bool NProblemGmmIPOPT::eval_jac_g(Index n, const Number* x, bool new_x,
//-----------------------------------------------------------------------------
bool NProblemGmmIPOPT::eval_h(Index n, const Number* x, bool new_x,
bool IPOPTProblemInstanceGmm::eval_h(Index n, const Number* x, bool new_x,
Number obj_factor, Index m, const Number* lambda,
bool new_lambda, Index nele_hess, Index* iRow,
Index* jCol, Number* values)
......@@ -865,7 +884,7 @@ bool NProblemGmmIPOPT::eval_h(Index n, const Number* x, bool new_x,
//-----------------------------------------------------------------------------
void NProblemGmmIPOPT::finalize_solution(SolverReturn status,
void IPOPTProblemInstanceGmm::finalize_solution(SolverReturn status,
Index n, const Number* x, const Number* z_L, const Number* z_U,
Index m, const Number* g, const Number* lambda,
Number obj_value,
......@@ -877,19 +896,43 @@ void NProblemGmmIPOPT::finalize_solution(SolverReturn status,
problem_->store_result(x);
}
bool NProblemGmmIPOPT::intermediate_callback(
Ipopt::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*/,
const IpoptData* /*ip_data*/,
IpoptCalculatedQuantities* /*ip_cq*/
)
void
IPOPTProblemInstanceGmm::
set_callback_function
(std::function<bool(const IPOPTCallbackParameters &)> func)
{
intermediate_callback_ = func;
}
bool IPOPTProblemInstanceGmm::intermediate_callback(
Ipopt::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,
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq
)
{
PROGRESS_TICK;
if(intermediate_callback_) {
IPOPTCallbackParameters callbackParameters {
mode,
iter, obj_value,
inf_pr, inf_du,
mu, d_norm,
regularization_size,
alpha_du, alpha_pr,
ls_trials,
ip_data,
ip_cq
};
return intermediate_callback_(callbackParameters);
}
return true;
}
......
<
......@@ -15,10 +15,13 @@
//== INCLUDES =================================================================
#include <vector>
#include <cstddef>
#include <functional>
#include <CoMISo/Config/CoMISoDefines.hh>
#include "NProblemGmmInterface.hh"
#include "NProblemInterface.hh"
#include "IPOPTSolverLean.hh"
#include "NProblemGmmInterface.hh"
#include "NProblemInterface.hh"
#include "NConstraintInterface.hh"
......@@ -27,28 +30,25 @@
#include <Base/Debug/DebTime.hh>
#include <gmm/gmm.h>
#include <CoMISo/Utils/gmm.hh>
#include <IpTNLP.hpp>
#include <IpIpoptApplication.hpp>
#include <IpSolveStatistics.hpp>
#include <vector>
#include <cstddef>
//== NAMESPACES ===============================================================
namespace COMISO {
//== FORWARDDECLARATIONS ======================================================
class NProblemGmmInterface; // deprecated
class NProblemInterface;
class NConstraintInterface;
struct IPOPTCallbackParameters;
//== CLASS DEFINITION PROBLEM INSTANCE=========================================================
class NProblemIPOPT : public Ipopt::TNLP
//== CLASS DEFINITION PROBLEM INSTANCE ========================================
class IPOPTProblemInstance : public Ipopt::TNLP
{
public:
......@@ -65,8 +65,11 @@ public:
typedef NProblemInterface::SMatrixNP SMatrixNP;
/** default constructor */
NProblemIPOPT(NProblemInterface* _problem, const std::vector<NConstraintInterface*>& _constraints, const bool _hessian_approximation = false)
: problem_(_problem), store_solution_(false), hessian_approximation_(_hessian_approximation)
IPOPTProblemInstance(NProblemInterface* _problem,
const std::vector<NConstraintInterface*>& _constraints,
const bool _hessian_approximation = false)
: problem_(_problem), store_solution_(false),
hessian_approximation_(_hessian_approximation)
{
split_constraints(_constraints);
analyze_special_properties(_problem, _constraints);
......@@ -76,26 +79,26 @@ public:
//@{
/** Method to return some info about the nlp */
virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
Index& nnz_h_lag, IndexStyleEnum& index_style);
Index& nnz_h_lag, IndexStyleEnum& index_style) override;
/** Method to return the bounds for my problem */
virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u,
Index m, Number* g_l, Number* g_u);
Index m, Number* g_l, Number* g_u) override;
/** Method to return the starting point for the algorithm */
virtual bool get_starting_point(Index n, bool init_x, Number* x,
bool init_z, Number* z_L, Number* z_U,
Index m, bool init_lambda,
Number* lambda);
Number* lambda) override;
/** Method to return the objective value */
virtual bool eval_f(Index n, const Number* x, bool new_x, Number& obj_value);
virtual bool eval_f(Index n, const Number* x, bool new_x, Number& obj_value) override;
/** Method to return the gradient of the objective */
virtual bool eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f);
virtual bool eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f) override;
/** Method to return the constraint residuals */
virtual bool eval_g(Index n, const Number* x, bool new_x, Index m, Number* g);
virtual bool eval_g(Index n, const Number* x, bool new_x, Index m, Number* g) override;
/** Method to return:
* 1) The structure of the jacobian (if "values" is NULL)
......@@ -103,7 +106,7 @@ public:
*/
virtual bool eval_jac_g(Index n, const Number* x, bool new_x,
Index m, Index nele_jac, Index* iRow, Index *jCol,
Number* values);
Number* values) override;
/** Method to return:
* 1) The structure of the hessian of the lagrangian (if "values" is NULL)
......@@ -112,7 +115,7 @@ public:
virtual bool eval_h(Index n, const Number* x, bool new_x,
Number obj_factor, Index m, const Number* lambda,
bool new_lambda, Index nele_hess, Index* iRow,
Index* jCol, Number* values);
Index* jCol, Number* values) override;
//@}
......@@ -124,9 +127,12 @@ public:
Index m, const Number* g, const Number* lambda,
Number obj_value,
const IpoptData* ip_data,
IpoptCalculatedQuantities* ip_cq);
IpoptCalculatedQuantities* ip_cq) override;
//@}
/** Set intermediate callback function object **/
void set_callback_function(std::function<bool(const IPOPTCallbackParameters &)>);
/** Intermediate Callback method for the user. Providing dummy
* default implementation. For details see IntermediateCallBack
* in IpNLP.hpp. */
......@@ -163,8 +169,8 @@ private:
*/
//@{
// MyNLP();
NProblemIPOPT(const NProblemIPOPT&);
NProblemIPOPT& operator=(const NProblemIPOPT&);