Variable API

More information can be found in the Variables section of the manual.

JuMP.@variableMacro
@variable(model, kw_args...)

Add an anonymous variable to the model model described by the keyword arguments kw_args and returns the variable.

@variable(model, expr, args..., kw_args...)

Add a variable to the model model described by the expression expr, the positional arguments args and the keyword arguments kw_args. The expression expr can either be (note that in the following the symbol <= can be used instead of and the symbol >=can be used instead of )

  • of the form varexpr creating variables described by varexpr;
  • of the form varexpr ≤ ub (resp. varexpr ≥ lb) creating variables described by varexpr with upper bounds given by ub (resp. lower bounds given by lb);
  • of the form varexpr == value creating variables described by varexpr with fixed values given by value; or
  • of the form lb ≤ varexpr ≤ ub or ub ≥ varexpr ≥ lb creating variables described by varexpr with lower bounds given by lb and upper bounds given by ub.
  • of the form varexpr in set creating variables described by varexpr constrained to belong to set, see Variables constrained on creation.

The expression varexpr can either be

  • of the form varname creating a scalar real variable of name varname;
  • of the form varname[...] or [...] creating a container of variables (see Containers in macros).

The recognized positional arguments in args are the following:

  • Bin: Sets the variable to be binary, i.e. either 0 or 1.
  • Int: Sets the variable to be integer, i.e. one of ..., -2, -1, 0, 1, 2, ...
  • Symmetric: Only available when creating a square matrix of variables, i.e. when varexpr is of the form varname[1:n,1:n] or varname[i=1:n,j=1:n]. It creates a symmetric matrix of variable, that is, it only creates a new variable for varname[i,j] with i ≤ j and sets varname[j,i] to the same variable as varname[i,j]. It is equivalent to using varexpr in SymMatrixSpace() as expr.
  • PSD: The square matrix of variable is both Symmetric and constrained to be positive semidefinite. It is equivalent to using varexpr in PSDCone() as expr.

The recognized keyword arguments in kw_args are the following:

  • base_name: Sets the name prefix used to generate variable names. It corresponds to the variable name for scalar variable, otherwise, the variable names are set to base_name[...] for each index ... of the axes axes.
  • lower_bound: Sets the value of the variable lower bound.
  • upper_bound: Sets the value of the variable upper bound.
  • start: Sets the variable starting value used as initial guess in optimization.
  • binary: Sets whether the variable is binary or not.
  • integer: Sets whether the variable is integer or not.
  • variable_type: See the "Note for extending the variable macro" section below.
  • set: Equivalent to using varexpr in value as expr where value is the value of the keyword argument.
  • container: Specify the container type, see Containers in macros.

Examples

The following are equivalent ways of creating a variable x of name x with lower bound 0:

# Specify everything in `expr`
@variable(model, x >= 0)
# Specify the lower bound using a keyword argument
@variable(model, x, lower_bound=0)
# Specify everything in `kw_args`
x = @variable(model, base_name="x", lower_bound=0)

The following are equivalent ways of creating a DenseAxisArray of index set [:a, :b] and with respective upper bounds 2 and 3 and names x[a] and x[b]. The upper bound can either be specified in expr:

ub = Dict(:a => 2, :b => 3)
@variable(model, x[i=keys(ub)] <= ub[i])

# output
1-dimensional DenseAxisArray{VariableRef,1,...} with index sets:
    Dimension 1, Symbol[:a, :b]
And data, a 2-element Array{VariableRef,1}:
 x[a]
 x[b]

or it can be specified with the upper_bound keyword argument:

@variable(model, y[i=keys(ub)], upper_bound=ub[i])

# output
1-dimensional DenseAxisArray{VariableRef,1,...} with index sets:
    Dimension 1, Symbol[:a, :b]
And data, a 2-element Array{VariableRef,1}:
 y[a]
 y[b]

Note for extending the variable macro

