(So this is perhaps the reason why we should only use normal Arrays in JuMP.)
And a further question is, is there a more efficient in-place method that refill a container with new constraints (without allocating new container)?
julia> c = @constraint(model, [i in 1:3], 0 == 1);
julia> delete.(model, c);
julia> c
3-element Vector{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.EqualTo{Float64}}, ScalarShape}}:
InvalidConstraintRef
InvalidConstraintRef
InvalidConstraintRef
julia> c .= @constraint(model, [i in 1:3], 0 == 2) # What is the most efficient way to do this?
3-element Vector{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.EqualTo{Float64}}, ScalarShape}}:
0 == 2
0 == 2
0 == 2
This is another Julia interface issue: the set of methods to implement to support all possible behaviors is not well defined. In this case, we’re just missing some methods. But I’m also not really sure I want to support this.
I think needless. Basic julia Array for containing variables and constraints are enough. We don’t need Dense or SparseAxisArray, they are hard to use Although they are not supported well, they can be used sometimes with minor modification, e.g.
julia> model = JuMP.Model(); v = [4, 2];
julia> JuMP.@variable(model, x[s = 1:2, c = 1:v[s]]);
julia> x[2, :]
JuMP.Containers.SparseAxisArray{JuMP.VariableRef, 1, Tuple{Int64}} with 2 entries:
[1] = x[2,1]
[2] = x[2,2]
julia> ans' # ERROR: `Base.size` is not implemented
julia> [i for i in x[2, :]]
2-element Vector{JuMP.VariableRef}:
x[2,1]
x[2,2]
julia> ans'
1×2 adjoint(::Vector{JuMP.VariableRef}) with eltype JuMP.VariableRef:
x[2,1] x[2,2]