Search code examples
pyomononlinear-optimizationxpress-optimizer

How to use Xpress NonLInear with Pyomo?


I wrote a dummy nonlinear example with Pyomo:

import pyomo.environ as pyo
model = pyo.ConcreteModel()
model.N = pyo.RangeSet(0, 2)
model.x = pyo.Var(model.N, within=pyo.NonNegativeReals, bounds=[5, 1000])
model.objective = pyo.Objective(expr=pyo.quicksum(model.x[j] for j in model.N))
def constraint_rule(model):
    return pyo.sqrt(model.x[0] + model.x[1]) == model.x[2]
    # return model.x[0] + model.x[1] <= model.x[2]
model.constraint = pyo.Constraint(rule=constraint_rule)
# solver = pyo.SolverFactory('knitroampl')
solver = pyo.SolverFactory('xpress_direct')
results = solver.solve(model, tee=True)

I can solve it with Knitro. I can solve a linear model with Xpress. But I didn't find how to solve the nonlinear model with Xpress. I get this error:

Traceback (most recent call last):
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/xpress_direct.py", line 258, in _get_expr_from_pyomo_expr
    xpress_expr, referenced_vars = self._get_expr_from_pyomo_repn(repn, max_degree)
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/xpress_direct.py", line 231, in _get_expr_from_pyomo_repn
    raise DegreeError('XpressDirect does not support expressions of degree {0}.'.format(degree))
pyomo.solvers.plugins.solvers.xpress_direct.DegreeError: XpressDirect does not support expressions of degree None.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "pyomo_xpress.py", line 12, in <module>
    results = solver.solve(model, tee=True)
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/direct_solver.py", line 120, in solve
    self._presolve(*args, **kwds)
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/direct_solver.py", line 63, in _presolve
    self._set_instance(model, kwds)
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/xpress_direct.py", line 319, in _set_instance
    self._add_block(model)
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/xpress_direct.py", line 322, in _add_block
    DirectOrPersistentSolver._add_block(self, block)
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/direct_or_persistent_solver.py", line 218, in _add_block
    self._add_constraint(con)
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/xpress_direct.py", line 339, in _add_constraint
    xpress_expr, referenced_vars = self._get_expr_from_pyomo_expr(
  File "/home/florian/.local/lib/python3.8/site-packages/pyomo/solvers/plugins/solvers/xpress_direct.py", line 262, in _get_expr_from_pyomo_expr
    raise DegreeError(msg)
pyomo.solvers.plugins.solvers.xpress_direct.DegreeError: XpressDirect does not support expressions of degree None.
expr: sqrt(x[0] + x[1]) - x[2]

Solution

  • The XpressDirect connector currently only supports linear and quadratic constraints/objectives. General non-linear expressions (like square root) are supported at the moment.

    You can square both sides of your equations, that should work.