65#include "IpoptConfig.h"
67#if defined(__GNUC__) && IPOPT_VERSION_MAJOR == 3 && IPOPT_VERSION_MINOR < 14
68#pragma GCC diagnostic ignored "-Wshadow"
70#include "IpIpoptApplication.hpp"
71#include "IpIpoptCalculatedQuantities.hpp"
72#include "IpSolveStatistics.hpp"
73#include "IpJournalist.hpp"
74#include "IpIpoptData.hpp"
75#include "IpTNLPAdapter.hpp"
76#include "IpOrigIpoptNLP.hpp"
77#include "IpLapack.hpp"
78#if defined(__GNUC__) && IPOPT_VERSION_MAJOR == 3 && IPOPT_VERSION_MINOR < 14
79#pragma GCC diagnostic warning "-Wshadow"
82#if IPOPT_VERSION_MAJOR < 3 || (IPOPT_VERSION_MAJOR == 3 && IPOPT_VERSION_MINOR < 12)
83#error "The Ipopt interface requires at least 3.12.0"
92#if defined(SCIP_THREADSAFE) && __cplusplus >= 201103L && IPOPT_VERSION_MAJOR == 3 && IPOPT_VERSION_MINOR < 14
93#define PROTECT_SOLVE_BY_MUTEX
95static std::mutex solve_mutex;
100#define NLPI_NAME "ipopt"
101#define NLPI_DESC "Ipopt interface"
102#define NLPI_PRIORITY 1000
104#define MAXPERTURB 0.01
105#define FEASTOLFACTOR 0.9
107#define DEFAULT_RANDSEED 71
153 "linear_system_scaling",
154 "nlp_scaling_method",
156 "hessian_approximation"
169 explicit SCIP_NlpiData()
170 : optfile(
NULL), print_level(-1), warm_start_push(1e-9)
221class ScipNLP :
public TNLP
231 int conv_lastrestoiter;
233 unsigned int current_x;
234 unsigned int last_f_eval_x;
235 unsigned int last_g_eval_x;
246 : nlpiproblem(nlpiproblem_), scip(scip_),
247 conv_lastrestoiter(-1),
248 current_x(1), last_f_eval_x(0), last_g_eval_x(0),
260 void initializeSolve(
266 nlpiproblem = nlpiproblem_;
281 IndexStyleEnum& index_style
285 bool get_bounds_info(
295 bool get_starting_point(
308 Index get_number_of_nonlinear_variables();
311 bool get_list_of_nonlinear_variables(
312 Index num_nonlin_vars,
313 Index* pos_nonlin_vars
317 bool get_var_con_metadata(
319 StringMetaDataMapType& var_string_md,
320 IntegerMetaDataMapType& var_integer_md,
321 NumericMetaDataMapType& var_numeric_md,
323 StringMetaDataMapType& con_string_md,
324 IntegerMetaDataMapType& con_integer_md,
325 NumericMetaDataMapType& con_numeric_md
381 const Number* lambda,
395 bool intermediate_callback(
403 Number regularization_size,
407 const IpoptData* ip_data,
408 IpoptCalculatedQuantities* ip_cq
412 void finalize_solution(
420 const Number* lambda,
422 const IpoptData* data,
423 IpoptCalculatedQuantities* cq
428class ScipJournal :
public Ipopt::Journal {
435 Ipopt::EJournalLevel default_level,
438 : Ipopt::Journal(name, default_level),
447 Ipopt::EJournalCategory category,
448 Ipopt::EJournalLevel level,
452 if( level == J_ERROR )
464 Ipopt::EJournalCategory category,
465 Ipopt::EJournalLevel level,
470 if( level == J_ERROR )
481 void FlushBufferImpl() { }
531 SCIPdebugMsg(
scip,
"Disable warmstart as no primal or dual solution available.\n");
550 warmstart ?
"warm" :
"cold",
555 SCIPdebugMsg(
scip,
"Starting solution for coldstart not available. Making up something by projecting 0 onto variable bounds and adding a random perturbation.\n");
569 for(
int i = 0;
i < n; ++
i )
597 if( nlpidata->print_level < 0 )
602 (void) nlpiproblem->
ipopt->Options()->SetIntegerValue(
"print_level", J_ERROR);
605 (void) nlpiproblem->
ipopt->Options()->SetIntegerValue(
"print_level", J_SUMMARY);
608 (void) nlpiproblem->
ipopt->Options()->SetIntegerValue(
"print_level", J_ITERSUMMARY);
611 (void) nlpiproblem->
ipopt->Options()->SetIntegerValue(
"print_level", J_DETAILED);
614 (void) nlpiproblem->
ipopt->Options()->SetIntegerValue(
"print_level",
MIN(J_ITERSUMMARY + (param.
verblevel-1), J_ALL));
619#ifdef SCIP_DISABLED_CODE
622 if( nlpidata->autoiterlim > 0 )
640 for(
int i = 0;
i < n; ++
i )
660 for(
int i = 0;
i < m; ++
i )
703 -0.0021259769 * jacnnz +2.0121042012 * sqrt(jacnnz)
704 -0.0374801925 * nlincons +2.9562232443 * sqrt(nlincons)
705 -0.0133039200 * nnlcons -0.0412118434 * sqrt(nnlcons)
706 -0.0702890379 * nnlvars +7.0920920430 * sqrt(nnlvars)
707 +0.0183592749 * nvarbnd -4.7218258847 * sqrt(nvarbnd)
708 +0.0112944627 *
nvars -0.8365873360 * sqrt(
nvars));
714 if( nlpidata->print_level >= J_SUMMARY || param.
verblevel > 0 )
718 (void) nlpiproblem->
ipopt->Options()->SetIntegerValue(
"max_iter", param.
iterlimit);
730 (void) nlpiproblem->
ipopt->Options()->SetNumericValue(
"dual_inf_tol", param.
opttol);
731 (void) nlpiproblem->
ipopt->Options()->SetNumericValue(
"compl_inf_tol", param.
opttol);
733 (void) nlpiproblem->
ipopt->Options()->SetNumericValue(
"tol", param.
solvertol);
735#if IPOPT_VERSION_MAJOR > 3 || IPOPT_VERSION_MINOR > 14 || (IPOPT_VERSION_MINOR == 14 && IPOPT_VERSION_RELEASE >= 2)
736 (void) nlpiproblem->
ipopt->Options()->UnsetValue(
"tol");
738 (void) nlpiproblem->
ipopt->Options()->SetNumericValue(
"tol", 1e-8);
742#if IPOPT_VERSION_MAJOR > 3 || IPOPT_VERSION_MINOR >= 14
743 (void) nlpiproblem->
ipopt->Options()->SetNumericValue(
"max_wall_time",
MAX(param.
timelimit, DBL_MIN));
745 (void) nlpiproblem->
ipopt->Options()->SetNumericValue(
"max_cpu_time",
MAX(param.
timelimit, DBL_MIN));
751 (void) nlpiproblem->
ipopt->Options()->SetIntegerValue(
"acceptable_iter", 0);
753#if IPOPT_VERSION_MAJOR > 3 || IPOPT_VERSION_MINOR > 14 || (IPOPT_VERSION_MINOR == 14 && IPOPT_VERSION_RELEASE >= 2)
754 (void) nlpiproblem->
ipopt->Options()->UnsetValue(
"acceptable_iter");
756 (void) nlpiproblem->
ipopt->Options()->SetIntegerValue(
"acceptable_iter", 15);
759 (void) nlpiproblem->
ipopt->Options()->SetStringValue(
"expect_infeasible_problem", param.
expectinfeas ?
"yes" :
"no");
761 if( !nlpiproblem->
ipopt->Options()->SetStringValue(
"warm_start_init_point", param.
warmstart ?
"yes" :
"no") && !param.
warmstart )
764 SCIPerrorMessage(
"Failed to set Ipopt warm_start_init_point option to no.");
771#ifdef COLLECT_SOLVESTATS
774void collectStatistic(
776 ApplicationReturnStatus status,
778 SmartPtr<SolveStatistics> stats
797 for(
int i = 0;
i < n; ++
i )
822 for(
int i = 0;
i < m; ++
i )
864 for(
int i = 0;
i < n; ++
i )
865 for(
int j = offset[
i]; j < offset[
i+1]; ++j )
869 linsys11nz += 2 * (jacnnz + nslacks);
873 linsys13nz = linsys11nz + m;
879 problem->
ipopt->Options()->GetBoolValue(
"expect_infeasible_problem", expectinfeas,
"");
881 static bool firstwrite =
true;
884 printf(
"IPOPTSTAT status,iter,time,nvars,nnlvars,nvarlb,nvarub,nlincons,nnlcons,objnl,jacnnz,hesnnz,linsys11nz,linsys13nz,linsys11density,linsys13density,expectinfeas\n");
888 printf(
"IPOPTSTAT %d,%d,%g,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%f,%f,%d\n",
889 status, stats->IterationCount(), stats->TotalWallclockTime(),
890 nvars, nnlvars, nvarlb, nvarub, nlincons, nnlcons, objnl, jacnnz, hesnnz, linsys11nz, linsys13nz, linsys11density, linsys13density, expectinfeas);
919 if( problem ==
NULL )
922 return (
void*)GetRawPtr(problem->
ipopt);
945 (*problem)->ipopt =
new IpoptApplication(
false);
948 SmartPtr<Journal> jrnl =
new ScipJournal(
"console", J_ITERSUMMARY,
scip);
949 jrnl->SetPrintLevel(J_DBG, J_NONE);
950 if( !(*problem)->ipopt->Jnlst()->AddJournal(jrnl) )
956 (*problem)->nlp =
new ScipNLP(*problem,
scip);
958 catch(
const std::bad_alloc& )
981 if( *paramval !=
'\0' )
1002 (void) (*problem)->ipopt->Options()->SetIntegerValue(
ipopt_int_params[
i], paramval,
false);
1005#if IPOPT_VERSION_MAJOR == 3 && IPOPT_VERSION_MINOR < 14
1009 (void) (*problem)->ipopt->Options()->SetNumericValue(
"bound_relax_factor", 0.0);
1015 (void) (*problem)->ipopt->Options()->SetStringValue(
"print_user_options",
"yes");
1017 (void) (*problem)->ipopt->Options()->SetStringValue(
"sb",
"yes");
1018 (void) (*problem)->ipopt->Options()->SetStringValueIfUnset(
"mu_strategy",
"adaptive");
1019 (void) (*problem)->ipopt->Options()->SetIntegerValue(
"max_iter", INT_MAX);
1020 (void) (*problem)->ipopt->Options()->SetNumericValue(
"nlp_lower_bound_inf", -
SCIPinfinity(
scip),
false);
1021 (void) (*problem)->ipopt->Options()->SetNumericValue(
"nlp_upper_bound_inf",
SCIPinfinity(
scip),
false);
1022 (void) (*problem)->ipopt->Options()->SetNumericValue(
"diverging_iterates_tol",
SCIPinfinity(
scip),
false);
1025 (void) (*problem)->ipopt->Options()->SetNumericValue(
"warm_start_bound_push", data->warm_start_push);
1026 (void) (*problem)->ipopt->Options()->SetNumericValue(
"warm_start_bound_frac", data->warm_start_push);
1027 (void) (*problem)->ipopt->Options()->SetNumericValue(
"warm_start_slack_bound_push", data->warm_start_push);
1028 (void) (*problem)->ipopt->Options()->SetNumericValue(
"warm_start_slack_bound_frac", data->warm_start_push);
1029 (void) (*problem)->ipopt->Options()->SetNumericValue(
"warm_start_mult_bound_push", data->warm_start_push);
1033 if( (*problem)->ipopt->Initialize(data->optfile) != Solve_Succeeded )
1035 SCIPerrorMessage(
"Error during initialization of Ipopt using optionfile \"%s\"\n", data->optfile);
1064 if( (*problem)->randnumgen !=
NULL )
1069#ifdef PRINT_NLPSTATS
1070 SCIPinfoMessage(
scip,
NULL,
"\nNLP solver IPOPT stats: ncalls = %d, nsuccess = %d, nlimit = %d, nlocinfeas = %d, nother = %d\n",
1071 (*problem)->ncalls, (*problem)->nsuccess, (*problem)->nlimit, (*problem)->nlocinfeas, (*problem)->nother);
1087 return GetRawPtr(problem->
nlp);
1182 if( (oldlb == oldub) != (lbs[
i] == ubs[
i]) )
1222 if( (oldlhs == oldrhs) != (lhss[
i] == rhss[
i]) )
1260 for(
i = 0;
i < dstatssize; ++
i )
1262 if( dstats[
i] != -1 )
1320 for(
i = 0;
i < dstatssize; ++
i )
1322 if( dstats[
i] != -1 )
1391 problem->
solobjval += objconstant - oldconstant;
1408 if( primalvalues !=
NULL )
1425 SCIPdebugMsg(
scip,
"invalidate initial guess primal values on user-request\n");
1431 if( consdualvalues !=
NULL && varlbdualvalues !=
NULL && varubdualvalues !=
NULL )
1472 ApplicationReturnStatus status;
1485 if( nlpidata->print_level >= J_SUMMARY || param.verblevel > 0 )
1493 if( param.timelimit == 0.0 )
1504#ifdef COLLECT_SOLVESTATS
1507 param.iterlimit = 1000;
1518 problem->
nlp->initializeSolve(problem, param);
1525#ifdef PROTECT_SOLVE_BY_MUTEX
1529 std::unique_lock<std::mutex> guard(solve_mutex, std::defer_lock);
1530 std::string linsolver;
1531 (void) problem->
ipopt->Options()->GetStringValue(
"linear_solver", linsolver,
"");
1532 if( linsolver ==
"mumps" )
1550 SCIPerrorMessage(
"Do not have expression interpreter that can compute function values and gradients. Cannot solve NLP with Ipopt.\n");
1559 (void) problem->
ipopt->Options()->SetStringValueIfUnset(
"hessian_approximation",
"limited-memory");
1560 problem->
nlp->approxhessian =
true;
1563 problem->
nlp->approxhessian =
false;
1567 problem->
ipopt->Options()->SetStringValue(
"derivative_test", problem->
nlp->approxhessian ?
"first-order" :
"second-order");
1570 status = problem->
ipopt->OptimizeTNLP(GetRawPtr(problem->
nlp));
1575 problem->
ipopt->Options()->SetStringValue(
"warm_start_same_structure", problem->
samestructure ?
"yes" :
"no");
1576 status = problem->
ipopt->ReOptimizeTNLP(GetRawPtr(problem->
nlp));
1582 case Solve_Succeeded:
1583 case Solved_To_Acceptable_Level:
1584 case Infeasible_Problem_Detected:
1585 case Search_Direction_Becomes_Too_Small:
1586 case Diverging_Iterates:
1587 case User_Requested_Stop:
1588 case Feasible_Point_Found:
1589 case Maximum_Iterations_Exceeded:
1590 case Restoration_Failed:
1591 case Error_In_Step_Computation:
1592 case Maximum_CpuTime_Exceeded:
1593#if IPOPT_VERSION_MAJOR > 3 || IPOPT_VERSION_MINOR >= 14
1594 case Maximum_WallTime_Exceeded:
1604 case Not_Enough_Degrees_Of_Freedom:
1610 case Invalid_Number_Detected:
1611 SCIPdebugMsg(
scip,
"Ipopt failed because of an invalid number in function or derivative value\n");
1620 case Insufficient_Memory:
1627 case Unrecoverable_Exception:
1628 case Internal_Error:
1631 SCIPerrorMessage(
"Ipopt returned with application return status %d\n", status);
1635 case Invalid_Problem_Definition:
1636 case Invalid_Option:
1637 case NonIpopt_Exception_Thrown:
1640 SCIPerrorMessage(
"Ipopt returned with application return status %d\n", status);
1644#if IPOPT_VERSION_MAJOR == 3 && IPOPT_VERSION_MINOR < 14
1645 SmartPtr<SolveStatistics> stats = problem->
ipopt->Statistics();
1647 if( IsValid(stats) )
1649 problem->
lastniter = stats->IterationCount();
1650 problem->
lasttime = stats->TotalWallclockTime();
1652#ifdef COLLECT_SOLVESTATS
1653 collectStatistic(
scip, status, problem, stats);
1657 SmartPtr<IpoptData> ip_data = problem->
ipopt->IpoptDataObject();
1659 if( IsValid(ip_data) )
1661 problem->
lastniter = ip_data->iter_count();
1662 problem->
lasttime = ip_data->TimingStats().OverallAlgorithm().TotalWallclockTime();
1671 catch( IpoptException& except )
1673 SCIPerrorMessage(
"Ipopt returned with exception: %s\n", except.Message().c_str());
1707 if( primalvalues !=
NULL )
1710 if( consdualvalues !=
NULL )
1713 if( varlbdualvalues !=
NULL )
1716 if( varubdualvalues !=
NULL )
1733 statistics->niterations = problem->
lastniter;
1734 statistics->totaltime = problem->
lasttime;
1756 nlpiCopyIpopt, nlpiFreeIpopt, nlpiGetSolverPointerIpopt,
1757 nlpiCreateProblemIpopt, nlpiFreeProblemIpopt, nlpiGetProblemPointerIpopt,
1758 nlpiAddVarsIpopt, nlpiAddConstraintsIpopt, nlpiSetObjectiveIpopt,
1759 nlpiChgVarBoundsIpopt, nlpiChgConsSidesIpopt, nlpiDelVarSetIpopt, nlpiDelConstraintSetIpopt,
1760 nlpiChgLinearCoefsIpopt, nlpiChgExprIpopt,
1761 nlpiChgObjConstantIpopt, nlpiSetInitialGuessIpopt, nlpiSolveIpopt, nlpiGetSolstatIpopt, nlpiGetTermstatIpopt,
1762 nlpiGetSolutionIpopt, nlpiGetStatisticsIpopt,
1771 &nlpidata->warm_start_push,
FALSE, 1e-9, 0.0, 1.0,
NULL,
NULL) );
1773 SmartPtr<RegisteredOptions> reg_options =
new RegisteredOptions();
1774 IpoptApplication::RegisterAllIpoptOptions(reg_options);
1781 if( !IsValid(option) )
1784 assert(option->Type() == OT_String);
1791 std::stringstream descr;
1792 descr << option->ShortDescription();
1796 std::vector<RegisteredOption::string_entry> validvals = option->GetValidStrings();
1797 if( validvals.size() > 1 )
1799 descr <<
" Valid values if not empty:";
1800 for( std::vector<RegisteredOption::string_entry>::iterator val = validvals.begin(); val != validvals.end(); ++val )
1801 descr <<
' ' << val->value_;
1804#if IPOPT_VERSION_MAJOR > 3 || IPOPT_VERSION_MINOR >= 14
1806 advanced = option->Advanced();
1817 SmartPtr<const RegisteredOption> option = reg_options->GetOption(
ipopt_int_params[
i]);
1820 if( !IsValid(option) )
1823 assert(option->Type() == OT_Integer);
1829 int lower = option->LowerInteger();
1830 int upper = option->UpperInteger();
1837 std::stringstream descr;
1838 descr << option->ShortDescription();
1839 descr <<
' ' << (lower-1) <<
" to use NLPI or Ipopt default.";
1841#if IPOPT_VERSION_MAJOR > 3 || IPOPT_VERSION_MINOR >= 14
1843 advanced = option->Advanced();
1848 i == 0 ? &nlpidata->print_level :
NULL, advanced,
1849 lower-1, lower-1, upper,
NULL,
NULL) );
1858 return "Ipopt " IPOPT_VERSION;
1864 return "Interior Point Optimizer developed by A. Waechter et.al. (github.com/coin-or/Ipopt)";
1880 return nlpiproblem->
oracle;
1884bool ScipNLP::get_nlp_info(
1889 IndexStyleEnum& index_style
1906 nnz_jac_g = offset ==
NULL ? 0 : offset[m];
1908 if( !approxhessian )
1914 nnz_h_lag = offset[n];
1921 index_style = TNLP::C_STYLE;
1927bool ScipNLP::get_bounds_info(
1936 const int* varlincounts;
1937 const int* varnlcounts;
1951 for(
int i = 0;
i < n; ++
i )
1961 for(
int i = 0;
i < n; ++
i )
1963 if( varlincounts[
i] == 0 && varnlcounts[
i] == 0 )
1965 SCIPdebugMsg(scip,
"fix unused variable x%d [%g,%g] to 0.0 or bound\n",
i, x_l[
i], x_u[
i]);
1967 x_l[
i] = x_u[
i] =
MAX(
MIN(x_u[
i], 0.0), x_l[
i]);
1971 for(
int i = 0;
i < m; ++
i )
1982bool ScipNLP::get_starting_point(
2002 assert(nlpiproblem->solprimalvalid);
2009 assert(nlpiproblem->soldualvalid);
2018 assert(nlpiproblem->soldualvalid);
2027Index ScipNLP::get_number_of_nonlinear_variables()
2038 for(
int i = 0;
i < n; ++
i )
2046bool ScipNLP::get_list_of_nonlinear_variables(
2047 Index num_nonlin_vars,
2048 Index* pos_nonlin_vars
2060 for(
int i = 0;
i < n; ++
i )
2064 assert(count < num_nonlin_vars);
2065 pos_nonlin_vars[count++] =
i;
2069 assert(count == num_nonlin_vars);
2075bool ScipNLP::get_var_con_metadata(
2077 StringMetaDataMapType& var_string_md,
2078 IntegerMetaDataMapType& var_integer_md,
2079 NumericMetaDataMapType& var_numeric_md,
2081 StringMetaDataMapType& con_string_md,
2082 IntegerMetaDataMapType& con_integer_md,
2083 NumericMetaDataMapType& con_numeric_md
2092 if( varnames !=
NULL )
2094 std::vector<std::string>& varnamesvec(var_string_md[
"idx_names"]);
2095 varnamesvec.reserve((
size_t)n);
2096 for(
int i = 0;
i < n; ++
i )
2098 if( varnames[
i] !=
NULL )
2100 varnamesvec.push_back(varnames[
i]);
2106 varnamesvec.push_back(buffer);
2111 std::vector<std::string>& consnamesvec(con_string_md[
"idx_names"]);
2112 consnamesvec.reserve((
size_t)m);
2113 for(
int i = 0;
i < m; ++
i )
2123 consnamesvec.push_back(buffer);
2131bool ScipNLP::eval_f(
2145 last_f_eval_x = current_x;
2151bool ScipNLP::eval_grad_f(
2170 new_x = last_f_eval_x < current_x;
2174 last_f_eval_x = current_x;
2180bool ScipNLP::eval_g(
2195 last_g_eval_x = current_x;
2204bool ScipNLP::eval_jac_g(
2221 if( values ==
NULL )
2223 const int* jacoffset;
2235 if( jacoffset !=
NULL )
2237 assert(jacoffset[0] == 0);
2238 assert(jacoffset[m] == nele_jac);
2240 for(
i = 0;
i < m; ++
i )
2241 for( ; j < jacoffset[
i+1]; ++j )
2254 new_x = last_g_eval_x < current_x;
2258 last_f_eval_x = current_x;
2271bool ScipNLP::eval_h(
2277 const Number* lambda,
2291 if( values ==
NULL )
2293 const int* heslagoffset;
2294 const int* heslagcol;
2304 assert(heslagoffset[0] == 0);
2305 assert(heslagoffset[n] == nele_hess);
2306 j = heslagoffset[0];
2307 for(
i = 0;
i < n; ++
i )
2308 for( ; j < heslagoffset[
i+1]; ++j )
2315 bool new_x_obj = new_x;
2316 bool new_x_cons = new_x;
2323 new_x_obj = last_f_eval_x < current_x;
2324 new_x_cons = last_g_eval_x < current_x;
2327 last_f_eval_x = current_x;
2328 last_g_eval_x = current_x;
2343bool ScipNLP::intermediate_callback(
2351 Number regularization_size,
2355 const IpoptData* ip_data,
2356 IpoptCalculatedQuantities* ip_cq
2367 if( obj_value <= param.lobjlimit && inf_pr <= param.feastol )
2381 conv_lastrestoiter = -1;
2383 else if( mode == RestorationPhaseMode )
2385 conv_lastrestoiter = iter;
2387 else if( conv_lastrestoiter == iter-1 )
2409 if( inf_pr <= conv_prtarget[
i] )
2418 else if( iter >= conv_iterlim[
i] )
2421 SCIPdebugMsg(scip,
"convcheck %d: inf_pr = %e > target %e; inf_du = %e target %e: ",
2422 i, inf_pr, conv_prtarget[
i], inf_du, conv_dutarget[
i]);
2428 SCIPdebugPrintf(
"continue, because restoration phase only %d iters ago\n", iter - conv_lastrestoiter);
2430 else if( mode == RegularMode && inf_du <= conv_dutarget[
i] && iter < conv_iterlim[
i] +
convcheck_maxiter[
i] )
2433 SCIPdebugPrintf(
"continue, because dual infeas. red. sufficient and only %d iters above limit\n", iter - conv_iterlim[
i]);
2438 if( inf_pr <= param.feastol )
2454void ScipNLP::finalize_solution(
2455 SolverReturn status,
2462 const Number* lambda,
2464 const IpoptData* data,
2465 IpoptCalculatedQuantities* cq
2474 bool check_feasibility =
false;
2475 ++(nlpiproblem->ncalls);
2481 ++(nlpiproblem->nsuccess);
2485 case STOP_AT_ACCEPTABLE_POINT:
2487 case FEASIBLE_POINT_FOUND:
2490 ++(nlpiproblem->nsuccess);
2494 case MAXITER_EXCEEDED:
2495 check_feasibility =
true;
2498 ++(nlpiproblem->nlimit);
2501 case CPUTIME_EXCEEDED:
2502#if IPOPT_VERSION_MAJOR > 3 || IPOPT_VERSION_MINOR >= 14
2503 case WALLTIME_EXCEEDED:
2505 check_feasibility =
true;
2508 ++(nlpiproblem->nlimit);
2511 case STOP_AT_TINY_STEP:
2512 case RESTORATION_FAILURE:
2513 case ERROR_IN_STEP_COMPUTATION:
2514 check_feasibility =
true;
2517 ++(nlpiproblem->nother);
2520 case LOCAL_INFEASIBILITY:
2523 ++(nlpiproblem->nlocinfeas);
2526 case USER_REQUESTED_STOP:
2530 case DIVERGING_ITERATES:
2533 ++(nlpiproblem->nsuccess);
2540 case INVALID_NUMBER_DETECTED:
2544 check_feasibility =
true;
2547 ++(nlpiproblem->nother);
2550 case TOO_FEW_DEGREES_OF_FREEDOM:
2551 case INTERNAL_ERROR:
2552 case INVALID_OPTION:
2555 ++(nlpiproblem->nother);
2561 ++(nlpiproblem->nother);
2565 SCIPerrorMessage(
"Ipopt returned with unknown solution status %d\n", status);
2568 ++(nlpiproblem->nother);
2579 if( nlpiproblem->soldualcons ==
NULL )
2583 if( nlpiproblem->soldualvarlb ==
NULL )
2587 if( nlpiproblem->soldualvarub ==
NULL )
2591 if( nlpiproblem->soldualcons ==
NULL || nlpiproblem->soldualvarlb ==
NULL || nlpiproblem->soldualvarub ==
NULL )
2602 nlpiproblem->solobjval = obj_value;
2603 nlpiproblem->solprimalvalid =
true;
2604 nlpiproblem->solprimalgiven =
false;
2605 nlpiproblem->soldualvalid =
true;
2606 nlpiproblem->soldualgiven =
false;
2609#if IPOPT_VERSION_MAJOR == 3 && IPOPT_VERSION_MINOR < 14
2610 nlpiproblem->solboundviol = 0.0;
2614 nlpiproblem->solconsviol = 0.0;
2619 nlpiproblem->solboundviol = cq->unscaled_curr_orig_bounds_violation(Ipopt::NORM_MAX);
2623 nlpiproblem->solconsviol = cq->unscaled_curr_nlp_constraint_violation(Ipopt::NORM_MAX);
2625 if( check_feasibility )
2629 if(
MAX(nlpiproblem->solconsviol, nlpiproblem->solboundviol) <= param.feastol )
2635 catch(
const IpoptNLP::Eval_Error& exc )
2637 SCIPdebugMsg(scip,
"Eval error when checking constraint viol: %s\n", exc.Message().c_str());
2638 assert(status == INVALID_NUMBER_DETECTED);
2648 SCIPdebugMsg(scip,
"Unknown exception when checking constraint viol\n");
2649 assert(status == INVALID_NUMBER_DETECTED);
2658 (void) nlpiproblem->ipopt->Options()->GetNumericValue(
"tol", tol,
"");
2663 bool infreasonable =
true;
2665 for(
int i = 0;
i < m && infreasonable; ++
i )
2667 if( fabs(lambda[
i]) < tol )
2670 if( lambda[
i] < 0.0 )
2678 SCIPdebugMessage(
"inconsistent dual, lambda = %g, but lhs = %g\n", lambda[
i], side);
2679 infreasonable =
false;
2690 SCIPdebugMessage(
"inconsistent dual, lambda = %g, but rhs = %g\n", lambda[
i], side);
2691 infreasonable =
false;
2696 infproof += lambda[
i] * (g[
i] - side);
2701 SCIPdebugMessage(
"infproof = %g should be positive to be valid\n", infproof);
2702 if( infproof <= 0.0 )
2703 infreasonable =
false;
2706 if( !infreasonable )
2727#if IPOPT_VERSION_MAJOR == 3 && IPOPT_VERSION_MINOR < 14
2728 IpLapackDsyev((
bool)computeeigenvectors, N,
a, N,
w, info);
2730 IpLapackSyev((
bool)computeeigenvectors, N,
a, N,
w, info);
2735 SCIPerrorMessage(
"There was an error when calling DSYEV. INFO = %d\n", info);
2766#if IPOPT_VERSION_MAJOR == 3 && IPOPT_VERSION_MINOR < 14
2767 IpLapackDgetrf(N, Acopy, pivotcopy, N, info);
2769 IpLapackGetrf(N, Acopy, pivotcopy, N, info);
2774 SCIPdebugMessage(
"There was an error when calling Dgetrf. INFO = %d\n", info);
2782#if IPOPT_VERSION_MAJOR == 3 && IPOPT_VERSION_MINOR < 14
2783 IpLapackDgetrs(N, 1, Acopy, N, pivotcopy, bcopy, N);
2785 IpLapackGetrs(N, 1, Acopy, N, pivotcopy, bcopy, N);
2837#if IPOPT_VERSION_MAJOR == 3 && IPOPT_VERSION_MINOR < 14
2838 IpLapackDgetrf(N, Acopy, pivotcopy, N, info);
2840 IpLapackGetrf(N, Acopy, pivotcopy, N, info);
2845 SCIPdebugMessage(
"There was an error when calling Dgetrf. INFO = %d\n", info);
2853#if IPOPT_VERSION_MAJOR == 3 && IPOPT_VERSION_MINOR < 14
2854 IpLapackDgetrs(N, 1, Acopy, N, pivotcopy, bcopy, N);
2856 IpLapackGetrs(N, 1, Acopy, N, pivotcopy, bcopy, N);
#define SCIP_CALL_ABORT(x)
methods to interpret (evaluate) an expression "fast"
int SCIPgetSubscipDepth(SCIP *scip)
SCIP_EXPRINTCAPABILITY SCIPexprintGetCapability(void)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
SCIP_RETCODE SCIPincludeNlpSolverIpopt(SCIP *scip)
SCIP_RETCODE SCIPnlpiOracleEvalObjectiveValue(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Real *objval)
SCIP_RETCODE SCIPnlpiOracleChgLinearCoefs(SCIP *scip, SCIP_NLPIORACLE *oracle, int considx, int nentries, const int *varidxs, const SCIP_Real *newcoefs)
SCIP_RETCODE SCIPnlpiOracleGetJacobianRowSparsity(SCIP *scip, SCIP_NLPIORACLE *oracle, const int **rowoffsets, const int **cols, const SCIP_Bool **colnlflags, int *nnlnz)
SCIP_RETCODE SCIPnlpiOracleGetHessianLagSparsity(SCIP *scip, SCIP_NLPIORACLE *oracle, const int **offset, const int **allnz, SCIP_Bool colwise)
SCIP_RETCODE SCIPnlpiOracleChgVarBounds(SCIP *scip, SCIP_NLPIORACLE *oracle, int nvars, const int *indices, const SCIP_Real *lbs, const SCIP_Real *ubs)
SCIP_RETCODE SCIPnlpiOracleAddConstraints(SCIP *scip, SCIP_NLPIORACLE *oracle, int nconss, const SCIP_Real *lhss, const SCIP_Real *rhss, const int *nlininds, int *const *lininds, SCIP_Real *const *linvals, SCIP_EXPR **exprs, const char **consnames)
SCIP_Bool SCIPnlpiOracleIsConstraintNonlinear(SCIP_NLPIORACLE *oracle, int considx)
SCIP_RETCODE SCIPnlpiOracleDelVarSet(SCIP *scip, SCIP_NLPIORACLE *oracle, int *delstats)
SCIP_RETCODE SCIPnlpiOracleEvalConstraintValues(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Real *convals)
SCIP_RETCODE SCIPnlpiOracleCreate(SCIP *scip, SCIP_NLPIORACLE **oracle)
void SCIPnlpiOracleGetVarCounts(SCIP *scip, SCIP_NLPIORACLE *oracle, const int **lincounts, const int **nlcounts)
char * SCIPnlpiOracleGetConstraintName(SCIP_NLPIORACLE *oracle, int considx)
SCIP_RETCODE SCIPnlpiOracleEvalObjectiveGradient(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Bool isnewx, SCIP_Real *objval, SCIP_Real *objgrad)
SCIP_RETCODE SCIPnlpiOracleResetEvalTime(SCIP *scip, SCIP_NLPIORACLE *oracle)
SCIP_RETCODE SCIPnlpiOracleSetObjective(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real constant, int nlin, const int *lininds, const SCIP_Real *linvals, SCIP_EXPR *expr)
SCIP_Real SCIPnlpiOracleGetConstraintRhs(SCIP_NLPIORACLE *oracle, int considx)
SCIP_Real SCIPnlpiOracleGetEvalTime(SCIP *scip, SCIP_NLPIORACLE *oracle)
SCIP_RETCODE SCIPnlpiOracleChgConsSides(SCIP *scip, SCIP_NLPIORACLE *oracle, int nconss, const int *indices, const SCIP_Real *lhss, const SCIP_Real *rhss)
SCIP_Real SCIPnlpiOracleGetConstraintLhs(SCIP_NLPIORACLE *oracle, int considx)
SCIP_RETCODE SCIPnlpiOracleAddVars(SCIP *scip, SCIP_NLPIORACLE *oracle, int nvars, const SCIP_Real *lbs, const SCIP_Real *ubs, const char **varnames)
SCIP_RETCODE SCIPnlpiOracleEvalHessianLag(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Bool isnewx_obj, SCIP_Bool isnewx_cons, SCIP_Real objfactor, const SCIP_Real *lambda, SCIP_Real *hessian, SCIP_Bool colwise)
int SCIPnlpiOracleGetNVars(SCIP_NLPIORACLE *oracle)
int SCIPnlpiOracleGetNConstraints(SCIP_NLPIORACLE *oracle)
SCIP_EXPRINTCAPABILITY SCIPnlpiOracleGetEvalCapability(SCIP *scip, SCIP_NLPIORACLE *oracle)
SCIP_Real SCIPnlpiOracleGetObjectiveConstant(SCIP_NLPIORACLE *oracle)
SCIP_Bool SCIPnlpiOracleIsVarNonlinear(SCIP *scip, SCIP_NLPIORACLE *oracle, int varidx)
SCIP_RETCODE SCIPnlpiOracleEvalJacobian(SCIP *scip, SCIP_NLPIORACLE *oracle, const SCIP_Real *x, SCIP_Bool isnewx, SCIP_Real *convals, SCIP_Real *jacobi)
SCIP_RETCODE SCIPnlpiOracleDelConsSet(SCIP *scip, SCIP_NLPIORACLE *oracle, int *delstats)
SCIP_RETCODE SCIPnlpiOracleSetProblemName(SCIP *scip, SCIP_NLPIORACLE *oracle, const char *name)
SCIP_RETCODE SCIPnlpiOracleChgObjConstant(SCIP *scip, SCIP_NLPIORACLE *oracle, SCIP_Real objconstant)
char ** SCIPnlpiOracleGetVarNames(SCIP_NLPIORACLE *oracle)
const SCIP_Real * SCIPnlpiOracleGetVarLbs(SCIP_NLPIORACLE *oracle)
const SCIP_Real * SCIPnlpiOracleGetVarUbs(SCIP_NLPIORACLE *oracle)
SCIP_RETCODE SCIPnlpiOracleFree(SCIP *scip, SCIP_NLPIORACLE **oracle)
struct SCIP_NlpiOracle SCIP_NLPIORACLE
const char * SCIPnlpiOracleGetProblemName(SCIP_NLPIORACLE *oracle)
SCIP_RETCODE SCIPnlpiOracleChgExpr(SCIP *scip, SCIP_NLPIORACLE *oracle, int considx, SCIP_EXPR *expr)
const char * SCIPgetSolverNameIpopt(void)
SCIP_RETCODE SCIPcallLapackDsyevIpopt(SCIP_Bool computeeigenvectors, int N, SCIP_Real *a, SCIP_Real *w)
SCIP_RETCODE SCIPsolveLinearEquationsIpopt(int N, SCIP_Real *A, SCIP_Real *b, SCIP_Real *x, SCIP_Bool *success)
void * SCIPgetNlpiOracleIpopt(SCIP_NLPIPROBLEM *nlpiproblem)
SCIP_Bool SCIPisIpoptAvailableIpopt(void)
const char * SCIPgetSolverDescIpopt(void)
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
SCIP_PARAM * SCIPgetParam(SCIP *scip, const char *name)
SCIP_RETCODE SCIPaddStringParam(SCIP *scip, const char *name, const char *desc, char **valueptr, SCIP_Bool isadvanced, const char *defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
SCIP_RETCODE SCIPincludeExternalCodeInformation(SCIP *scip, const char *name, const char *description)
#define SCIPallocBlockMemoryArray(scip, ptr, num)
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
SCIP_RETCODE SCIPincludeNlpi(SCIP *scip, const char *name, const char *description, int priority, SCIP_DECL_NLPICOPY((*nlpicopy)), SCIP_DECL_NLPIFREE((*nlpifree)), SCIP_DECL_NLPIGETSOLVERPOINTER((*nlpigetsolverpointer)), SCIP_DECL_NLPICREATEPROBLEM((*nlpicreateproblem)), SCIP_DECL_NLPIFREEPROBLEM((*nlpifreeproblem)), SCIP_DECL_NLPIGETPROBLEMPOINTER((*nlpigetproblempointer)), SCIP_DECL_NLPIADDVARS((*nlpiaddvars)), SCIP_DECL_NLPIADDCONSTRAINTS((*nlpiaddconstraints)), SCIP_DECL_NLPISETOBJECTIVE((*nlpisetobjective)), SCIP_DECL_NLPICHGVARBOUNDS((*nlpichgvarbounds)), SCIP_DECL_NLPICHGCONSSIDES((*nlpichgconssides)), SCIP_DECL_NLPIDELVARSET((*nlpidelvarset)), SCIP_DECL_NLPIDELCONSSET((*nlpidelconsset)), SCIP_DECL_NLPICHGLINEARCOEFS((*nlpichglinearcoefs)), SCIP_DECL_NLPICHGEXPR((*nlpichgexpr)), SCIP_DECL_NLPICHGOBJCONSTANT((*nlpichgobjconstant)), SCIP_DECL_NLPISETINITIALGUESS((*nlpisetinitialguess)), SCIP_DECL_NLPISOLVE((*nlpisolve)), SCIP_DECL_NLPIGETSOLSTAT((*nlpigetsolstat)), SCIP_DECL_NLPIGETTERMSTAT((*nlpigettermstat)), SCIP_DECL_NLPIGETSOLUTION((*nlpigetsolution)), SCIP_DECL_NLPIGETSTATISTICS((*nlpigetstatistics)), SCIP_NLPIDATA *nlpidata)
SCIP_NLPIDATA * SCIPnlpiGetData(SCIP_NLPI *nlpi)
SCIP_Bool SCIPisSolveInterrupted(SCIP *scip)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPrandomGetReal(SCIP_RANDNUMGEN *randnumgen, SCIP_Real minrandval, SCIP_Real maxrandval)
int SCIPsnprintf(char *t, int len, const char *s,...)
SCIPfreeRandom(scip, &heurdata->randnumgen)
SCIPcreateRandom(scip, &heurdata->randnumgen, DEFAULT_RANDSEED, TRUE))
assert(minobj< SCIPgetCutoffbound(scip))
static const char * paramname[]
#define BMSduplicateMemoryArray(ptr, source, num)
#define BMSallocMemoryArray(ptr, num)
#define BMSfreeMemoryArray(ptr)
#define BMScopyMemoryArray(ptr, source, num)
void SCIPmessageVPrintError(const char *formatstr, va_list ap)
void SCIPmessageVPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, const char *formatstr, va_list ap)
void SCIPmessagePrintErrorHeader(const char *sourcefile, int sourceline)
static const SCIP_Real convcheck_minred[convcheck_nchecks]
static const char * ipopt_int_params[]
integer parameters of Ipopt to make available via SCIP parameters
static const int convcheck_startiter
static const int convcheck_nchecks
static SCIP_RETCODE solveLinearProb3(SCIP_Real *A, SCIP_Real *b, SCIP_Real *x, SCIP_Bool *success)
static const char * ipopt_string_params[]
string parameters of Ipopt to make available via SCIP parameters
static SCIP_RETCODE ensureStartingPoint(SCIP *scip, SCIP_NLPIPROBLEM *problem, SCIP_Bool &warmstart)
static SCIP_RETCODE handleNlpParam(SCIP *scip, SCIP_NLPIDATA *nlpidata, SCIP_NLPIPROBLEM *nlpiproblem, SCIP_NLPPARAM param)
pass NLP solve parameters to Ipopt
static const int convcheck_maxiter[convcheck_nchecks]
static void invalidateSolved(SCIP_NLPIPROBLEM *problem)
static void invalidateSolution(SCIP_NLPIPROBLEM *problem)
methods to store an NLP and request function, gradient, and Hessian values
char * SCIPparamGetString(SCIP_PARAM *param)
int SCIPparamGetInt(SCIP_PARAM *param)
int SCIPparamGetIntDefault(SCIP_PARAM *param)
public methods for message output
public data structures and miscellaneous methods
public methods for handling parameter settings
public methods for problem copies
public methods for memory management
public methods for message handling
public methods for NLPI solver interfaces
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for random numbers
SCIP_NLPPARAM_FASTFAIL fastfail
SmartPtr< IpoptApplication > ipopt
SCIP_RANDNUMGEN * randnumgen
SCIP_NLPTERMSTAT termstat
#define SCIP_EXPRINTCAPABILITY_GRADIENT
#define SCIP_EXPRINTCAPABILITY_HESSIAN
#define SCIP_EXPRINTCAPABILITY_FUNCVALUE
unsigned int SCIP_EXPRINTCAPABILITY
struct SCIP_RandNumGen SCIP_RANDNUMGEN
#define SCIP_DECL_NLPISOLVE(x)
struct SCIP_NlpiProblem SCIP_NLPIPROBLEM
#define SCIP_DECL_NLPICHGLINEARCOEFS(x)
#define SCIP_DECL_NLPICHGOBJCONSTANT(x)
#define SCIP_NLPPARAM_PRINT(param)
#define SCIP_DECL_NLPIGETSOLUTION(x)
#define SCIP_DECL_NLPISETOBJECTIVE(x)
#define SCIP_DECL_NLPICREATEPROBLEM(x)
#define SCIP_DECL_NLPIGETSTATISTICS(x)
#define SCIP_DECL_NLPIDELCONSSET(x)
#define SCIP_DECL_NLPICHGCONSSIDES(x)
#define SCIP_DECL_NLPIDELVARSET(x)
#define SCIP_DECL_NLPICHGEXPR(x)
#define SCIP_DECL_NLPIADDVARS(x)
@ SCIP_NLPPARAM_FASTFAIL_OFF
@ SCIP_NLPPARAM_FASTFAIL_AGGRESSIVE
enum SCIP_NlpSolStat SCIP_NLPSOLSTAT
#define SCIP_DECL_NLPISETINITIALGUESS(x)
#define SCIP_DECL_NLPIFREEPROBLEM(x)
@ SCIP_NLPTERMSTAT_TIMELIMIT
@ SCIP_NLPTERMSTAT_NUMERICERROR
@ SCIP_NLPTERMSTAT_EVALERROR
@ SCIP_NLPTERMSTAT_LOBJLIMIT
@ SCIP_NLPTERMSTAT_ITERLIMIT
@ SCIP_NLPTERMSTAT_OUTOFMEMORY
@ SCIP_NLPTERMSTAT_INTERRUPT
#define SCIP_DECL_NLPICOPY(x)
#define SCIP_DECL_NLPIGETSOLVERPOINTER(x)
#define SCIP_DECL_NLPIGETSOLSTAT(x)
#define SCIP_DECL_NLPICHGVARBOUNDS(x)
#define SCIP_DECL_NLPIGETPROBLEMPOINTER(x)
#define SCIP_DECL_NLPIFREE(x)
#define SCIP_DECL_NLPIADDCONSTRAINTS(x)
@ SCIP_NLPSOLSTAT_UNBOUNDED
@ SCIP_NLPSOLSTAT_LOCINFEASIBLE
@ SCIP_NLPSOLSTAT_FEASIBLE
@ SCIP_NLPSOLSTAT_UNKNOWN
#define SCIP_DECL_NLPIGETTERMSTAT(x)
struct SCIP_NlpParam SCIP_NLPPARAM
enum SCIP_NlpTermStat SCIP_NLPTERMSTAT
struct SCIP_NlpiData SCIP_NLPIDATA
struct SCIP_Param SCIP_PARAM
enum SCIP_Retcode SCIP_RETCODE