# How to create JuMP expressions without adding them to a model?

**URL:** https://discourse.julialang.org/t/how-to-create-jump-expressions-without-adding-them-to-a-model/68012
**Category:** Optimization (Mathematical)
**Tags:** jump
**Created:** [September 10, 2021, 11:31pm UTC](https://discourse.julialang.org/t/how-to-create-jump-expressions-without-adding-them-to-a-model/68012 "2021-09-10T23:31:34Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![ForceBru](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/forcebru/32/21389_2.png) [@ForceBru](https://discourse.julialang.org/u/ForceBru)
#### Post date: [September 10, 2021, 11:31pm UTC](https://discourse.julialang.org/t/how-to-create-jump-expressions-without-adding-them-to-a-model/68012/1 "2021-09-10T23:31:34Z")

</div>

I’m trying to build a GARCH(1, 1) model, and this requires recursively constructing the variance:

\sigma\_t^2 = \alpha + \beta \epsilon\_{t-1}^2 + \gamma \sigma\_{t-1}^2

Since the variances are unobserved (only the epsilons are), I have to pull \sigma\_1^2 out of thin air to initialize the model. Thus, I can’t do:

```julia
@NLexpression(
    model,
    variances[t=2:T], α + β * series[t - 1]^2 + γ * variances[t - 1]
)

```

…because the variable `variances` doesn’t exist here. Doing:

```julia
@NLexpressions(
    model,
    begin
        variances[1], initial_variance
        variances[t=2:T], α + β * series[t - 1]^2 + γ * variances[t - 1]
    end
)

```

…doesn’t work because I can’t redefine `variances` in the second line. The error message suggests using the anonymous construction syntax, but I specifically _need_ to reference `variances` by name.

This doesn’t work either, because `variances` is undefined on the RHS:

```julia
@NLexpression(
    model,
    variances[t=2:5], α + β * series[t-1] + γ * (t - 1 < 1 ? initial_variance : variances[t-1])
)

```

* * *

Currently I’m creating a lot of expressions in a loop:

```julia
variances = Vector{JuMP.NonlinearExpression}(undef, T)

for t ∈ eachindex(series)
    variances[t] = if t ≤ 1
        @NLexpression(model, initial_variance)
    else
        @NLexpression(model, α + β * series[t - 1]^2 + γ * variances[t - 1])
    end
end

```

`variances` is used only once to construct the log-likelihood, but inspecting `model.nlp_data.nlexpr` reveals that these intermediate expressions I created in the loop are stored in the model (and there are thousands of them), even though I don’t need them anymore.

* * *

Is it possible to create expressions _without_ storing them in the model? Are there better ways of computing such recursive expressions like the one for \sigma\_t^2?

---

<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: [September 10, 2021, 11:41pm UTC](https://discourse.julialang.org/t/how-to-create-jump-expressions-without-adding-them-to-a-model/68012/2 "2021-09-10T23:41:36Z")

</div>

> Currently I’m creating a lot of expressions in a loop:

Yes. This is the right way to do it.

> even though I don’t need them anymore.

Is this a bottleneck in your code? Is there a problem with doing it? Why do you want them removed?

> Is it possible to create expressions _without_ storing them in the model?

No.

> Are there better ways of computing such recursive expressions

If you only need a particular t, e.g., `T`, then you could write out the expression as a sum, rather than in recursive form.

---

<div class="post-metadata">

### Author: ![ForceBru](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/forcebru/32/21389_2.png) [@ForceBru](https://discourse.julialang.org/u/ForceBru)
#### Post date: [September 10, 2021, 11:51pm UTC](https://discourse.julialang.org/t/how-to-create-jump-expressions-without-adding-them-to-a-model/68012/3 "2021-09-10T23:51:12Z")

</div>

> Why do you want them removed?

I have a `struct GARCH` that contains a JuMP model, and a `fit!` method, like in SciKit-learn. The `fit!` method calculates the variances and adds all these expressions to the same model on each call. This leads to thousands upon thousands of expressions that are only used once, but stick around until the model object is garbage collected (I fit many models using the same `GARCH` object).

So, I don’t want the old expressions to keep piling up like this.

* * *

I need \sigma\_t^2 for all t \in \{1, 2, \dots, T\}, and the expression for \sigma\_3^2 already looks pretty complicated - not sure how to write out \sigma\_t^2 as a sum for any t…

_EDIT_: I guess the simplest solution is to create a new model on each call to `fit!`

---

<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: [September 11, 2021, 12:27am UTC](https://discourse.julialang.org/t/how-to-create-jump-expressions-without-adding-them-to-a-model/68012/4 "2021-09-11T00:27:08Z")

</div>

The expressions have to stick around for us to compute derivatives using them.

> not sure how to write out σt as a sum for any t …

Something like this? Not sure if I got it right, because I don’t know what are variables and what are data, but it should point you in the right direction.

```julia
@NLexpression(
    model, 
    expr[t=1:T], 
    γ^t * initial_variance + sum(γ^(t-i) * (α + β * series[i]^2) for i in 1:t),
)

```

---

<div class="post-metadata">

### Author: ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)
#### Post date: [September 11, 2021, 6:20am UTC](https://discourse.julialang.org/t/how-to-create-jump-expressions-without-adding-them-to-a-model/68012/5 "2021-09-11T06:20:40Z")

</div>

Unless this is a learning exercise I would use ARCHModels.jl which is a brilliant package

[https://github.com/s-broda/ARCHModels.jl](https://github.com/s-broda/ARCHModels.jl)

---

<div class="post-metadata">

### Author: ![ForceBru](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/forcebru/32/21389_2.png) [@ForceBru](https://discourse.julialang.org/u/ForceBru)
#### Post date: [September 11, 2021, 11:56am UTC](https://discourse.julialang.org/t/how-to-create-jump-expressions-without-adding-them-to-a-model/68012/6 "2021-09-11T11:56:27Z")

</div>

I’m trying to implement MN-GARCH (Mixed Normal GARCH), and I’m sort of testing the waters with GARCH(1, 1) for educational purposes. I know there’s the R package [MSGARCH](https://cran.r-project.org/web/packages/MSGARCH/index.html) that can fit MN-GARCH, but it doesn’t seem to support models for means of the mixture components - only for variances. So, I’m going to try and implement this…

* * *

For anyone who stumbles upon this in the future - I ended up redefining the model on each call to `fit!`, like this:

```julia
function fit!(garch::MyGARCH, series::AbstractVector{<:Real}, ϵ::Real=1e-10)
    # Redefine the model
    garch.model = Model(Ipopt.Optimizer)
    @variables(garch.model, begin
        α0 ≥ ϵ
        α ≥ ϵ
        β ≥ ϵ
    end)

    # Compute variances in a loop, as shown in the original post
    # variances = ...

    register(garch.model, :normal_pdf, 3, normal_pdf, autodiff=true)

    @NLobjective(
        garch.model, Max,
        sum(
            log(normal_pdf(ϵ, 0, sqrt(σ_sq)))
            for (ϵ, σ_sq) ∈ zip(series, variances)
        )
    )

    optimize!(garch.model)

    garch
end

```
