# JuMP+Ipopt producing infeasible solutions for constraints with small upper bounds

**URL:** <https://discourse.julialang.org/t/jump-ipopt-producing-infeasible-solutions-for-constraints-with-small-upper-bounds/68306>\
**Category:** Optimization (Mathematical)\
**Tags:** jump\
**Created:** [September 17, 2021, 4:59am UTC](https://discourse.julialang.org/t/jump-ipopt-producing-infeasible-solutions-for-constraints-with-small-upper-bounds/68306 "2021-09-17T04:59:32Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [September 17, 2021, 4:59am UTC](https://discourse.julialang.org/t/jump-ipopt-producing-infeasible-solutions-for-constraints-with-small-upper-bounds/68306/1 "2021-09-17T04:59:32Z")

</div>

```julia
using JuMP, Ipopt

function parametertest()
    m = Model(Ipopt.Optimizer)
    set_silent(m)
    
    a = [0.15, 0.16, 0.72, -0.80, -12.0]
    
    @variable(m, x[1:5])
    @variable(m, abs_x[1:5])
    
    for i in 1:5
        @constraint(m, abs_x[i] ≥ x[i])
        @constraint(m, abs_x[i] ≥ -x[i])
    end
    
    @NLparameter(m, gamma == 0.0)
    @NLconstraint(m, Lasso, sum(abs_x[i] for i in 1:5) ≤ gamma)
    
    @objective(m, Min, sum((a[i] - x[i])^2 for i in 1:5))
    
    gammas = [1e-10, 0.1, 1.0, 15.0, 200]
    
    for g in gammas
        set_value(gamma, g)
        optimize!(m)

        @show value(gamma)
        @show value(sum(value(abs_x[i]) for i in 1:5))
    end
end

parametertest()

```

yields

```julia
value(gamma) = 1.0e-10
value(sum((value(abs_x[i]) for i = 1:5))) = 1.000154534191108e-8 # Infeasible!
value(gamma) = 0.1
value(sum((value(abs_x[i]) for i = 1:5))) = 0.10000000989464701
value(gamma) = 1.0
value(sum((value(abs_x[i]) for i = 1:5))) = 1.0000000098860817
value(gamma) = 15.0
value(sum((value(abs_x[i]) for i = 1:5))) = 14.642196754232643
value(gamma) = 200.0
value(sum((value(abs_x[i]) for i = 1:5))) = 143.0505423096824

```

Notice that in the first case, the _absolute_ error is on the order of `1e-8`, but the _relative_ error is a factor of 100! Is there a way I can tell Ipopt not to accept a solution until the _relative_ error is acceptably small?

In this particular case, better results can be obtained by multiplying both sides of the `@NLconstraint` by a constant like `1e10`, but it is not always obvious beforehand which constant is appropriate.

---

<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 17, 2021, 5:08am UTC](https://discourse.julialang.org/t/jump-ipopt-producing-infeasible-solutions-for-constraints-with-small-upper-bounds/68306/2 "2021-09-17T05:08:46Z")

</div>

Almost all solvers use absolute tolerance as their convergence criteria. You should reformulate your model to avoid such small values.

Although not explicitly for NLP, Gurobi have a good series of documentation on numerical issues: [https://www.gurobi.com/documentation/9.0/refman/num\_grb\_guidelines\_for\_num.html](https://www.gurobi.com/documentation/9.0/refman/num_grb_guidelines_for_num.html)

You should for constants in your model to differ by at most ~6 orders of magnitude. Here, yours differ by 12 (1e-10 and 2e2).

Ipopt has a variety of tolerances you can experiment with, but the underlying issue is poor scaling of your model: [Ipopt: Ipopt Options](https://coin-or.github.io/Ipopt/OPTIONS.html#OPTIONS_REF). Fix that first, rather than playing with tolerances.

Edit: or use the absolute 1e-8 solution.

---

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [September 17, 2021, 5:30am UTC](https://discourse.julialang.org/t/jump-ipopt-producing-infeasible-solutions-for-constraints-with-small-upper-bounds/68306/3 "2021-09-17T05:30:19Z")

</div>

Thank you. I should probably have figured this out on my own. This is a challenging issue when working with a lasso-type constraint as in the example in the OP, because often what I want to do is try several values of the constraint across many orders of magnitude in order to find the best tradeoff.
