Ipopt has trouble with `Vector{AffExpr} in MOI.Zeros`

I have a JuMP model where solving with HiGHS and Ipopt results in different objective_values.

A JuMP Model
├ solver: Ipopt
├ objective_sense: MIN_SENSE
│ └ objective_function_type: AffExpr
├ num_variables: 54
├ num_constraints: 98
│ ├ AffExpr in MOI.EqualTo{Float64}: 34
│ ├ AffExpr in MOI.GreaterThan{Float64}: 10
│ ├ Vector{AffExpr} in MOI.Zeros: 6
│ ├ VariableRef in MOI.EqualTo{Float64}: 2
│ ├ VariableRef in MOI.GreaterThan{Float64}: 26
│ └ VariableRef in MOI.LessThan{Float64}: 20
└ Names registered in the model

julia> set_optimizer(ldr, HiGHS.Optimizer)
julia> optimize!(ldr)
julia> objective_value(ldr)
119250.0

julia> set_optimizer(ldr, Ipopt.Optimizer)
julia> optimize!(ldr)
julia> objective_value(ldr)
136249.99968899257

Digging a little bit, if I replaced the constraints Vector{AffExpr} in MOI.Zeros: 6 by an explicit JuMP.fix, the issue goes away.

Do you have a reproducible example?

Do write_to_file(ldr, "model.mof.json") then email me the file.

It’s probably because of a difference in the feasibility tolerances. Did you check the log of each solver? Did you check primal_status and termination_status?

Indeed, there’s something strange. I’ll send you the .mof file for further investigation, but already what I saw:

Final Ipopt iterations, terminate with a relatively large inf_du:

  50  1.1965911e+05 1.71e-07 7.93e+01  -1.0 3.80e+01    -  5.94e-01 5.00e-01f  2
  51  1.2021863e+05 6.16e-08 7.81e+01  -1.0 2.82e+03    -  1.50e-02 6.44e-01h  1
  52  1.2360692e+05 6.15e-08 7.80e+01  -1.0 5.55e+06    -  3.23e-04 1.91e-03h  1
  53  1.2364079e+05 6.15e-08 6.12e+01  -1.0 1.88e+05    -  2.15e-01 5.63e-04h  1
  54  1.2328007e+05 5.53e-08 6.11e+01  -1.0 3.00e+04    -  2.82e-03 9.64e-02f  1
  55  1.2327828e+05 5.52e-08 2.66e+01  -1.0 9.09e+03    -  5.64e-01 1.59e-03f  2
  56  1.2512279e+05 1.75e-09 2.63e+01  -1.0 3.55e+03    -  1.30e-02 1.00e+00h  1
  57  1.3614664e+05 1.74e-09 2.63e+01  -1.0 8.00e+06    -  4.48e-04 2.65e-03h  1
  58  1.3625688e+05 1.74e-09 1.61e+01  -1.0 2.38e+05    -  3.87e-01 8.90e-04h  1
  59  1.3623728e+05 6.84e-11 1.24e-02  -1.0 3.74e+01    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  60  1.3624993e+05 1.82e-11 8.68e-03  -1.7 3.20e+01    -  1.00e+00 1.00e+00h  1
  61  1.3625000e+05 5.34e-12 6.84e-03  -3.8 1.86e+00    -  1.00e+00 1.00e+00h  1
  62  1.3625000e+05 2.91e-11 5.12e+02  -5.7 1.47e-02    -  1.00e+00 1.00e+00h  1
  63  1.3625000e+05 1.84e-08 5.12e+02  -8.6 6.46e-03    -  5.57e-02 8.72e-01f  1
  64  1.3625000e+05 1.84e-08 5.12e+02  -8.6 3.95e+00    -  1.00e+00 1.29e-03h  1
  65  1.3625000e+05 2.87e-08 1.59e+01  -8.6 7.37e-04    -  1.00e+00 9.37e-01h  1
  66  1.3625000e+05 3.57e-09 1.34e+01  -8.6 9.66e-06    -  1.00e+00 8.64e-01f  1
  67  1.3625000e+05 1.11e-09 1.43e+01  -8.6 4.43e-06    -  7.12e-01 8.89e-01f  1
  68  1.3625000e+05 8.23e-11 1.88e+00  -8.6 5.82e-07    -  1.00e+00 1.00e+00f  1
  69  1.3625000e+05 4.15e-11 1.21e+00  -9.0 2.35e-06    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  70  1.3625000e+05 2.91e-11 1.06e-01  -9.0 8.37e-09    -  1.00e+00 1.00e+00h  1

Number of Iterations....: 70

And here are the final termination tolerances / errors (again, dual infeas seems a bit too large)

Objective...............:   1.5571428535884865e+04    1.3624999968899257e+05
Dual infeasibility......:   1.0554932188526453e-01    9.2355656649606466e-01
Constraint violation....:   2.4253192047278087e-11    2.9103830456733704e-11
Variable bound violation:   9.9992929492032090e-08    9.9992929492032090e-08
Complementarity.........:   9.7074573973334761e-10    8.4940252226667915e-09
Overall NLP error.......:   9.7074573973334761e-10    9.2355656649606466e-01

The solution status in JuMP seems good:

├ solver_name          : Ipopt
├ Termination
│ ├ termination_status : LOCALLY_SOLVED
│ ├ result_count       : 1
│ └ raw_status         : Solve_Succeeded
├ Solution (result = 1)
│ ├ primal_status        : FEASIBLE_POINT
│ ├ dual_status          : FEASIBLE_POINT
│ ├ objective_value      : 1.36250e+05
│ └ dual_objective_value : 1.20614e+05
└ Work counters
  ├ solve_time (sec)   : 2.66000e-01
  └ barrier_iterations : 70

