Modeling and solving nonlinear problems
Version 8.3 of the Xpress Optimizer suite introduces nonlinear modeling in the Python interface. It allows for creating and solving nonlinear, possibly nonconvex problems with similar functions as for linear, quadratic, and conic problems and their mixed integer counterpart.
A nonlinear problem can be defined by creating one or more variables and then adding constraints and an objective function. This can be done using the same Python calls as one would do for other problems. The available operators are +, -, *, /, ** (which is the Python equivalent for the power operator, " ^ "). Univariate functions can also be used from the following list: sin, cos, tan, asin, acos, atan, exp, log, log10, abs, sign, and sqrt. Multivariate functions are min and max, which can receive an arbitrary number of arguments.
Examples of nonlinear constraints are as follows:
import xpress as xp import math x = xp.var () p = xp.problem () p.addVariable (x) # polynomial constraint p.addConstraint (x**4 + 2 * x**2 - 5 >= 0) # A terrible way to constrain x to be integer p.addConstraint (xp.sin (math.pi * x) == 0) p.addConstraint (x**2 * xp.sign (x) <= 4)
Note that non-native mathematical functions such as log and sin must be prefixed with xpress or its alias, xp in this case. This can be avoided by importing all symbols from xpress using the import * command as follows
from xpress import * x = var() a = sin(x)
but this hides namespaces and is usually frowned upon.
User functions are also accepted in the Python interface, and must be specified with the keyword user and the function as the first argument. They are handled in the Nonlinear solver in a transparent way, so all is needed is to define a Python function to be run as the user function and specify it in the problem with user, as in the following example:
import xpress as xp import math def mynorm (x1, x2): return math.sqrt (x1**2 + x2**2) def myfun (v1, v2, v3): return v1 / v2 + math.cos (v3) x,y = xp.var (), xp.var () p = xp.problem () p.addVariables (x,y) p.setObjective (user (mynorm, x, y)) p.addConstraint (x+y >= 2) p.addConstraint (user (myfun, x**2, x**3, 1/y) <= 3)
As a final word of caution, solving nonlinear problem requires a preprocessing step that is transparent to the user except for two steps: first, if the objective function has a nonlinear component f(x) then a new constraint (called objective transfer row or objtransrow) and a new variable, the objective transfer column or objtranscol) are called that are defined as follows:
objtransrow: - objtranscol + f(x) = 0
The resulting problem is equivalent in that the set of optimal (resp. feasible) solutions of this problem will be the same as those of the original problem. The user, however, will notice an increase by one of both the number of rows and of columns when a nonlinear objective function is set.
The second caveat is about yet another variable that may be added to the problem for reasons having to do with one of the Xpress Nonlinear solvers. This variable is called equalscol and it is fixed to 1. Its existence and value are therefore of no interest to the user.
The reader can find more information on this in the Xpress Nonlinear reference manual.