The single scalar variable or each scalar variable of the container are created using add_variable(model, build_variable(_error, info, extra_args...; extra_kw_args...)) where

  • model is the model passed to the @variable macro;
  • _error is an error function with a single String argument showing the @variable call in addition to the error message given as argument;
  • info is the VariableInfo struct containing the information gathered in expr, the recognized keyword arguments (except base_name and variable_type) and the recognized positional arguments (except Symmetric and PSD);
  • extra_args are the unrecognized positional arguments of args plus the value of the variable_type keyword argument if present. The variable_type keyword argument allows the user to pass a position argument to build_variable without the need to give a positional argument to @variable. In particular, this allows the user to give a positional argument to the build_variable call when using the anonymous single variable syntax @variable(model, kw_args...); and
  • extra_kw_args are the unrecognized keyword argument of kw_args.

Examples

The following creates a variable x of name x with lower_bound 0 as with the first example above but does it without using the @variable macro

info = VariableInfo(true, 0, false, NaN, false, NaN, false, NaN, false, false)
JuMP.add_variable(model, JuMP.build_variable(error, info), "x")

The following creates a DenseAxisArray of index set [:a, :b] and with respective upper bounds 2 and 3 and names x[a] and x[b] as with the second example above but does it without using the @variable macro

# Without the `@variable` macro
x = JuMP.Containers.container(i -> begin
        info = VariableInfo(false, NaN, true, ub[i], false, NaN, false, NaN, false, false)
        x[i] = JuMP.add_variable(model, JuMP.build_variable(error, info), "x[$i]")
    end, JuMP.Containers.vectorized_product(keys(ub)))

# output
1-dimensional DenseAxisArray{VariableRef,1,...} with index sets:
    Dimension 1, Symbol[:a, :b]
And data, a 2-element Array{VariableRef,1}:
 x[a]
 x[b]

The following are equivalent ways of creating a Matrix of size N x N with variables custom variables created with a JuMP extension using the Poly(X) positional argument to specify its variables:

# Using the `@variable` macro
@variable(model, x[1:N,1:N], Symmetric, Poly(X))
# Without the `@variable` macro
x = Matrix{JuMP.variable_type(model, Poly(X))}(N, N)
info = VariableInfo(false, NaN, false, NaN, false, NaN, false, NaN, false, false)
for i in 1:N, j in i:N
    x[i,j] = x[j,i] = JuMP.add_variable(model, build_variable(error, info, Poly(X)), "x[$i,$j]")
end
source
JuMP.@variablesMacro
@variables(model, args...)

Adds multiple variables to model at once, in the same fashion as the @variable macro.

The model must be the first argument, and multiple variables can be added on multiple lines wrapped in a begin ... end block.

Examples

@variables(model, begin
    x
    y[i = 1:2] >= 0, (start = i)
    z, Bin, (start = 0, base_name = "Z")
end)
Note

Keyword arguments must be contained within parentheses (refer to the example above).

source
JuMP.nameMethod
name(v::VariableRef)::String

Get a variable's name attribute.

source
JuMP.set_nameMethod
set_name(v::VariableRef, s::AbstractString)

Set a variable's name attribute.

source
JuMP.variable_by_nameFunction
variable_by_name(model::AbstractModel,
                 name::String)::Union{AbstractVariableRef, Nothing}

Returns the reference of the variable with name attribute name or Nothing if no variable has this name attribute. Throws an error if several variables have name as their name attribute.

julia> model = Model();

julia> @variable(model, x)
x

julia> variable_by_name(model, "x")
x

julia> @variable(model, base_name="x")
x

julia> variable_by_name(model, "x")
ERROR: Multiple variables have the name x.
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] get(::MOIU.Model{Float64}, ::Type{MathOptInterface.VariableIndex}, ::String) at /home/blegat/.julia/dev/MathOptInterface/src/Utilities/model.jl:222
 [3] get at /home/blegat/.julia/dev/MathOptInterface/src/Utilities/universalfallback.jl:201 [inlined]
 [4] get(::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.AbstractOptimizer,MathOptInterface.Utilities.UniversalFallback{MOIU.Model{Float64}}}, ::Type{MathOptInterface.VariableIndex}, ::String) at /home/blegat/.julia/dev/MathOptInterface/src/Utilities/cachingoptimizer.jl:490
 [5] variable_by_name(::Model, ::String) at /home/blegat/.julia/dev/JuMP/src/variables.jl:268
 [6] top-level scope at none:0

