It is not currently possible to multiply two MLinExpr objects together to create an MQuadExpr object. For example, assume we want to add the following constraint to our model:

$$\begin{align} y &= (Ax + b)^\top (Ax + b). \end{align}$$

The following code results in a `Cannot multiply with an MLinExpr from the left` GurobiError:

import gurobipy as gp

import numpy as np

m = gp.Model()

x = m.addMVar(3)

y = m.addMVar(1)

A = np.random.rand(4,3)

b = np.random.rand(4)

m.addConstr(y == (A @ x + b) @ (A @ x + b)) # error!

Instead, we add an auxiliary MVar \( z \) to our model that is equal to \( A x + b \). Then, we set \( y \) equal to the inner product \( z^\top z \):

import gurobipy as gp

import numpy as np

m = gp.Model()

x = m.addMVar(3)

y = m.addMVar(1)

z = m.addMVar(4)

A = np.random.rand(4,3)

b = np.random.rand(4)

m.addConstr(z == A @ x + b)

m.addConstr(y == z @ z)

The first version of the Python matrix API was included in the release of Gurobi 9.0. The developers are continually working on behavior like this to improve the usability of the matrix API.

### Further information

- How do I pointwise multiply a numpy vector with a (1,) MVar with the matrix-friendly Python API?
- How do I pointwise multiply two MVars with the matrix-friendly Python API?
- How do I multiply an array and a 2-D MVar object using the matrix-friendly Python API?