lines 8-564 of file: cppad_ipopt/src/cppad_ipopt_nlp.hpp {xrst_begin cppad_ipopt_nlp app} {xrst_spell fg infeasibility iterates lagrange libs lipopt maxiter naninf rll unrecoverable } Nonlinear Programming Using the CppAD Interface to Ipopt ######################################################## Deprecated 2012-11-28 ********************* This interface to Ipopt is deprecated, use :ref:`ipopt_solve-name` instead. Syntax ****** | # ``include`` ``"cppad_ipopt_nlp.hpp"`` | ``cppad_ipopt_solution`` *solution* ; | ``cppad_ipopt_nlp`` *cppad_nlp* ( | |tab| *n* , *m* , *x_i* , *x_l* , *x_u* , *g_l* , *g_u* , & *fg_info* , & *solution* | ) | ``export LD_LIBRARY_PATH`` = ``$LD_LIBRARY_PATH:`` *ipopt_library_paths* Purpose ******* The class ``cppad_ipopt_nlp`` is used to solve nonlinear programming problems of the form .. math:: \begin{array}{rll} {\rm minimize} & f(x) \\ {\rm subject \; to} & g^l \leq g(x) \leq g^u \\ & x^l \leq x \leq x^u \end{array} This is done using `Ipopt `_ optimizer and `CppAD `_ Algorithmic Differentiation package. cppad_ipopt namespace ********************* All of the declarations for these routines are in the ``cppad_ipopt`` namespace (not the ``CppAD`` namespace). For example; :ref:`cppad_ipopt_nlp@SizeVector` below actually denotes the type ``cppad_ipopt::SizeVector`` . ipopt_library_paths ******************* If you are linking to a shared version of the Ipopt library, you may have to add a path to the ``LD_LIBRARY_PATH`` . You can determine the directory you need to add using the command ``pkg-config ipopt --libs`` The output will have the following form ``-L`` *dir* ``-lipopt`` You may need to add the directory %dir% to ``LD_LIBRARY_PATH%`` ; e.g., ``export LD_LIBRARY_PATH`` =" *dir* : ``$LD_LIBRARY_PATH`` " fg(x) ***** The function :math:`fg : \B{R}^n \rightarrow \B{R}^{m+1}` is defined by .. math:: :nowrap: \begin{eqnarray} fg_0 (x) & = & f(x) \\ fg_1 (x) & = & g_0 (x) \\ & \vdots & \\ fg_m (x) & = & g_{m-1} (x) \end{eqnarray} Index Vector ============ We define an *index vector* as a vector of non-negative integers for which none of the values are equal; i.e., it is both a vector and a set. If :math:`I` is an index vector :math:`|I|` is used to denote the number of elements in :math:`I` and :math:`\| I \|` is used to denote the value of the maximum element in :math:`I`. Projection ========== Given an index vector :math:`J` and a positive integer :math:`n` where :math:`n > \| J \|`, we use :math:`J \otimes n` for the mapping :math:`( J \otimes n ) : \B{R}^n \rightarrow \B{R}^{|J|}` defined by .. math:: [ J \otimes n ] (x)_j = x_{J(j)} for :math:`j = 0 , \ldots |J| - 1`. Injection ========= Given an index vector :math:`I` and a positive integer :math:`m` where :math:`m > \| I \|`, we use :math:`m \otimes I` for the mapping :math:`( m \otimes I ): \B{R}^{|I|} \rightarrow \B{R}^m` defined by .. math:: [ m \otimes I ] (y)_i = \left\{ \begin{array}{ll} y_k & {\rm if} \; i = I(k) \; {\rm for \; some} \; k \in \{ 0 , \cdots, |I|-1 \} \\ 0 & {\rm otherwise} \end{array} \right. Representation ============== In many applications, each of the component functions of :math:`fg(x)` only depend on a few of the components of :math:`x`. In this case, expressing :math:`fg(x)` in terms of simpler functions with fewer arguments can greatly reduce the amount of work required to compute its derivatives. We use the functions :math:`r_k : \B{R}^{q(k)} \rightarrow \B{R}^{p(k)}` for :math:`k = 0 , \ldots , K` to express our representation of :math:`fg(x)` in terms of simpler functions as follows .. math:: fg(x) = \sum_{k=0}^{K-1} \; \sum_{\ell=0}^{L(k) - 1} [ (m+1) \otimes I_{k,\ell} ] \; \circ \; r_k \; \circ \; [ J_{k,\ell} \otimes n ] \; (x) where :math:`\circ` represents function composition, for :math:`k = 0 , \ldots , K - 1`, and :math:`\ell = 0 , \ldots , L(k)`, :math:`I_{k,\ell}` and :math:`J_{k,\ell}` are index vectors with :math:`| J_{k,\ell} | = q(k)`, :math:`\| J_{k,\ell} \| < n`, :math:`| I_{k,\ell} | = p(k)`, and :math:`\| I_{k,\ell} \| \leq m`. Simple Representation ********************* In the simple representation, :math:`r_0 (x) = fg(x)`, :math:`K = 1`, :math:`q(0) = n`, :math:`p(0) = m+1`, :math:`L(0) = 1`, :math:`I_{0,0} = (0 , \ldots , m)`, and :math:`J_{0,0} = (0 , \ldots , n-1)`. SizeVector ********** The type ``SizeVector`` is defined by the ``cppad_ipopt_nlp.hpp`` include file to be a :ref:`SimpleVector-name` class with elements of type ``size_t`` . NumberVector ************ The type ``NumberVector`` is defined by the ``cppad_ipopt_nlp.hpp`` include file to be a :ref:`SimpleVector-name` class with elements of type ``Ipopt::Number`` . ADNumber ******** The type ``ADNumber`` is defined by the ``cppad_ipopt_nlp.hpp`` include file to be a an AD type that can be used to compute derivatives. ADVector ******** The type ``ADVector`` is defined by the ``cppad_ipopt_nlp.hpp`` include file to be a :ref:`SimpleVector-name` class with elements of type ``ADNumber`` . n * The argument *n* has prototype ``size_t`` *n* It specifies the dimension of the argument space; i.e., :math:`x \in \B{R}^n`. m * The argument *m* has prototype ``size_t`` *m* It specifies the dimension of the range space for :math:`g`; i.e., :math:`g : \B{R}^n \rightarrow \B{R}^m`. x_i *** The argument *x_i* has prototype ``const NumberVector&`` *x_i* and its size is equal to :math:`n`. It specifies the initial point where Ipopt starts the optimization process. x_l *** The argument *x_l* has prototype ``const NumberVector&`` *x_l* and its size is equal to :math:`n`. It specifies the lower limits for the argument in the optimization problem; i.e., :math:`x^l`. x_u *** The argument *x_u* has prototype ``const NumberVector&`` *x_u* and its size is equal to :math:`n`. It specifies the upper limits for the argument in the optimization problem; i.e., :math:`x^u`. g_l *** The argument *g_l* has prototype ``const NumberVector&`` *g_l* and its size is equal to :math:`m`. It specifies the lower limits for the constraints in the optimization problem; i.e., :math:`g^l`. g_u *** The argument *g_u* has prototype ``const NumberVector&`` *g_u* and its size is equal to :math:`n`. It specifies the upper limits for the constraints in the optimization problem; i.e., :math:`g^u`. fg_info ******* The argument *fg_info* has prototype *FG_info fg_info* where the class *FG_info* is derived from the base class ``cppad_ipopt_fg_info`` . Certain virtual member functions of *fg_info* are used to compute the value of :math:`fg(x)`. The specifications for these member functions are given below: fg_info.number_functions ======================== This member function has prototype ``virtual size_t cppad_ipopt_fg_info::number_functions`` ( ``void`` ) If *K* has type ``size_t`` , the syntax *K* = *fg_info* . ``number_functions`` () sets *K* to the number of functions used in the representation of :math:`fg(x)`; i.e., :math:`K` in the :ref:`cppad_ipopt_nlp@fg(x)@Representation` above. The ``cppad_ipopt_fg_info`` implementation of this function corresponds to the simple representation mentioned above; i.e. *K* = 1 . fg_info.eval_r ============== This member function has the prototype ``virtual ADVector cppad_ipopt_fg_info::eval_r`` ( ``size_t`` *k* , ``const ADVector&`` *u* ) = 0; Thus it is a pure virtual function and must be defined in the derived class *FG_info* . This function computes the value of :math:`r_k (u)` used in the :ref:`cppad_ipopt_nlp@fg(x)@Representation` for :math:`fg(x)`. If *k* in :math:`\{0 , \ldots , K-1 \}` has type ``size_t`` , *u* is an ``ADVector`` of size *q* ( *k* ) and *r* is an ``ADVector`` of size *p* ( *k* ) the syntax *r* = *fg_info* . ``eval_r`` ( *k* , *u* ) set *r* to the vector :math:`r_k (u)`. fg_info.retape ============== This member function has the prototype ``virtual bool cppad_ipopt_fg_info::retape`` ( ``size_t`` *k* ) If *k* in :math:`\{0 , \ldots , K-1 \}` has type ``size_t`` , and *retape* has type ``bool`` , the syntax *retape* = *fg_info* . ``retape`` ( *k* ) sets *retape* to true or false. If *retape* is true, ``cppad_ipopt_nlp`` will retape the operation sequence corresponding to :math:`r_k (u)` for every value of *u* . An ``cppad_ipopt_nlp`` object should use much less memory and run faster if *retape* is false. You can test both the true and false cases to make sure the operation sequence does not depend on *u* . The ``cppad_ipopt_fg_info`` implementation of this function sets *retape* to true (while slower it is also safer to always retape). fg_info.domain_size =================== This member function has prototype ``virtual size_t cppad_ipopt_fg_info::domain_size`` ( ``size_t`` *k* ) If *k* in :math:`\{0 , \ldots , K-1 \}` has type ``size_t`` , and *q* has type ``size_t`` , the syntax *q* = *fg_info* . ``domain_size`` ( *k* ) sets *q* to the dimension of the domain space for :math:`r_k (u)`; i.e., :math:`q(k)` in the :ref:`cppad_ipopt_nlp@fg(x)@Representation` above. The ``cppad_ipopt_h_base`` implementation of this function corresponds to the simple representation mentioned above; i.e., :math:`q = n`. fg_info.range_size ================== This member function has prototype ``virtual size_t cppad_ipopt_fg_info::range_size`` ( ``size_t`` *k* ) If *k* in :math:`\{0 , \ldots , K-1 \}` has type ``size_t`` , and *p* has type ``size_t`` , the syntax *p* = *fg_info* . ``range_size`` ( *k* ) sets *p* to the dimension of the range space for :math:`r_k (u)`; i.e., :math:`p(k)` in the :ref:`cppad_ipopt_nlp@fg(x)@Representation` above. The ``cppad_ipopt_h_base`` implementation of this function corresponds to the simple representation mentioned above; i.e., :math:`p = m+1`. fg_info.number_terms ==================== This member function has prototype ``virtual size_t cppad_ipopt_fg_info::number_terms`` ( ``size_t`` *k* ) If *k* in :math:`\{0 , \ldots , K-1 \}` has type ``size_t`` , and *L* has type ``size_t`` , the syntax *L* = *fg_info* . ``number_terms`` ( *k* ) sets *L* to the number of terms in representation for this value of *k* ; i.e., :math:`L(k)` in the :ref:`cppad_ipopt_nlp@fg(x)@Representation` above. The ``cppad_ipopt_h_base`` implementation of this function corresponds to the simple representation mentioned above; i.e., :math:`L = 1`. fg_info.index ============= This member function has prototype | |tab| ``virtual void cppad_ipopt_fg_info::index`` ( | |tab| |tab| ``size_t`` *k* , ``size_t`` *ell* , ``SizeVector&`` *I* , ``SizeVector&`` *J* | |tab| ) The argument *k* has type ``size_t`` and is a value between zero and :math:`K-1` inclusive. The argument *ell* has type ``size_t`` and is a value between zero and :math:`L(k)-1` inclusive. The argument *I* is a :ref:`SimpleVector-name` with elements of type ``size_t`` and size greater than or equal to :math:`p(k)`. The input value of the elements of *I* does not matter. The output value of the first :math:`p(k)` elements of *I* must be the corresponding elements of :math:`I_{k,ell}` in the :ref:`cppad_ipopt_nlp@fg(x)@Representation` above. The argument *J* is a :ref:`SimpleVector-name` with elements of type ``size_t`` and size greater than or equal to :math:`q(k)`. The input value of the elements of *J* does not matter. The output value of the first :math:`q(k)` elements of *J* must be the corresponding elements of :math:`J_{k,ell}` in the :ref:`cppad_ipopt_nlp@fg(x)@Representation` above. The ``cppad_ipopt_h_base`` implementation of this function corresponds to the simple representation mentioned above; i.e., for :math:`i = 0 , \ldots , m`, *I* [ *i* ] = *i* , and for :math:`j = 0 , \ldots , n-1`, *J* [ *j* ] = *j* . solution ******** After the optimization process is completed, *solution* contains the following information: status ====== The *status* field of *solution* has prototype ``cppad_ipopt_solution::solution_status`` *solution* . ``status`` It is the final Ipopt status for the optimizer. Here is a list of the possible values for the status: .. list-table:: :widths: auto * - *status* - Meaning * - not_defined - The optimizer did not return a final status to this ``cppad_ipopt_nlp`` object. * - unknown - The status returned by the optimizer is not defined in the Ipopt documentation for ``finalize_solution`` . * - success - Algorithm terminated successfully at a point satisfying the convergence tolerances (see Ipopt options). * - maxiter_exceeded - The maximum number of iterations was exceeded (see Ipopt options). * - stop_at_tiny_step - Algorithm terminated because progress was very slow. * - stop_at_acceptable_point - Algorithm stopped at a point that was converged, not to the 'desired' tolerances, but to 'acceptable' tolerances (see Ipopt options). * - local_infeasibility - Algorithm converged to a non-feasible point (problem may have no solution). * - user_requested_stop - This return value should not happen. * - diverging_iterates - It the iterates are diverging. * - restoration_failure - Restoration phase failed, algorithm doesn't know how to proceed. * - error_in_step_computation - An unrecoverable error occurred while Ipopt tried to compute the search direction. * - invalid_number_detected - Algorithm received an invalid number (such as ``nan`` or ``inf`` ) from the users function *fg_info* . ``eval`` or from the CppAD evaluations of its derivatives (see the Ipopt option ``check_derivatives_for_naninf`` ). * - internal_error - An unknown Ipopt internal error occurred. Contact the Ipopt authors through the mailing list. x = The ``x`` field of *solution* has prototype ``NumberVector`` *solution* . ``x`` and its size is equal to :math:`n`. It is the final :math:`x` value for the optimizer. z_l === The ``z_l`` field of *solution* has prototype ``NumberVector`` *solution* . ``z_l`` and its size is equal to :math:`n`. It is the final Lagrange multipliers for the lower bounds on :math:`x`. z_u === The ``z_u`` field of *solution* has prototype ``NumberVector`` *solution* . ``z_u`` and its size is equal to :math:`n`. It is the final Lagrange multipliers for the upper bounds on :math:`x`. g = The ``g`` field of *solution* has prototype ``NumberVector`` *solution* . ``g`` and its size is equal to :math:`m`. It is the final value for the constraint function :math:`g(x)`. lambda ====== The ``lambda`` field of *solution* has prototype ``NumberVector`` *solution* . ``lambda`` and its size is equal to :math:`m`. It is the final value for the Lagrange multipliers corresponding to the constraint function. obj_value ========= The ``obj_value`` field of *solution* has prototype ``Number`` *solution* . ``obj_value`` It is the final value of the objective function :math:`f(x)`. {xrst_end cppad_ipopt_nlp}