# Duality gap in Convex.jl

**URL:** https://discourse.julialang.org/t/duality-gap-in-convex-jl/93741
**Category:** Optimization (Mathematical)
**Created:** [January 29, 2023, 7:14pm UTC](https://discourse.julialang.org/t/duality-gap-in-convex-jl/93741 "2023-01-29T19:14:53Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![ajd](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ajd/32/46350_2.png) [@ajd](https://discourse.julialang.org/u/ajd)
#### Post date: [January 29, 2023, 7:14pm UTC](https://discourse.julialang.org/t/duality-gap-in-convex-jl/93741/1 "2023-01-29T19:14:53Z")

</div>

Using the SCS solver with Convex.jl, the output of the solver includes in its printed output the duality gap:

```julia
------------------------------------------------------------------
	       SCS v3.2.1 - Splitting Conic Solver
	(c) Brendan O'Donoghue, Stanford University, 2012
------------------------------------------------------------------
problem: variables n: 2701, constraints m: 7851
cones: z: primal zero / dual free vars: 1
	  l: linear vars: 50
	  q: soc vars: 7800, qsize: 2600
settings: eps_abs: 1.0e-04, eps_rel: 1.0e-04, eps_infeas: 1.0e-07
	  alpha: 1.50, scale: 1.00e-01, adaptive_scale: 1
	  max_iters: 100000, normalize: 1, rho_x: 1.00e-06
	  acceleration_lookback: 10, acceleration_interval: 10
lin-sys: sparse-direct-amd-qdldl
	  nnz(A): 15151, nnz(P): 0
------------------------------------------------------------------
 iter | pri res | dua res | gap | obj | scale | time (s)
------------------------------------------------------------------
     0| 4.39e+00 1.00e+00 4.96e+01 2.43e+01 1.00e-01 1.02e-02 
   250| 4.43e-03 7.32e-03 2.04e-01 7.26e+00 1.00e-01 1.34e-01 
   425| 2.05e-04 1.91e-05 1.42e-04 6.96e+00 3.15e-02 2.24e-01 
------------------------------------------------------------------
status: solved
timings: total: 2.24e-01s = setup: 8.90e-03s + solve: 2.15e-01s
	 lin-sys: 9.77e-02s, cones: 5.55e-02s, accel: 5.25e-03s
------------------------------------------------------------------
objective = 6.961736
------------------------------------------------------------------

```

Is there a simple way to access the final duality gap programmatically using Convex.jl?

---

<div class="post-metadata">

### Author: ![ericphanson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ericphanson/32/215186_2.png) [@ericphanson](https://discourse.julialang.org/u/ericphanson)
#### Post date: [January 29, 2023, 7:43pm UTC](https://discourse.julialang.org/t/duality-gap-in-convex-jl/93741/2 "2023-01-29T19:43:49Z")

</div>

You can query the underlying [MathOptInterface](https://jump.dev/MathOptInterface.jl/stable/) model. For example, if we [copy the tutorial example](https://jump.dev/Convex.jl/stable/quick_tutorial/),

> **Tutorial code**
>
> ```julia
> # Make the Convex.jl module available
> using Convex, SCS
> 
> # Generate random problem data
> m = 4; n = 5
> A = randn(m, n); b = randn(m, 1)
> 
> # Create a (column vector) variable of size n x 1.
> x = Variable(n)
> 
> # The problem is to minimize ||Ax - b||^2 subject to x >= 0
> # This can be done by: minimize(objective, constraints)
> problem = minimize(sumsquares(A * x - b), [x >= 0])
> 
> # Solve the problem by calling solve!
> solve!(problem, SCS.Optimizer; silent_solver = true)
> 
> # Check the status of the problem
> problem.status # :Optimal, :Infeasible, :Unbounded etc.
> 
> # Get the optimum value
> problem.optval
> 
> ```

We can get the duality gap as:

```julia
julia> import MathOptInterface as MOI

julia> MOI.get(problem.model, MOI.ObjectiveValue()) - MOI.get(problem.model, MOI.DualObjectiveValue())
7.153038624529984e-6

```

---

<div class="post-metadata">

### Author: ![ajd](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ajd/32/46350_2.png) [@ajd](https://discourse.julialang.org/u/ajd)
#### Post date: [January 29, 2023, 7:50pm UTC](https://discourse.julialang.org/t/duality-gap-in-convex-jl/93741/3 "2023-01-29T19:50:31Z")

</div>

Thank you! Of course, this is exactly what I need.
