= NOTE: The information on this page has been copied into the [http://www.coin-or.org/Ipopt/documentation/node33.html Ipopt documentation]. =
= Optimal Sensitivity Based on IPOPT =
== Introduction ==
This project provides a toolbox that uses NLP sensitivity theory to generate fast approximations to solutions when parameters in the problem change.
This toolbox has been developed primarily by Hans Pirnay (RWTH-Aachen), Rodrigo López-Negrete (CMU), and Lorenz Biegler (CMU). If you have problems or questions please email them to the Ipopt mailing list.
Sensitivity of nonlinear programming problems is a key
step in any optimization study. Sensitivity provides
information on regularity and curvature conditions at KKT points,
assesses which variables play dominant roles in the optimization, and
provides first order estimates for parametric nonlinear programs.
Moreover, for NLP algorithms that use exact second derivatives,
sensitivity can be implemented very efficiently within NLP solvers and
provide valuable information with very little added computation. This
implementation provides IPOPT with the capabilities to calculate
sensitivities, and approximate perturbed solutions with them.
The basic sensitivity strategy implemented here is based on the
application of the Implicit Function Theorem (IFT) to the KKT conditions
of the NLP. As shown by Fiacco (1983),
sensitivities can be obtained from a solution with suitable regularity
conditions merely by solving a linearization of the KKT
conditions. More details can be found in the [https://projects.coin-or.org/Ipopt/export/1992/trunk/Ipopt/contrib/sIPOPT/doc/sipopt_manual.pdf documentation] or in the implementation paper:
H. Pirnay, R. Lopez-Negrete, and L.T. Biegler, '''[http://dx.doi.org/10.1007/s12532-012-0043-2 Optimal Sensitivity based on IPOPT]''', ''Math Prog Comp'', 4(4):307--331, 2012.
If you are using sIpopt for your research please cite the paper above.
Also, a preprint can be found '''[http://www.optimization-online.org/DB_HTML/2011/04/3008.html here]'''.
== Alternative Implementation ==
sIPOPT was developed under the constraint that it must work with the regular IPOPT code.
Due to this constraint, some compromises had to be made.
However, there is an ongoing effort to develop sIPOPT 2, which is a fork of the IPOPT code that allows for the explicit definition of parametric NLPs.
This code can be found [https://github.com/athrpf/sipopt2 on github].
If you have questions about sIPOPT 2, please contact [http://www.avt.rwth-aachen.de/AVT/index.php?id=68&showUid=657 Hans Pirnay].
== Installation ==
The ﬁrst step to install the software is to install the trunk version of IPOPT, once this is done installing
sIPOPT is very simple. IPOPT’s installation instructions can be found in the [http://www.coin-or.org/Ipopt/documentation/ IPOPT documentation].
Also note that in the following we refer to $IPOPT as the main folder, where the Ipopt/, !ThirdParty/,
!BuildTools/, . . . , folders are located.
If you wish to use the AMPL interface, make sure that your IPOPT
installation also includes it. To do this you need to download the ASL library, with the get.ASL script
located in $IPOPT/ThirdParty/ASL.
Finally, we assume that you created a build folder to install IPOPT in $IPOPT/build/. In this case, to download the trunk version of IPOPT you would type:
{{{
$ svn co https://projects.coin-or.org/svn/Ipopt/trunk $IPOPT
}}}
Once IPOPT has been compiled and installed, we can proceed to build sIPOPT. To do this go to the
$IPOPT/build/Ipopt/contrib/sIPOPT/ folder, and type make there.
{{{
$ cd $IPOPT/build/Ipopt/contrib/sIPOPT
$ make
}}}
If no errors are shown after compilation you can proceed to install the libraries and to generate the
AMPL executable. To do this type
{{{
$ make install
}}}
This should copy the generated libraries (libsipopt.*) to $IPOPT/build/lib, and the AMPL executable (ipopt_sens) to $IPOPT/build/bin/.
== Example ==
To illustrate the use of the toolbox we solve the following NLP
{{{
min x1^2 + x2^2 + x3^2
st
6x1 + 3x2 + 2x3 − p1 = 0
p2 x1 + x2 − x3 − 1 = 0
x1 , x2 , x3 ≥ 0,
}}}
and we perturb the parameters p1 and p2 from pa^T^ = [p1 p2] = [5 1] to pb^T^ = [4.5 1]. For this case the AMPL code is shown below.
{{{
reset ;
# Suffixes for sensitivity update
suffix sens_state_0, IN;
suffix sens_state_1, IN;
suffix sens_state_value_1, IN;
suffix sens_sol_state_1, OUT;
suffix sens_init_constr, IN;
suffix sens_sol_state_1_z_U, OUT ;
suffix sens_sol_state_1_z_L, OUT ;
# Original value of parameters
param et1p ;
param et2p ;
# Original parameter values
let et1p := 5 ;
let et2p := 1 ;
# Define variables, with bounds and initial guess
var x1 >= 0, := 0.15 ;
var x2 >= 0, := 0.15 ;
var x3 >= 0, := 0.00 ;
# Artificial variables so IPOPT sees the parameters
var et1 ;
var et2 ;
# objective function
minimize objf: x1^2 + x2^2 + x3^2 ;
# constraints
subject to
r1: 6*x1 + 3*x2 + 2*x3 - et1 = 0 ;
r2: et2*x1 + x2 - x3 - 1 = 0 ;
# Artificial constraints to pass parameters to IPOPT
r3: et1 = et1p ;
r4: et2 = et2p ;
# Define solver and Ampl options in this case we don't want Ampl's
# presolve to accidentally remove artificial variables.
options solver ipopt_sens ;
option presolve 0;
# compute sensitivity
option ipopt_options "run_sens yes" ;
# define an order to the parameters that will change.
# In step 0, only et1 changes, and has position 1
let et1.sens_state_0 := 1 ;
# in the first step/change et1 has position 1
let et1.sens_state_1 := 1 ;
# Perturbed value of parameter et1 (in step 1)
let et1.sens_state_value_1 := 4.5 ;
# In step 0, et2 has position 1
let et2.sens_state_0 := 2 ;
# in the first step/change et1 has position 2
let et2.sens_state_1 := 2 ;
# Perturbed value of parameter et2 (in step 1)
let et2.sens_state_value_1 := 1 ;
# Artificial constraints
let r3.sens_init_constr := 1 ;
let r4.sens_init_constr := 1 ;
# solve problem
solve ;
#**********************************************
# Print nominal solution and bound multipliers
#**********************************************
display x1, x2, x3, et1, et2 ;
display x1.ipopt_zU_out, x2.ipopt_zU_out, x3.ipopt_zU_out,
et1.ipopt_zU_out, et2.ipopt_zU_out ;
display x1.ipopt_zL_out, x2.ipopt_zL_out, x3.ipopt_zL_out,
et1.ipopt_zL_out, et2.ipopt_zL_out ;
# Constraint multipliers
display r1, r2, r3, r4 ;
#************************
# Print updated solution
#************************
display x1.sens_sol_state_1, x2.sens_sol_state_1,
x3.sens_sol_state_1, et1.sens_sol_state_1,
et2.sens_sol_state_1 ;
display x1.sens_sol_state_1_z_U, x2.sens_sol_state_1_z_U,
x3.sens_sol_state_1_z_U,
et1.sens_sol_state_1_z_U, et2.sens_sol_state_1_z_U ;
display x1.sens_sol_state_1_z_L, x2.sens_sol_state_1_z_L,
x3.sens_sol_state_1_z_L,
et1.sens_sol_state_1_z_L, et2.sens_sol_state_1_z_L ;
# and updated constraint multipliers
display r1.sens_sol_state_1, r2.sens_sol_state_1,
r3.sens_sol_state_1, r4.sens_sol_state_1 ;
}}}