julia> var = @variable(model, base_name="y")
y

julia> variable_by_name(model, "y")
y

julia> set_name(var, "z")

julia> variable_by_name(model, "y")

julia> variable_by_name(model, "z")
z

julia> @variable(model, u[1:2])
2-element Array{VariableRef,1}:
 u[1]
 u[2]

julia> variable_by_name(model, "u[2]")
u[2]
source
JuMP.set_start_valueFunction
set_start_value(variable::VariableRef, value::Number)

Set the start value (MOI attribute VariablePrimalStart) of the variable v to value. See also start_value.

Note: VariablePrimalStarts are sometimes called "MIP-starts" or "warmstarts".

source
JuMP.start_valueFunction
start_value(v::VariableRef)

Return the start value (MOI attribute VariablePrimalStart) of the variable v. See also set_start_value.

Note: VariablePrimalStarts are sometimes called "MIP-starts" or "warmstarts".

source
JuMP.LowerBoundRefFunction
LowerBoundRef(v::VariableRef)

Return a constraint reference to the lower bound constraint of v. Errors if one does not exist.

source
JuMP.UpperBoundRefFunction
UpperBoundRef(v::VariableRef)

Return a constraint reference to the upper bound constraint of v. Errors if one does not exist.

source
JuMP.fix_valueFunction
fix_value(v::VariableRef)

Return the value to which a variable is fixed. Error if one does not exist. See also is_fixed.

source
JuMP.fixFunction
fix(v::VariableRef, value::Number; force::Bool = false)

Fix a variable to a value. Update the fixing constraint if one exists, otherwise create a new one. See also unfix.

If the variable already has variable bounds and force=false, calling fix will throw an error. If force=true, existing variable bounds will be deleted, and the fixing constraint will be added. Note a variable will have no bounds after a call to unfix.

source
JuMP.unfixFunction
unfix(v::VariableRef)

Delete the fixing constraint of a variable.

source
JuMP.FixRefFunction
FixRef(v::VariableRef)

Return a constraint reference to the constraint fixing the value of v. Errors if one does not exist.

source
JuMP.unset_integerFunction
unset_integer(variable_ref::VariableRef)

Remove the integrality constraint on the variable variable_ref.

source
JuMP.IntegerRefFunction
IntegerRef(v::VariableRef)

Return a constraint reference to the constraint constrainting v to be integer. Errors if one does not exist.

source
JuMP.unset_binaryFunction
unset_binary(variable_ref::VariableRef)

Remove the binary constraint on the variable variable_ref.

source
JuMP.BinaryRefFunction
BinaryRef(v::VariableRef)

Return a constraint reference to the constraint constrainting v to be binary. Errors if one does not exist.

source
JuMP.relax_integralityFunction
relax_integrality(model::Model)

Modifies model to "relax" all binary and integrality constraints on variables. Specifically,

  • Binary constraints are deleted, and variable bounds are tightened if necessary to ensure the variable is constrained to the interval $[0, 1]$.
  • Integrality constraints are deleted without modifying variable bounds.
  • An error is thrown if semi-continuous or semi-integer constraints are present (support may be added for these in the future).
  • All other constraints are ignored (left in place). This includes discrete constraints like SOS and indicator constraints.

Returns a function that can be called without any arguments to restore the original model. The behavior of this function is undefined if additional changes are made to the affected variables in the meantime.

Example

julia> model = Model();

julia> @variable(model, x, Bin);

julia> @variable(model, 1 <= y <= 10, Int);

julia> @objective(model, Min, x + y);

julia> undo_relax = relax_integrality(model);

julia> print(model)
Min x + y
Subject to
 x ≥ 0.0
 y ≥ 1.0
 x ≤ 1.0
 y ≤ 10.0

julia> undo_relax()

julia> print(model)
Min x + y
Subject to
 y ≥ 1.0
 y ≤ 10.0
 y integer
 x binary
source
JuMP.all_variablesFunction
all_variables(model::Model)::Vector{VariableRef}

Returns a list of all variables currently in the model. The variables are ordered by creation time.

Example

