All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
nlpi_ipopt.cpp
Go to the documentation of this file.
22 * @todo use new_x: Ipopt sets new_x = false if any function has been evaluated for the current x already, while oracle allows new_x to be false only if the current function has been evaluated for the current x before
29 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
71 #define FEASTOLFACTOR 0.05 /**< factor for user-given feasibility tolerance to get feasibility tolerance that is actually passed to Ipopt */
81 * The targets are updated once they are reached and the limit on allowed iterations to reach the new target is reset.
89 * it is unlikely that Ipopt will continue to decrease primal infeasibility, since it may now target on
91 * - If the target on dual infeasibility reduction has been achieved, we are below twice the iteration limit, and
95 * However, in restoration mode, dual infeasibility does not correspond to the original problem and
100 static const int convcheck_maxiter[convcheck_nchecks] = { 5, 15, 30 }; /**< maximal number of iterations to achieve each convergence check */
101 static const SCIP_Real convcheck_minred[convcheck_nchecks] = { 1.0, 0.5, 0.1 }; /**< minimal required infeasibility reduction in each convergence check */
134 SCIP_Bool firstrun; /**< whether the next NLP solve will be the first one (with the current problem structure) */
140 SCIP_Real* lastsoldualcons; /**< dual solution values of constraints from last run, if available */
141 SCIP_Real* lastsoldualvarlb; /**< dual solution values of variable lower bounds from last run, if available */
142 SCIP_Real* lastsoldualvarub; /**< dual solution values of variable upper bounds from last run, if available */
143 SCIP_Real lastsolinfeas;/**< infeasibility (constraint violation) of solution stored in lastsolprimals */
164 SCIP_Real conv_prtarget[convcheck_nchecks]; /**< target primal infeasibility for each convergence check */
165 SCIP_Real conv_dutarget[convcheck_nchecks]; /**< target dual infeasibility for each convergence check */
166 int conv_iterlim[convcheck_nchecks]; /**< iteration number where target primal infeasibility should to be achieved */
170 bool approxhessian; /**< do we tell Ipopt to approximate the hessian? (may also be false if user set to approx. hessian via option file) */
258 bool new_x, /**< whether some function evaluation method has been called for this point before */
266 bool new_x, /**< whether some function evaluation method has been called for this point before */
274 bool new_x, /**< whether some function evaluation method has been called for this point before */
286 bool new_x, /**< whether some function evaluation method has been called for this point before */
304 bool new_x, /**< whether some function evaluation method has been called for this point before */
308 bool new_lambda, /**< whether the hessian has been evaluated for these values of lambda before */
314 Number* values /**< buffer to store values of nonzero hessian entries, or NULL if structure is requested */
337 /** This method is called when the algorithm is complete so the TNLP can store/write the solution. */
409 /** clears the last solution arrays and sets the solstat and termstat to unknown and other, resp. */
428 * Sets tol and constr_viol_tol to FEASTOLFACTOR*feastol and acceptable_tol and acceptable_viol_tol to feastol.
429 * Since the users and Ipopts conception of feasibility may differ, we let Ipopt try to compute solutions
431 * Only if Ipopt has problems to achieve this accuracy, we also accept solutions that are accurate w.r.t. feastol only.
432 * The additional effort for computing a more accurate solution should be small if one can assume fast convergence when close to a local minimizer.
446 /* It seem to be better to let Ipopt relax bounds a bit to ensure that a relative interior exists.
448 * If the user wants to set a tight feasibility tolerance, then (s)he has probably difficulties to compute accurate enough solutions.
449 * Thus, we turn off the bound_relax_factor completely if it would be below its default value of 1e-8.
451 nlpiproblem->ipopt->Options()->SetNumericValue("bound_relax_factor", feastol < 1e-8/FEASTOLFACTOR ? 0.0 : FEASTOLFACTOR * feastol);
579 (*problem)->ipopt->RegOptions()->AddStringOption2("store_intermediate", "whether to store the most feasible intermediate solutions", "no", "yes", "", "no", "", "useful when Ipopt looses a once found feasible solution and then terminates with an infeasible point");
602 SCIPerrorMessage("Error when modifiying Ipopt options using options string\n%s\n", data->defoptions.c_str());
610 SCIPerrorMessage("Error during initialization of Ipopt using optionfile \"%s\"\n", (*problem)->optfile.c_str());
712 * - exprvaridxs indices of variables in expression tree, maps variable indices in expression tree to indices in nlp
753 * - exprvaridxs indices of variables in expression tree, maps variable indices in expression tree to indices in nlp
911 * - quadelems new elements in quadratic matrix (replacing already existing ones or adding new ones)
934 * - exprtree new expression tree for constraint or objective, or NULL to only remove previous tree
999 * - varlbdualvalues initial dual values for variable lower bounds, or NULL to clear previous values
1000 * - varubdualvalues initial dual values for variable upper bounds, or NULL to clear previous values
1013 if( BMSduplicateMemoryArray(&problem->initguess, primalvalues, SCIPnlpiOracleGetNVars(problem->oracle)) == NULL )
1059 /* if the expression interpreter does not support function values and gradients and hessians, and the problem is not at most quadratic,
1062 if( (SCIPexprintGetCapability() & (SCIP_EXPRINTCAPABILITY_FUNCVALUE | SCIP_EXPRINTCAPABILITY_GRADIENT | SCIP_EXPRINTCAPABILITY_HESSIAN)) != (SCIP_EXPRINTCAPABILITY_FUNCVALUE | SCIP_EXPRINTCAPABILITY_GRADIENT | SCIP_EXPRINTCAPABILITY_HESSIAN)
1069 SCIPerrorMessage("Do not have expression interpreter that can compute function values and gradients. Cannot solve NLP with Ipopt.\n");
1075 /* enable hessian approximation if we are nonquadratic and the expression interpreter does not support hessians */
1089 /* ReOptimizeNLP with Ipopt <= 3.10.3 could return a solution not within bounds if all variables are fixed (see Ipopt ticket #179) */
1090 #if (IPOPT_VERSION_MAJOR > 3) || (IPOPT_VERSION_MAJOR == 3 && IPOPT_VERSION_MINOR > 10) || (IPOPT_VERSION_MAJOR == 3 && IPOPT_VERSION_MINOR == 10 && IPOPT_VERSION_RELEASE > 3)
1110 SCIPdebugMessage("Ipopt failed because of an invalid number in function or derivative value\n");
1175 * - consdualvalues buffer to store pointer to array to dual values of constraints, or NULL if not needed
1176 * - varlbdualvalues buffer to store pointer to array to dual values of variable lower bounds, or NULL if not needed
1177 * - varubdualvalues buffer to store pointer to array to dual values of variable lower bounds, or NULL if not needed
1400 SCIPmessagePrintWarning(data->messagehdlr, "from scratch parameter not supported by Ipopt interface yet. Ignored.\n");
1426 problem->ipopt->Options()->SetIntegerValue("print_level", MIN(J_ITERSUMMARY + (ival-1), J_ALL));
1431 SCIPerrorMessage("Value %d for parameter from verbosity level out of range {0, 1, 2}\n", ival);
1517 * - problem datastructure for problem instance, can be NULL only if type == SCIP_NLPPAR_INFINITY
1617 * - problem datastructure for problem instance, can be NULL only if type == SCIP_NLPPAR_INFINITY
1677 SCIPmessagePrintWarning(data->messagehdlr, "Parameter lower objective limit not supported by Ipopt interface yet. Ignored.\n");
1908 SCIPerrorMessage("Error initializing Ipopt using optionfile \"%s\"\n", problem->optfile.c_str());
1973 nlpiChgLinearCoefsIpopt, nlpiChgQuadraticCoefsIpopt, nlpiChgExprtreeIpopt, nlpiChgNonlinCoefIpopt,
1974 nlpiChgObjConstantIpopt, nlpiSetInitialGuessIpopt, nlpiSolveIpopt, nlpiGetSolstatIpopt, nlpiGetTermstatIpopt,
2002 /** gives a pointer to the IpoptApplication object stored in Ipopt-NLPI's NLPI problem data structure */
2012 /** gives a pointer to the NLPIORACLE object stored in Ipopt-NLPI's NLPI problem data structure */
2149 SCIPdebugMessage("Ipopt started without intial primal values; make up starting guess by projecting 0 onto variable bounds\n");
2161 x[i] = SCIPgetRandomReal(MAX(lb, -MAXPERTURB*MIN(1.0, ub-lb)), MIN(ub, MAXPERTURB*MIN(1.0, ub-lb)), &perturbseed);
2183 var_types[i] = (SCIPnlpiOracleGetVarDegree(nlpiproblem->oracle, i) <= 1 ? LINEAR : NON_LINEAR);
2202 const_types[i] = (SCIPnlpiOracleGetConstraintDegree(nlpiproblem->oracle, i) <= 1 ? LINEAR : NON_LINEAR);
2314 bool new_x, /**< whether some function evaluation method has been called for this point before */
2330 bool new_x, /**< whether some function evaluation method has been called for this point before */
2341 return SCIPnlpiOracleEvalObjectiveGradient(nlpiproblem->oracle, x, TRUE, &dummy, grad_f) == SCIP_OKAY;
2348 bool new_x, /**< whether some function evaluation method has been called for this point before */
2368 bool new_x, /**< whether some function evaluation method has been called for this point before */
2371 Index* iRow, /**< buffer to store row indices of nonzero jacobian entries, or NULL if values are requested */
2372 Index* jCol, /**< buffer to store column indices of nonzero jacobian entries, or NULL if values are requested */
2373 Number* values /**< buffer to store values of nonzero jacobian entries, or NULL if structure is requested */
2420 bool new_x, /**< whether some function evaluation method has been called for this point before */
2424 bool new_lambda, /**< whether the hessian has been evaluated for these values of lambda before */
2426 Index* iRow, /**< buffer to store row indices of nonzero hessian entries, or NULL if values are requested */
2427 Index* jCol, /**< buffer to store column indices of nonzero hessian entries, or NULL if values are requested */
2428 Number* values /**< buffer to store values of nonzero hessian entries, or NULL if structure is requested */
2447 if( SCIPnlpiOracleGetHessianLagSparsity(nlpiproblem->oracle, &heslagoffset, &heslagcol) != SCIP_OKAY )
2461 if( SCIPnlpiOracleEvalHessianLag(nlpiproblem->oracle, x, TRUE, obj_factor, lambda, values) != SCIP_OKAY )
2488 if( nlpiproblem->storeintermediate && mode == RegularMode && inf_pr < nlpiproblem->lastsolinfeas )
2504 SCIPdebugMessage("update lastsol: inf_pr old = %g -> new = %g\n", nlpiproblem->lastsolinfeas, inf_pr);
2511 if( BMSallocMemoryArray(&nlpiproblem->lastsolprimals, SCIPnlpiOracleGetNVars(nlpiproblem->oracle)) == NULL ||
2512 BMSallocMemoryArray(&nlpiproblem->lastsoldualcons, SCIPnlpiOracleGetNConstraints(nlpiproblem->oracle)) == NULL ||
2513 BMSallocMemoryArray(&nlpiproblem->lastsoldualvarlb, SCIPnlpiOracleGetNVars(nlpiproblem->oracle)) == NULL ||
2514 BMSallocMemoryArray(&nlpiproblem->lastsoldualvarub, SCIPnlpiOracleGetNVars(nlpiproblem->oracle)) == NULL )
2527 tnlp_adapter->ResortG(*ip_data->curr()->y_c(), *ip_data->curr()->y_d(), nlpiproblem->lastsoldualcons);
2530 BMSclearMemoryArray(nlpiproblem->lastsoldualvarlb, SCIPnlpiOracleGetNVars(nlpiproblem->oracle));
2531 BMSclearMemoryArray(nlpiproblem->lastsoldualvarub, SCIPnlpiOracleGetNVars(nlpiproblem->oracle));
2534 tnlp_adapter->ResortBnds(*ip_data->curr()->z_L(), nlpiproblem->lastsoldualvarlb, *ip_data->curr()->z_U(), nlpiproblem->lastsoldualvarub);
2593 SCIPdebugPrintf("continue, because restoration phase only %d iters ago\n", iter - conv_lastrestoiter);
2595 else if( mode == RegularMode && inf_du <= conv_dutarget[i] && iter < conv_iterlim[i] + convcheck_maxiter[i] )
2597 /* if dual reduction is sufficient, we allow for twice the number of iterations to reach primal infeas reduction */
2598 SCIPdebugPrintf("continue, because dual infeas. red. sufficient and only %d iters above limit\n", iter - conv_iterlim[i]);
2613 /** This method is called when the algorithm is complete so the TNLP can store/write the solution.
2645 /* if stop at acceptable point, then dual infeasibility can be arbitrary large, so claim only feasibility */
2673 /* still check feasibility, since we let Ipopt solve with higher tolerance than actually required */
2714 /* if Ipopt reports its solution as locally infeasible or we don't know feasibility, then report the intermediate point with lowest constraint violation, if available */
2715 if( (x == NULL || nlpiproblem->lastsolstat == SCIP_NLPSOLSTAT_LOCINFEASIBLE || nlpiproblem->lastsolstat == SCIP_NLPSOLSTAT_UNKNOWN) && nlpiproblem->lastsolinfeas != SCIP_INVALID )
2725 nlpiproblem->ipopt->Options()->GetNumericValue("acceptable_constr_viol_tol", constrvioltol, "");
2731 SCIPdebugMessage("drop Ipopt's final point and report intermediate locally %sfeasible solution with infeas %g instead (acceptable: %g)\n",
2732 nlpiproblem->lastsolstat == SCIP_NLPSOLSTAT_LOCINFEASIBLE ? "in" : "", nlpiproblem->lastsolinfeas, constrvioltol);
2772 nlpiproblem->ipopt->Options()->GetNumericValue("acceptable_constr_viol_tol", constrvioltol, "");
2783 * Thus, we use IpLapack if F77_FUNC is not defined and access Lapack's Dsyev directly if F77_FUNC is defined.
2795 SCIP_Real* a, /**< matrix data on input (size N*N); eigenvectors on output if computeeigenvectors == TRUE */
2817 char* jobz, /**< 'N' to compute eigenvalues only, 'V' to compute eigenvalues and eigenvectors */
2820 double* A, /**< matrix A on entry; orthonormal eigenvectors on exit, if jobz == 'V' and info == 0; if jobz == 'N', then the matrix data is destroyed */
2824 int* LWORK, /**< length of WORK; if LWORK = -1, then the optimal workspace size is calculated and returned in WORK(1) */
2825 int* info /**< == 0: successful exit; < 0: illegal argument at given position; > 0: failed to converge */
2835 SCIP_Real* a, /**< matrix data on input (size N*N); eigenvectors on output if computeeigenvectors == TRUE */
|