# @expression v.s. @constraint (when to use what)

**URL:** <https://discourse.julialang.org/t/expression-v-s-constraint-when-to-use-what/65008>\
**Category:** Optimization (Mathematical)\
**Created:** [July 20, 2021, 11:58pm UTC](https://discourse.julialang.org/t/expression-v-s-constraint-when-to-use-what/65008 "2021-07-20T23:58:28Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![SingingKim](https://avatars.discourse-cdn.com/v4/letter/s/5fc32e/32.png) [@SingingKim](https://discourse.julialang.org/u/SingingKim)\
**Post date:** [July 20, 2021, 11:58pm UTC](https://discourse.julialang.org/t/expression-v-s-constraint-when-to-use-what/65008/1 "2021-07-20T23:58:28Z")

</div>

I’m pretty sure this question will be redundant, but I could not find an answer anywhere. My question is more like asking a style guide so that my code can avoid any unnecessary build/calculation time.

Q1. My guess is basically I should use `@expression` whenever possible rather than using `@constraint` to reduce the size of an optimization problem. Can anyone confirm this?

Q2. In pre-solve or any internal process to determine the class of optimization (either provided by JuMP or Solvers), can one be faster than the other? For example, in model2 below, it is straightforward that the objective is quadratic (variable x variable), but I’m not sure how model1 determines it is quadratic (variable x expression).

In the examples below, `model1` uses `@expression` to define the objective while `model2` uses `@constraint`.

```julia
using JuMP, Ipopt
model1 = Model(Ipopt.Optimizer)
@variables(model1, begin
    x >= 0
    y >= 0
end)
ex = @expression(model1, 2x + y - 1)
@objective(model1, Min, 2 * x * ex - 1)
optimize!(model1)
value(ex)

```

```julia
using JuMP, Ipopt
model2 = Model(Ipopt.Optimizer)
@variables(model2, begin
    x >= 0
    y >= 0
    ex
end)
@constraint(model2, ex == 2x + y - 1)
@objective(model2, Min, 2 * x * ex - 1)
optimize!(model2)
value(model2[:ex])

```

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [July 21, 2021, 1:17am UTC](https://discourse.julialang.org/t/expression-v-s-constraint-when-to-use-what/65008/2 "2021-07-21T01:17:14Z")

</div>

> [@SingingKim](#):
>
> My guess is basically I should use `@expression` whenever possible rather than using `@constraint` to reduce the size of an optimization problem. Can anyone confirm this?

Yes. Expressions get substituted into the final model. The constraint approach will add an extra decision variable and an extra constraint. Some solvers have presolve routines that take care of this, but others, like Ipopt, don’t.

Your second question is related: the substitution happens at the JuMP level _before_ the problem reaches the solver. So the solver will see the objective `4 * x^2 + 2 * x * y - 2x - 1` in the first model.

To summarize: expressions are uniformly good. They can make the code more readable, and JuMP can (in some cases) build the problem more efficiently (particularly `@NLexpression` when used in `@NLconstraint` and `@NLobjective`. `@expression` less so).

---

<div class="post-metadata">

**Author:** ![SingingKim](https://avatars.discourse-cdn.com/v4/letter/s/5fc32e/32.png) [@SingingKim](https://discourse.julialang.org/u/SingingKim)\
**Post date:** [July 21, 2021, 1:48am UTC](https://discourse.julialang.org/t/expression-v-s-constraint-when-to-use-what/65008/3 "2021-07-21T01:48:21Z")

</div>

@odow Thank you for the clear explanation!

---

<div class="post-metadata">

**Author:** ![Shuhua](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuhua/32/27618_2.png) [@Shuhua](https://discourse.julialang.org/u/Shuhua)\
**Post date:** [July 21, 2021, 2:52am UTC](https://discourse.julialang.org/t/expression-v-s-constraint-when-to-use-what/65008/4 "2021-07-21T02:52:19Z")

</div>

> [@odow](#):
>
> To summarize: expressions are uniformly good.

Is `ex = 2x + y - 1` equivalent to `ex = @expression(model1, 2x + y - 1)`? In the following example, both approaches lead to the same result and `typeof(ex) = AffExpr`.

```julia
using JuMP, GLPK
model1 = Model(GLPK.Optimizer)
@variables(model1, begin
    x >= 0
    y >= 0
end)
# ex = @expression(model1, 2x + y - 1)
ex = 2x + y - 1
@show typeof(ex)
@objective(model1, Min, 2 * x + ex - 1)
optimize!(model1)
value(ex)

```

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [July 21, 2021, 2:56am UTC](https://discourse.julialang.org/t/expression-v-s-constraint-when-to-use-what/65008/5 "2021-07-21T02:56:34Z")

</div>

Read [https://jump.dev/JuMP.jl/stable/tutorials/Getting%20started/performance\_tips/#Use-macros-to-build-expressions](https://jump.dev/JuMP.jl/stable/tutorials/Getting%20started/performance_tips/#Use-macros-to-build-expressions)

---

<div class="post-metadata">

**Author:** ![Shuhua](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shuhua/32/27618_2.png) [@Shuhua](https://discourse.julialang.org/u/Shuhua)\
**Post date:** [July 21, 2021, 3:11am UTC](https://discourse.julialang.org/t/expression-v-s-constraint-when-to-use-what/65008/6 "2021-07-21T03:11:57Z")

</div>

Thank you. I just noticed it. In short, `ex = @expression(model1, 2x + y - 1)` is preferred:

> Use JuMP’s macros (or [`add_to_expression!`](https://jump.dev/JuMP.jl/stable/reference/expressions/#JuMP.add_to_expression!) to build expressions. Avoid constructing expressions outside the macros.

As a side note, it may be better to define a _named_ expression with `@expression(model1, ex, 2x + y - 1)` such that we can access it later in a different scope with `model[:ex]`, e.g., when a `model` is returned from a builder function.