model = Model()
@variable(model, x)
@variable(model, y)
all_variables(model)

# output

2-element Array{VariableRef,1}:
 x
 y
source
JuMP.VariableRefType
VariableRef <: AbstractVariableRef

Holds a reference to the model and the corresponding MOI.VariableIndex.

source
JuMP.indexMethod
index(v::VariableRef)::MOI.VariableIndex

Return the index of the variable that corresponds to v in the MOI backend.

source
JuMP.optimizer_indexMethod
optimizer_index(v::VariableRef)::MOI.VariableIndex

Return the index of the variable that corresponds to v in the optimizer model. It throws NoOptimizer if no optimizer is set and throws an ErrorException if the optimizer is set but is not attached.

source
JuMP.add_variableFunction
add_variable(m::Model, v::AbstractVariable, name::String="")

Add a variable v to Model m and sets its name.

source
JuMP.build_variableFunction
build_constraint(_error::Function, variables, ::SymMatrixSpace)

Return a VariablesConstrainedOnCreation of shape SymmetricMatrixShape creating variables in MOI.Reals, i.e. "free" variables unless they are constrained after their creation.

This function is used by the @variable macro as follows:

@variable(model, Q[1:2, 1:2], Symmetric)
source
build_variable(_error::Function, variables, ::SkewSymmetricMatrixSpace)

Return a VariablesConstrainedOnCreation of shape SkewSymmetricMatrixShape creating variables in MOI.Reals, i.e. "free" variables unless they are constrained after their creation.

This function is used by the @variable macro as follows:

@variable(model, Q[1:2, 1:2] in SkewSymmetricMatrixSpace())
source
build_constraint(_error::Function, variables, ::PSDCone)

Return a VariablesConstrainedOnCreation of shape SymmetricMatrixShape constraining the variables to be positive semidefinite.

This function is used by the @variable macro as follows:

@variable(model, Q[1:2, 1:2], PSD)
source
JuMP.parse_one_operator_variableFunction
parse_one_operator_variable(_error::Function, infoexpr::_VariableInfoExpr, sense::Val{S}, value) where S

Update infoexr for a variable expression in the @variable macro of the form variable name S value.

source
JuMP.AbstractVariableRefType
AbstractVariableRef

Variable returned by add_variable. Affine (resp. quadratic) operations with variables of type V<:AbstractVariableRef and coefficients of type T create a GenericAffExpr{T,V} (resp. GenericQuadExpr{T,V}).

source
JuMP.VariableNotOwnedType
struct VariableNotOwned{V <: AbstractVariableRef} <: Exception
    variable::V
end

The variable variable was used in a model different to owner_model(variable).

source
JuMP.VariableConstrainedOnCreationType
VariablesConstrainedOnCreation <: AbstractVariable

Variable scalar_variables constrained to belong to set. Adding this variable can be understood as doing:

function JuMP.add_variable(model::Model, variable::JuMP.VariableConstrainedOnCreation, names)
    var_ref = JuMP.add_variable(model, variable.scalar_variable, name)
    JuMP.add_constraint(model, JuMP.VectorConstraint(var_ref, variable.set))
    return var_ref
end

but adds the variables with MOI.add_constrained_variable(model, variable.set) instead. See the MOI documentation for the difference between adding the variables with MOI.add_constrained_variable and adding them with MOI.add_variable and adding the constraint separately.

source
JuMP.VariablesConstrainedOnCreationType
VariablesConstrainedOnCreation <: AbstractVariable

Vector of variables scalar_variables constrained to belong to set. Adding this variable can be thought as doing:

function JuMP.add_variable(model::Model, variable::JuMP.VariablesConstrainedOnCreation, names)
    var_refs = JuMP.add_variable.(model, variable.scalar_variables,
                                  JuMP.vectorize(names, variable.shape))
    JuMP.add_constraint(model, JuMP.VectorConstraint(var_refs, variable.set))
    return JuMP.reshape_vector(var_refs, variable.shape)
end

but adds the variables with MOI.add_constrained_variables(model, variable.set) instead. See the MOI documentation for the difference between adding the variables with MOI.add_constrained_variables and adding them with MOI.add_variables and adding the constraint separately.

source