Cannot multiply a quadratic expression by an affine expression

I am trying to define an expression P = Q’ * R * Q using @expression but it is not cooperating. I tried to split the matrix product and even use @NLexpression macro but no luck. Can someone suggest a way to define P?

using LinearAlgebra
using JuMP
model = Model()
n = 5
@variable(model, R[1:n, 1:n] , Symmetric)
@variable(model, Q[1:n, 1:n] , Symmetric)

#method 1

@expression(model, P , Q’ * R * Q)

#method 2

@expression(model, P1, R * Q)

@expression(model, P2, Q’ * P1 )

#method 3

@expression(model, P1, R * Q)

@NLexpression(model, P2, Q’ * P1 )

println(model)

I think that’s because all nonlinear expressions must be scalars?

Yeah that’s what the error message says actually. Does that mean I can’t define matrix product at all?

Does that mean I can’t define matrix product at all?

Correct. In the current version of JuMP, you cannot create expressions like X * Y * Z where X, Y and Z are arrays of JuMP variables.

One work-around is:

using JuMP, LinearAlgebra
n = 5
model = Model()
@variable(model, R[1:n, 1:n], Symmetric)
@variable(model, Q[1:n, 1:n], Symmetric)
@variable(model, RQ[1:n, 1:n], Symmetric)
@constraint(model, RQ .== R * Q)
@expression(model, P, Q' * QR)

This limitation is fixed in the work-in-progress nonlinear rewrite: https://github.com/jump-dev/JuMP.jl/pull/3106.

Thanks for the help. Apparently the workaround still doesn’t work. I got the following error

MethodError: no method matching *(::Adjoint{VariableRef, Symmetric{VariableRef, Matrix{VariableRef}}}, ::Type{QR})
Closest candidates are:
*(::Any, ::Any, ::Any, ::Any…) at /Volumes/Julia-1.7.2/Julia-1.7.app/Contents/Resources/julia/share/julia/base/operators.jl:655
*(::Union{MathOptInterface.ScalarAffineFunction{T}, MathOptInterface.ScalarQuadraticFunction{T}, MathOptInterface.VectorAffineFunction{T}, MathOptInterface.VectorQuadraticFunction{T}}, ::T) where T at ~/.julia/packages/MathOptInterface/LqT2k/src/Utilities/functions.jl:3300
*(::AbstractMatrix{T}, ::LinearAlgebra.AbstractRotation{S}) where {T, S} at /Volumes/Julia-1.7.2/Julia-1.7.app/Contents/Resources/julia/share/julia/stdlib/v1.7/LinearAlgebra/src/givens.jl:20

Stacktrace:
[1] operate(::typeof(*), ::Adjoint{VariableRef, Symmetric{VariableRef, Matrix{VariableRef}}}, ::Type)
@ MutableArithmetics ~/.julia/packages/MutableArithmetics/Lnlkl/src/interface.jl:186
[2] operate(::typeof(MutableArithmetics.add_mul), ::MutableArithmetics.Zero, ::Adjoint{VariableRef, Symmetric{VariableRef, Matrix{VariableRef}}}, ::Type)
@ MutableArithmetics ~/.julia/packages/MutableArithmetics/Lnlkl/src/rewrite.jl:40
[3] operate_fallback!!(::MutableArithmetics.IsNotMutable, ::typeof(MutableArithmetics.add_mul), ::MutableArithmetics.Zero, ::Adjoint{VariableRef, Symmetric{VariableRef, Matrix{VariableRef}}}, ::Type)
@ MutableArithmetics ~/.julia/packages/MutableArithmetics/Lnlkl/src/interface.jl:555
[4] operate!!(::typeof(MutableArithmetics.add_mul), ::MutableArithmetics.Zero, ::Adjoint{VariableRef, Symmetric{VariableRef, Matrix{VariableRef}}}, ::Type)
@ MutableArithmetics ~/.julia/packages/MutableArithmetics/Lnlkl/src/rewrite.jl:94
[5] macro expansion
@ ~/.julia/packages/MutableArithmetics/Lnlkl/src/rewrite.jl:294 [inlined]
[6] macro expansion
@ ~/.julia/packages/JuMP/60Bnj/src/macros.jl:1352 [inlined]
[7] top-level scope
@ In[1]:8
[8] eval
@ ./boot.jl:373 [inlined]
[9] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
@ Base ./loading.jl:1196

1 Like

I made a typo. Should be RQ, not QR :slight_smile:

Perfect thanks a lot!!

1 Like