Skip to content

Commit

Permalink
Merge pull request #274 from chrhansk/feature-deriv-documentation
Browse files Browse the repository at this point in the history
Improve documentation of callback functions
  • Loading branch information
moorepants authored Oct 22, 2024
2 parents a6fcb88 + b6d272d commit bc8a034
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 69 deletions.
217 changes: 155 additions & 62 deletions cyipopt/cython/ipopt_wrapper.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -160,63 +160,156 @@ cdef class Problem:
Parameters
----------
n : integer
n : :py:class:`int`
Number of primal variables.
m : integer
m : :py:class:`int`
Number of constraints.
problem_obj: object, optional (default=None)
An object holding the problem's callbacks. If None, cyipopt will use
problem_obj: :py:class:`object`, optional (default=None)
An object holding the problem's callbacks. If `None`, cyipopt will use
``self``, this is useful when subclassing ``Problem``. The object is
required to have the following attributes and methods (some are
optional):
- ``objective`` : function pointer
Callback function for evaluating objective function. The
callback functions accepts one parameter: x (value of the
optimization variables at which the objective is to be
evaluated). The function should return the objective function
value at the point x.
- ``constraints`` : function pointer
Callback function for evaluating constraint functions. The
callback functions accepts one parameter: x (value of the
optimization variables at which the constraints are to be
evaluated). The function should return the constraints values
at the point x.
- ``gradient`` : function pointer
Callback function for evaluating gradient of objective
function. The callback functions accepts one parameter: x
(value of the optimization variables at which the gradient is
to be evaluated). The function should return the gradient of
the objective function at the point x.
- ``jacobian`` : function pointer
Callback function for evaluating Jacobian of constraint
functions. The callback functions accepts one parameter: x
(value of the optimization variables at which the Jacobian is
to be evaluated). The function should return the values of the
Jacobian as calculated using x. The values should be returned
- .. py:function:: objective(x)
Callback function for evaluating objective function
at the given point `x`.
**Parameters**
x : :py:class:`numpy.ndarray`, shape `(n, )`
Value of the optimization variables at which the objective
is to be evaluated.
**Returns**
:py:class:`float`
Objective function value at the point x.
- .. py:function:: constraints(x)
Callback function for evaluating constraint functions at the
given point `x`.
**Parameters**
x : :py:class:`numpy.ndarray`, shape `(n, )`
Value of the optimization variables at which the constraints
are to be evaluated.
**Returns**
:py:class:`numpy.ndarray`, shape `(m, )`
Constraint values at the point x.
- .. py:function:: gradient(x)
Callback function for evaluating gradient of objective function
at the given point `x`.
**Parameters**
x : :py:class:`numpy.ndarray`, shape `(n, )`
Value of the optimization variables at which the gradient
is to be evaluated.
**Returns**
:py:class:`numpy.ndarray`, shape `(n, )`
Gradient of the objective function at the point x.
- .. py:function:: jacobian(x)
Callback function for evaluating Jacobian of constraint functions
at the given point `x`. The values should be returned
as a 1-dim numpy array (using the same order as you used when
specifying the sparsity structure)
- ``jacobianstructure`` : function pointer, optional (default=None)
Callback function that accepts no parameters and returns the
sparsity structure of the Jacobian (the row and column indices
only). If None, the Jacobian is assumed to be dense.
- ``hessian`` : function pointer, optional (default=None)
Callback function for evaluating Hessian of the Lagrangian
function. The callback functions accepts three parameters x
(value of the optimization variables at which the Hessian is to
be evaluated), lambda (values for the constraint multipliers at
which the Hessian is to be evaluated) objective_factor the
factor in front of the objective term in the Hessian. The
**Parameters**
x : :py:class:`numpy.ndarray`, shape `(n, )`
Value of the optimization variables at which the Jacobian is
to be evaluated.
**Returns**
:py:class:`numpy.ndarray`, shape `(jac_nnz, )`
Jacobian of the constraint functions at the point x.
- .. py:function:: jacobianstructure()
Optional callback function that returns the sparsity structure of the
Jacobian of the constraints. The function should return a tuple
of two :py:class:`numpy.ndarray`\ s of integers,
the first array contains the row indices
and the second array contains the column indices of the non-zero
elements of the Jacobian. Both arrays should have the same
length of `jac_nnz`, and indexing is zero-based.
If this callback is not provided, the Jacobian is assumed
to be dense (`jac_nnz` = `m` * `n`) using row-major (C-style) order.
**Returns**
:py:class:`tuple`
Tuple containing two numpy arrays, the first array contains
the row indices and the second array contains the column
indices of the non-zero elements of the Jacobian.
- .. py:function:: hessian(x, lambda, objective_factor)
Optional callback function for evaluating the Hessian of the Lagrangian
function with respect to the primal variables :math:`x`. The Lagrangian
is given by
.. math:: \mathcal{L}(x, \lambda) = \lambda_0 f(x) + \sum_{i=1}^{m} \lambda_i g_i(x)
where :math:`\lambda_1, \ldots, \lambda_m` are the Lagrange multipliers
and :math:`\lambda_0` is the objective factor. The
function should return the values of the Hessian as calculated
using x, lambda and objective_factor. The values should be
returned as a 1-dim numpy array (using the same order as you
used when specifying the sparsity structure). If ``None``, the
Hessian is calculated numerically.
- ``hessianstructure`` : function pointer, optional (default=None)
Callback function that accepts no parameters and returns the
sparsity structure of the Hessian of the lagrangian (the row
and column indices only). If ``None``, the Hessian is assumed
to be dense.
using `x`, `lambda` and `objective_factor`. The values should be
returned as a 1-dimensional array-like structure (using the same order as you
used when specifying the sparsity structure).
If this callback is not provided, the Hessian is calculated numerically.
**Parameters**
x : :py:class:`numpy.ndarray`, shape `(n, )`
Value of the optimization variables at which the Hessian is
to be evaluated.
lambda : :py:class:`numpy.ndarray`, shape `(m, )`
Values for the Lagrange multipliers.
objective_factor : :py:class:`float`
Factor for the objective term of the Hessian (usually 1).
**Returns**
:py:class:`numpy.ndarray`, shape `(hess_nnz, )`
Hessian of the Lagrangian function at the point x.
- .. py:function:: hessianstructure()
Optional callback function that returns the sparsity structure of the
Hessian of the Lagrangian. The function should return a tuple
of two :py:class:`numpy.ndarray`\ s, the first array contains the row indices
and the second array contains the column indices of the non-zero
elements of the Hessian. Both arrays should have the same
length of `hess_nnz`, and indexing is zero-based. Furthermore,
since the Hessian is symmetric, the indices must only correspond
to the lower triangular part of the Hessian (i.e., `row >= col`).
If this callback is not provided, the Hessian is assumed
to be dense (`hess_nnz` = `n` * (`n` + 1) / 2) using row-major
(C-style) order.
**Returns**
:py:class:`tuple`
Tuple containing two numpy arrays, the first array contains
the row indices and the second array contains the column
indices of the non-zero elements of the Hessian.
- ``intermediate`` : function pointer, optional (default=None)
Optional. Callback function that is called once per iteration
(during the convergence check), and can be used to obtain
Expand Down Expand Up @@ -603,25 +696,25 @@ cdef class Problem:
Returns
-------
x : array, shape(n, )
x : :py:class:`numpy.ndarray`, shape `(n, )`
Optimal solution.
info: dictionary
info: :py:class:`dict` with the following entries
``x``: ndarray, shape(n, )
``x``: :py:class:`numpy.ndarray`, shape `(n, )`
optimal solution
``g``: ndarray, shape(m, )
``g``: :py:class:`numpy.ndarray`, shape `(m, )`
constraints at the optimal solution
``obj_val``: float
``obj_val``: :py:class:`float`
objective value at optimal solution
``mult_g``: ndarray, shape(m, )
``mult_g``: :py:class:`numpy.ndarray`, shape `(m, )`
final values of the constraint multipliers
``mult_x_L``: ndarray, shape(n, )
``mult_x_L``: :py:class:`numpy.ndarray`, shape `(n, )`
bound multipliers at the solution
``mult_x_U``: ndarray, shape(n, )
``mult_x_U``: :py:class:`numpy.ndarray`, shape `(n, )`
bound multipliers at the solution
``status``: integer
``status``: :py:class:`int`
gives the status of the algorithm
``status_msg``: string
``status_msg``: :py:class:`str`
gives the status of the algorithm as a message
"""
Expand Down Expand Up @@ -705,12 +798,12 @@ cdef class Problem:
Parameters
----------
scaled: Bool
scaled: :py:class:`bool`
Whether the scaled iterate vectors should be returned
Returns
-------
dict or None
:py:class:`dict` or `None`
A dict containing the iterate vector with keys ``"x"``,
``"mult_x_L"``, ``"mult_x_U"``, ``"g"``, and ``"mult_g"``.
If iterate vectors cannot be obtained, ``None`` is returned.
Expand Down Expand Up @@ -790,12 +883,12 @@ cdef class Problem:
Parameters
----------
scaled: Bool
scaled: :py:class:`bool`
Whether to scale the returned violations
Returns
-------
dict or None
:py:class:`dict` or `None`
A dict containing the violation vector with keys
``"x_L_violation"``, ``"x_U_violation"``, ``"compl_x_L"``,
``"compl_x_U"``, ``"grad_lag_x"``, ``"g_violation"``,
Expand Down
14 changes: 7 additions & 7 deletions cyipopt/scipy_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class IpoptProblemWrapper(object):
args : tuple, optional
Extra arguments passed to the objective function and its derivatives
(``fun``, ``jac``, ``hess``).
kwargs : dictionary, optional
kwargs : :py:class:`dict`, optional
Extra keyword arguments passed to the objective function and its
derivatives (``fun``, ``jac``, ``hess``).
jac : callable, optional
Expand All @@ -66,7 +66,7 @@ class IpoptProblemWrapper(object):
hessp : callable, optional
If ``None``, the Hessian is computed using IPOPT's numerical methods.
Explicitly defined Hessians are not yet supported for this class.
constraints : {Constraint, dict} or List of {Constraint, dict}, optional
constraints : {Constraint, :py:class:`dict`} or List of {Constraint, :py:class:`dict`}, optional
See :py:func:`scipy.optimize.minimize` for more information. Note that
the jacobian of each constraint corresponds to the `'jac'` key and must
be a callable function with signature ``jac(x) -> {ndarray,
Expand Down Expand Up @@ -431,10 +431,10 @@ def minimize_ipopt(fun,
args : tuple, optional
Extra arguments passed to the objective function and its
derivatives (``fun``, ``jac``, and ``hess``).
kwargs : dictionary, optional
kwargs : :py:class:`dict`, optional
Extra keyword arguments passed to the objective function and its
derivatives (``fun``, ``jac``, ``hess``).
method : str, optional
method : :py:class:`str`, optional
If unspecified (default), Ipopt is used.
:py:func:`scipy.optimize.minimize` methods can also be used.
jac : callable, optional
Expand All @@ -449,7 +449,7 @@ def minimize_ipopt(fun,
If `method` is one of the SciPy methods, this is a callable that
produces the inner product of the Hessian and a vector. Otherwise, an
error will be raised if a value other than ``None`` is provided.
bounds : sequence of shape(n, ) or :py:class:`scipy.optimize.Bounds`, optional
bounds : sequence of `array-like` shape(n, ) or :py:class:`scipy.optimize.Bounds`, optional
Simple bounds on decision variables. There are two ways to specify the
bounds:
Expand All @@ -468,10 +468,10 @@ def minimize_ipopt(fun,
constraint function ``fun`` must return a tuple ``(con_val, con_jac)``
consisting of the evaluated constraint ``con_val`` and the evaluated
Jacobian ``con_jac``.
tol : float, optional (default=1e-8)
tol : :py:class:`float`, optional (default=1e-8)
The desired relative convergence tolerance, passed as an option to
Ipopt. See [1]_ for details.
options : dict, optional
options : :py:class:`dict`, optional
A dictionary of solver options.
When `method` is unspecified (default: Ipopt), the options
Expand Down
1 change: 1 addition & 0 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,5 +262,6 @@
# -----------------------------------------------------------------------------
intersphinx_mapping = {
'python': ('https://docs.python.org/dev', None),
'numpy': ('https://numpy.org/doc/stable/', None),
'scipy': ('https://docs.scipy.org/doc/scipy/reference', None),
}

0 comments on commit bc8a034

Please sign in to comment.