Very curiously, the problem seems extremely “fine-tuned”. If I perturb the problem data by a small number (and even fix-ing some variable to x+1 and reducing the RHS to y-1 makes Ipopt find the correct solution:

Objective...............:   1.3628571371245105e+04    1.1924999949839467e+05
Dual infeasibility......:   1.5258800077477094e-05    1.3351450067792457e-04
Constraint violation....:   1.1842378929335004e-14    1.4210854715202004e-14
Variable bound violation:   9.9980509205011003e-08    9.9980509205011003e-08
Complementarity.........:   2.5167856828294000e-09    2.2021874724757249e-08
Overall NLP error.......:   2.5167856828294000e-09    1.3351450067792457e-04

I can’t reproduce with the file you sent me. And nothing sticks out as being bad with the model.

What’s the output of primal_feasibility_report(model) when it gets the wrong objective?

Do you have the full log? Did you set any other attributes? A starting value?

Try set_attribute(model, "dual_inf_tol", 1e-6)

How are you making the Zeros constraints?

Curious. I have tried reading back the file to a fresh julia session, and it does give the wrong result with Ipopt. I have Ipopt v1.15.0 and JuMP v1.31.1. I’ll send you the julia source code, but it is strange.

It seems normal. The maximum value was a bit smaller than 1e-4, on constraints c7_1 : 600 volume[2,2] + θ[2] >= 135000 and c4_1 : 2500 volume[2,1] + θ[1] >= 310000

I did not set any attribute, nor anything else. I’ll separately post the full Ipopt logs.

It did not help. It keeps converging to the same solution, and stops because it can’t improve:

  71  1.3625000e+05 2.91e-11 1.23e-03  -9.0 9.58e-09    -  1.00e+00 1.00e+00H  1
  72  1.3625000e+05 1.42e-14 2.77e-04  -9.0 3.42e-11    -  1.00e+00 1.00e+00h  1
  73  1.3625000e+05 1.42e-14 2.75e-04  -9.0 7.47e-11    -  1.00e+00 1.00e+00   0
  74  1.3625000e+05 1.42e-14 2.75e-04  -9.0 3.40e-11    -  1.00e+00 1.00e+00T  0

[...]

EXIT: Search Direction is becoming Too Small.

With @constraint, on a vector of decision variables (that turns out to have length 1). For example
@constraint(ldr, volume_ldr[t,t+1:T] == 0) with t=1 and T=2.

If I were to replace this constraint with a fix., then Ipopt converges to the correct solution. Also, just tested that replacing by @constraint(ldr, volume_ldr[t,t+1:T] .== 0) also works (note the .== instead of just ==).

Original model:

julia> m2 = JuMP.read_from_file("ipopt_bug_model.mof.json")
A JuMP Model
├ solver: none
├ objective_sense: MIN_SENSE
│ └ objective_function_type: AffExpr
├ num_variables: 54
├ num_constraints: 98
│ ├ AffExpr in MOI.EqualTo{Float64}: 34
│ ├ AffExpr in MOI.GreaterThan{Float64}: 10
│ ├ Vector{AffExpr} in MOI.Zeros: 6
│ ├ VariableRef in MOI.EqualTo{Float64}: 2
│ ├ VariableRef in MOI.GreaterThan{Float64}: 26
│ └ VariableRef in MOI.LessThan{Float64}: 20
└ Names registered in the model: none

julia> set_optimizer(m2, Ipopt.Optimizer)

julia> optimize!(m2)

******************************************************************************
This program contains Ipopt, a library for large-scale nonlinear optimization.
 Ipopt is released as open source code under the Eclipse Public License (EPL).
         For more information visit https://github.com/coin-or/Ipopt
******************************************************************************

This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

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

Total number of variables............................:       52
                     variables with only lower bounds:        6
                variables with lower and upper bounds:       20
                     variables with only upper bounds:        0
Total number of equality constraints.................:       40
Total number of inequality constraints...............:       10
        inequality constraints with only lower bounds:       10
   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  5.5009945e+01 3.90e+05 1.00e+02  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  7.3498737e+01 3.90e+05 9.99e+01  -1.0 1.62e+04    -  9.68e-05 3.09e-04h  1
   2  9.8341133e+01 3.89e+05 9.98e+01  -1.0 1.41e+04    -  2.85e-04 4.04e-04h  1
   3  1.8419194e+02 3.87e+05 9.99e+01  -1.0 1.29e+04    -  5.65e-04 2.20e-03h  1
   4  4.9973186e+02 3.81e+05 9.99e+01  -1.0 1.14e+04    -  1.48e-03 6.01e-03h  1
   5  3.8713917e+02 3.76e+05 9.98e+01  -1.0 1.22e+04    -  1.40e-03 3.39e-03f  1
   6  4.9056945e+02 3.69e+05 9.90e+01  -1.0 1.37e+04    -  7.63e-03 5.12e-03h  1
   7  5.5454064e+02 3.66e+05 9.77e+01  -1.0 1.66e+04    -  1.38e-02 1.70e-03h  1
   8  5.5683941e+02 3.66e+05 1.28e+02  -1.0 1.83e+04    -  4.27e-03 8.31e-05h  1
   9  6.2125913e+02 3.63e+05 9.73e+01  -1.0 1.85e+04    -  2.51e-05 2.57e-03h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10  1.6721999e+03 3.29e+05 9.72e+01  -1.0 2.80e+04    -  8.04e-05 2.72e-02h  1
  11  1.6812522e+03 3.28e+05 1.21e+02  -1.0 2.88e+04    -  4.16e-02 2.30e-04h  1
  12  1.7217178e+03 3.27e+05 1.17e+02  -1.0 3.41e+04    -  1.95e-04 8.50e-04h  1
  13  3.8273739e+03 2.73e+05 1.39e+02  -1.0 3.43e+04    -  1.61e-03 4.48e-02h  1
  14  6.4294396e+03 2.49e+05 1.57e+02  -1.0 3.66e+04    -  4.53e-02 5.54e-02h  1
  15  6.5394637e+03 2.48e+05 1.56e+02  -1.0 3.46e+04    -  3.76e-04 1.51e-03h  1
  16  1.3808903e+04 2.17e+05 1.05e+02  -1.0 3.46e+04    -  1.15e-03 8.14e-02h  1
  17  1.3883275e+04 2.17e+05 1.08e+02  -1.0 3.18e+04    -  7.01e-03 9.01e-04h  1
  18  1.4050898e+04 2.17e+05 1.07e+02  -1.0 3.17e+04    -  5.11e-05 1.05e-03h  1
  19  2.8668862e+04 1.86e+05 9.80e+01  -1.0 3.17e+04    -  1.05e-03 8.90e-02h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20  2.8815551e+04 1.86e+05 9.09e+01  -1.0 2.89e+04    -  8.39e-03 9.82e-04h  1
  21  2.8819026e+04 1.86e+05 1.38e+02  -1.0 2.90e+04    -  2.38e-04 3.10e-05h  1
  22  2.8820860e+04 1.86e+05 2.03e+02  -1.0 3.13e+04    -  4.06e-05 2.09e-05h  1
  23r 2.8820860e+04 1.86e+05 9.99e+02   4.3 0.00e+00    -  0.00e+00 4.72e-07R  3
  24r 3.4704027e+04 1.48e+05 8.08e+03   4.3 2.69e+07    -  3.66e-03 2.74e-04f  1
  25  3.4769544e+04 1.48e+05 4.35e+02  -1.0 7.48e+04    -  7.38e-04 2.05e-03h  1
  26  3.4800697e+04 1.48e+05 4.35e+02  -1.0 7.25e+04    -  6.70e-04 5.21e-04h  1
  27  3.5197118e+04 1.47e+05 4.33e+02  -1.0 7.97e+04    -  9.03e-04 6.56e-03h  1
  28  3.6401751e+04 1.46e+05 4.27e+02  -1.0 7.98e+04    -  8.08e-03 1.88e-02h  1
  29  3.7564990e+04 1.45e+05 4.24e+02  -1.0 7.88e+04    -  4.15e-03 1.22e-02h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30  4.1305000e+04 1.38e+05 4.07e+02  -1.0 7.83e+04    -  1.32e-03 8.37e-02h  1
  31  4.1352792e+04 1.37e+05 1.15e+03  -1.0 6.74e+04    -  5.72e-02 1.03e-03h  1
  32  4.2042321e+04 1.36e+05 3.74e+02  -1.0 1.05e+05    -  1.20e-04 1.14e-02h  1
  33  5.3230622e+04 1.16e+05 4.94e+02  -1.0 1.10e+05    -  1.09e-02 1.79e-01h  1
  34  5.7962689e+04 1.08e+05 4.47e+02  -1.0 8.99e+04    -  8.79e-02 8.20e-02h  1
  35  6.9279665e+04 9.29e+04 5.12e+02  -1.0 8.25e+04    -  5.25e-02 1.75e-01h  1
  36  6.9412281e+04 9.27e+04 5.12e+02  -1.0 6.81e+04    -  4.06e-01 2.60e-03h  1
  37  8.3918433e+04 6.89e+04 5.12e+02  -1.0 6.79e+04    -  1.74e-02 3.37e-01h  1
  38  8.4063678e+04 6.87e+04 5.55e+02  -1.0 4.50e+04    -  4.06e-01 5.08e-03h  1
  39  8.4076076e+04 6.87e+04 2.88e+02  -1.0 2.65e+04    -  5.58e-04 6.02e-04h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  40  8.4153599e+04 6.85e+04 7.97e+02  -1.0 5.84e+04    -  1.01e-05 2.19e-03h  1
  41  1.2353330e+05 6.86e-06 8.32e+02  -1.0 6.67e+04    -  2.23e-03 1.00e+00h  1
  42  1.2352828e+05 2.94e-06 6.18e+02  -1.0 3.09e+00    -  4.49e-01 1.00e+00f  1
  43  1.2347645e+05 3.52e-06 4.24e+02  -1.0 4.38e+01    -  8.83e-02 1.00e+00f  1
  44  1.2068163e+05 3.37e-06 4.24e+02  -1.0 5.55e+04    -  9.85e-04 5.25e-02f  1
  45  1.2065369e+05 3.36e-06 3.61e+02  -1.0 1.09e+05    -  1.47e-01 2.68e-04f  1
  46  1.2065462e+05 5.02e-07 2.19e+02  -1.0 1.46e+01    -  3.93e-01 1.00e+00f  1
  47  1.2064263e+05 6.68e-08 2.01e+02  -1.0 1.67e+02    -  8.39e-02 5.94e-01f  1
  48  1.1966409e+05 3.43e-07 1.99e+02  -1.0 1.26e+04    -  8.24e-03 9.75e-01f  1
  49  1.1965427e+05 3.43e-07 1.95e+02  -1.0 6.26e+05    -  1.96e-02 1.96e-04f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  50  1.1965911e+05 1.71e-07 7.93e+01  -1.0 3.80e+01    -  5.94e-01 5.00e-01f  2
  51  1.2021863e+05 6.16e-08 7.81e+01  -1.0 2.82e+03    -  1.50e-02 6.44e-01h  1
  52  1.2360692e+05 6.15e-08 7.80e+01  -1.0 5.55e+06    -  3.23e-04 1.91e-03h  1
  53  1.2364079e+05 6.15e-08 6.12e+01  -1.0 1.88e+05    -  2.15e-01 5.63e-04h  1
  54  1.2328007e+05 5.53e-08 6.11e+01  -1.0 3.00e+04    -  2.82e-03 9.64e-02f  1
  55  1.2327828e+05 5.52e-08 2.66e+01  -1.0 9.09e+03    -  5.64e-01 1.59e-03f  2
  56  1.2512279e+05 1.75e-09 2.63e+01  -1.0 3.55e+03    -  1.30e-02 1.00e+00h  1
  57  1.3614664e+05 1.74e-09 2.63e+01  -1.0 8.00e+06    -  4.48e-04 2.65e-03h  1
  58  1.3625688e+05 1.74e-09 1.61e+01  -1.0 2.38e+05    -  3.87e-01 8.90e-04h  1
  59  1.3623728e+05 6.84e-11 1.24e-02  -1.0 3.74e+01    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  60  1.3624993e+05 1.82e-11 8.68e-03  -1.7 3.20e+01    -  1.00e+00 1.00e+00h  1
  61  1.3625000e+05 5.34e-12 6.84e-03  -3.8 1.86e+00    -  1.00e+00 1.00e+00h  1
  62  1.3625000e+05 2.91e-11 5.12e+02  -5.7 1.47e-02    -  1.00e+00 1.00e+00h  1
  63  1.3625000e+05 1.84e-08 5.12e+02  -8.6 6.46e-03    -  5.57e-02 8.72e-01f  1
  64  1.3625000e+05 1.84e-08 5.12e+02  -8.6 3.95e+00    -  1.00e+00 1.29e-03h  1
  65  1.3625000e+05 2.87e-08 1.59e+01  -8.6 7.37e-04    -  1.00e+00 9.37e-01h  1
  66  1.3625000e+05 3.57e-09 1.34e+01  -8.6 9.66e-06    -  1.00e+00 8.64e-01f  1
  67  1.3625000e+05 1.11e-09 1.43e+01  -8.6 4.43e-06    -  7.12e-01 8.89e-01f  1
  68  1.3625000e+05 8.23e-11 1.88e+00  -8.6 5.82e-07    -  1.00e+00 1.00e+00f  1
  69  1.3625000e+05 4.15e-11 1.21e+00  -9.0 2.35e-06    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  70  1.3625000e+05 2.91e-11 1.06e-01  -9.0 8.37e-09    -  1.00e+00 1.00e+00h  1

Number of Iterations....: 70

                                   (scaled)                 (unscaled)
Objective...............:   1.5571428535884865e+04    1.3624999968899257e+05
Dual infeasibility......:   1.0554932188526453e-01    9.2355656649606466e-01
Constraint violation....:   2.4253192047278087e-11    2.9103830456733704e-11
Variable bound violation:   9.9992929492032090e-08    9.9992929492032090e-08
Complementarity.........:   9.7074573973334761e-10    8.4940252226667915e-09
Overall NLP error.......:   9.7074573973334761e-10    9.2355656649606466e-01


Number of objective function evaluations             = 76
Number of objective gradient evaluations             = 71
Number of equality constraint evaluations            = 76
Number of inequality constraint evaluations          = 76
Number of equality constraint Jacobian evaluations   = 1
Number of inequality constraint Jacobian evaluations = 1
Number of Lagrangian Hessian evaluations             = 2
Total seconds in IPOPT                               = 0.138

EXIT: Optimal Solution Found.

With dual tol = 1e-6:

julia> set_attribute(m2, "dual_inf_tol", 1e-6)

julia> optimize!(m2)
This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

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

Total number of variables............................:       52
                     variables with only lower bounds:        6
                variables with lower and upper bounds:       20
                     variables with only upper bounds:        0
Total number of equality constraints.................:       40
Total number of inequality constraints...............:       10
        inequality constraints with only lower bounds:       10
   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  5.5009945e+01 3.90e+05 1.00e+02  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  7.3498737e+01 3.90e+05 9.99e+01  -1.0 1.62e+04    -  9.68e-05 3.09e-04h  1
   2  9.8341133e+01 3.89e+05 9.98e+01  -1.0 1.41e+04    -  2.85e-04 4.04e-04h  1
   3  1.8419194e+02 3.87e+05 9.99e+01  -1.0 1.29e+04    -  5.65e-04 2.20e-03h  1
   4  4.9973186e+02 3.81e+05 9.99e+01  -1.0 1.14e+04    -  1.48e-03 6.01e-03h  1
   5  3.8713917e+02 3.76e+05 9.98e+01  -1.0 1.22e+04    -  1.40e-03 3.39e-03f  1
   6  4.9056945e+02 3.69e+05 9.90e+01  -1.0 1.37e+04    -  7.63e-03 5.12e-03h  1
   7  5.5454064e+02 3.66e+05 9.77e+01  -1.0 1.66e+04    -  1.38e-02 1.70e-03h  1
   8  5.5683941e+02 3.66e+05 1.28e+02  -1.0 1.83e+04    -  4.27e-03 8.31e-05h  1
   9  6.2125913e+02 3.63e+05 9.73e+01  -1.0 1.85e+04    -  2.51e-05 2.57e-03h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10  1.6721999e+03 3.29e+05 9.72e+01  -1.0 2.80e+04    -  8.04e-05 2.72e-02h  1
  11  1.6812522e+03 3.28e+05 1.21e+02  -1.0 2.88e+04    -  4.16e-02 2.30e-04h  1
  12  1.7217178e+03 3.27e+05 1.17e+02  -1.0 3.41e+04    -  1.95e-04 8.50e-04h  1
  13  3.8273739e+03 2.73e+05 1.39e+02  -1.0 3.43e+04    -  1.61e-03 4.48e-02h  1
  14  6.4294396e+03 2.49e+05 1.57e+02  -1.0 3.66e+04    -  4.53e-02 5.54e-02h  1
  15  6.5394637e+03 2.48e+05 1.56e+02  -1.0 3.46e+04    -  3.76e-04 1.51e-03h  1
  16  1.3808903e+04 2.17e+05 1.05e+02  -1.0 3.46e+04    -  1.15e-03 8.14e-02h  1
  17  1.3883275e+04 2.17e+05 1.08e+02  -1.0 3.18e+04    -  7.01e-03 9.01e-04h  1
  18  1.4050898e+04 2.17e+05 1.07e+02  -1.0 3.17e+04    -  5.11e-05 1.05e-03h  1
  19  2.8668862e+04 1.86e+05 9.80e+01  -1.0 3.17e+04    -  1.05e-03 8.90e-02h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20  2.8815551e+04 1.86e+05 9.09e+01  -1.0 2.89e+04    -  8.39e-03 9.82e-04h  1
  21  2.8819026e+04 1.86e+05 1.38e+02  -1.0 2.90e+04    -  2.38e-04 3.10e-05h  1
  22  2.8820860e+04 1.86e+05 2.03e+02  -1.0 3.13e+04    -  4.06e-05 2.09e-05h  1
  23r 2.8820860e+04 1.86e+05 9.99e+02   4.3 0.00e+00    -  0.00e+00 4.72e-07R  3
  24r 3.4704027e+04 1.48e+05 8.08e+03   4.3 2.69e+07    -  3.66e-03 2.74e-04f  1
  25  3.4769544e+04 1.48e+05 4.35e+02  -1.0 7.48e+04    -  7.38e-04 2.05e-03h  1
  26  3.4800697e+04 1.48e+05 4.35e+02  -1.0 7.25e+04    -  6.70e-04 5.21e-04h  1
  27  3.5197118e+04 1.47e+05 4.33e+02  -1.0 7.97e+04    -  9.03e-04 6.56e-03h  1
  28  3.6401751e+04 1.46e+05 4.27e+02  -1.0 7.98e+04    -  8.08e-03 1.88e-02h  1
  29  3.7564990e+04 1.45e+05 4.24e+02  -1.0 7.88e+04    -  4.15e-03 1.22e-02h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30  4.1305000e+04 1.38e+05 4.07e+02  -1.0 7.83e+04    -  1.32e-03 8.37e-02h  1
  31  4.1352792e+04 1.37e+05 1.15e+03  -1.0 6.74e+04    -  5.72e-02 1.03e-03h  1
  32  4.2042321e+04 1.36e+05 3.74e+02  -1.0 1.05e+05    -  1.20e-04 1.14e-02h  1
  33  5.3230622e+04 1.16e+05 4.94e+02  -1.0 1.10e+05    -  1.09e-02 1.79e-01h  1
  34  5.7962689e+04 1.08e+05 4.47e+02  -1.0 8.99e+04    -  8.79e-02 8.20e-02h  1
  35  6.9279665e+04 9.29e+04 5.12e+02  -1.0 8.25e+04    -  5.25e-02 1.75e-01h  1
  36  6.9412281e+04 9.27e+04 5.12e+02  -1.0 6.81e+04    -  4.06e-01 2.60e-03h  1
  37  8.3918433e+04 6.89e+04 5.12e+02  -1.0 6.79e+04    -  1.74e-02 3.37e-01h  1
  38  8.4063678e+04 6.87e+04 5.55e+02  -1.0 4.50e+04    -  4.06e-01 5.08e-03h  1
  39  8.4076076e+04 6.87e+04 2.88e+02  -1.0 2.65e+04    -  5.58e-04 6.02e-04h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  40  8.4153599e+04 6.85e+04 7.97e+02  -1.0 5.84e+04    -  1.01e-05 2.19e-03h  1
  41  1.2353330e+05 6.86e-06 8.32e+02  -1.0 6.67e+04    -  2.23e-03 1.00e+00h  1
  42  1.2352828e+05 2.94e-06 6.18e+02  -1.0 3.09e+00    -  4.49e-01 1.00e+00f  1
  43  1.2347645e+05 3.52e-06 4.24e+02  -1.0 4.38e+01    -  8.83e-02 1.00e+00f  1
  44  1.2068163e+05 3.37e-06 4.24e+02  -1.0 5.55e+04    -  9.85e-04 5.25e-02f  1
  45  1.2065369e+05 3.36e-06 3.61e+02  -1.0 1.09e+05    -  1.47e-01 2.68e-04f  1
  46  1.2065462e+05 5.02e-07 2.19e+02  -1.0 1.46e+01    -  3.93e-01 1.00e+00f  1
  47  1.2064263e+05 6.68e-08 2.01e+02  -1.0 1.67e+02    -  8.39e-02 5.94e-01f  1
  48  1.1966409e+05 3.43e-07 1.99e+02  -1.0 1.26e+04    -  8.24e-03 9.75e-01f  1
  49  1.1965427e+05 3.43e-07 1.95e+02  -1.0 6.26e+05    -  1.96e-02 1.96e-04f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  50  1.1965911e+05 1.71e-07 7.93e+01  -1.0 3.80e+01    -  5.94e-01 5.00e-01f  2
  51  1.2021863e+05 6.16e-08 7.81e+01  -1.0 2.82e+03    -  1.50e-02 6.44e-01h  1
  52  1.2360692e+05 6.15e-08 7.80e+01  -1.0 5.55e+06    -  3.23e-04 1.91e-03h  1
  53  1.2364079e+05 6.15e-08 6.12e+01  -1.0 1.88e+05    -  2.15e-01 5.63e-04h  1
  54  1.2328007e+05 5.53e-08 6.11e+01  -1.0 3.00e+04    -  2.82e-03 9.64e-02f  1
  55  1.2327828e+05 5.52e-08 2.66e+01  -1.0 9.09e+03    -  5.64e-01 1.59e-03f  2
  56  1.2512279e+05 1.75e-09 2.63e+01  -1.0 3.55e+03    -  1.30e-02 1.00e+00h  1
  57  1.3614664e+05 1.74e-09 2.63e+01  -1.0 8.00e+06    -  4.48e-04 2.65e-03h  1
  58  1.3625688e+05 1.74e-09 1.61e+01  -1.0 2.38e+05    -  3.87e-01 8.90e-04h  1
  59  1.3623728e+05 6.84e-11 1.24e-02  -1.0 3.74e+01    -  1.00e+00 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  60  1.3624993e+05 1.82e-11 8.68e-03  -1.7 3.20e+01    -  1.00e+00 1.00e+00h  1
  61  1.3625000e+05 5.34e-12 6.84e-03  -3.8 1.86e+00    -  1.00e+00 1.00e+00h  1
  62  1.3625000e+05 2.91e-11 5.12e+02  -5.7 1.47e-02    -  1.00e+00 1.00e+00h  1
  63  1.3625000e+05 1.84e-08 5.12e+02  -8.6 6.46e-03    -  5.57e-02 8.72e-01f  1
  64  1.3625000e+05 1.84e-08 5.12e+02  -8.6 3.95e+00    -  1.00e+00 1.29e-03h  1
  65  1.3625000e+05 2.87e-08 1.59e+01  -8.6 7.37e-04    -  1.00e+00 9.37e-01h  1
  66  1.3625000e+05 3.57e-09 1.34e+01  -8.6 9.66e-06    -  1.00e+00 8.64e-01f  1
  67  1.3625000e+05 1.11e-09 1.43e+01  -8.6 4.43e-06    -  7.12e-01 8.89e-01f  1
  68  1.3625000e+05 8.23e-11 1.88e+00  -8.6 5.82e-07    -  1.00e+00 1.00e+00f  1
  69  1.3625000e+05 4.15e-11 1.21e+00  -9.0 2.35e-06    -  1.00e+00 1.00e+00h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  70  1.3625000e+05 2.91e-11 1.06e-01  -9.0 8.37e-09    -  1.00e+00 1.00e+00h  1
  71  1.3625000e+05 2.91e-11 1.23e-03  -9.0 9.58e-09    -  1.00e+00 1.00e+00H  1
  72  1.3625000e+05 1.42e-14 2.77e-04  -9.0 3.42e-11    -  1.00e+00 1.00e+00h  1
  73  1.3625000e+05 1.42e-14 2.75e-04  -9.0 7.47e-11    -  1.00e+00 1.00e+00   0
  74  1.3625000e+05 1.42e-14 2.75e-04  -9.0 3.40e-11    -  1.00e+00 1.00e+00T  0

Number of Iterations....: 74

                                   (scaled)                 (unscaled)
Objective...............:   1.5571428535885436e+04    1.3624999968899757e+05
Dual infeasibility......:   2.7481774326076902e-04    2.4046552535317289e-03
Constraint violation....:   1.4210854715202004e-14    1.4210854715202004e-14
Variable bound violation:   9.9992929492032090e-08    9.9992929492032090e-08
Complementarity.........:   9.0949470177244030e-10    7.9580786405088522e-09
Overall NLP error.......:   9.0949470177244030e-10    2.4046552535317289e-03


Number of objective function evaluations             = 81
Number of objective gradient evaluations             = 75
Number of equality constraint evaluations            = 81
Number of inequality constraint evaluations          = 81
Number of equality constraint Jacobian evaluations   = 1
Number of inequality constraint Jacobian evaluations = 1
Number of Lagrangian Hessian evaluations             = 2
Total seconds in IPOPT                               = 0.153

EXIT: Search Direction is becoming Too Small.

Version with .== in the @constraint (good solution):

This is Ipopt version 3.14.19, running with linear solver MUMPS 5.9.0.

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

Total number of variables............................:       52
                     variables with only lower bounds:        6
                variables with lower and upper bounds:       20
                     variables with only upper bounds:        0
Total number of equality constraints.................:       40
Total number of inequality constraints...............:       10
        inequality constraints with only lower bounds:       10
   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  5.5009945e+01 3.90e+05 1.00e+02  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
   1  7.3498737e+01 3.90e+05 9.99e+01  -1.0 1.62e+04    -  9.68e-05 3.09e-04h  1
   2  9.8341133e+01 3.89e+05 9.98e+01  -1.0 1.41e+04    -  2.85e-04 4.04e-04h  1
   3  1.8419194e+02 3.87e+05 9.99e+01  -1.0 1.29e+04    -  5.65e-04 2.20e-03h  1
   4  4.9973544e+02 3.81e+05 9.99e+01  -1.0 1.14e+04    -  1.48e-03 6.01e-03h  1
   5  3.8714152e+02 3.76e+05 9.98e+01  -1.0 1.22e+04    -  1.40e-03 3.39e-03f  1
   6  4.9057198e+02 3.69e+05 9.90e+01  -1.0 1.37e+04    -  7.63e-03 5.12e-03h  1
   7  5.5454246e+02 3.66e+05 9.77e+01  -1.0 1.66e+04    -  1.38e-02 1.70e-03h  1
   8  5.5684124e+02 3.66e+05 1.28e+02  -1.0 1.83e+04    -  4.27e-03 8.31e-05h  1
   9  6.2126123e+02 3.63e+05 9.73e+01  -1.0 1.85e+04    -  2.51e-05 2.57e-03h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  10  1.6722016e+03 3.29e+05 9.72e+01  -1.0 2.80e+04    -  8.04e-05 2.72e-02h  1
  11  1.6812539e+03 3.28e+05 1.21e+02  -1.0 2.88e+04    -  4.16e-02 2.30e-04h  1
  12  1.7217194e+03 3.27e+05 1.17e+02  -1.0 3.41e+04    -  1.95e-04 8.50e-04h  1
  13  3.8273821e+03 2.73e+05 1.39e+02  -1.0 3.43e+04    -  1.61e-03 4.48e-02h  1
  14  6.4294409e+03 2.49e+05 1.57e+02  -1.0 3.66e+04    -  4.53e-02 5.54e-02h  1
  15  6.5394659e+03 2.48e+05 1.56e+02  -1.0 3.46e+04    -  3.76e-04 1.51e-03h  1
  16  1.3808904e+04 2.17e+05 1.05e+02  -1.0 3.46e+04    -  1.15e-03 8.14e-02h  1
  17  1.3883275e+04 2.17e+05 1.08e+02  -1.0 3.18e+04    -  7.01e-03 9.01e-04h  1
  18  1.4050915e+04 2.17e+05 1.07e+02  -1.0 3.17e+04    -  5.11e-05 1.05e-03h  1
  19  2.8668863e+04 1.86e+05 9.80e+01  -1.0 3.17e+04    -  1.05e-03 8.90e-02h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  20  2.8815552e+04 1.86e+05 9.09e+01  -1.0 2.89e+04    -  8.39e-03 9.82e-04h  1
  21  2.8819027e+04 1.86e+05 1.38e+02  -1.0 2.90e+04    -  2.38e-04 3.10e-05h  1
  22  2.8820861e+04 1.86e+05 2.03e+02  -1.0 3.13e+04    -  4.07e-05 2.09e-05h  1
  23r 2.8820861e+04 1.86e+05 9.99e+02   4.3 0.00e+00    -  0.00e+00 4.73e-07R  3
  24r 3.4730739e+04 1.49e+05 8.02e+03   4.3 2.71e+07    -  3.63e-03 2.74e-04f  1
  25  3.4866009e+04 1.48e+05 4.35e+02  -1.0 5.27e+04    -  3.45e-03 2.04e-03h  1
  26  3.5052907e+04 1.48e+05 4.85e+02  -1.0 7.98e+04    -  5.32e-04 3.23e-03h  1
  27  3.5483086e+04 1.47e+05 4.82e+02  -1.0 8.08e+04    -  3.58e-03 7.18e-03h  1
  28  3.6829095e+04 1.46e+05 4.73e+02  -1.0 8.02e+04    -  8.59e-03 1.96e-02h  1
  29  4.1476475e+04 1.38e+05 4.30e+02  -1.0 7.89e+04    -  6.39e-04 9.06e-02h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  30  4.1511856e+04 1.38e+05 1.15e+03  -1.0 6.92e+04    -  6.02e-02 8.25e-04h  1
  31  4.2189890e+04 1.36e+05 4.25e+02  -1.0 1.05e+05    -  1.22e-04 1.14e-02h  1
  32  5.4036630e+04 1.15e+05 1.24e+03  -1.0 1.10e+05    -  1.06e-02 1.91e-01h  1
  33  5.8464780e+04 1.08e+05 1.14e+03  -1.0 8.86e+04    -  8.17e-02 7.63e-02h  1
  34  6.9289948e+04 9.31e+04 1.00e+03  -1.0 8.19e+04    -  5.94e-02 1.69e-01h  1
  35  6.9417785e+04 9.30e+04 9.28e+02  -1.0 6.81e+04    -  3.96e-01 2.51e-03h  1
  36  8.3789182e+04 6.93e+04 6.94e+02  -1.0 6.79e+04    -  1.73e-02 3.33e-01h  1
  37  8.3933128e+04 6.91e+04 7.08e+02  -1.0 4.52e+04    -  4.03e-01 5.01e-03h  1
  38  8.3945189e+04 6.90e+04 6.96e+02  -1.0 2.77e+04    -  5.27e-04 5.74e-04h  1
  39  8.4251817e+04 6.85e+04 7.44e+02  -1.0 6.42e+04    -  3.31e-05 8.01e-03h  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  40  1.2353340e+05 7.62e-06 8.49e+02  -1.0 6.65e+04    -  9.48e-03 1.00e+00h  1
  41  1.2352793e+05 3.06e-08 4.28e+02  -1.0 3.23e+00    -  4.98e-01 1.00e+00f  1
  42  1.2306859e+05 3.80e-08 4.24e+02  -1.0 4.66e+02    -  9.91e-03 1.00e+00f  1
  43  1.2067587e+05 3.79e-08 4.24e+02  -1.0 1.90e+06    -  2.51e-04 1.32e-03f  1
  44  1.2065194e+05 3.79e-08 3.36e+02  -1.0 8.00e+04    -  2.07e-01 3.12e-04f  1
  45  1.2065034e+05 1.46e-11 6.40e+01  -1.0 9.75e+00    -  8.10e-01 1.00e+00f  1
  46  1.2060400e+05 9.84e-09 6.13e+01  -1.0 2.69e+02    -  4.25e-02 1.00e+00f  1
  47  1.2026796e+05 9.77e-09 6.12e+01  -1.0 3.56e+05    -  8.27e-04 7.55e-03f  1
  48  1.2026628e+05 9.75e-09 2.29e+01  -1.0 7.88e+03    -  6.25e-01 1.71e-03f  2
  49  1.2015621e+05 5.21e-08 2.24e+01  -1.0 1.33e+03    -  2.18e-02 1.00e+00f  1
iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
  50  1.1927288e+05 4.26e-08 2.23e+01  -1.0 1.68e+05    -  7.95e-03 6.58e-02f  1
  51  1.1926405e+05 4.24e-08 9.45e+00  -1.0 4.58e+04    -  9.57e-01 2.41e-03f  1
  52  1.1926583e+05 3.97e-08 1.00e-06  -1.0 2.07e+01    -  1.00e+00 1.00e+00f  1
  53  1.1925045e+05 2.91e-11 2.83e-08  -2.5 4.00e+00    -  1.00e+00 1.00e+00f  1
  54  1.1925002e+05 9.95e-14 1.50e-09  -3.8 1.26e-01    -  1.00e+00 1.00e+00f  1
  55  1.1925000e+05 1.42e-14 1.85e-11  -5.7 5.76e-03    -  1.00e+00 1.00e+00f  1
  56  1.1925000e+05 2.84e-14 1.99e-06  -8.6 7.13e-05    -  1.00e+00 1.00e+00f  1

Number of Iterations....: 56

                                   (scaled)                 (unscaled)
Objective...............:   1.3628571371245105e+04    1.1924999949839467e+05
Dual infeasibility......:   1.9867339204893142e-06    1.7383921804281499e-05
Constraint violation....:   2.8421709430404007e-14    2.8421709430404007e-14
Variable bound violation:   9.9980509205011003e-08    9.9980509205011003e-08
Complementarity.........:   2.5061989815744199e-09    2.1929241088776175e-08
Overall NLP error.......:   2.5061989815744199e-09    1.7383921804281499e-05


Number of objective function evaluations             = 61
Number of objective gradient evaluations             = 57
Number of equality constraint evaluations            = 61
Number of inequality constraint evaluations          = 61
Number of equality constraint Jacobian evaluations   = 1
Number of inequality constraint Jacobian evaluations = 1
Number of Lagrangian Hessian evaluations             = 2
Total seconds in IPOPT                               = 0.154

EXIT: Optimal Solution Found.

A JuMP Model
├ solver: Ipopt
├ objective_sense: MIN_SENSE
│ └ objective_function_type: AffExpr
├ num_variables: 54
├ num_constraints: 98
│ ├ AffExpr in MOI.EqualTo{Float64}: 40
│ ├ AffExpr in MOI.GreaterThan{Float64}: 10
│ ├ VariableRef in MOI.EqualTo{Float64}: 2
│ ├ VariableRef in MOI.GreaterThan{Float64}: 26
│ └ VariableRef in MOI.LessThan{Float64}: 20

I’m not sure what’s going on :confused: This seems to be Windows-specific, so it’s not something I can replicate.

If you do print_active_bridges you find that it is doing exactly the .== 0 reformulation:

julia> print_active_bridges(model)
 * Supported objective: MOI.ScalarAffineFunction{Float64}
 * Supported constraint: MOI.ScalarAffineFunction{Float64}-in-MOI.EqualTo{Float64}
 * Supported constraint: MOI.ScalarAffineFunction{Float64}-in-MOI.GreaterThan{Float64}
 * Supported constraint: MOI.VariableIndex-in-MOI.EqualTo{Float64}
 * Supported constraint: MOI.VariableIndex-in-MOI.GreaterThan{Float64}
 * Supported constraint: MOI.VariableIndex-in-MOI.LessThan{Float64}
 * Unsupported constraint: MOI.VectorAffineFunction{Float64}-in-MOI.Zeros
 |  bridged by:
 |   MOIB.Constraint.ScalarizeBridge{Float64, MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}}
 |  may introduce:
 |   * Supported constraint: MOI.ScalarAffineFunction{Float64}-in-MOI.EqualTo{Float64}

