jump-dev / JuMP.jl

Modeling language for Mathematical Optimization (linear, mixed-integer, conic, semidefinite, nonlinear)
http://jump.dev/JuMP.jl/
Other
2.17k stars 390 forks source link

Error when adding a constraint with a partially initialized Symmetric matrix #3771

Closed araujoms closed 2 weeks ago

araujoms commented 2 weeks ago

If I have a Symmetric or Hermitian matrix that contains some #undef, I get an error when trying to use that in a constraint, even though the undefined elements shouldn't affect the result of the calculation. MWE:

using LinearAlgebra
using JuMP
model = Model()
@variable(model, x[1:4])
M = Matrix{AffExpr}(undef,(2,2))
M[1]=x[1]
M[3]=x[2]
M[4]=x[3]
M2=Symmetric(M)
@constraint(model, M2 == Symmetric(randn(2,2)))

Note that if I complete the matrix then the constraint is added correctly:

M[2]=x[4]
@constraint(model, M2 == Symmetric(randn(2,2)))

Of course, the code I'm showing here doesn't make any sense, but this is just a MWE, I swear I got this error when doing a legitimate computation.

odow commented 2 weeks ago

Here's the full stack trace:

julia> @constraint(model, M2 == Symmetric(randn(2,2)))
ERROR: UndefRefError: access to undefined reference
Stacktrace:
  [1] getindex
    @ ./essentials.jl:14 [inlined]
  [2] getindex
    @ ./multidimensional.jl:696 [inlined]
  [3] _broadcast_getindex
    @ ./broadcast.jl:675 [inlined]
  [4] _getindex
    @ ./broadcast.jl:705 [inlined]
  [5] _broadcast_getindex
    @ ./broadcast.jl:681 [inlined]
  [6] getindex
    @ ./broadcast.jl:636 [inlined]
  [7] macro expansion
    @ ./broadcast.jl:1004 [inlined]
  [8] macro expansion
    @ ./simdloop.jl:77 [inlined]
  [9] copyto!
    @ ./broadcast.jl:1003 [inlined]
 [10] copyto!
    @ ./broadcast.jl:956 [inlined]
 [11] copy
    @ ./broadcast.jl:928 [inlined]
 [12] materialize
    @ ./broadcast.jl:903 [inlined]
 [13] broadcast_preserving_zero_d
    @ ./broadcast.jl:892 [inlined]
 [14] -(A::Matrix{AffExpr}, B::Matrix{Float64})
    @ Base ./arraymath.jl:8
 [15] -(A::Symmetric{AffExpr, Matrix{AffExpr}}, B::Symmetric{Float64, Matrix{Float64}})
    @ LinearAlgebra ~/.julia/juliaup/julia-1.10.3+0.x64.apple.darwin14/share/julia/stdlib/v1.10/LinearAlgebra/src/symmetric.jl:506
 [16] sub_mul
    @ ~/.julia/packages/MutableArithmetics/iovKe/src/MutableArithmetics.jl:38 [inlined]
 [17] operate
    @ ~/.julia/packages/MutableArithmetics/iovKe/src/interface.jl:210 [inlined]
 [18] operate_fallback!!
    @ ~/.julia/packages/MutableArithmetics/iovKe/src/interface.jl:624 [inlined]
 [19] operate!!(op::typeof(MutableArithmetics.sub_mul), x::Symmetric{AffExpr, Matrix{…}}, args::Symmetric{Float64, Matrix{…}})
    @ MutableArithmetics ~/.julia/packages/MutableArithmetics/iovKe/src/rewrite.jl:97
 [20] macro expansion
    @ ~/.julia/packages/MutableArithmetics/iovKe/src/rewrite.jl:325 [inlined]
 [21] macro expansion
    @ ~/.julia/packages/JuMP/Gwn88/src/macros.jl:257 [inlined]
 [22] macro expansion
    @ ~/.julia/packages/JuMP/Gwn88/src/macros/@constraint.jl:131 [inlined]
 [23] macro expansion
    @ ~/.julia/packages/JuMP/Gwn88/src/macros.jl:393 [inlined]
 [24] top-level scope
    @ REPL[140]:1

This does't seem easily fixable, because this is not specific to JuMP:

julia> M = Matrix{BigInt}(undef,(2, 2))
2×2 Matrix{BigInt}:
 #undef  #undef
 #undef  #undef

julia> M[1] = 1
1

julia> M[3] = 2
2

julia> M[4] = 3
3

julia> LHS = Symmetric(M)
2×2 Symmetric{BigInt, Matrix{BigInt}}:
 1  2
 2  3

julia> RHS = Symmetric(randn(2, 2))
2×2 Symmetric{Float64, Matrix{Float64}}:
 0.529429   0.0591194
 0.0591194  0.267419

julia> LHS - RHS
ERROR: UndefRefError: access to undefined reference
Stacktrace:
  [1] getindex
    @ ./essentials.jl:14 [inlined]
  [2] getindex
    @ ./multidimensional.jl:696 [inlined]
  [3] _broadcast_getindex
    @ ./broadcast.jl:675 [inlined]
  [4] _getindex
    @ ./broadcast.jl:705 [inlined]
  [5] _broadcast_getindex
    @ ./broadcast.jl:681 [inlined]
  [6] getindex
    @ ./broadcast.jl:636 [inlined]
  [7] macro expansion
    @ ./broadcast.jl:1004 [inlined]
  [8] macro expansion
    @ ./simdloop.jl:77 [inlined]
  [9] copyto!
    @ ./broadcast.jl:1003 [inlined]
 [10] copyto!
    @ ./broadcast.jl:956 [inlined]
 [11] copy
    @ ./broadcast.jl:928 [inlined]
 [12] materialize
    @ ./broadcast.jl:903 [inlined]
 [13] broadcast_preserving_zero_d
    @ ./broadcast.jl:892 [inlined]
 [14] -(A::Matrix{BigInt}, B::Matrix{Float64})
    @ Base ./arraymath.jl:8
 [15] -(A::Symmetric{BigInt, Matrix{BigInt}}, B::Symmetric{Float64, Matrix{Float64}})
    @ LinearAlgebra ~/.julia/juliaup/julia-1.10.3+0.x64.apple.darwin14/share/julia/stdlib/v1.10/LinearAlgebra/src/symmetric.jl:506
 [16] top-level scope
    @ REPL[163]:1
araujoms commented 2 weeks ago

Oh, sorry for wasting your time. I thought the problem was in JuMP's code; the underlying Julia issue has already been fixed by JuliaLang/julia#52942. I've just tested with the current git and it works.