# Ipopt produces wrong results in Windows

**URL:** https://discourse.julialang.org/t/ipopt-produces-wrong-results-in-windows/122414
**Category:** Optimization (Mathematical)
**Created:** [November 8, 2024, 10:57am UTC](https://discourse.julialang.org/t/ipopt-produces-wrong-results-in-windows/122414 "2024-11-08T10:57:57Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![jbytecode](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jbytecode/32/17719_2.png) [@jbytecode](https://discourse.julialang.org/u/jbytecode)
#### Post date: [November 8, 2024, 10:57am UTC](https://discourse.julialang.org/t/ipopt-produces-wrong-results-in-windows/122414/1 "2024-11-08T10:57:57Z")

</div>

Suppose the function optimizes a model for a given set of integer vectors

```Julia
function bestworst(pref_to_best::Vector{Int}, pref_to_worst::Vector{Int})

    n = length(pref_to_best)

    best_index = argmin(pref_to_best)

    worst_index = argmin(pref_to_worst)

    model = Model(Ipopt.Optimizer)

    @variable(model, ε >= 0)

    @variable(model, w[1:n] >= 0)

    @objective(model, Min, ε)

    indices = collect(1:n)

    bestindices = indices[indices.!=best_index]
    
    worstindices = indices[indices.!=worst_index]

    for i in bestindices
        @constraint(model, abs(w[best_index] / w[i] - pref_to_best[i]) <= ε)
    end

    for i in worstindices
        @constraint(model, abs(w[i] / w[worst_index] - pref_to_worst[i]) <= ε)
    end

    @constraint(model, sum(w) == 1)

    optimize!(model)

    result = (value(ε), value.(w))

    return result
end

```

I am calling the function with some special values of

```Julia
pref_to_best = [8, 2, 1]
pref_to_worst = [1, 5, 8]
result = bestworst(pref_to_best, pref_to_worst)

```

In Ubuntu and MacOS, the optimal \varepsilon is 0.26 and the w vector is `[0.071, 0.338, 0.589]` as expected when it’s compared to a reference paper. However, in Windows, the resulted \varepsilon is 0.72 and the w vector is `[-1.0000000050256285e-8, 0.6114327292759807, -9.99694897769469e-9]`.

I have only Ubuntu installed machines and I obtained those results in the GitHub CI:

> <https://github.com/jbytecode/JMcDM/actions/runs/11740450299/job/32707021543>

What is the reason of having different and wrong results using Ipopt in Windows?

Note that the implementation is initial and includes some redundant constraints. I will reduce the model in the final implementation.

Thank you in advance.

Edit: Constraints were initially defined using `@constraint` , after the failure, I changed them to `@NLconstraint`, it seems it is not necessary now.

---

<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: [November 10, 2024, 3:21am UTC](https://discourse.julialang.org/t/ipopt-produces-wrong-results-in-windows/122414/2 "2024-11-10T03:21:17Z")

</div>

I have a few comments:

- You must _always, always_ check whether the solver terminated with a solution before querying `value`. Use `is_solved_and_feasible(model)` for most common cases, and check `termination_status(model)` or `solution_summary(model)` for details if it does not solve correctly.
- Ipopt assumes that the functions are twice differentiable. Since we provide only callback oracles, it cannot “see” that you have used `abs`, so the algorithm will happily step back-and-forth across the non-differentiable point. I don’t have Windows to confirm, but I assume that you are hitting an iteration limit and Ipopt is returning whatever the solution of the last iteration was.
- You have `1 / w[i]`, which is not defined at your starting point of `w[i] = 0`. Set a non-default starting point (e.g., `1 / n`):

Here’s how I would write your code (I didn’t run it to test, be wary typos.)

```Julia
function bestworst(pref_to_best::Vector{Int}, pref_to_worst::Vector{Int})
    n = length(pref_to_best)
    best_index = argmin(pref_to_best)
    worst_index = argmin(pref_to_worst)
    indices = collect(1:n)
    bestindices = indices[indices.!=best_index]
    worstindices = indices[indices.!=worst_index]
    model = Model(Ipopt.Optimizer)
    @variable(model, ε >= 0)
    @variable(model, w[1:n] >= 0, start = 1 / n)
    @objective(model, Min, ε)
    for i in bestindices
        @constraint(model, -ε <= w[best_index] / w[i] - pref_to_best[i] <= ε)
    end
    for i in worstindices
        @constraint(model, -ε <= w[i] / w[worst_index] - pref_to_worst[i] <= ε)
    end
    @constraint(model, sum(w) == 1)
    optimize!(model)
    @assert is_solved_and_feasible(model)
    return value(ε), value.(w)
end

```

---

<div class="post-metadata">

### Author: ![jbytecode](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jbytecode/32/17719_2.png) [@jbytecode](https://discourse.julialang.org/u/jbytecode)
#### Post date: [November 10, 2024, 10:03am UTC](https://discourse.julialang.org/t/ipopt-produces-wrong-results-in-windows/122414/3 "2024-11-10T10:03:33Z")

</div>

Hi @odow

Thank you for your detailed review and answer. Setting the initial values of the decision variables in the feasible region mainly solves the problem.

Additionally, I had to change the constraints

```julia
@constraint(model, abs(w[i] / w[worst_index] - pref_to_worst[i]) <= ε)

```

to

```julia
@constraint(model, w[i] / w[worst_index] - pref_to_worst[i] <= ε)
@constraint(model, -ε <= w[i] / w[worst_index] - pref_to_worst[i])

```

just because

```julia
@constraint(model, -ε <= w[i] / w[worst_index] - pref_to_worst[i] <= ε)

```

is not allowed.

By the way, it is still an issue that the initial implementation was working in Ubuntu and MacOS successfully, however it was failing in Windows. But at the end, it is not an issue in my case now.

Thank you!

---

<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: [November 10, 2024, 6:21pm UTC](https://discourse.julialang.org/t/ipopt-produces-wrong-results-in-windows/122414/4 "2024-11-10T18:21:29Z")

</div>

Do you have a log of the Windows failure? What happens? What is the termination status?

---

<div class="post-metadata">

### Author: ![jbytecode](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jbytecode/32/17719_2.png) [@jbytecode](https://discourse.julialang.org/u/jbytecode)
#### Post date: [November 10, 2024, 6:26pm UTC](https://discourse.julialang.org/t/ipopt-produces-wrong-results-in-windows/122414/5 "2024-11-10T18:26:04Z")

</div>

Only the information that I have is the CI output of GitHub actions:

> <https://github.com/jbytecode/JMcDM/actions/runs/11740450299/job/32707021543>

---

<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: [November 10, 2024, 6:36pm UTC](https://discourse.julialang.org/t/ipopt-produces-wrong-results-in-windows/122414/6 "2024-11-10T18:36:27Z")

</div>

Perhaps I didn’t understand. Did the new version fail? Or is your question still why did the old version fail only on Windows?

In which case, the answer is luck/numerical differences. The problem violates the assumptions of Ipopt, so it isn’t guaranteed to converge to a local minimum.

---

<div class="post-metadata">

### Author: ![jbytecode](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jbytecode/32/17719_2.png) [@jbytecode](https://discourse.julialang.org/u/jbytecode)
#### Post date: [November 10, 2024, 6:41pm UTC](https://discourse.julialang.org/t/ipopt-produces-wrong-results-in-windows/122414/7 "2024-11-10T18:41:19Z")

</div>

No, the problem is solved by introducing a good and a feasible start for the decision variables.

Yes, the previous problem was solving in each start in Ubuntu and MacOS but not in Windows. I understand it is about luck, but it is still unclear, why it was consistently solving in Ubuntu and MacOS, but not in Windows. Maybe, it is because of a predefined seed of random numbers?

---

<div class="post-metadata">

### Author: ![jbytecode](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jbytecode/32/17719_2.png) [@jbytecode](https://discourse.julialang.org/u/jbytecode)
#### Post date: [November 10, 2024, 6:49pm UTC](https://discourse.julialang.org/t/ipopt-produces-wrong-results-in-windows/122414/8 "2024-11-10T18:49:37Z")

</div>

the new feature works like a charm thank to your comments:

> <https://github.com/jbytecode/JMcDM/blob/main/src/bestworst.jl>
