Skip to main content

Computing L1 and L2 matrix norms in objective



1 comment

  • Riley Clement
    Gurobi Staff Gurobi Staff

    Hi Gabriel,

    Is there a way to add all absolute values of an MLinExpr object in gurobi?

    The short answer is: no, you have to introduce auxiliary variables.

    It looks like you're wanting to set the 1-norm as the objective function:


    You can appeal to gurobipy.norm here but it can't directly use MLinExpr in the arguments, either a list of variables of a 1-dim MVar, so you need to introduce auxiliary variables:

    aux1 = model.addMVar((N_1, N_1), lb=-float("inf"))
    model.addConstr(aux1 == delta)
    aux2 = model.addVar()
    model.addConstr(aux2 == gp.norm(aux1.reshape((N_1*N_1)),1))

    Yes, this is clunky, and we will almost certainly simplify this in a future release.

    Additionally, I would also like to minimize these norms only on the off-diagonal entries of delta. Does gurobipy offer functions similar to np.triu and np.tril? Or is it possible to select entries of delta with a mask of indices?

    Nothing like triu or tril unfortunately but numpy.triu_indices will come in handy:

    k = 1 # diagonal offset
    n,m = delta.shape
    i,j = np.triu_indices(n=n,m=n,k=k)
    off_diag_vars = delta[i,j] # pulls the expressions into 1D MLinExpr
    aux1 = model.addMVar(off_diag_vars.shape, lb=-float("inf"))
    model.addConstr(aux1 == off_diag_vars)
    aux2 = model.addVar()
    model.addConstr(aux2 == gp.norm(aux1,1))

    - Riley




Please sign in to leave a comment.