\documentclass[a4paper]{article}
\usepackage{listings} \lstset{numbers=left, numberstyle=\tiny, numbersep=5pt} \lstset{language=Perl} 

\begin{document}
\section{Introduction}
The advanced step NMPC code compiles into a library that holds the code for the Schur complement computation, and an executable which holds an interface to AMPL. This document describes the usage of the asNMPC code using the C++ and the AMPL interface. 

\section{AMPL Interface}
Since many models are written in AMPL, this interface makes it very easy to apply any of the capabilities of the AsNMPC code to your existing models. The usage of the different tools using this AMPL interface is described below. 
\subsection{Advanced Step NMPC}
Given a discretized DAE model of an optimal control problem in AMPL, applying the advanced step algorithm is very easy. Suppose a model
\begin{equation}
  \label{discretized_OCP_asnmpc}
  \begin{array}{cc}
    \min\limits_z& \phi(z)\\
    s.t.& c(z) = 0\\
    & z_0-w_0 = 0\\
    & z\geq 0
  \end{array}
\end{equation}
Not that for the asNMPC formulation, there need to be explicitly defined variables $z_0$ for the initial values (whereas usually, these are just parameters). To define the values for these new variables, additional initial value constraints $z_0-w_0=0$ have to be added. Given this formulation, only four suffixes need to be set to initialize the asNMPC problem:
\begin{description}
\item[nmpc\_state\_0] This suffix has to be set for the initial variables $z_0$. The suffixes have to be set to values from 1 to length($z_0$). This enumeration is crucial.
\item[nmpc\_state\_1] This suffix has to be set for the discretized variables at timestep $t$ corresponding to the inital variables $z_0$. They have to be indexed the same way as nmpc\_state\_0.
\item[nmpc\_state\_value\_1] This suffix holds the perturbed values for the variables at timestep $t$. It has to be set for the same variables as nmpc\_state\_1.
\item[nmpc\_init\_constr] This suffix has to be set for the inital value constraints $z_0 - w_0=0$. If a constraint is an initial value constraint, set this suffix to 1 (no indexing is necessary).
\end{description}
If you have set these suffixes, the only thing missing is to enable the asNMPC algorithm by setting the solver option 
\begin{verbatim}
option ipopt_options 'run_nmpc yes';
\end{verbatim}
This option can alternatively be set in the ipopt.opt file.

To make sure that the initial value constraints are not eliminated by AMPL, the presolve feature should be turned off as well:
\begin{verbatim}
option presolve 0;
\end{verbatim}

After the algorithm has completed successfully, the solution is stored in the following AMPL suffixes:
\begin{description}
\item[nmpc\_sol\_state\_1] This suffix is set for the variables and the constraints. It holds the variable and constraint multiplier values computed in the advanced step algorithm
\item[nmpc\_sol\_state\_1\_z\_L] This suffix holds the advanced step bound multipliers for the lower bounds on the variables.
\item[nmpc\_sol\_state\_1\_z\_U] ... the same for the upper bounds.
\end{description}

An example implementation of the above is provided in the directory 
\begin{verbatim}
examples/hicks_ampl
\end{verbatim} 
There, the asNMPC code is applied to the reactor model described in \cite{Hicks1971}.

The AMPL interface as described above only works for simulations, where the future measurement is known beforehand. Using the AMPL model definiton with an outside measurement device is generally possible. If you intend on using this feature in a real-time environment, please contact the author.
\subsection{Parametric Sensitivity}
The parametric sensitivity feature uses the same suffixes as the asNMPC algorithm. The parameters need to be defined as variables and set using the initial value constraints described above. The only difference in the parametric case is that the suffixes nmpc\_state\_0 and nmpc\_state\_1 are not set for different variables, but both for the parameters.

A small example of the parametric sensitivity feature is located in the directory
\begin{verbatim}
examples/parametric_ampl
\end{verbatim}
\subsection{Reduced Hessian}
The reduced hessian feature is even easier to use. The critical problem is to decide which variables will be free variables at the optimal solution. The free variables have to be marked by setting the suffix
\begin{verbatim}
red_hessian
\end{verbatim}
to $1..n$, where $n$ is the number of free variables. The columns of the inverse reduced hessian, which will be printed, is determined by the ordering of these indices. The algorithm is enabled by setting the solver option
\begin{verbatim}
option ipopt_options 'compute_red_hessian yes';
\end{verbatim}

An example of the reduced hessian calculation can be found in 
\begin{verbatim}
examples/red_hess_ampl
\end{verbatim}
\section{C++ Interface}
The C++ interface is very simple to apply to an existing {\tt Ipopt::TNLP} implementation. With the member function {\tt TNLP::::get\_var\_con\_metadata}, Ipopt provides a feature very similar to that of AMPL suffixes. 

The procedure of making a TNLP class capable to be used with the asNMPC code follows the same lines as in AMPL. First, the parameters / initial values have to be introduced as variables. Then, the initial value equations need to be added to the constraints, and the jacobian computation has to be adjusted accordingly. Finally, the suffixes have to be set the same way they would in AMPL as described above, using the member function {\tt TNLP::::get\_var\_con\_metadata}. This is illustrated in the examples {\tt examples/redhess\_cpp} and {\tt examples/parametric\_cpp}
\section{Options}
There are several new options that can be set in the {\tt ipopt.opt} file, that determine the behavior of the asNMPC code. The most important options are the ones that turn the execution of the additional post-optimal code on and off. These options are 
\begin{verbatim}
run_nmpc yes
\end{verbatim}
for the advanced step and parametric sensitivity computation, and
\begin{verbatim}
compute_red_hessian yes
\end{verbatim}
for the reduced hessian computation. 

Further options for the advanced step code are
\begin{description}
\item[select\_step] This option determines which formula is used to compute the advanced step. The options are \texttt{advanced} for the full advanced step with Schur complement and multiplier correction, \texttt{sensitivity} for the Schur step without multiplier correction, \texttt{ift} for the fast backsolve without Schur complement computation, but with multiplier correction, and finally \texttt{iftsensitivity} the same as \texttt{ift}, but without multiplier correction. For parametric problems, the options \texttt{sensitivity} and \texttt{iftsensitivity} should be used, whereas for advanced step problems, the options \texttt{advanced} and \texttt{ift} are more suitable.
\item[n\_nmpc\_steps] In general, the advanced step is designed to accomodate an arbitrary number of advanced steps. Right now, however, this value has to be set to either 0 or 1.
\item[nmpc\_boundcheck] If set to \texttt{yes}, this option turns on the bound correction algorithm within the advanced step. 
\item[nmpc\_bound\_eps] This option sets the value by which the bounds are to be relaxed in the boundcheck mode. 
\item[nmpc\_max\_pdpert] For certain problems, IPOPT uses inertia correction of the primal dual matrix to achieve better convergence properties. This inertia correction changes the matrix and renders it useless for the use with AsNMPC. This option sets an upper bound, which the inertia correction may have. If any of the inertia correction values is above this bound, the AsNMPC algorithm is aborted.
\item[rh\_eigendecomp] If this option is set to yes, the reduced hessian code will compute the eigenvalue decomposition of the reduced hessian matrix. 
\end{description}
\bibliographystyle{plain}
\bibliography{asnmpc}
\end{document}
