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).

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