Automatic symbolic derivatives / code generation
Probably the most convenient way to use ipyopt is to let sympy compute your derivatives automatically. This however is only possible out of the box for simple functions without exotic matrix operations / special functions (i.e. Bessel functions).
At this stage, ipyopt only ships a proof of concept to show that this
is possible. Therefore the module ipyopt.sym_compile
is to be considered experimental.
Its array_sym
function can be used to declare symbolic vector
valued variables to be used in the objective function f
and the
constraint residuals g
. You then define expressions for f
and
g
. Currently the variable used in this expression has to be
exactly x
. Choosing a different letter wont work in the current
version.
The expressions for f
and g
are sufficient. ipyopt.sym_compile
will then be able to
automatically build derivatives
generate C code for all expressions
compile the C code to a python extension
load the python extension and return the contained PyCapsule objects in a dict.
The returned dict can directly be passed to ipyopt.Problem
.
Here is Ipopt’s hs071
example reimplemented using this approach:
import numpy
import ipyopt
from ipyopt.sym_compile import array_sym, SymNlp
n = 4
m = 2
x = array_sym("x", n)
f = x[0] * x[3] * (x[0] + x[1] + x[2]) + x[2]
g = [x[0] * x[1] * x[2] * x[3], x[0] * x[0] + x[1] * x[1] + x[2] * x[2] + x[3] * x[3]]
c_api = SymNlp(f, g).compile()
nlp = ipyopt.Problem(
n=n,
x_l=numpy.ones(n),
x_u=numpy.full(n, 5.0),
m=m,
g_l=numpy.array([25.0, 40.0]),
g_u=numpy.array([2.0e19, 40.0]),
**c_api,
)