JuMP to Convex

Hi,
I’m new to Julia. Working on converting an optimization model from JuMP to Convex.

m = Model(Ipopt.Optimizer)

variable(m, x1 >= 0)
variable(m, x2 >= 0)

NLobjective(m, Max, 126x1 - 9x2^2 + 182x2 - 13x2^2)

constraint(m, x1 <= 4)
constraint(m, 2x2 <= 12)
constraint(m, 3x1 + 2x2 <= 25)

Any guidance is appreciated.

Are you talking about formulating the problem with Convex.jl? Convex has a pretty different syntax; check out e.g. this tutorial to see.

Convex also works somewhat differently than JuMP, since it is designed around conic problems; see for example this section of the docs on extended formulations. That means nonlinear solvers like Ipopt can’t be used with Convex.jl.

However, your problem does seem to have a conic formulation you can use with Convex:

julia> using Convex, COSMO

julia> x1 = Variable()
Variable
size: (1, 1)
sign: real
vexity: affine
id: 251…394

julia> x2 = Variable()
Variable
size: (1, 1)
sign: real
vexity: affine
id: 745…182

julia> objective = 126 * x1 - 9 * square(x2) + 182 * x2 - 13 * square(x2)
+ (concave; real)
β”œβ”€ * (affine; real)
β”‚  β”œβ”€ 126
β”‚  └─ real variable (id: 251…394)
β”œβ”€ - (concave; negative)
β”‚  └─ * (convex; positive)
β”‚     β”œβ”€ 9
β”‚     └─ qol_elem (convex; positive)
β”‚        β”œβ”€ …
β”‚        └─ …
β”œβ”€ * (affine; real)
β”‚  β”œβ”€ 182
β”‚  └─ real variable (id: 745…182)
└─ - (concave; negative)
   └─ * (convex; positive)
      β”œβ”€ 13
      └─ qol_elem (convex; positive)
         β”œβ”€ …
         └─ …

julia> constrs = [ x1 <= 4, 2*x2 <= 12, 3*x1 + 2*x2 <= 25 ]
3-element Array{Convex.LtConstraint,1}:
 <= constraint (affine)
β”œβ”€ real variable (id: 251…394)
└─ 4
 <= constraint (affine)
β”œβ”€ * (affine; real)
β”‚  β”œβ”€ 2
β”‚  └─ real variable (id: 745…182)
└─ 12
 <= constraint (affine)
β”œβ”€ + (affine; real)
β”‚  β”œβ”€ * (affine; real)
β”‚  β”‚  β”œβ”€ 3
β”‚  β”‚  └─ real variable (id: 251…394)
β”‚  └─ * (affine; real)
β”‚     β”œβ”€ 2
β”‚     └─ real variable (id: 745…182)
└─ 25

julia> problem = maximize(objective, constrs)
maximize
└─ + (concave; real)
   β”œβ”€ * (affine; real)
   β”‚  β”œβ”€ 126
   β”‚  └─ real variable (id: 251…394)
   β”œβ”€ - (concave; negative)
   β”‚  └─ * (convex; positive)
   β”‚     β”œβ”€ …
   β”‚     └─ …
   β”œβ”€ * (affine; real)
   β”‚  β”œβ”€ 182
   β”‚  └─ real variable (id: 745…182)
   └─ - (concave; negative)
      └─ * (convex; positive)
         β”œβ”€ …
         └─ …
subject to
β”œβ”€ <= constraint (affine)
β”‚  β”œβ”€ real variable (id: 251…394)
β”‚  └─ 4
β”œβ”€ <= constraint (affine)
β”‚  β”œβ”€ * (affine; real)
β”‚  β”‚  β”œβ”€ 2
β”‚  β”‚  └─ real variable (id: 745…182)
β”‚  └─ 12
└─ <= constraint (affine)
   β”œβ”€ + (affine; real)
   β”‚  β”œβ”€ * (affine; real)
   β”‚  β”‚  β”œβ”€ …
   β”‚  β”‚  └─ …
   β”‚  └─ * (affine; real)
   β”‚     β”œβ”€ …
   β”‚     └─ …
   └─ 25

status: `solve!` not called yet

julia> solve!(problem, COSMO.Optimizer)
------------------------------------------------------------------
          COSMO v0.7.7 - A Quadratic Objective Conic Solver
                         Michael Garstka
                University of Oxford, 2017 - 2020
------------------------------------------------------------------

Problem:  x ∈ R^{5},
          constraints: A ∈ R^{12x5} (15 nnz),
          matrix size to factor: 17x17,
          Floating-point precision: Float64
Sets:     Nonnegatives of dim: 5
          SecondOrderCone of dim: 3
          SecondOrderCone of dim: 3
          ZeroSet of dim: 1
Settings: Ο΅_abs = 1.0e-04, Ο΅_rel = 1.0e-04,
          Ο΅_prim_inf = 1.0e-06, Ο΅_dual_inf = 1.0e-04,
          ρ = 0.1, Οƒ = 1e-06, Ξ± = 1.6,
          max_iter = 2500,
          scaling iter = 10 (on),
          check termination every 40 iter,
          check infeasibility every 40 iter,
          KKT system solver: QDLDL
Setup Time: 0.06ms

Iter:   Objective:      Primal Res:     Dual Res:       Rho:
1       -4.8505e+03     5.3450e+01      5.4218e+01      1.0000e-01
40      -1.0916e+03     5.9188e-01      2.7359e-01      1.0000e-01
80      -8.2161e+02     1.9067e-01      1.3309e+00      1.0000e-01
120     -9.1560e+02     1.0889e-01      8.2135e-01      1.0000e-01
160     -8.6509e+02     5.7417e-02      4.1368e-01      1.0000e-01
200     -8.8906e+02     2.9174e-02      2.2977e-01      1.0000e-01
240     -8.7667e+02     1.7140e-02      1.2106e-01      1.0000e-01
280     -8.8263e+02     8.6168e-03      6.4531e-02      1.0000e-01
320     -8.7954e+02     5.3640e-03      3.4586e-02      1.0000e-01
360     -8.8100e+02     2.7692e-03      1.8063e-02      1.0000e-01
400     -8.8022e+02     1.7995e-03      9.7904e-03      1.0000e-01
440     -8.8057e+02     9.6593e-04      5.0276e-03      1.0000e-01
480     -8.8038e+02     6.4959e-04      2.7635e-03      1.0000e-01
520     -8.8046e+02     3.6258e-04      1.3895e-03      1.0000e-01
560     -8.8041e+02     2.5010e-04      7.8054e-04      1.0000e-01
600     -8.8042e+02     1.4421e-04      3.8051e-04      1.0000e-01
640     -8.8041e+02     1.0115e-04      2.2133e-04      1.0000e-01
680     -8.8041e+02     5.9727e-05      1.0284e-04      1.0000e-01

------------------------------------------------------------------
>>> Results
Status: Solved
Iterations: 680
Optimal objective: -880.4
Runtime: 0.011s (10.85ms)

Then you can find the optimal value of the problem and the optimal values of the variables by

julia> problem.optval
880.4139895737471

julia> evaluate(x1)
4.000000045551431

julia> evaluate(x2)
4.1364021235771595

Here, I’ve chosen the optimizer COSMO.jl which supports the second-order cone (SOCP) formulation used in this problem, but you could also try any of the other solvers listed here which support SOCP constraints.

Edit(@odow): removed some spurious lines from the REPL output.

6 Likes