# Why \_removing\_ unused variables makes ipopt taking longer?

**URL:** https://discourse.julialang.org/t/why-removing-unused-variables-makes-ipopt-taking-longer/127541
**Category:** Optimization (Mathematical)
**Created:** [March 31, 2025, 9:44am UTC](https://discourse.julialang.org/t/why-removing-unused-variables-makes-ipopt-taking-longer/127541 "2025-03-31T09:44:49Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)
#### Post date: [March 31, 2025, 9:44am UTC](https://discourse.julialang.org/t/why-removing-unused-variables-makes-ipopt-taking-longer/127541/1 "2025-03-31T09:44:49Z")

</div>

I have a model that was originally global and making it multi-regional, I transformed all my variables adding a regional dimension, created the equivalent “global” version for each of them defined mostly as the sum, tested with a single item in the regional dimensions and all is going fine.  
Now, thinking to improve performance, I am attempting to remove the now useless global variables, that is just defined e.g. `EIND(time) = sum(EIND_R(time,region) for region in regions)` and setting them in a post-optimization computation. However, by removing these unused variable (even only one), for which there is no constraint (contraints, e.g. \>= 0, are set on each regional equivalent), it is just defined as the sum of the regional equivalent as above, the solver (IPOPT) takes more iteration and more time instead of less. Why may it do that ?

---

<div class="post-metadata">

### Author: ![sylvaticus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sylvaticus/32/203883_2.png) [@sylvaticus](https://discourse.julialang.org/u/sylvaticus)
#### Post date: [March 31, 2025, 10:48am UTC](https://discourse.julialang.org/t/why-removing-unused-variables-makes-ipopt-taking-longer/127541/2 "2025-03-31T10:48:46Z")

</div>

I managed to create a minimal working example:

Base version:

```julia

using Ipopt, JuMP

ridx = 1:2
tidx = 1:1000

# ------------------------------------

m = Model(optimizer_with_attributes(Ipopt.Optimizer,"print_level" => 5))

@variables m begin
    FOO_R[tidx,ridx] >= 4.0              
    GOO_R[tidx,ridx] >= 0.0      
end             

@constraint(m, gooeq[ti in tidx, ri in ridx], GOO_R[ti,ri] == FOO_R[ti,ri]^2 + FOO_R[ti,ri]^(1/2))

@objective(m, Min, sum( 5 * GOO_R[ti,ri]^(1/3) for ti in tidx, ri in ridx))
optimize!(m)

```

This on my pc solves in 60 iteration and 0.373 seconds.  
If I _add_ summation versions of the variables I got:

```julia
m2 = Model(optimizer_with_attributes(Ipopt.Optimizer,"print_level" => 5))

@variables m2 begin
    FOO_R[tidx,ridx] >= 4.0  
    FOO[tidx]              
    GOO_R[tidx,ridx] >= 0.0      
    GOO[tidx]  
end             

@constraint(m2, fooglobal[ti in tidx], FOO[ti] == sum(FOO_R[ti,ri] for ri in ridx))
@constraint(m2, gooeq[ti in tidx, ri in ridx], GOO_R[ti,ri] == FOO_R[ti,ri]^2 + FOO_R[ti,ri]^(1/2))
@constraint(m2, googlobal[ti in tidx], GOO[ti] == sum(GOO_R[ti,ri] for ri in ridx))

@objective(m2, Min, sum( 5 * GOO_R[ti,ri]^(1/3) for ti in tidx, ri in ridx))

optimize!(m2)

```

That requires only 56 iterations and 0.280 seconds.

While the difference here is tiny, in my real case model made of many variables the difference becomes bigger at each “global” variable that I remove..

---

<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: [March 31, 2025, 8:22pm UTC](https://discourse.julialang.org/t/why-removing-unused-variables-makes-ipopt-taking-longer/127541/3 "2025-03-31T20:22:08Z")

</div>

I don’t know if there is an easy answer for you. They’re solving a different problem, and they don’t find identical solutions (but they’re the same to tolerance). I could equally have expected that the performance difference would be the other way around.

For this particular model you can do much better though:

```julia
julia> begin
           m3 = Model(optimizer_with_attributes(Ipopt.Optimizer,"print_level" => 5))
           @variable(m3, FOO_R[tidx,ridx] >= 4.0)
           @expression(m3, FOO[ti in tidx], sum(FOO_R[ti,:]))
           @expression(m3, GOO[ti in tidx], sum(GOO_R[ti,:]))
           @expression(m3, GOO_R[ti in tidx, ri in ridx], FOO_R[ti,ri]^2 + sqrt(FOO_R[ti,ri]))
           @objective(m3, Min, 5 * sum(cbrt.(GOO_R)))
           optimize!(m3)
       end
This is Ipopt version 3.14.17, running with linear solver MUMPS 5.7.3.

Number of nonzeros in equality constraint Jacobian...: 0
Number of nonzeros in inequality constraint Jacobian.: 0
Number of nonzeros in Lagrangian Hessian.............: 2000

Total number of variables............................: 2000
                     variables with only lower bounds: 2000
                variables with lower and upper bounds: 0
                     variables with only upper bounds: 0
Total number of equality constraints.................: 0
Total number of inequality constraints...............: 0
        inequality constraints with only lower bounds: 0
   inequality constraints with lower and upper bounds: 0
        inequality constraints with only upper bounds: 0

iter objective inf_pr inf_du lg(mu) ||d|| lg(rg) alpha_du alpha_pr ls
   0 2.6367357e+04 0.00e+00 9.97e-01 -1.0 0.00e+00 - 0.00e+00 0.00e+00 0
   1 2.6288238e+04 0.00e+00 5.35e-03 -1.7 6.02e-02 - 1.00e+00 3.29e-01f 2
   2 2.6213178e+04 0.00e+00 5.61e-06 -2.5 1.88e-02 - 1.00e+00 1.00e+00f 1
   3 2.6207714e+04 0.00e+00 2.85e-08 -3.8 1.36e-03 - 1.00e+00 1.00e+00f 1
   4 2.6207417e+04 0.00e+00 6.99e-11 -5.7 7.41e-05 - 1.00e+00 1.00e+00f 1
   5 2.6207414e+04 0.00e+00 1.11e-14 -8.6 9.20e-07 - 1.00e+00 1.00e+00f 1

Number of Iterations....: 5

                                   (scaled) (unscaled)
Objective...............: 2.6207413786943041e+04 2.6207413786943041e+04
Dual infeasibility......: 1.1102230246251565e-14 1.1102230246251565e-14
Constraint violation....: 0.0000000000000000e+00 0.0000000000000000e+00
Variable bound violation: 3.8748328989868241e-08 3.8748328989868241e-08
Complementarity.........: 2.5057897359559346e-09 2.5057897359559346e-09
Overall NLP error.......: 2.5057897359559346e-09 2.5057897359559346e-09

Number of objective function evaluations = 11
Number of objective gradient evaluations = 6
Number of equality constraint evaluations = 0
Number of inequality constraint evaluations = 0
Number of equality constraint Jacobian evaluations = 0
Number of inequality constraint Jacobian evaluations = 0
Number of Lagrangian Hessian evaluations = 5
Total seconds in IPOPT = 0.025

EXIT: Optimal Solution Found.

```
