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,
)

Module sym_compile