What happens if you move the .== formulation from after @variables to the end just before return ldr? I wonder if it is something to do with the order of the constraints.

Bingo! Indeed, moving the .== to the end will make Ipopt finish in the wrong place. I guess this is a floating-point windows-specific issue, but at least we’re getting closer. I’ll try to replicate on Windows 10 (…) and let you know. As you can imagine, using fix at the end gives the correct answer, probably because that’s sent to the solver in a different order / way.

I can reproduce this in CI: Add a test with bfpc's instance from Discourse - Pull Request #546 - jump-dev/Ipopt.jl - GitHub

Even more curiously: on Ubuntu over WSL (5.15.167.4-microsoft-standard-WSL2 kernel, ubuntu Noble), julia 1.12.6, [87dc4568] HiGHS v1.24.1 [b6b21f68] Ipopt v1.15.0 [4076af6c] JuMP v1.31.1, and declaring .== constraints TWICE at the end of the formulation (I did not do it on purpose, just a copy-paste bug), I get

iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
   0  5.5009945e+01 3.90e+05 1.00e+02  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
WARNING: Problem in step computation; switching to emergency mode.
   1r 5.5009945e+01 3.90e+05 9.99e+02   4.4 0.00e+00  20.0 0.00e+00 0.00e+00R  1
WARNING: Problem in step computation; switching to emergency mode.
Cannot call restoration phase at point that is almost feasible for the restoration NLP (violation 0.000000e+00).
Abort in line search due to no other fall back.
Step computation in the restoration phase failed.

