Python API - MQuadExpr#

class MQuadExpr#

Gurobi quadratic matrix expression object. Quadratic matrix expressions are used to build quadratic objective functions and quadratic constraints. They are temporary objects that typically have short lifespans.

You generally build quadratic matrix expressions using overloaded operators. For example, if x is an MVar object and A is a 2-D matrix (dense or sparse), then x @ A @ x and x @ x are both MQuadExpr objects. Arithmetic operations supported on MQuadExpr objects are addition, subtraction (e.g., expr = x @ A @ x - y @ B @ y), and multiplication by a constant (e.g. expr = 2 * x @ A @ y).

An MQuadExpr object has a shape representing its dimensions, a size that counts the total number of elements, and an ndim that gives the number of dimensions. These properties lean on their counterparts in NumPy’s ndarray class.

When working with MQuadExpr objects, you need to make sure that the operands’ shapes are compatible. The first step in building an MQuadExpr is often to build an MLinExpr (e.g., |expr = x @ A @ x|), so we refer you to the discussion of MLinExpr shape rules first. Rules for other operations on MQuadExpr objects are generally similar to those for MLinExpr objects, and both classes follow NumPy rules, so we refer you to the NumPy documentation for details.

The full list of overloaded operators on MQuadExpr objects is as follows: +, +=, -, -=, *, and *=. In Python parlance, we’ve defined the following QuadExpr functions: __add__, __radd__, __iadd__, __sub__, __rsub__, __isub__, __neg__, __mul__, __rmul__, and __imul__.

We’ve also overloaded the comparison operators (==, <=, and >=), to make it easier to build constraints from quadratic expressions.

clear()#

Reset this expression to all zeros.

Example:
expr = 2 * model.addMVar(3)**2 + 1
expr.clear()  # All three entries are reset to constant 0.0
copy()#

Create a copy of a quadratic matrix expression.

Returns:

Copy of expression object.

Example:
orig = x @ Q @ x + p @ x
copy = orig.copy()
copy += 2.0  # Leaves 'orig' untouched
getValue()#

Compute the value of a quadratic matrix expression using the current solution.

Returns:

Value of expression as an ndarary.

Example:
qexpr = x @ A @ x
model.addConstr(qexpr == 0)
model.optimize()
val = qexpr.getValue()
item()#

For an MQuadExpr that contains a single element, returns a copy of that element as a QuadExpr object. Calling this method on an MQuadExpr with more than one element will raise a ValueError.

Returns:

A QuadExpr object

Example:
mqe = 2 * model.addMVar((2, 2))** + 1
mqe_sub = mqe[0, 1]  # A 0-D MQuadExpr encapsulating one QuadExpr object
mqe_qe = mqe[0, 1].item()  # A copy of the resident QuadExpr object
property ndim#

The number of dimensions in this expression.

Returns:

An int

Example:
expr1 = 2 * model.addMVar((3,))**2 + 1
print(expr1.ndim)  #  "1"
expr2 =  2 * model.addMVar((1, 3))**2 + 1
print(expr2.ndim)  #  "2"
property shape#

The shape of this expression.

Returns:

A tuple of int

Example:
expr1 = 2 * model.addMVar((3,))**2 + 1
print(expr1.shape)  #  "(3,)"
expr2 = 2 * model.addMVar((1, 3))**2 + 1
print(expr2.shape)  #  "(1, 3)"
property size#

The total number of elements in this expression.

Returns:

An int

Example:
expr1 = 2 * model.addMVar((3,))**2 + 1
print(expr1.size)  #  "3"
expr2 = 2 * model.addMVar((2, 3))**2 + 1
print(expr2.size)  #  "6"
sum(axis=None)#

Sum the elements of this MQuadExpr; returns an MQuadExpr object.

Parameters:

axis – An int, or None. Sum along the specified axis. If set to None, summation takes place along all axes of this MQuadExpr.

Returns:

An MQuadExpr representing the sum.

Example:
expr = 2 * model.addMVar((2, 2))**2 - 1
sum_row = expr.sum(axis=0)  # Sum along the rows
sum_col = expr.sum(axis=1)  # Sum along the columns
sum_all = expr.sum()  # Sum all elements, result is 0-D
zeros(shape)#

Construct an all-zero MQuadExpr object of given shape.

Parameters:

shape – An int, or tuple of int. The requested shape.

Returns:

An MQuadExpr, initialized to zero.

Example:
mle = gp.MQuadExpr.zeros(3)
x = model.addMVar(3)
mle += 2 * x**2
__eq__()#

Overloads the == operator, creating a TempConstr object that captures an equality constraint. The result is typically immediately passed to Model.addConstr.

Returns:

A TempConstr object.

Example:
m.addConstr(x @ Q @ y == 1)
__ge__(arg)#

Overloads the >= operator, creating a TempConstr object that captures an inequality constraint. The result is typically immediately passed to Model.addConstr.

Returns:

A TempConstr object.

Example:
m.addConstr(x @ Q @ y >= 1)
__getitem__()#

Index or slice this MQuadExpr.

Returns:

An MQuadExpr object.

Example:
mqe = 2 * m.addMVar((2,2))**2
col0 = mqe[:, 0]  # The first column of mqe, 1-D result
elmt = mqe[1, 0]  # The element at position (1, 0), 0-D result

You can index and slice MQuadExpr objects like you would index NumPy’s ndarray, and indexing behavior is straightforward to understand if you only read from the returned object. When you write to the returned object, be aware some kinds of indexing return NumPy views on the indexed expression (e.g., slices), while others result in copies being returned (e.g., fancy indexing). Here is an example:

Example:
mqe = 2 * m.addMVar(4)**2
leading_part_1 = mqe[:2]
leading_part_2 = mqe[[0,1]]
leading_part_1 += 99  # This modifies mqe, too
leading_part_2 += 1  # This doesn't modify mqe

If you are unsure about any of these concepts and want to avoid any risk of accidentally writing back to the indexed object, you should always combine indexing with the copy method.

Example:
expr = 2 * model.addMVar((2,2))**2 + 1
first_col = expr[:, 0].copy()
first_col =+ 1  # Leaves expr untouched
__le__()#

Overloads the <= operator, creating a TempConstr object that captures an inequality constraint. The result is typically immediately passed to Model.addConstr.

Returns:

A TempConstr object.

Example:
m.addConstr(x @ Q @ y <= 1)
__setitem__()#

Assign into this MQuadExpr.

Example:
mqe = 2 * model.addMVar((2,2))**2
v = model.addVar()
w = model.addVar()
mqe[:] = v + 1  # Overwrite mqe with four independent copies of 'v+1'
mqe[1, 1] = w*w  # Overwrite the entry at position (1, 1) of mqe with 'w**2'

Note that assignment into an existing MQuadExpr always entails multiple data copies and is less efficient than building matrix expressions through operations with MVar objects.