JuMP broadcasting in @constraint involving expressions throws error

An example is given below.

using JuMP
model = JuMP.Model()
@expression(model, x, zeros(AffExpr, 1, 4))
@expression(model, y, zeros(AffExpr, 2, 4))
@constraint(model, y .>= x)  # A: OK
@constraint(model, x .<= y)   # B: error

The above code B throws an error:

DimensionMismatch("destination axes (Base.OneTo(1), Base.OneTo(4)) are not compatible with source axes (Base.OneTo(2), Base.OneTo(4))")

However, if x and y are variable containers, then both code A and B are correct.
Is broadcasting in @constraint involving expressions undirectional? (there is the so-called source and destination in the error info)

Any help is much appreciated. @odow

1 Like

That looks like a bug:

julia> model = JuMP.Model()
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: NO_OPTIMIZER
Solver name: No optimizer attached.

julia> @expression(model, x, zeros(AffExpr, 1, 4))
1×4 Matrix{AffExpr}:
 0  0  0  0

julia> @expression(model, y, zeros(AffExpr, 2, 4))
2×4 Matrix{AffExpr}:
 0  0  0  0
 0  0  0  0

julia> @constraint(model, y .>= x)  # A: OK
2×4 Matrix{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.GreaterThan{Float64}}, ScalarShape}}:
 0 ≥ 0.0  0 ≥ 0.0  0 ≥ 0.0  0 ≥ 0.0
 0 ≥ 0.0  0 ≥ 0.0  0 ≥ 0.0  0 ≥ 0.0

julia> @constraint(model, x .<= y)
ERROR: DimensionMismatch("destination axes (Base.OneTo(1), Base.OneTo(4)) are not compatible with source axes (Base.OneTo(2), Base.OneTo(4))")
Stacktrace:
 [1] throwdm(axdest::Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}}, axsrc::Tuple{Base.OneTo{Int64}, Base.OneTo{Int64}})
   @ Base.Broadcast ./broadcast.jl:1060
 [2] copyto!
   @ ./broadcast.jl:972 [inlined]
 [3] copyto!
   @ ./broadcast.jl:936 [inlined]
 [4] broadcast!(op::typeof(MutableArithmetics.sub_mul), A::Matrix{AffExpr}, args::Matrix{AffExpr})
   @ MutableArithmetics ~/.julia/packages/MutableArithmetics/VLWSd/src/broadcast.jl:117
 [5] broadcast_fallback!
   @ ~/.julia/packages/MutableArithmetics/VLWSd/src/broadcast.jl:173 [inlined]
 [6] broadcast!!(::typeof(MutableArithmetics.sub_mul), ::Matrix{AffExpr}, ::Matrix{AffExpr})
   @ MutableArithmetics ~/.julia/packages/MutableArithmetics/VLWSd/src/broadcast.jl:145
 [7] macro expansion
   @ ~/.julia/packages/MutableArithmetics/VLWSd/src/rewrite.jl:294 [inlined]
 [8] macro expansion
   @ ~/.julia/dev/JuMP/src/macros.jl:823 [inlined]
 [9] top-level scope
   @ REPL[6]:1

In general though, that broadcasting could be confusing. You’re probably better to use explicit indexing:

@constraint(model, [i=1:2, j=1:4], x[1, j] <= y[i, j])

Edit: opened an issue: Broadcasting mismatched expressions in constraint fails · Issue #2997 · jump-dev/JuMP.jl · GitHub

1 Like