Number of Iterations....: 1

                                   (scaled)                 (unscaled)
Objective...............:   6.2868508560000000e+00    5.5009944990000001e+01
Dual infeasibility......:   1.0000000000000000e+02    8.7500000000000000e+02
Constraint violation....:   2.4998996634336665e+04    3.8992198997800995e+05
Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
Complementarity.........:   2.9999000301000001e+02    2.6249125263375004e+03
Overall NLP error.......:   2.4998996634336665e+04    3.8992198997800995e+05


Number of objective function evaluations             = 2
Number of objective gradient evaluations             = 2
Number of equality constraint evaluations            = 2
Number of inequality constraint evaluations          = 2
Number of equality constraint Jacobian evaluations   = 1
Number of inequality constraint Jacobian evaluations = 1
Number of Lagrangian Hessian evaluations             = 2
Total seconds in IPOPT                               = 0.003

EXIT: Restoration Failed!

This is probably a different issue (since this has nothing to do with Vectror{AffExpr}). Maybe asking for Ipopt to handle this kind of issue is not reasonable. Sorry for the noise.

Hi,

I was pinged by @amontoison. I played around with UnoSolver.jl + MA57 and an AMPL version of your instance, and found out something interesting. I’m guessing something similar happens with IPOPT (the implementations, while not identical, are quite close).

