@NLexpression involving multilinear algebra

What is the recommended way to implement

@NLexpression(model, tr(kron(A,B)*kron(C,D,E))

where A,B,C,D,E are (references of) matrices of JuMP variables created by @variable of compatible sizes (so matrix multiplication can be performed).

There isn’t a good way to do this in JuMP at the moment. See also: WIP: [Nonlinear] begin experiments with NonlinearExpr by odow · Pull Request #3106 · jump-dev/JuMP.jl · GitHub

You might be interested instead in GitHub - jump-dev/Convex.jl: A Julia package for disciplined convex programming

1 Like

Thank you; I’ll have a look at the WIP branch.

Do you @odow think the following could work?

# L (and likewise R) is intended to be the left and right matrix
# L::Matrix{NonlinearExpression} built by hand at the Julia level (and not in JuMP)
@NLexpression(model, sum(L[i,j]*R[j,i] for i in 1:size(L,1) for j in 1:size(L,2))

Here if I could build ANL::Matrix{NonlinearExpression} where each entry is just a variable in the original A but as a nonlinear expression, e.g. ANL[1,1] = @NLexpression(model, A[1,1]) then kron and matrix multiplication could work at the Julia level.

One approach you could do is to create a series of projected quadratic equality constraints:

model = Model()
@variable(model, A[1:2, 1:2])
@variable(model, B[1:2, 1:2])
@variable(model, C[1:4, 1:4])
@variable(model, D[1:4, 1:4])
@constraint(model, D .== kron(A, B))
@variable(model, E[1:16, 1:16])
@constraint(model, E .== kron(D, C))  # kron(A, B, C)
@objective(model, Min, tr(E))

You could also write the kron expression as an explicit outer product with sums, similar to what you’re doing.

I’ll have a look at the WIP branch.

To clarify, you shouldn’t use this. It’s still under development.

1 Like