# YALMIP vs JuMP

**URL:** <https://discourse.julialang.org/t/yalmip-vs-jump/30776>\
**Category:** Optimization (Mathematical)\
**Created:** [November 6, 2019, 4:05am UTC](https://discourse.julialang.org/t/yalmip-vs-jump/30776 "2019-11-06T04:05:18Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![raktim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raktim/32/11188_2.png) [@raktim](https://discourse.julialang.org/u/raktim)\
**Post date:** [November 6, 2019, 4:05am UTC](https://discourse.julialang.org/t/yalmip-vs-jump/30776/1 "2019-11-06T04:05:18Z")

</div>

I compared JuMP and YALMIP’s performance in parsing convex problem. I noticed a difference in the problem size of the final optimization problem that is passed to Mosek. The problem from JuMP was quite large, than YALMIP.

- YALMIP generated problem has 5 constraints, 0 scalar variables, 2 matrix variables

- JuMP generated problem has 18 constraints, 5 scalar variables, 2 matrix variables

Both give the exact same answer. Any comments on why this is the case? Am I formulating the problem incorrectly in JuMP? Any help in this regard will be greatly appreciated. Details of the test problem are below.

Thanks.

# Problem Statement

Design of LQR for a system \dot{x} = Ax + Bu, with u=Kx. This is solved using a SDP problem. I am not getting into the details of LQR theory here. The codes for YALMIP and JuMP are as following.

### YALMIP (MATLAB)

clc; clear;

A = [0 1; -1 -1];  
B = [0;1];  
Q = [1 0; 0 0.1];  
R = 1;

Y = sdpvar(2,2);  
W = sdpvar(1,2)  
Z = zeros(2,1);

M11 = (A_Y + B_W) + (A_Y + B_W)‘;  
M = [M11 Y W’;  
Y -inv(Q) Z;  
W Z’ -inv( R );]  
constr = [M \<= 0, Y\>=0];  
optimize(constr,-trace(Y));  
disp(trace(value(Y)));

### JuMP Code

using JuMP, MosekTools, LinearAlgebra  
A = [0. 1; -1 -1];  
B = [0.;1];

model = Model(with\_optimizer(Mosek.Optimizer));  
@variable(model, Y[1:2, 1:2], Symmetric);  
@variable(model, W[1:2]);

Q = [1 0; 0 0.1];  
R = 1;  
Z = zeros(2,1);

M11 = (A_Y + B_W’) + (A_Y + B_W’)‘;  
M = [M11 Y W;  
Y -inv(Q) Z;  
W’ Z’ -inv(R);]

@SDconstraint(model,Symmetric(M) \<= zeros(size(M)));  
@SDconstraint(model,Symmetric(Y) \>= zeros(size(Y)));  
@objective(model,Max,tr(Y));  
println(“Calling optimize!(…)”);  
JuMP.optimize!(model);  
println(tr(value.(Y)));

### MOSEK Output from YALMIP

MOSEK Version 9.0.89 (Build date: 2019-5-24 09:53:18)  
Copyright (c) MOSEK ApS, Denmark. WWW: [mosek.com](http://mosek.com)  
Platform: MACOSX/64-X86

Problem  
Name :  
Objective sense : min  
Type : CONIC (conic optimization problem)  
Constraints : 5  
Cones : 0  
Scalar variables : 0  
Matrix variables : 2  
Integer variables : 0

Optimizer started.  
Presolve started.  
Linear dependency checker started.  
Linear dependency checker terminated.  
Eliminator started.  
Freed constraints in eliminator : 0  
Eliminator terminated.  
Eliminator - tries : 1 time : 0.00  
Lin. dep. - tries : 1 time : 0.00  
Lin. dep. - number : 0  
Presolve terminated. Time: 0.01  
Problem  
Name :  
Objective sense : min  
Type : CONIC (conic optimization problem)  
Constraints : 5  
Cones : 0  
Scalar variables : 0  
Matrix variables : 2  
Integer variables : 0

Optimizer - threads : 8  
Optimizer - solved problem : the primal  
Optimizer - Constraints : 5  
Optimizer - Cones : 1  
Optimizer - Scalar variables : 3 conic : 3  
Optimizer - Semi-definite variables: 1 scalarized : 15  
Factor - setup time : 0.00 dense det. time : 0.00  
Factor - ML order time : 0.00 GP order time : 0.00  
Factor - nonzeros before factor : 15 after factor : 15  
Factor - dense dim. : 0 flops : 6.14e+02  
ITE PFEAS DFEAS GFEAS PRSTATUS POBJ DOBJ MU TIME  
0 1.7e+00 9.0e+00 1.3e+01 0.00e+00 1.200000000e+01 0.000000000e+00 1.0e+00 0.02  
1 3.6e-01 1.9e+00 4.2e+00 -7.61e-01 7.493854220e+00 1.637944828e+00 2.1e-01 0.06  
2 9.2e-02 4.9e-01 6.4e-01 4.11e-01 5.431599917e+00 3.638549110e+00 5.4e-02 0.06  
3 2.0e-02 1.1e-01 9.4e-02 2.68e-01 6.802314950e+00 6.369265942e+00 1.2e-02 0.06  
4 2.4e-04 1.3e-03 1.2e-04 9.08e-01 6.662079753e+00 6.655739510e+00 1.4e-04 0.06  
5 8.9e-06 4.7e-05 8.0e-07 1.00e+00 6.660644505e+00 6.660411659e+00 5.2e-06 0.07  
6 8.9e-07 4.7e-06 2.6e-08 1.00e+00 6.660618400e+00 6.660594963e+00 5.2e-07 0.07  
7 8.7e-08 4.6e-07 7.8e-10 1.00e+00 6.660615958e+00 6.660613675e+00 5.1e-08 0.07  
8 8.7e-09 4.6e-08 2.5e-11 1.00e+00 6.660615311e+00 6.660615082e+00 5.1e-09 0.07  
9 3.6e-10 4.4e-09 2.1e-13 1.00e+00 6.660615168e+00 6.660615158e+00 2.1e-10 0.07  
Optimizer terminated. Time: 0.10

Interior-point solution summary  
Problem status : PRIMAL\_AND\_DUAL\_FEASIBLE  
Solution status : OPTIMAL  
Primal. obj: 6.6606151676e+00 nrm: 4e+00 Viol. con: 4e-09 barvar: 0e+00  
Dual. obj: 6.6606151582e+00 nrm: 1e+01 Viol. con: 0e+00 barvar: 2e-08  
Optimizer summary  
Optimizer - time: 0.10  
Interior-point - iterations : 9 time: 0.07  
Basis identification - time: 0.00  
Primal - iterations : 0 time: 0.00  
Dual - iterations : 0 time: 0.00  
Clean primal - iterations : 0 time: 0.00  
Clean dual - iterations : 0 time: 0.00  
Simplex - time: 0.00  
Primal simplex - iterations : 0 time: 0.00  
Dual simplex - iterations : 0 time: 0.00  
Mixed integer - relaxations: 0 time: 0.00

6.660615158242211

### MOSEK Output from JuMP

Problem  
Name :  
Objective sense : max  
Type : CONIC (conic optimization problem)  
Constraints : 18  
Cones : 0  
Scalar variables : 5  
Matrix variables : 2  
Integer variables : 0

Optimizer started.  
Presolve started.  
Linear dependency checker started.  
Linear dependency checker terminated.  
Eliminator started.  
Freed constraints in eliminator : 0  
Eliminator terminated.  
Eliminator started.  
Freed constraints in eliminator : 0  
Eliminator terminated.  
Eliminator - tries : 2 time : 0.00  
Lin. dep. - tries : 1 time : 0.00  
Lin. dep. - number : 0  
Presolve terminated. Time: 0.00  
Problem  
Name :  
Objective sense : max  
Type : CONIC (conic optimization problem)  
Constraints : 18  
Cones : 0  
Scalar variables : 5  
Matrix variables : 2  
Integer variables : 0

Optimizer - threads : 8  
Optimizer - solved problem : the primal  
Optimizer - Constraints : 18  
Optimizer - Cones : 2  
Optimizer - Scalar variables : 9 conic : 9  
Optimizer - Semi-definite variables: 1 scalarized : 15  
Factor - setup time : 0.00 dense det. time : 0.00  
Factor - ML order time : 0.00 GP order time : 0.00  
Factor - nonzeros before factor : 153 after factor : 153  
Factor - dense dim. : 0 flops : 2.76e+03  
ITE PFEAS DFEAS GFEAS PRSTATUS POBJ DOBJ MU TIME  
0 9.0e+00 1.0e+00 1.0e+00 0.00e+00 0.000000000e+00 0.000000000e+00 1.0e+00 0.00  
1 1.9e+00 2.1e-01 3.3e-01 -7.58e-01 1.494060954e+00 -2.347484915e-01 2.1e-01 0.00  
2 4.8e-01 5.4e-02 4.8e-02 3.97e-01 3.216540796e+00 2.621094335e+00 5.4e-02 0.00  
3 1.3e-01 1.5e-02 1.1e-02 1.56e-01 6.236366207e+00 5.794301541e+00 1.5e-02 0.00  
4 2.8e-03 3.1e-04 3.0e-05 8.65e-01 6.647109017e+00 6.639514147e+00 3.1e-04 0.00  
5 6.2e-05 6.9e-06 9.9e-08 1.00e+00 6.660351189e+00 6.660190874e+00 6.9e-06 0.00  
6 5.8e-06 6.5e-07 2.8e-09 1.00e+00 6.660595719e+00 6.660580869e+00 6.5e-07 0.00  
7 4.9e-07 5.4e-08 6.8e-11 1.00e+00 6.660614264e+00 6.660613014e+00 5.4e-08 0.00  
8 4.8e-08 5.3e-09 2.1e-12 1.00e+00 6.660615113e+00 6.660614990e+00 5.3e-09 0.00  
9 6.2e-10 6.1e-10 3.1e-15 1.00e+00 6.660615160e+00 6.660615159e+00 6.9e-11 0.00  
Optimizer terminated. Time: 0.01

6.660615160346445

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [November 6, 2019, 7:00am UTC](https://discourse.julialang.org/t/yalmip-vs-jump/30776/2 "2019-11-06T07:00:17Z")

</div>

Looking at the timing for YALMIP:

```
Optimizer terminated. Time: 0.10

```

comparted to the timing for JuMP:

```
Optimizer terminated. Time: 0.01

```

I would say JuMP did better, even if the number of variables and constraints was higher.

---

<div class="post-metadata">

**Author:** ![Amin\_Yahyaabadi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amin_yahyaabadi/32/9826_2.png) [@Amin\_Yahyaabadi](https://discourse.julialang.org/u/Amin_Yahyaabadi)\
**Post date:** [November 6, 2019, 7:05am UTC](https://discourse.julialang.org/t/yalmip-vs-jump/30776/3 "2019-11-06T07:05:45Z")

</div>

@raktim Nice investigation!  
By the way, If you put your codes inside ``` it is easier to read.

---

<div class="post-metadata">

**Author:** ![blegat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blegat/32/217090_2.png) [@blegat](https://discourse.julialang.org/u/blegat)\
**Post date:** [November 6, 2019, 8:29am UTC](https://discourse.julialang.org/t/yalmip-vs-jump/30776/4 "2019-11-06T08:29:09Z")

</div>

You need to replace

```julia
@variable(model, Y[1:2, 1:2], Symmetric)
@SDconstraint(model,Symmetric(Y) >= zeros(size(Y)))

```

By

```julia
@variable(model, Y[1:2, 1:2], PSD)

```

---

<div class="post-metadata">

**Author:** ![raktim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raktim/32/11188_2.png) [@raktim](https://discourse.julialang.org/u/raktim)\
**Post date:** [November 6, 2019, 2:53pm UTC](https://discourse.julialang.org/t/yalmip-vs-jump/30776/5 "2019-11-06T14:53:05Z")

</div>

Improved things a bit. Now we have 15 constraints, 2 scalar variables, and 2 matrix variables. I am more worried about the increased number of constraints.

For the problem I am trying to solve, which is a bit more complex:

**JuMP results in:**  
Problem  
Name :  
Objective sense : min  
Type : CONIC (conic optimization problem)  
Constraints : 40604  
Cones : 0  
Scalar variables : 105  
Matrix variables : 4  
Integer variables : 0

Optimal cost: 1.358  
Time: 1087.15 s

**YALMIP results in**  
Problem  
Name :  
Objective sense : min  
Type : CONIC (conic optimization problem)  
Constraints : 66  
Cones : 0  
Scalar variables : 1  
Matrix variables : 3  
Integer variables : 0

Optimal cost: 1.358  
Time: 0.55 s

Both return the same answer. But why does JuMP impose so many more constraints. This is affecting solution time significantly. Perhaps YALMIP is more efficient in implementing SD constraints, or I am missing something here.

---

<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 6, 2019, 3:38pm UTC](https://discourse.julialang.org/t/yalmip-vs-jump/30776/6 "2019-11-06T15:38:34Z")

</div>

There are a few reasons why this could be happening.

Please read [Please read: make it easier to help you](https://discourse.julialang.org/t/psa-make-it-easier-to-help-you/14757) and provide a working example of the code you are trying to improve. It is impossible to offer advice without knowing what you’ve tried!

Make sure to include what versions of Julia/JuMP you are using.

---

<div class="post-metadata">

**Author:** ![raktim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raktim/32/11188_2.png) [@raktim](https://discourse.julialang.org/u/raktim)\
**Post date:** [November 7, 2019, 12:41am UTC](https://discourse.julialang.org/t/yalmip-vs-jump/30776/7 "2019-11-07T00:41:57Z")

</div>

Hi odow,  
I posted the code (both YALMIP and JuMP) in the initial posting.

Versions:  
JuMP v0.20.1  
MathOptInterface v0.9.7  
MosekTools v0.9.1  
Julia 1.2

---

<div class="post-metadata">

**Author:** ![raktim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raktim/32/11188_2.png) [@raktim](https://discourse.julialang.org/u/raktim)\
**Post date:** [November 7, 2019, 12:45am UTC](https://discourse.julialang.org/t/yalmip-vs-jump/30776/8 "2019-11-07T00:45:29Z")

</div>

Julia code link:

> **[lqrTest.jl](https://www.dropbox.com/s/106105mb2c9fywf/lqrTest.jl?dl=0)**
>
> Shared with Dropbox

MATLAB YALMIP code link:

> **[testLQR.m](https://www.dropbox.com/s/8afd8xvwlkufc6m/testLQR.m?dl=0)**
>
> Shared with Dropbox

The issue is JuMP seems to be imposing more constraints than YALMIP.

---

<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 7, 2019, 8:39pm UTC](https://discourse.julialang.org/t/yalmip-vs-jump/30776/9 "2019-11-07T20:39:42Z")

</div>

You should take a read of the relevant documentation:  
[https://www.juliaopt.org/JuMP.jl/v0.20.0/constraints/#Semidefinite-constraints-1](https://www.juliaopt.org/JuMP.jl/v0.20.0/constraints/#Semidefinite-constraints-1)  
[https://www.juliaopt.org/JuMP.jl/v0.20.0/constraints/#JuMP.PSDCone](https://www.juliaopt.org/JuMP.jl/v0.20.0/constraints/#JuMP.PSDCone)

You probably want

```julia
a = @constraint(model, Symmetric(-M) in PSDCone())

```

instead of

```julia
b = @SDconstraint(model,Symmetric(M) <= zeros(size(M)))

```

If you follow the example in the `PSDCone` documentation, you will see that the `@SDconstraint` approach is adding many more constraints (as you guess).

```nohighlight
julia> jump_function(constraint_object(a))
15-element Array{GenericAffExpr{Float64,VariableRef},1}:
 -2 Y[1,2]                       
 -Y[2,2] + Y[1,1] + Y[1,2] - W[1]
 2 Y[1,2] + 2 Y[2,2] - 2 W[2]    
 -Y[1,1]                         
 -Y[1,2]                         
 1                               
 -Y[1,2]                         
 -Y[2,2]                         
 0                               
 10                              
 -W[1]                           
 -W[2]                           
 0                               
 0                               
 1                               

julia> jump_function(constraint_object(b))
25-element Array{GenericAffExpr{Float64,VariableRef},1}:
 -2 Y[1,2]                       
 -Y[2,2] + Y[1,1] + Y[1,2] - W[1]
 -Y[1,1]                         
 -Y[1,2]                         
 -W[1]                           
 -Y[2,2] + Y[1,1] + Y[1,2] - W[1]
 2 Y[1,2] + 2 Y[2,2] - 2 W[2]    
 -Y[1,2]                         
 -Y[2,2]                         
 -W[2]                           
 -Y[1,1]                         
 -Y[1,2]                         
 1                               
 0                               
 0                               
 -Y[1,2]                         
 -Y[2,2]                         
 0                               
 10                              
 0                               
 -W[1]                           
 -W[2]                           
 0                               
 0                               
 1                               
``
```

---

<div class="post-metadata">

**Author:** ![blegat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blegat/32/217090_2.png) [@blegat](https://discourse.julialang.org/u/blegat)\
**Post date:** [November 7, 2019, 9:51pm UTC](https://discourse.julialang.org/t/yalmip-vs-jump/30776/10 "2019-11-07T21:51:18Z")

</div>

Conic solvers usually don’t support both conic variables and conic constraints.  
They either have the primal form as interface (variables in cones and equality constraints):

```julia
min c' x
A x = b
x in K

```

or the dual form as interface (free variables and and affine constraints in cones):

```julia
min c' x
A x + b in K
x free

```

Mosek for instance uses the primal form.

When you model, your model is sometimes closer to the primal or sometimes to the dual form.  
If your model is closer to the primal form, you should give it as is to Mosek.  
Otherwise, you should give the dual form to Mosek.  
As you have seen, modeling the primal form is error prone as writing `@constraint(model, X >= zeros(X))` creates an affine constraints hence need to create slack variables in primal form!  
So the user should be more disciplined and create make sure the constraint on the variables are not interpreted as affine constraints.  
The modeling language should also allow creating constraints on variables (which is not the case in YALMIP and that can prevent you to create the best model sometimes, see [@mforets presentation at JuMP-dev](https://www.youtube.com/watch?v=4mf2W4y7PJo&t=805s))  
For these reasons, YALMIP always use the dual form for modeling and dualize the problem when the solver needs the primal form.

In JuMP, we just give the problem to the solver as it is modeled by the user and if you want to dual to be given instead you have to say it explicitly using [Dualization.jl](https://github.com/JuliaOpt/Dualization.jl).  
In your case, you can do

```julia
using JuMP, MosekTools, LinearAlgebra
A = [0. 1; -1 -1];
B = [0.;1];

model = Model(with_optimizer(() -> Dualization.DualOptimizer(Mosek.Optimizer())))
@variable(model, Y[1:2, 1:2], PSD)
@variable(model, W[1:2])

Q = [1 0; 0 0.1]
R = 1
Z = zeros(2,1)

M11 = (A*Y + B*W') + (A*Y + B*W')'
M = [M11 Y W;
     Y -inv(Q) Z;
     W' Z' -inv(R);]

@constraint(model, Symmetric(-M) in PSDCone())
@objective(model, Max, tr(Y))
JuMP.optimize!(model)
println(tr(value.(Y)))

```

Note that here, doing `@constraint(model, Y >= zeros(size(Y)))` and `@constraint(model, M <= 0)` instead would lead the same result as you are modeling in dual form since Mosek is in primal form and you use Dualization.jl.

This gives

```julia
Problem
  Name :                 
  Objective sense : min             
  Type : CONIC (conic optimization problem)
  Constraints : 5               
  Cones : 0               
  Scalar variables : 0               
  Matrix variables : 2               
  Integer variables : 0               

Optimizer started.
Presolve started.
Linear dependency checker started.
Linear dependency checker terminated.
Eliminator started.
Freed constraints in eliminator : 0
Eliminator terminated.
Eliminator - tries : 1 time : 0.00            
Lin. dep. - tries : 1 time : 0.00            
Lin. dep. - number : 0               
Presolve terminated. Time: 0.00    
Problem
  Name :                 
  Objective sense : min             
  Type : CONIC (conic optimization problem)
  Constraints : 5               
  Cones : 0               
  Scalar variables : 0               
  Matrix variables : 2               
  Integer variables : 0               

Optimizer - threads : 4               
Optimizer - solved problem : the primal      
Optimizer - Constraints : 5
Optimizer - Cones : 1
Optimizer - Scalar variables : 3 conic : 3               
Optimizer - Semi-definite variables: 1 scalarized : 15              
Factor - setup time : 0.00 dense det. time : 0.00            
Factor - ML order time : 0.00 GP order time : 0.00            
Factor - nonzeros before factor : 15 after factor : 15              
Factor - dense dim. : 0 flops : 6.14e+02        
ITE PFEAS DFEAS GFEAS PRSTATUS POBJ DOBJ MU TIME  
0 1.7e+00 9.0e+00 1.3e+01 0.00e+00 1.200000000e+01 0.000000000e+00 1.0e+00 0.00  
1 3.6e-01 1.9e+00 4.2e+00 -7.61e-01 7.493854220e+00 1.637944828e+00 2.1e-01 0.00  
2 9.2e-02 4.9e-01 6.4e-01 4.11e-01 5.431599917e+00 3.638549110e+00 5.4e-02 0.00  
3 2.0e-02 1.1e-01 9.4e-02 2.68e-01 6.802314950e+00 6.369265942e+00 1.2e-02 0.00  
4 2.4e-04 1.3e-03 1.2e-04 9.08e-01 6.662079753e+00 6.655739510e+00 1.4e-04 0.00  
5 8.9e-06 4.7e-05 8.0e-07 1.00e+00 6.660644505e+00 6.660411659e+00 5.2e-06 0.00  
6 8.9e-07 4.7e-06 2.6e-08 1.00e+00 6.660618400e+00 6.660594963e+00 5.2e-07 0.00  
7 8.7e-08 4.6e-07 7.8e-10 1.00e+00 6.660615958e+00 6.660613675e+00 5.1e-08 0.00  
8 8.7e-09 4.6e-08 2.5e-11 1.00e+00 6.660615311e+00 6.660615082e+00 5.1e-09 0.00  
9 3.6e-10 2.5e-09 2.1e-13 1.00e+00 6.660615168e+00 6.660615158e+00 2.1e-10 0.00  
Optimizer terminated. Time: 0.00    

6.660615158242325

```

as with YALMIP

---

<div class="post-metadata">

**Author:** ![raktim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raktim/32/11188_2.png) [@raktim](https://discourse.julialang.org/u/raktim)\
**Post date:** [November 7, 2019, 10:14pm UTC](https://discourse.julialang.org/t/yalmip-vs-jump/30776/11 "2019-11-07T22:14:25Z")

</div>

This makes things clear! Thank you for taking time to address this.

---

<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 7, 2019, 11:53pm UTC](https://discourse.julialang.org/t/yalmip-vs-jump/30776/12 "2019-11-07T23:53:32Z")

</div>

I feel like this is great content for the JuMP documentation.

---

<div class="post-metadata">

**Author:** ![raktim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raktim/32/11188_2.png) [@raktim](https://discourse.julialang.org/u/raktim)\
**Post date:** [November 8, 2019, 12:34am UTC](https://discourse.julialang.org/t/yalmip-vs-jump/30776/13 "2019-11-08T00:34:49Z")

</div>

I think so too! Coming from cvx/YALMIP, I find it hard to transfer to JuMP. I am documenting these, especially for folks coming from control/estimation and are used to cvx/YALMIP. Perhaps it can be included with JuMP examples in the future.

With Dualization, things are better. However I am still running into difficulties in implementing constraints such as s\ge0 where s\in\mathcal{R}^n.

The documentation for Dualization is probably aimed at developers at this time.  
I have to spend some time on this to figure these basic things.

It may be better to dualize the problem just before calling \texttt{optimize!(...)}. But then I don’t know how to recover the primal variables from the dual solution.  
Where can I get information about this?

I am going to mark this topic as resolved.

---

<div class="post-metadata">

**Author:** ![blegat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/blegat/32/217090_2.png) [@blegat](https://discourse.julialang.org/u/blegat)\
**Post date:** [November 8, 2019, 7:19am UTC](https://discourse.julialang.org/t/yalmip-vs-jump/30776/14 "2019-11-08T07:19:23Z")

</div>

> recover the primal variables from the dual solution.

Dualization dualize both the model and the results so you can just get the primal solution and Dualization take care of asking the dual of the corresponding constraint instead.
