Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
CoMISo
CoMISo
Commits
2c20415f
Commit
2c20415f
authored
Nov 14, 2019
by
Patric Schmitz
Browse files
IPOPTSolverLean becomes IPOPTSolver
removing redundant IPOPTSolver implementation
parent
45f2b252
Pipeline
#12797
passed with stages
in 7 minutes and 15 seconds
Changes
5
Pipelines
1
Expand all
Hide whitespace changes
Inline
Side-by-side
Examples/small_cplex_soc/main.cc
View file @
2c20415f
...
...
@@ -114,14 +114,13 @@ int main(void)
std
::
cout
<<
"---------- 5) Solve with IPOPT solver... "
<<
std
::
endl
;
COMISO
::
IPOPTSolver
ipopt
;
ipopt
.
app
().
Options
()
->
SetStringValue
(
"derivative_test"
,
"second-order"
);
ipopt
.
set_ipopt_option
(
"derivative_test"
,
"second-order"
);
ipopt
.
solve
(
&
lsqp
,
constraints
);
#endif
std
::
cout
<<
"---------- 6) Print solution..."
<<
std
::
endl
;
for
(
int
i
=
0
;
i
<
n
;
++
i
)
std
::
cerr
<<
"x_"
<<
i
<<
" = "
<<
lsqp
.
x
()[
i
]
<<
std
::
endl
;
return
0
;
}
NSolver/IPOPTSolver.cc
View file @
2c20415f
This diff is collapsed.
Click to expand it.
NSolver/IPOPTSolver.hh
View file @
2c20415f
...
...
@@ -8,134 +8,144 @@
#ifndef COMISO_IPOPTSOLVER_HH
#define COMISO_IPOPTSOLVER_HH
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
#include <CoMISo/Config/config.hh>
#if COMISO_IPOPT_AVAILABLE
//== INCLUDES =================================================================
#include <CoMISo/Config/CoMISoDefines.hh>
#include <CoMISo/Utils/StopWatch.hh>
#include <CoMISo/Utils/gmm.hh>
#include <vector>
#include <cstddef>
#include "NProblemGmmInterface.hh"
#include "NProblemInterface.hh"
#include "NConstraintInterface.hh"
#include "BoundConstraint.hh"
#include "IPOPTProblemInstance.hh"
#include <IpTNLP.hpp>
#include <IpIpoptApplication.hpp>
#include <IpSolveStatistics.hpp>
#include <functional>
#include <vector>
#include <string>
//== FORWARDDECLARATIONS ======================================================
#include <CoMISo/Config/CoMISoDefines.hh>
//== NAMESPACES ===============================================================
namespace
COMISO
{
//== FORWARDDECLARATIONS ======================================================
class
NProblemInterface
;
class
NConstraintInterface
;
struct
IPOPTCallbackParameters
;
//== CLASS DEFINITION =========================================================
/** \class IPOPTSolver
Solver for Interior Point optimization problems.
/** \class NewtonSolver NewtonSolver.hh <ACG/.../NewtonSolver.hh>
Solves an interior point problem, given an NProblemInterface
instance and optionally a set of constraints as well as "lazy
constraints" via NConstraintInterface.
Brief Description.
A more elaborate description follows.
Lazy constraints are not active while the initial solution to the
problem is computed. After the first solution is found, the lazy
constraints are checked and added to the set of active constraints
if they are violated. This process is then repeated until all
constraints are satisfied OR a maximum number of solution attempts
has been reached. In that case the optimization is started once
more, with all lazy constraints active.
*/
class
COMISODLLEXPORT
IPOPTSolver
{
public:
/// Default constructor -> set up IpOptApplication
IPOPTSolver
();
// ********** SOLVE **************** //
// solve -> returns ipopt status code
//------------------------------------------------------
// enum ApplicationReturnStatus
// {
// Solve_Succeeded=0,
// Solved_To_Acceptable_Level=1,
// Infeasible_Problem_Detected=2,
// Search_Direction_Becomes_Too_Small=3,
// Diverging_Iterates=4,
// User_Requested_Stop=5,
// Feasible_Point_Found=6,
//
// Maximum_Iterations_Exceeded=-1,
// Restoration_Failed=-2,
// Error_In_Step_Computation=-3,
// Maximum_CpuTime_Exceeded=-4,
// Not_Enough_Degrees_Of_Freedom=-10,
// Invalid_Problem_Definition=-11,
// Invalid_Option=-12,
// Invalid_Number_Detected=-13,
//
// Unrecoverable_Exception=-100,
// NonIpopt_Exception_Thrown=-101,
// Insufficient_Memory=-102,
// Internal_Error=-199
// };
//------------------------------------------------------
int
solve
(
NProblemInterface
*
_problem
,
const
std
::
vector
<
NConstraintInterface
*>&
_constraints
);
// same as above with additional lazy constraints that are only added iteratively to the problem if not satisfied
int
solve
(
NProblemInterface
*
_problem
,
const
std
::
vector
<
NConstraintInterface
*>&
_constraints
,
const
std
::
vector
<
NConstraintInterface
*>&
_lazy_constraints
,
const
double
_almost_infeasible
=
0.5
,
const
int
_max_passes
=
5
);
// for convenience, if no constraints are given
int
solve
(
NProblemInterface
*
_problem
);
// deprecated interface for backwards compatibility
int
solve
(
NProblemGmmInterface
*
_problem
,
std
::
vector
<
NConstraintInterface
*>&
_constraints
);
// ********* CONFIGURATION ********************* //
// access the ipopt-application (for setting parameters etc.)
// examples: app().Options()->SetIntegerValue("max_iter", 100);
// app().Options()->SetStringValue("derivative_test", "second-order");
// app().Options()->SetStringValue("hessian_approximation", "limited-memory");
IPOPTSolver
();
~
IPOPTSolver
();
// *********** OPTIONS **************//
/*!
Set options of the underlying ipopt solver.
For a thorough list and documentation of available options, refer
to: https://www.coin-or.org/Ipopt/documentation/node40.html
*/
void
set_ipopt_option
(
std
::
string
,
const
int
&
);
void
set_ipopt_option
(
std
::
string
,
const
double
&
);
void
set_ipopt_option
(
std
::
string
,
const
std
::
string
&
);
/*!
Get options of the underlying ipopt solver.
The type of option {int, double, std::string} needs to be passed as
template argument.
*/
template
<
typename
T
>
T
get_ipopt_option
(
std
::
string
option
);
/*!
Set the maximum number of iterations
*/
void
set_max_iterations
(
const
int
_max_iterations
);
int
get_max_iterations
()
const
;
/*! Set the threshold on the lazy inequality constraint to decide
if we are near the constraint boundary.
*/
void
set_almost_infeasible_threshold
(
const
double
_alm_infsb_thrsh
);
double
get_almost_infeasible_threshold
()
const
;
/*!
Set the max number of incremental lazy constraint iterations before switching
to the fully constrained problem.
\note The default value is 5.
*/
void
set_incremental_lazy_constraint_max_iteration_number
(
const
int
_incr_lazy_cnstr_max_iter_nmbr
);
int
get_incremental_lazy_constraint_max_iteration_number
()
const
;
/*
Turn on/off solving the fully constraint problem after exhausting the
incremental lazy constraint iterations.
\note The default value of this is true.
*/
void
set_enable_all_lazy_contraints
(
const
bool
_enbl_all_lzy_cnstr
);
bool
get_enable_all_lazy_contraints
()
const
;
/*
Set intermediate callback function object. For the definition of
IPOPTCallbackParameters include the IPOPTCallbackParameters.hh
header.
If the callback function returns false, IPOPT will terminate
prematurely with the User_Requested_Stop status.
*/
void
set_callback_function
(
std
::
function
<
bool
(
const
IPOPTCallbackParameters
&
)
>
);
Ipopt
::
IpoptApplication
&
app
()
{
return
(
*
app_
);
}
// ********** SOLVE **************** //
//! Solve a problem instance with an optional set of constraints.
//! \throws Outcome
void
solve
(
NProblemInterface
*
_problem
,
const
std
::
vector
<
NConstraintInterface
*>&
_constraints
=
{});
void
set_print_level
(
const
int
_level
)
{
app
().
Options
()
->
SetIntegerValue
(
"print_level"
,
_level
);
print_level_
=
_level
;
}
//! Same as above with additional lazy constraints that are only
//! added iteratively to the problem if not satisfied.
//! \throws Outcome
void
solve
(
NProblemInterface
*
_problem
,
const
std
::
vector
<
NConstraintInterface
*>&
_constraints
,
const
std
::
vector
<
NConstraintInterface
*>&
_lazy_constraints
);
protected:
double
*
P
(
std
::
vector
<
double
>&
_v
)
{
if
(
!
_v
.
empty
())
return
((
double
*
)
&
_v
[
0
]);
else
return
0
;
}
//! Get the computed solution energy
double
energy
();
private:
class
Impl
;
Impl
*
impl_
;
// smart pointer to IpoptApplication to set options etc.
Ipopt
::
SmartPtr
<
Ipopt
::
IpoptApplication
>
app_
;
int
print_level_
;
// inhibit copy
IPOPTSolver
(
const
IPOPTSolver
&
);
IPOPTSolver
&
operator
=
(
const
IPOPTSolver
&
);
};
//=============================================================================
}
// namespace COMISO
//=============================================================================
#endif // COMISO_IPOPT_AVAILABLE
//=============================================================================
#endif //
ACG
_IPOPTSOLVER_HH defined
#endif //
COMISO
_IPOPTSOLVER_HH defined
//=============================================================================
NSolver/IPOPTSolverLean.cc
deleted
100644 → 0
View file @
45f2b252
//=============================================================================
//
// CLASS IPOPTSolverLean - IMPLEMENTATION
//
//=============================================================================
//== INCLUDES =================================================================
//== COMPILE-TIME PACKAGE REQUIREMENTS ========================================
#include <CoMISo/Config/config.hh>
#if COMISO_IPOPT_AVAILABLE
//=============================================================================
#include "NProblemGmmInterface.hh"
#include "NProblemInterface.hh"
#include "NConstraintInterface.hh"
#include "BoundConstraint.hh"
#include "CoMISo/Utils/CoMISoError.hh"
#include <Base/Debug/DebConfig.hh>
#include <Base/Debug/DebTime.hh>
#include <CoMISo/Utils/gmm.hh>
#include <IpTNLP.hpp>
#include <IpIpoptApplication.hpp>
#include <IpSolveStatistics.hpp>
#include "IPOPTProblemInstance.hh"
#include "IPOPTSolverLean.hh"
//== NAMESPACES ===============================================================
namespace
COMISO
{
//== IMPLEMENTATION ===========================================================
class
IPOPTSolverLean
::
Impl
{
public:
Impl
()
:
app_
(
IpoptApplicationFactory
()),
// Create an instance of IpoptApplication
alm_infsb_thrsh_
(
0.5
),
incr_lazy_cnstr_max_iter_nmbr_
(
5
),
enbl_all_lzy_cnstr_
(
true
)
{
setup_ipopt_defaults
();
}
void
set_ipopt_option
(
std
::
string
,
const
int
&
);
void
set_ipopt_option
(
std
::
string
,
const
double
&
);
void
set_ipopt_option
(
std
::
string
,
const
std
::
string
&
);
template
<
typename
T
>
T
get_ipopt_option
(
std
::
string
);
private:
void
setup_ipopt_defaults
();
public:
Ipopt
::
SmartPtr
<
Ipopt
::
IpoptApplication
>
app_
;
std
::
function
<
bool
(
const
IPOPTCallbackParameters
&
)
>
intermediate_callback_
;
double
alm_infsb_thrsh_
;
int
incr_lazy_cnstr_max_iter_nmbr_
;
bool
enbl_all_lzy_cnstr_
;
private:
// default ipopt options
static
const
std
::
string
ipopt_default_hsl_solver
;
static
const
int
ipopt_default_max_iter
;
static
const
int
ipopt_default_mumps_mem_percent
;
};
const
std
::
string
IPOPTSolverLean
::
Impl
::
ipopt_default_hsl_solver
=
"ma57"
;
const
int
IPOPTSolverLean
::
Impl
::
ipopt_default_max_iter
=
200
;
const
int
IPOPTSolverLean
::
Impl
::
ipopt_default_mumps_mem_percent
=
5
;
void
IPOPTSolverLean
::
Impl
::
set_ipopt_option
(
std
::
string
option
,
const
int
&
value
)
{
app_
->
Options
()
->
SetIntegerValue
(
option
,
value
);
}
void
IPOPTSolverLean
::
Impl
::
set_ipopt_option
(
std
::
string
option
,
const
double
&
value
)
{
app_
->
Options
()
->
SetNumericValue
(
option
,
value
);
}
void
IPOPTSolverLean
::
Impl
::
set_ipopt_option
(
std
::
string
option
,
const
std
::
string
&
value
)
{
app_
->
Options
()
->
SetStringValue
(
option
,
value
);
}
template
<
typename
T
>
T
IPOPTSolverLean
::
Impl
::
get_ipopt_option
(
std
::
string
)
{
// @TODO print warning about unsupported option type!
}
template
<
>
int
IPOPTSolverLean
::
Impl
::
get_ipopt_option
<
int
>
(
std
::
string
option
)
{
int
value
;
app_
->
Options
()
->
GetIntegerValue
(
option
,
value
,
""
);
return
value
;
}
template
<
>
double
IPOPTSolverLean
::
Impl
::
get_ipopt_option
<
double
>
(
std
::
string
option
)
{
double
value
;
app_
->
Options
()
->
GetNumericValue
(
option
,
value
,
""
);
return
value
;
}
template
<
>
std
::
string
IPOPTSolverLean
::
Impl
::
get_ipopt_option
<
std
::
string
>
(
std
::
string
option
)
{
std
::
string
value
;
app_
->
Options
()
->
GetStringValue
(
option
,
value
,
""
);
return
value
;
}
void
IPOPTSolverLean
::
Impl
::
setup_ipopt_defaults
()
{
// Switch to HSL if available
#if COMISO_HSL_AVAILABLE
set_ipopt_option
(
"linear_solver"
,
ipopt_default_hsl_solver
);
#else
set_ipopt_option
(
"linear_solver"
,
"mumps"
);
#endif
#ifdef DEB_ON
if
(
!
Debug
::
Config
::
query
().
console
())
#endif
{
// Block any output on cout and cerr from Ipopt.
set_ipopt_option
(
"suppress_all_output"
,
"yes"
);
}
#ifdef WIN32
// Restrict memory to be able to run larger problems on windows
// with the default mumps solver
// TODO: find out what this does and whether it makes sense to do it
set_ipopt_option
(
"mumps_mem_percent"
,
ipopt_default_mumps_mem_percent
);
#endif
// set maximum solver iterations
set_ipopt_option
(
"max_iter"
,
ipopt_default_max_iter
);
}
//-----------------------------------------------------------------------------
IPOPTSolverLean
::
IPOPTSolverLean
()
:
impl_
(
new
Impl
)
{
}
IPOPTSolverLean
::
~
IPOPTSolverLean
()
{
delete
impl_
;
}
void
IPOPTSolverLean
::
set_ipopt_option
(
std
::
string
option
,
const
int
&
value
)
{
impl_
->
set_ipopt_option
(
option
,
value
);
}
void
IPOPTSolverLean
::
set_ipopt_option
(
std
::
string
option
,
const
double
&
value
)
{
impl_
->
set_ipopt_option
(
option
,
value
);
}
void
IPOPTSolverLean
::
set_ipopt_option
(
std
::
string
option
,
const
std
::
string
&
value
)
{
impl_
->
set_ipopt_option
(
option
,
value
);
}
template
<
typename
T
>
T
IPOPTSolverLean
::
get_ipopt_option
(
std
::
string
option
)
{
return
impl_
->
get_ipopt_option
<
T
>
(
option
);
}
template
int
IPOPTSolverLean
::
get_ipopt_option
<
int
>(
std
::
string
);
template
double
IPOPTSolverLean
::
get_ipopt_option
<
double
>(
std
::
string
);
template
std
::
string
IPOPTSolverLean
::
get_ipopt_option
<
std
::
string
>(
std
::
string
);
void
IPOPTSolverLean
::
set_max_iterations
(
const
int
_max_iterations
)
{
impl_
->
set_ipopt_option
(
"max_iter"
,
_max_iterations
);
}
int
IPOPTSolverLean
::
get_max_iterations
()
const
{
return
impl_
->
get_ipopt_option
<
int
>
(
"max_iter"
);
}
void
IPOPTSolverLean
::
set_almost_infeasible_threshold
(
const
double
_alm_infsb_thrsh
)
{
impl_
->
alm_infsb_thrsh_
=
_alm_infsb_thrsh
;
}
double
IPOPTSolverLean
::
get_almost_infeasible_threshold
()
const
{
return
impl_
->
alm_infsb_thrsh_
;
}
void
IPOPTSolverLean
::
set_incremental_lazy_constraint_max_iteration_number
(
const
int
_incr_lazy_cnstr_max_iter_nmbr
)
{
impl_
->
incr_lazy_cnstr_max_iter_nmbr_
=
_incr_lazy_cnstr_max_iter_nmbr
;
}
int
IPOPTSolverLean
::
get_incremental_lazy_constraint_max_iteration_number
()
const
{
return
impl_
->
incr_lazy_cnstr_max_iter_nmbr_
;
}
void
IPOPTSolverLean
::
set_enable_all_lazy_contraints
(
const
bool
_enbl_all_lzy_cnstr
)
{
impl_
->
enbl_all_lzy_cnstr_
=
_enbl_all_lzy_cnstr
;
}
bool
IPOPTSolverLean
::
get_enable_all_lazy_contraints
()
const
{
return
impl_
->
enbl_all_lzy_cnstr_
;
}
void
IPOPTSolverLean
::
set_callback_function
(
std
::
function
<
bool
(
const
IPOPTCallbackParameters
&
)
>
func
)
{
impl_
->
intermediate_callback_
=
func
;
}
static
void
throw_ipopt_solve_failure
(
Ipopt
::
ApplicationReturnStatus
const
status
)
{
DEB_enter_func
DEB_error
(
" IPOPT solve failure code is "
<<
status
)
// TODO: we could translate these return codes, but will not do it for now
// enum ApplicationReturnStatus
// {
// Solve_Succeeded=0,
// Solved_To_Acceptable_Level=1,
// Infeasible_Problem_Detected=2,
// Search_Direction_Becomes_Too_Small=3,
// Diverging_Iterates=4,
// User_Requested_Stop=5,
// Feasible_Point_Found=6,
//
// Maximum_Iterations_Exceeded=-1,
// Restoration_Failed=-2,
// Error_In_Step_Computation=-3,
// Maximum_CpuTime_Exceeded=-4,
// Not_Enough_Degrees_Of_Freedom=-10,
// Invalid_Problem_Definition=-11,
// Invalid_Option=-12,
// Invalid_Number_Detected=-13,
//
// Unrecoverable_Exception=-100,
// NonIpopt_Exception_Thrown=-101,
// Insufficient_Memory=-102,
// Internal_Error=-199
// };
//------------------------------------------------------
switch
(
status
)
{
case
Ipopt
::
Maximum_Iterations_Exceeded
:
COMISO_THROW
(
IPOPT_MAXIMUM_ITERATIONS_EXCEEDED
);
case
Ipopt
::
NonIpopt_Exception_Thrown
:
// this could be due to a thrown PROGRESS_ABORTED exception, ...
PROGRESS_RESUME_ABORT
;
// ... so check if we need to resume it
default:
COMISO_THROW
(
IPOPT_OPTIMIZATION_FAILED
);
}
}
static
void
check_ipopt_status
(
Ipopt
::
ApplicationReturnStatus
const
_stat
)
{
if
(
_stat
!=
Ipopt
::
Solve_Succeeded
&&
_stat
!=
Ipopt
::
Solved_To_Acceptable_Level
)
throw_ipopt_solve_failure
(
_stat
);
}
void
IPOPTSolverLean
::
solve
(
NProblemInterface
*
_problem
,
const
std
::
vector
<
NConstraintInterface
*>&
_constraints
)
{
DEB_time_func_def
;
//----------------------------------------------------------------------------
// 1. Create an instance of IPOPT NLP
//----------------------------------------------------------------------------
Ipopt
::
SmartPtr
<
Ipopt
::
TNLP
>
np
=
new
IPOPTProblemInstance
(
_problem
,
_constraints
);
IPOPTProblemInstance
*
np2
=
dynamic_cast
<
IPOPTProblemInstance
*>
(
Ipopt
::
GetRawPtr
(
np
));
np2
->
set_callback_function
(
impl_
->
intermediate_callback_
);
//----------------------------------------------------------------------------
// 2. exploit special characteristics of problem
//----------------------------------------------------------------------------
DEB_out
(
2
,
"exploit detected special properties: "
);
if
(
np2
->
hessian_constant
())
{
DEB_out
(
2
,
"*constant hessian* "
);
impl_
->
app_
->
Options
()
->
SetStringValue
(
"hessian_constant"
,
"yes"
);
}
if
(
np2
->
jac_c_constant
())
{
DEB_out
(
2
,
"*constant jacobian of equality constraints* "
);
impl_
->
app_
->
Options
()
->
SetStringValue
(
"jac_c_constant"
,
"yes"
);
}
if
(
np2
->
jac_d_constant
())
{
DEB_out
(
2
,
"*constant jacobian of in-equality constraints*"
);
impl_
->
app_
->
Options
()
->
SetStringValue
(
"jac_d_constant"
,
"yes"
);