# The Uno (Unifying Nonlinear Optimization) solver

**URL:** https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883
**Category:** Optimization (Mathematical)
**Tags:** nonlinear-optimizati, nonconvex-optimizati, nonlinear-programmin, sqp
**Created:** [June 19, 2024, 8:23pm UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883 "2024-06-19T20:23:45Z")
**Posts on this page:** 20
**Page:** 2

<div class="post-metadata">

### Author: ![cvanaret](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cvanaret/32/11594_2.png) [@cvanaret](https://discourse.julialang.org/u/cvanaret)
#### Post date: [July 7, 2025, 1:20pm UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/21 "2025-07-07T13:20:23Z")

</div>

**[Uno v2.0.0](https://github.com/cvanaret/Uno) is out!**  
Already available in your favorite language: [Uno\_jll](https://github.com/JuliaBinaryWrappers/Uno_jll.jl).

The major changes are:

- a more powerful unification framework with ingredients such as _Hessian model_ (exact, identity, zero), _regularization strategy_ (primal, primal-dual, none) and _inequality handling method_ (inequality constrained, interior-point).

 ![wheel](https://global.discourse-cdn.com/julialang/original/3X/3/2/324027556c2159194ad77ffffdefdb4bfec73d50.png)

- the null space active-set QP solver [BQPD](https://www.mcs.anl.gov/~leyffer/solvers.html) is now available as [precompiled binaries](https://github.com/leyffer/BQPD_jll.jl/releases) and a binary package [BQPD\_jll](https://juliahub.com/ui/Packages/General/BQPD_jll) 🥳 This means we can now use the `filtersqp` preset (trust-region filter SQP method) within `Uno_jll`:

```julia
julia> using JuMP, AmplNLWriter, Uno_jll
julia> options = String["preset=filtersqp", "QP_solver=BQPD"];
julia> model = Model(() -> AmplNLWriter.Optimizer(Uno_jll.amplexe, options));
julia> @variable(model, x <= 0.5, start = -2);
julia> @variable(model, y, start = 1);
julia> @objective(model, Min, 100 * (y - x^2)^2 + (1 - x)^2);
julia> @constraint(model, x*y >= 1);
julia> @constraint(model, x + y^2 >= 0);
julia> optimize!(model)
Original model /tmp/jl_gTmcsU/model.nl
2 variables, 2 constraints (0 equality, 2 inequality)
Reformulated model /tmp/jl_gTmcsU/model.nl
2 variables, 2 constraints (0 equality, 2 inequality)

Used overwritten options:
- QP_solver = BQPD
- TR_min_radius = 1e-8
- TR_radius = 10
- constraint_relaxation_strategy = feasibility_restoration
- filter_type = standard
- globalization_mechanism = TR
- globalization_strategy = fletcher_filter_method
- hessian_model = exact
- inequality_handling_method = inequality_constrained
- l1_constraint_violation_coefficient = 1.
- loose_tolerance = 1e-6
- progress_norm = L1
- protect_actual_reduction_against_roundoff = no
- regularization_strategy = none
- residual_norm = L2
- switch_to_optimality_requires_linearized_feasibility = yes
- tolerance = 1e-6

─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 iter TR iter TR radius phase step norm objective primal feas stationarity complementarity status          
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 0 - 1.0000e+01 OPT - 9.0900e+02 4.0000e+00 2.4797e+03 0.0000e+00 initial point   
 1 1 1.0000e+01 OPT 2.0000e+00 2.6000e+01 1.0000e+00 5.5713e+03 2.8887e+03 ✔ (h-type)      
 2 1 1.0000e+01 OPT - - - - - infeasible subproblem
 2 1 1.0000e+01 FEAS 7.5000e-01 2.5250e+01 1.1250e+00 - - ✘ (restoration) 
 - 2 3.7500e-01 FEAS 3.7500e-01 4.1504e-01 9.5312e-01 3.9528e-01 0.0000e+00 ✔ (restoration) 
 3 1 7.5000e-01 FEAS 7.5000e-01 3.9312e+01 5.6250e-01 5.0000e-01 0.0000e+00 ✔ (restoration) 
 4 1 1.5000e+00 FEAS 1.1250e+00 3.0650e+02 0.0000e+00 1.6654e+04 1.4508e+04 ✔ (restoration) 
 5 1 1.5000e+00 OPT 0.0000e+00 3.0650e+02 0.0000e+00 0.0000e+00 0.0000e+00 0 primal step   
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
 iter TR iter TR radius phase step norm objective primal feas stationarity complementarity status          
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Uno 2.0.0 (TR Fletcher-filter restoration inequality-constrained method with exact Hessian and no regularization)
Mon Jul 7 15:13:07 2025
────────────────────────────────────────
Optimization status: Success
Iterate status: Feasible KKT point
Objective value: 306.5
Primal feasibility: 0
┌ Stationarity residual: 0
└ Complementarity residual: 0
┌ Feasibility stationarity residual:	0
└ Feasibility complementarity residual:	0
┌ Infeasibility measure: 0
│ Objective measure: 306.5
└ Auxiliary measure: 0
CPU time: 0.015675s
Iterations: 5
Objective evaluations: 3
Constraints evaluations: 7
Objective gradient evaluations: 6
Jacobian evaluations: 6
Hessian evaluations: 6
Number of subproblems solved: 7

```

cc @cgeoga

A comprehensive description of the changes from v1.3.0 can be found [here](https://github.com/cvanaret/Uno/releases/tag/v2.0.0).

I’m actively working on the following features:

- L-BFGS Hessian approximation;
- SLP-EQP method;
- a barrier method that better exploits the structure of the original problem;
- an exponential barrier method, an alternative to IPOPT’s log barrier method;
- Python bindings.

If you’re attending the ICCOPT 2025 conference in two weeks, don’t miss [our session on Recent advances in open-source continuous solvers](https://iccopt2025usc.sched.com/event/1dqmu/parallel-sessions-4v-recent-advances-in-open-source-continuous-solvers) with talks about the HiGHS, acados and Uno solvers.

---

<div class="post-metadata">

### Author: ![cgeoga](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cgeoga/32/216186_2.png) [@cgeoga](https://discourse.julialang.org/u/cgeoga)
#### Post date: [July 11, 2025, 6:08pm UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/22 "2025-07-11T18:08:44Z")

</div>

Wow, seriously exciting! Thanks for all your work on this @cvanaret. Is a C API on the short- or medium-term horizon, or would you say that the library needs to stabilize more before it makes sense to start developing that? I don’t have a good understanding of how hard it is to produce one, like whether or not it requires big internal rewrites or things like that.

Thanks again for everything here! I do have some problems where I can go through `AMPLNLWriter` and I’m super stoked to try out the FilterSQP preset.

---

<div class="post-metadata">

### Author: ![cvanaret](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cvanaret/32/11594_2.png) [@cvanaret](https://discourse.julialang.org/u/cvanaret)
#### Post date: [July 11, 2025, 10:24pm UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/23 "2025-07-11T22:24:10Z")

</div>

Thank you for the kind words @cgeoga!  
I’m working on the Python bindings at the moment, which gives me a pretty good idea how much of Uno I should expose on the Python side. I don’t think it will be a lot of effort to write a C API. I’m quite busy at the moment, but the end of the year sounds realistic 🙂

Let me know how the filtersqp preset performs! Tip: the preset uses `globalization_strategy=fletcher_filter_method`, but do give `globalization_strategy=waechter_filter_method` (a la IPOPT) a shot as well.

---

<div class="post-metadata">

### Author: ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)
#### Post date: [July 12, 2025, 4:14am UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/24 "2025-07-12T04:14:59Z")

</div>

Naive question – if we ignore the bounds on `C(x)`, is Uno competitive with just optimization routines from Optimization.jl?

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [July 12, 2025, 11:04am UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/25 "2025-07-12T11:04:37Z")

</div>

It should be usable in the Optimization.jl interface via the AMPLWriter stuff. We should probably document how to do it. I’d like to see a PR to have the SciMLBenchmarks.jl machine test it in the battery of global optimizer tests:

> **[Black-Box Global Optimizer Benchmarks · The SciML Benchmarks](https://docs.sciml.ai/SciMLBenchmarksOutput/dev/GlobalOptimization/blackbox_global_optimizers/)**

I’d be interested to see where it lands. It’s not really possible to know if it’s useful until such a comparison is done. I assume at face value that it will be good as it has globalizing stuff + uses differentiability, so it “should” be better than say differential evolution, but at the end of the day we only recommend what the benchmarks say 😅

---

<div class="post-metadata">

### Author: ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)
#### Post date: [July 12, 2025, 2:11pm UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/26 "2025-07-12T14:11:27Z")

</div>

Any way to get NOMAD.jl into this benchmark?

---

<div class="post-metadata">

### Author: ![ChrisRackauckas](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chrisrackauckas/32/77_2.png) [@ChrisRackauckas](https://discourse.julialang.org/u/ChrisRackauckas)
#### Post date: [July 13, 2025, 1:06pm UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/27 "2025-07-13T13:06:54Z")

</div>

Just PR the benchmark file and bump the manifest.

> <https://github.com/SciML/SciMLBenchmarks.jl/blob/master/benchmarks/GlobalOptimization/blackbox_global_optimizers.jmd>

---

<div class="post-metadata">

### Author: ![cvanaret](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cvanaret/32/11594_2.png) [@cvanaret](https://discourse.julialang.org/u/cvanaret)
#### Post date: [July 14, 2025, 1:36pm UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/28 "2025-07-14T13:36:23Z")

</div>

Optimization.jl looks like a pretty broad toolbox. Comparing local Newton methods (SQP/barrier) against metaheuristics makes little sense to me, but Uno for bound constrained problems should be more or less on par with IPOPT, SNOPT, L-BFGS-B and so on.

---

<div class="post-metadata">

### Author: ![cvanaret](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cvanaret/32/11594_2.png) [@cvanaret](https://discourse.julialang.org/u/cvanaret)
#### Post date: [July 14, 2025, 1:44pm UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/29 "2025-07-14T13:44:07Z")

</div>

I can give it a shot when I have more time, but as I wrote in the previous message, I think this is a weird comparison. Newton methods “solve” (because we have a first-order characterization of stationary points) while metaheuristics “search”. It’s like comparing 🍎 and 🍊 (local methods vs global search methods).  
That said, I have nothing against metaheuristics, I used Differential Evolution a lot [during my PhD](https://www.researchgate.net/publication/337947149) as a primal strategy for solving global optimization problems. Combining local methods and metaheuristics (within the so-called memetic algorithms) makes total sense to me.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [July 14, 2025, 8:13pm UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/30 "2025-07-14T20:13:10Z")

</div>

3 posts were split to a new topic: [Optimization on unit sphere?](https://discourse.julialang.org/t/optimization-on-unit-sphere/130720)

---

<div class="post-metadata">

### Author: ![CeterisPartybus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ceterispartybus/32/46868_2.png) [@CeterisPartybus](https://discourse.julialang.org/u/CeterisPartybus)
#### Post date: [July 14, 2025, 8:03pm UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/32 "2025-07-14T20:03:15Z")

</div>

> [@cvanaret](#):
>
> **[Uno v2.0.0](https://github.com/cvanaret/Uno) is out!**  
> Already available in your favorite language: [Uno\_jll](https://github.com/JuliaBinaryWrappers/Uno_jll.jl).

Wow, Uno 2.0 looks impressive. Thanks!

Can one mimic the NCL solver ([GitHub - JuliaSmoothOptimizers/NCL.jl: A nonlinearly-constrained augmented-Lagrangian method](https://github.com/JuliaSmoothOptimizers/NCL.jl)) with Uno as well?

---

<div class="post-metadata">

### Author: ![cvanaret](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cvanaret/32/11594_2.png) [@cvanaret](https://discourse.julialang.org/u/cvanaret)
#### Post date: [July 15, 2025, 9:47am UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/33 "2025-07-15T09:47:39Z")

</div>

That’s a great question 😃  
When I came up with the unification framework, I always had augmented Lagrangian methods (as constraint relaxation strategies, see [wheel diagram](https://discourse.julialang.org/t/the-uno-unifying-nonconvex-optimization-solver/115883/21)) in the back of my mind. They’re not implemented in Uno yet, but the abstractions are there. I heard about NCL a few years ago at a Michael Saunders talk and I’m definitely going to test that!

---

<div class="post-metadata">

### Author: ![amontoison](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amontoison/32/218741_2.png) [@amontoison](https://discourse.julialang.org/u/amontoison)
#### Post date: [July 17, 2025, 8:02pm UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/34 "2025-07-17T20:02:50Z")

</div>

@CeterisPartybus We need a C interface in Uno to be able to plug it into `NCL.jl`.  
We plan to discuss and work on it with @cvanaret next week at ICCOPT.  
Do you have a specific application in mind?

That said, a direct integration into Uno is probably more relevant. We are working on a new evolution of `NCL` and how to exploit it from a linear algebra perspective, with specific KKT formulations.  
We are collaborating with @frapac and @sshin23 on `MadNLP.jl` and GPU usage.

It should be quite easy to integrate it into Uno afterward.

---

<div class="post-metadata">

### Author: ![CeterisPartybus](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ceterispartybus/32/46868_2.png) [@CeterisPartybus](https://discourse.julialang.org/u/CeterisPartybus)
#### Post date: [July 17, 2025, 8:29pm UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/35 "2025-07-17T20:29:34Z")

</div>

Thanks for the answer. Correct me if I am wrong but I understand that the idea of Uno is to allow the user to combine strategies to build a ‘custom’ algorithm. So, I should be able to configure Uno to mimic the NCL algorithm as well, right?

I do not have an application in mind but was merely wondering if I could actually do that.

---

<div class="post-metadata">

### Author: ![sshin23](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sshin23/32/205225_2.png) [@sshin23](https://discourse.julialang.org/u/sshin23)
#### Post date: [July 18, 2025, 1:33pm UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/36 "2025-07-18T13:33:31Z")

</div>

Very cool & ambitious work! Congratulations @cvanaret for the 2.0.0 release.

Would it be possible to write an [NLPModels.jl](https://github.com/JuliaSmoothOptimizers/NLPModels.jl) wrapper? NLPModels.jl is a very thin template for NLPs (specifying callbacks and dimensions, etc.), so writing a wrapper wouldn’t be too much work. It’d make it possible to use Uno for a variety of NLP test cases and modeling environments such as [ADNLPModels.jl](https://github.com/JuliaSmoothOptimizers/ADNLPModels.jl) and [ExaModels.jl](https://github.com/exanauts/ExaModels.jl). Or maybe that’s what you’re planning to do at ICCOPT @amontoison?

---

<div class="post-metadata">

### Author: ![amontoison](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amontoison/32/218741_2.png) [@amontoison](https://discourse.julialang.org/u/amontoison)
#### Post date: [July 18, 2025, 2:33pm UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/37 "2025-07-18T14:33:22Z")

</div>

@sshin23 It is what we have in mind 🙂  
We want to test a new feature of Uno that we work on with Nick Gould and Sven Leyffer and for that we want to use `CUTEst.jl`.  
If we have a C interface, we can do like Ipopt.jl and KNITRO.jl and add extensions for MOI.jl / NLPModels.jl.

---

<div class="post-metadata">

### Author: ![cvanaret](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cvanaret/32/11594_2.png) [@cvanaret](https://discourse.julialang.org/u/cvanaret)
#### Post date: [September 26, 2025, 8:06pm UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/38 "2025-09-26T20:06:37Z")

</div>

After a 250-commit PR, @amontoison and I finally saw the light at the end of the tunnel and released **Uno’s C and Julia interfaces in Uno 2.1.0** 🥳

`Uno.jl` has:

- a thin wrapper around the complete C API;
- an interface to [NLPModels.jl](https://github.com/JuliaSmoothOptimizers/NLPModels.jl) for solving problems following the NLPModels API, such as [CUTEst](https://github.com/JuliaSmoothOptimizers/CUTEst.jl), [ADNLPModels.jl](https://github.com/JuliaSmoothOptimizers/ADNLPModels.jl), or [ExaModels.jl](https://github.com/exanauts/ExaModels.jl);
- an interface to [MathOptInterface.jl](https://github.com/jump-dev/MathOptInterface.jl) for handling [JuMP](https://github.com/jump-dev/JuMP.jl) models _(under development)_

👉 check out [the Uno repo](https://github.com/cvanaret/Uno?tab=readme-ov-file#julia).

---

<div class="post-metadata">

### Author: ![franckgaga](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/franckgaga/32/218241_2.png) [@franckgaga](https://discourse.julialang.org/u/franckgaga)
#### Post date: [September 26, 2025, 8:14pm UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/39 "2025-09-26T20:14:36Z")

</div>

Awesome work @cvanaret, super excited to test the MathOptInterface.jl soon!

---

<div class="post-metadata">

### Author: ![cvanaret](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cvanaret/32/11594_2.png) [@cvanaret](https://discourse.julialang.org/u/cvanaret)
#### Post date: [October 9, 2025, 11:47am UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/40 "2025-10-09T11:47:08Z")

</div>

Dear all,  
We’ve fixed a few bugs in the C and Julia interfaces: here’s [**Uno 2.2.1**](https://github.com/cvanaret/Uno/releases/tag/v2.2.1)!  
Now all vectors that are passed to the model creation are copied internally, which means you can pass temporaries.

Thanks to da man @amontoison 🍀

We’re now working on improving the documentation 🙂 There’s also a tiny bug left: when several instances are solved sequentially, the numbers of function evaluations accumulate. I suspect it’s due to these quantities being static variables in the C++ code.

We’re also trying to [register Uno to `JuliaRegistries`](https://github.com/JuliaRegistries/General/pull/139982) and most likely we won’t get the name `Uno.jl` (too short). The best candidates at the moment are `UnoSolver.jl` and `UnifyingNonlinearOptimization.jl`.

---

<div class="post-metadata">

### Author: ![cvanaret](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cvanaret/32/11594_2.png) [@cvanaret](https://discourse.julialang.org/u/cvanaret)
#### Post date: [October 28, 2025, 9:20am UTC](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883/41 "2025-10-28T09:20:44Z")

</div>

[UnoSolver.jl](https://juliahub.com/ui/Packages/General/UnoSolver) is now a registered Julia package 🥳  
It can be used via [NLPModels.jl](https://github.com/JuliaSmoothOptimizers/NLPModels.jl) and [MathOptInterface.jl](https://github.com/jump-dev/MathOptInterface.jl). Thank you to MVP @amontoison for making it happen!

I’m now working on documentation and tutorials (something like _First steps with Uno_). Until then, here’s a small appetizer: Uno can mimic filterSQP (SQP method) and IPOPT (barrier method); all you have to do is set the Uno preset to `filtersqp` or `ipopt` like so:

```julia
using UnoSolver, JuMP

jump_model = Model(() -> UnoSolver.Optimizer(preset="filtersqp"))
x0 = [-2, 1]
uvar = [0.5, Inf]
@variable(jump_model, x[i = 1:2] ≤ uvar[i], start = x0[i])
@objective(jump_model, Min, 100 * (x[2] - x[1]^2)^2 + (1 - x[1])^2)
@constraint(jump_model, x[1] * x[2] - 1 ≥ 0)
@constraint(jump_model, x[1] + x[2]^2 ≥ 0)

optimize!(jump_model)

termination_status(jump_model) # solver termination status
objective_value(jump_model) # objective value
value.(x) # primal solution

```

The next [Uno features](https://github.com/cvanaret/Uno/releases) will include:

- an L-BFGS (a type of quasi-Newton) Hessian approximation;
- SLP-EQP methods: first solve a trust-region LP to get an estimation of the active-set, then an equality-constrained QP in which the active inequality constraints are treated as equalities and the inactive constraints are dropped. This approach combines efficiency and robustness (LP solvers and linear solvers are mature technology), and warmstarting capabilities.

Try it out and give us some feedback!

[Previous page](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883.md?page=1)

[Next page](https://discourse.julialang.org/t/the-uno-unifying-nonlinear-optimization-solver/115883.md?page=3)
