Hi all,
May I have your suggestions on how to use add_to_expression!() to add one multi-dimension expressions to another?
Say I have an expression A with dimension (n x m), and an expression B with dimension (n x m).
I received the following errors if I coded add_to_expression!(A, B):
ERROR: LoadError: MethodError: no method matching add_to_expression!(::Matrix{JuMP.AffExpr}, ::Matrix{JuMP.AffExpr})
Closest candidates are:
add_to_expression!(::JuMP.GenericAffExpr{C, V}, ::V) where {C, V} at /Users/qingyuxu/.julia/packages/JuMP/zn6NT/src/aff_expr.jl:382
add_to_expression!(::JuMP.GenericAffExpr{C, V}, ::V, ::Union{Number, LinearAlgebra.UniformScaling}) where {C, V} at /Users/qingyuxu/.julia/packages/JuMP/zn6NT/src/aff_expr.jl:408
add_to_expression!(::JuMP.GenericQuadExpr{C, V}, ::Union{JuMP.GenericAffExpr{C, V}, V}, ::Union{Number, LinearAlgebra.UniformScaling}) where {C, V} at /Users/qingyuxu/.julia/packages/JuMP/zn6NT/src/quad_expr.jl:314
...
P.S. I used to do A +=B, but JuMP warns me ā+=ā is less efficient. Also, if A and B are vectors, add_to_expressions!() seems to work well.
P.S.2 I used += to get rid of the loops in the first place, so I am afraid looping through dimensions cannot help me here.
Thereās no explicit support for this, but you have a couple of options.
Assuming A and B have the same dimensions, then you can use broadcasting:
add_to_expression!.(A, B)
This will call add_to_expression! on each element pair of A and B.
Second, although I see your p.p.s., just use a loop! It wonāt be any slower.
Third, if your problem is small enough, just use +=. Itās a warning, not an error. So if itās fast enough for you, donāt worry about the ābestā thing to do.
You might also be able to restructure your code to avoid constructing expressions outside the macros. Hereās an explanation in the docs for why we warn that += is less efficient: Performance tips Ā· JuMP
Thanks @odow, this is just wonderful! I love the idea of broadcasting!
For loop not being slower, is the reason because broadcasting or += will undergo looping anyway?
(the main reason I want to use += or add_to_expressions!, but not loop, is that I want to reduce the length of the code)
for (a, b) in zip(A, B)
add_to_expression!(a, b)
end
is essentially equivalent to
add_to_expression!.(A, B)
There should be minimal performance differences.
I love the idea of broadcasting!
And yes! Quite powerful and applicable to any Julia function, not just JuMP. This is one issue we struggle with in terms of documentation. We donāt provide explicit syntax in JuMP for a lot of operations because you can compose other Julia operators to the same effect.