Initializing help system before first use

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) 2*x1, 2*x2)

def myfun(v1, v2, v3):
  return v1 / v2 + math.cos(v3)

x,y = xp.var(), xp.var()

p = xp.problem()

p.addVariable(x,y)

p.setObjective(xp.user (mynorm, x, y, derivatives=True))

p.addConstraint(x+y >= 2)
p.addConstraint(xp.user (myfun, x**2, x**3, 1/y) <= 3)

Note that user functions can be specified so that they can return derivatives. If we do not wish to return derivatives, a Python function in k variables must return a single number. If we want to provide the solver with derivatives, then the function must return a tuple of k+1 numbers.

When defining a user function that provides derivatives (see mynorm in the example), we must set the derivative=True parameter in the xpress.user call. The derivative parameter is False by default. If a function returns a tuple of values but it is defined with derivatives=False or, viceversa, if it returns a single value but it is defined with derivatives=True, the behaviour is undefined.

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.

It should also be noted that the control xslp_postsolve is set to 1 by default when the solver uses the SLP nonlinear solver. This is necessary to ensure that the solution retrieved after a solve() or nlpoptimize() call refers to the original problem and not to a possible reformulation. The reader can find more information on this in the Xpress Nonlinear reference manual.

© 2001-2020 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.