How to view which model the variable belongs to?

Hi, all

Here, I create two variables which belong to two different model, respectively, like:
m1 = Model()
m2 = Model()
@variable(m1, x)
@variable(m2, y)

How can I know x and y belong to which model?

I already know if i use the code following:
I may get the information about model m1.

but if i get a AffExpr, like z = x1 + x2, x1 and x2 belong to model m1
z.model will push a error

Can some function can show the model information about AffExpr ?

How can I know x and y belong to which model?

For variables there is

julia> owner_model(x) === m1

julia> owner_model(x) === m2

julia> owner_model(y) === m1

julia> owner_model(y) === m2

But not for AffExpr.

julia> z = x + x
2 x

julia> owner_model(z)
ERROR: MethodError: no method matching owner_model(::AffExpr)
Closest candidates are:
  owner_model(::ConstraintRef) at /Users/oscar/.julia/packages/JuMP/b3hGi/src/constraints.jl:39
  owner_model(::AbstractVariableRef) at /Users/oscar/.julia/packages/JuMP/b3hGi/src/variables.jl:179
 [1] top-level scope
   @ REPL[20]:1

julia> owner_model(first(z.terms)[1])
A JuMP Model
Feasibility problem with:
Variable: 1
Model mode: AUTOMATIC
CachingOptimizer state: NO_OPTIMIZER
Solver name: No optimizer attached.
Names registered in the model: x

Why do you need this? You can probably structure your code to avoid needing this lookup.

For a very simple reason, I want to create a generalized constraint with absolute value, but I don’t want to write a few lines of constraints every time I create it. So I built a function, as shown below.

function abs_(model, x)
n, m = size(x)
str1 = randstring(5)
absx = @variable(model, [1:n, 1:m])
@constraints(model, begin
x .<= absx
x .>= -absx
return absx

But I’m very lazy. I don’t even want to write the word “model”, so I’m looking for a way to identify the model to which the input variable or expression belongs

1 Like

I’ve opend a feature request: Implement owner_model for expressions · Issue #2678 · jump-dev/JuMP.jl · GitHub

For now, you could do something like this:

using JuMP
_owner_model(x::VariableRef) = owner_model(x)
_owner_model(x::AffExpr) = owner_model(first(x.terms)[1])
function my_abs(x::Union{VariableRef,AffExpr})
    model = _owner_model(x)
    abs_x = @variable(model)
    @constraint(model, x <= abs_x)
    @constraint(model, x >= abs_x)
    return abs_x

model = Model()
@variable(model, x[1:2, 1:2])
y = my_abs.(x)
z = my_abs.(x .+ x')

Oh, thank you very much!
At present, the best solution seems to be to add a new method whenever I encounter an error code.

1 Like