Expressions

Expressions

JuMP has three types of expressions: affine, quadratic, and nonlinear. These expressions can be inserted into constraints or into the objective. This is particularly useful if an expression is used in multiple places in the model.

Affine expressions

There are four ways of constructing an affine expression in JuMP: with the @expression macro, with operator overloading, with the AffExpr constructor, and with add_to_expression!.

Macros

The recommended way to create an affine expression is via the @expression macro.

model = Model()
@variable(model, x)
@variable(model, y)
ex = @expression(model, 2x + y - 1)

# output

2 x + y - 1

This expression can be used in the objective or added to a constraint. For example:

@objective(model, Min, 2 * ex - 1)
objective_function(model)

# output

4 x + 2 y - 3

Just like variables and constraints, named expressions can also be created. For example

model = Model()
@variable(model, x[i = 1:3])
@expression(model, expr[i = 1:3], i * sum(x[j] for j in i:3))
expr

# output

3-element Array{GenericAffExpr{Float64,VariableRef},1}:
 x[1] + x[2] + x[3]
 2 x[2] + 2 x[3]
 3 x[3]

Operator overloading

Expressions can also be created without macros. However, note that in some cases, this can be much slower that constructing an expression using macros.

model = Model()
@variable(model, x)
@variable(model, y)
ex = 2x + y - 1

# output

2 x + y - 1

Constructors

A third way to create an affine expression is by the AffExpr constructor. The first argument is the constant term, and the remaining arguments are variable-coefficient pairs.

model = Model()
@variable(model, x)
@variable(model, y)
ex = AffExpr(-1.0, x => 2.0, y => 1.0)

# output

2 x + y - 1

add_to_expression!

The fourth way to create an affine expression is by using add_to_expression!. Compared to the operator overloading method, this approach is faster because it avoids constructing temporary objects. The @expression macro uses add_to_expression! behind-the-scenes.

model = Model()
@variable(model, x)
@variable(model, y)
ex = AffExpr(-1.0)
add_to_expression!(ex, 2.0, x)
add_to_expression!(ex, 1.0, y)

# output

2 x + y - 1

Removing zero terms

Use drop_zeros! to remove terms from an affine expression with a 0 coefficient.

julia> model = Model();

julia> @variable(model, x)
x

julia> @expression(model, ex, 0 * x + 1)
0 x + 1

julia> drop_zeros!(ex)

julia> ex
1

Quadratic expressions

Like affine expressions, there are four ways of constructing a quadratic expression in JuMP: macros, operator overloading, constructors, and add_to_expression!.

Macros

The @expression macro can be used to create quadratic expressions by including quadratic terms.

model = Model()
@variable(model, x)
@variable(model, y)
ex = @expression(model, x^2 + 2 * x * y + y^2 + x + y - 1)

# output

x² + 2 x*y + y² + x + y - 1

Operator overloading

Operator overloading can also be used to create quadratic expressions. The same performance warning (discussed in the affine expression section) applies.

model = Model()
@variable(model, x)
@variable(model, y)
ex = x^2 + 2 * x * y + y^2 + x + y - 1

# output

x² + 2 x*y + y² + x + y - 1

Constructors

Quadratic expressions can also be created using the QuadExpr constructor. The first argument is an affine expression, and the remaining arguments are pairs, where the first term is a JuMP.UnorderedPair and the second term is the coefficient.

model = Model()
@variable(model, x)
@variable(model, y)
aff_expr = AffExpr(-1.0, x => 1.0, y => 1.0)
quad_expr = QuadExpr(aff_expr, UnorderedPair(x, x) => 1.0,
                     UnorderedPair(x, y) => 2.0, UnorderedPair(y, y) => 1.0)

# output

x² + 2 x*y + y² + x + y - 1

add_to_expression!

Finally, add_to_expression! can also be used to add quadratic terms.

model = Model()
@variable(model, x)
@variable(model, y)
ex = QuadExpr(x + y - 1.0)
add_to_expression!(ex, 1.0, x, x)
add_to_expression!(ex, 2.0, x, y)
add_to_expression!(ex, 1.0, y, y)

# output

x² + 2 x*y + y² + x + y - 1

Removing zero terms

Use drop_zeros! to remove terms from a quadratic expression with a 0 coefficient.

julia> model = Model();

julia> @variable(model, x)
x

julia> @expression(model, ex, 0 * x^2 + x + 1)
0 x² + x + 1

julia> drop_zeros!(ex)

julia> ex
x + 1

Nonlinear expressions

Nonlinear expressions can be constructed only using the @NLexpression macro and can be used only in @NLobjective, @NLconstraint, and other @NLexpressions. Moreover, quadratic and affine expressions cannot be used in the nonlinear macros. For more details, see the Nonlinear Modeling section.

Reference

JuMP.@expressionMacro.
@expression(args...)

Efficiently builds a linear or quadratic expression but does not add to model immediately. Instead, returns the expression which can then be inserted in other constraints. For example:

@expression(m, shared, sum(i*x[i] for i=1:5))
@constraint(m, shared + y >= 5)
@constraint(m, shared + z <= 10)

The ref accepts index sets in the same way as @variable, and those indices can be used in the construction of the expressions:

@expression(m, expr[i=1:3], i*sum(x[j] for j=1:3))

Anonymous syntax is also supported:

expr = @expression(m, [i=1:3], i*sum(x[j] for j=1:3))
add_to_expression!(expression, terms...)

Updates expression in place to expression + (*)(terms...). This is typically much more efficient than expression += (*)(terms...). For example, add_to_expression!(expression, a, b) produces the same result as expression += a*b, and add_to_expression!(expression, a) produces the same result as expression += a.

Only a few methods are defined, mostly for internal use, and only for the cases when (1) they can be implemented efficiently and (2) expression is capable of storing the result. For example, add_to_expression!(::AffExpr, ::VariableRef, ::VariableRef) is not defined because a GenericAffExpr cannot store the product of two variables.

JuMP.drop_zeros!Function.
drop_zeros!(expr::GenericAffExpr)

Remove terms in the affine expression with 0 coefficients.

drop_zeros!(expr::GenericQuadExpr)

Remove terms in the quadratic expression with 0 coefficients.