During some iterations, the regularization loop behaves like this:

Testing factorization with regularization factors (0, 0)
Performing numerical factorization of the indefinite system
Expected inertia  (54, 42, 0)
Estimated inertia (55, 41, 0)

Testing factorization with regularization factors (1.11111e-05, 0)
Performing numerical factorization of the indefinite system
Expected inertia  (54, 42, 0)
Estimated inertia (55, 40, 1)

Testing factorization with regularization factors (8.88889e-05, 0)
Performing numerical factorization of the indefinite system
Expected inertia  (54, 42, 0)
Estimated inertia (55, 41, 0)

Testing factorization with regularization factors (0.000711111, 0)
Performing numerical factorization of the indefinite system
Expected inertia  (54, 42, 0)
Estimated inertia (55, 41, 0)

Testing factorization with regularization factors (0.00568889, 0)
Performing numerical factorization of the indefinite system
Expected inertia  (54, 42, 0)
Estimated inertia (55, 41, 0)

Testing factorization with regularization factors (0.0455111, 0)
Performing numerical factorization of the indefinite system
Expected inertia  (54, 42, 0)
Estimated inertia (54, 41, 1)

Testing factorization with regularization factors (0.364089, 0)
Performing numerical factorization of the indefinite system
Expected inertia  (54, 42, 0)
Estimated inertia (54, 40, 2)

Testing factorization with regularization factors (2.91271, 0)
Performing numerical factorization of the indefinite system
Expected inertia  (54, 42, 0)
Estimated inertia (54, 40, 2)

Testing factorization with regularization factors (23.3017, 0)
Performing numerical factorization of the indefinite system
Expected inertia  (54, 42, 0)
Estimated inertia (54, 40, 2)

Testing factorization with regularization factors (2330.17, 0)
Performing numerical factorization of the indefinite system
Expected inertia  (54, 42, 0)
Estimated inertia (54, 40, 2)
...

At the beginning, the estimated inertia contains one positive eigenvalue too many, which is not covered by the IPOPT regularization strategy (also implemented in Uno), so it dumbly tries to increase the primal reg coefficient. This then turns an estimated negative eigenvalue into an estimated zero eigenvalue! The IPOPT strategy always assumes that zero eigenvalues can be detected upfront, so the singularity test happens outside of the loop. In this case, it can never recover from singularity, and just keeps increasing the primal reg coefficient until it exceeds some large threshold (1e20).
Meanwhile, the inertia jumps around a bit. I’m guessing some pivots are so close to 0 that they constantly get misclassified.

Seems like a difficult instance numerically…