123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- // Copyright (C) 2004, 2006 International Business Machines and others.
- // All Rights Reserved.
- // This code is published under the Eclipse Public License.
- //
- // $Id: MyNLP.cpp 2005 2011-06-06 12:55:16Z stefan $
- //
- // Authors: Carl Laird, Andreas Waechter IBM 2004-11-05
- #include "MyNLP.hpp"
- #include <cassert>
- using namespace Ipopt;
- /* Constructor. */
- MyNLP::MyNLP()
- {}
- MyNLP::~MyNLP()
- {}
- bool MyNLP::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
- Index& nnz_h_lag, IndexStyleEnum& index_style)
- {
- // The problem described in MyNLP.hpp has 2 variables, x1, & x2,
- n = 2;
- // one equality constraint,
- m = 1;
- // 2 nonzeros in the jacobian (one for x1, and one for x2),
- nnz_jac_g = 2;
- // and 2 nonzeros in the hessian of the lagrangian
- // (one in the hessian of the objective for x2,
- // and one in the hessian of the constraints for x1)
- nnz_h_lag = 2;
- // We use the standard fortran index style for row/col entries
- index_style = FORTRAN_STYLE;
- return true;
- }
- bool MyNLP::get_bounds_info(Index n, Number* x_l, Number* x_u,
- Index m, Number* g_l, Number* g_u)
- {
- // here, the n and m we gave IPOPT in get_nlp_info are passed back to us.
- // If desired, we could assert to make sure they are what we think they are.
- assert(n == 2);
- assert(m == 1);
- // x1 has a lower bound of -1 and an upper bound of 1
- x_l[0] = -1.0;
- x_u[0] = 1.0;
- // x2 has no upper or lower bound, so we set them to
- // a large negative and a large positive number.
- // The value that is interpretted as -/+infinity can be
- // set in the options, but it defaults to -/+1e19
- x_l[1] = -1.0e19;
- x_u[1] = +1.0e19;
- // we have one equality constraint, so we set the bounds on this constraint
- // to be equal (and zero).
- g_l[0] = g_u[0] = 0.0;
- return true;
- }
- bool MyNLP::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)
- {
- // Here, we assume we only have starting values for x, if you code
- // your own NLP, you can provide starting values for the others if
- // you wish.
- assert(init_x == true);
- assert(init_z == false);
- assert(init_lambda == false);
- // we initialize x in bounds, in the upper right quadrant
- x[0] = 0.5;
- x[1] = 1.5;
- return true;
- }
- bool MyNLP::eval_f(Index n, const Number* x, bool new_x, Number& obj_value)
- {
- // return the value of the objective function
- Number x2 = x[1];
- obj_value = -(x2 - 2.0) * (x2 - 2.0);
- return true;
- }
- bool MyNLP::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f)
- {
- // return the gradient of the objective function grad_{x} f(x)
- // grad_{x1} f(x): x1 is not in the objective
- grad_f[0] = 0.0;
- // grad_{x2} f(x):
- Number x2 = x[1];
- grad_f[1] = -2.0*(x2 - 2.0);
- return true;
- }
- bool MyNLP::eval_g(Index n, const Number* x, bool new_x, Index m, Number* g)
- {
- // return the value of the constraints: g(x)
- Number x1 = x[0];
- Number x2 = x[1];
- g[0] = -(x1*x1 + x2 - 1.0);
- return true;
- }
- bool MyNLP::eval_jac_g(Index n, const Number* x, bool new_x,
- Index m, Index nele_jac, Index* iRow, Index *jCol,
- Number* values)
- {
- if (values == NULL) {
- // return the structure of the jacobian of the constraints
- // element at 1,1: grad_{x1} g_{1}(x)
- iRow[0] = 1;
- jCol[0] = 1;
- // element at 1,2: grad_{x2} g_{1}(x)
- iRow[1] = 1;
- jCol[1] = 2;
- }
- else {
- // return the values of the jacobian of the constraints
- Number x1 = x[0];
- // element at 1,1: grad_{x1} g_{1}(x)
- values[0] = -2.0 * x1;
- // element at 1,2: grad_{x1} g_{1}(x)
- values[1] = -1.0;
- }
- return true;
- }
- bool MyNLP::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)
- {
- if (values == NULL) {
- // return the structure. This is a symmetric matrix, fill the lower left
- // triangle only.
- // element at 1,1: grad^2_{x1,x1} L(x,lambda)
- iRow[0] = 1;
- jCol[0] = 1;
- // element at 2,2: grad^2_{x2,x2} L(x,lambda)
- iRow[1] = 2;
- jCol[1] = 2;
- // Note: off-diagonal elements are zero for this problem
- }
- else {
- // return the values
- // element at 1,1: grad^2_{x1,x1} L(x,lambda)
- values[0] = -2.0 * lambda[0];
- // element at 2,2: grad^2_{x2,x2} L(x,lambda)
- values[1] = -2.0 * obj_factor;
- // Note: off-diagonal elements are zero for this problem
- }
- return true;
- }
- void MyNLP::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,
- const IpoptData* ip_data,
- IpoptCalculatedQuantities* ip_cq)
- {
- // here is where we would store the solution to variables, or write to a file, etc
- // so we could use the solution. Since the solution is displayed to the console,
- // we currently do nothing here.
- }
|