# Objective function "limit reached" status in JuMP

**URL:** <https://discourse.julialang.org/t/objective-function-limit-reached-status-in-jump/39349>\
**Category:** Optimization (Mathematical)\
**Created:** [May 12, 2020, 2:54pm UTC](https://discourse.julialang.org/t/objective-function-limit-reached-status-in-jump/39349 "2020-05-12T14:54:08Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![ivborissov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ivborissov/32/2841_2.png) [@ivborissov](https://discourse.julialang.org/u/ivborissov)\
**Post date:** [May 12, 2020, 2:54pm UTC](https://discourse.julialang.org/t/objective-function-limit-reached-status-in-jump/39349/1 "2020-05-12T14:54:08Z")

</div>

Hi,

Can `JuMP` report that an objective function has reached some predefined limit?  
My problem looks the following. I am looking for a `Min` or `Max` value of a variable `x[1]` within the bounds (lets say `[1e-9,1e9]`) w.r.t some non-linear constraint `f(x)<=alpha`:

```julia
m=Model(optimizer_with_attributes(Ipopt.Optimizer, "max_cpu_time" => 60.0))
@variable(m, x[j=1:n], start=init_x[j])
JuMP.register(m, :f, n, f, autodiff=true)
@objective(m, Min, x[1])
@NLconstraint(m, f(x...) <= alpha)

```

To set the bounds I either need to define variables limits:

```julia
@variable(m, 1e-9<=x[j=1:n]<=1e9, start=init_x[j])

```

Or to add constraints:

```julia
@constraint(m, con1, 1e-9 <= x[1] <= 1e9)

```

However reaching the bound (`1e-9` or `1e9`) may result in the following `JuMP.termination_status` (I am testing Ipopt and KNITRO) : `LOCALLY_SOLVED`, `ALMOST_OPTIMAL`, `LOCALLY_INFEASIBLE`. So it is hard to say whether an optimizer has reached the bound or a “real” minimum (maximum) was found near the bound.  
Is there a way to rewrite this problem that `JuMP` can distinguish between those two cases? Previously I used `NLopt` which has some `STOPVAL_REACHED` option which terminates the optimization when the solver reaches some predefined value.

---

<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:** [May 12, 2020, 3:30pm UTC](https://discourse.julialang.org/t/objective-function-limit-reached-status-in-jump/39349/2 "2020-05-12T15:30:14Z")

</div>

If Ipopt reaches the time limit, you should get `termination_status(m) == MOI.TIME_LIMIT`.

We can’t treat your bounds as special, because we don’t know that you intend them to be special. You would need to check the variable values of the solution and determine if they are “too close” for you.

---

<div class="post-metadata">

**Author:** ![ivborissov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ivborissov/32/2841_2.png) [@ivborissov](https://discourse.julialang.org/u/ivborissov)\
**Post date:** [May 12, 2020, 4:20pm UTC](https://discourse.julialang.org/t/objective-function-limit-reached-status-in-jump/39349/3 "2020-05-12T16:20:21Z")

</div>

Thanks for your response! I see that Ipopt tries to converge to bound values and report them as local optima. Indeed in this case I would prefer the solver to report that no optima has been found within the bounds. Like NLopts `stopval` behavior ( from NLopt docs “Another termination test that NLopt supports is that you can tell the optimization to stop when the objective function value `f(x)` reaches some specified value, `stopval` , for any feasible point `x`”). Is it doable with other NL optimizers in JuMP or perhaps with some reformulation of the original problem?

---

<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:** [May 12, 2020, 5:23pm UTC](https://discourse.julialang.org/t/objective-function-limit-reached-status-in-jump/39349/4 "2020-05-12T17:23:30Z")

</div>

I don’t think Ipopt has an option to terminate based on the objective value. Here are the list of options: [Ipopt: Ipopt Options](https://coin-or.github.io/Ipopt/OPTIONS.html#OPTIONS_REF)

Presumably you could add a constraint `@constraint(m, x[1] >= stopval)` instead.

> Indeed in this case I would prefer the solver to report that no optima has been found within the bounds.

We can’t do this for the reasons mentioned above; a locally optimal solution might exist at the bound.

---

<div class="post-metadata">

**Author:** ![ivborissov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ivborissov/32/2841_2.png) [@ivborissov](https://discourse.julialang.org/u/ivborissov)\
**Post date:** [May 13, 2020, 12:03pm UTC](https://discourse.julialang.org/t/objective-function-limit-reached-status-in-jump/39349/5 "2020-05-13T12:03:07Z")

</div>

Thanks, I see the reason why bounds are not treated as special points. Adding `stopval` as constraints `@constraint(m, 1e-9 <= x[1] <= 1e9)` can be a solution. I will need to set up constraint tolerance than to distinguish an optimum on the bound from “internal” optimum

---

<div class="post-metadata">

**Author:** ![ivborissov](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ivborissov/32/2841_2.png) [@ivborissov](https://discourse.julialang.org/u/ivborissov)\
**Post date:** [May 13, 2020, 2:46pm UTC](https://discourse.julialang.org/t/objective-function-limit-reached-status-in-jump/39349/6 "2020-05-13T14:46:43Z")

</div>

@odow It seems a rule to state that Ipopt has found an optimum on the bound (constraint) can be `isapprox(objective_value(m), stopval, atol=tol)` where `tol` is Ipopt option `Ipopt.Optimizer(tol=1e-8)` and `stopval` is the bound. Ipopt also has options to set up constraint tolerances (`constr_viol_tol`, `acceptable_constr_viol_tol`). Can they also help better determine a “bound optimum” here?  
For KNITRO it seems the setting I was looking for is `fstopval`  
[https://www.artelys.com/docs/knitro/3\_referenceManual/userOptions.html#fstopval](https://www.artelys.com/docs/knitro/3_referenceManual/userOptions.html#fstopval)
