cvxgrp / CVXR

An R modeling language for convex optimization problems.

Home Page:https://cvxr.rbind.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Wrong table about SCS and QP in homepage

xinran1228 opened this issue · comments

On:
https://cvxr.rbind.io/

Under "Supported Solvers", I think SCS can not support QP.

Please see the SCS reference, https://cran.r-project.org/web/packages/scs/scs.pdf, it is not mentioned that scs can solve QP.
In addition, using SCS in QP will produce incorrect results. For example,
image

What is the value of res_scs$status?

"optimal"
image

The issue is likely the termination criterion. Play around with the solver parameters.

PS. I am unlikely to expend any more time on this thread if you continue to post pictures and/or not provide a self-contained reproducible example.

Sorry, I am not very familiar with the process of issues. That's the code.
Please take a look.

To Reproduce

library(PortfolioAnalytics)
library(CVXR)

# load data
data(edhec)
ret_edhec <- tail(edhec, 60)

# CVXR optimization
X <- as.matrix(ret_edhec)
N <- ncol(ret_edhec)
wts <- Variable(N)
sigma_value <- cov(ret_edhec)
obj <- quad_form(wts, sigma_value)

# long_only full_investment portfolio
prob_cvxr <- Problem(Minimize(obj), constraints = list(wts >= 0, sum(wts) == 1))

# SCS problem
res_scs <- CVXR::solve(prob_cvxr, solver = "SCS")
sqrt(res_scs$value)
res_scs$status

res_osqp <- CVXR::solve(prob_cvxr, solver = "OSQP")
sqrt(res_osqp$value)

res_ecos <- CVXR::solve(prob_cvxr, solver = "ECOS")
sqrt(res_ecos$value)

See below. Solvers have different default parameters and termination criteria. These are all discussed in the examples: https://cvxr.rbind.io/cvxr_examples/cvxr_solver-parameters/.

> res_scs <- CVXR::solve(prob_cvxr, solver = "SCS", verbose = TRUE, eps_abs = 1e-6, eps_rel = 1e-6)
------------------------------------------------------------------
	       SCS v3.0.0 - Splitting Conic Solver
	(c) Brendan O'Donoghue, Stanford University, 2012
------------------------------------------------------------------
problem:  variables n: 14, constraints m: 29
cones: 	  z: primal zero / dual free vars: 1
	  l: linear vars: 13
	  q: soc vars: 15, qsize: 1
settings: eps_abs: 1.0e-06, eps_rel: 1.0e-06, eps_infeas: 1.0e-07
	  alpha: 1.50, scale: 1.00e-01, adaptive_scale: 1
	  max_iters: 2500, normalize: 1, warm_start: 0
lin-sys:  sparse-direct
	  nnz(A): 197, nnz(P): 0
------------------------------------------------------------------
 iter | pri res | dua res |   gap   |   obj   |  scale  | time (s)
------------------------------------------------------------------
     0| 1.04e+00  3.78e-02  3.78e-02  1.89e-02  1.00e-01  1.72e-05 
   250| 1.02e-05  4.95e-08  9.86e-09  1.03e-05  6.73e-04  3.23e-04 
   275| 1.76e-06  8.58e-09  1.73e-09  1.03e-05  6.73e-04  3.55e-04 
------------------------------------------------------------------
status:  solved
timings: total: 4.61e-04s = setup: 1.04e-04s + solve: 3.57e-04s
	 lin-sys: 2.35e-04s, cones: 2.93e-05s, accel: 0.00e+00s
------------------------------------------------------------------
objective = 0.000010
------------------------------------------------------------------
> sqrt(res_scs$value)
[1] 0.003210955
> res_scs$status
[1] "optimal"
> res_osqp <- CVXR::solve(prob_cvxr, solver = "OSQP", verbose = TRUE, eps_abs = 1e-6, eps_rel = 1e-6)
-----------------------------------------------------------------
           OSQP v0.6.0  -  Operator Splitting QP Solver
              (c) Bartolomeo Stellato,  Goran Banjac
        University of Oxford  -  Stanford University 2019
-----------------------------------------------------------------
problem:  variables n = 13, constraints m = 14
          nnz(P) + nnz(A) = 117
settings: linear system solver = qdldl,
          eps_abs = 1.0e-06, eps_rel = 1.0e-06,
          eps_prim_inf = 1.0e-04, eps_dual_inf = 1.0e-04,
          rho = 1.00e-01 (adaptive),
          sigma = 1.00e-06, alpha = 1.60, max_iter = 10000
          check_termination: on (interval 25),
          scaling: on, scaled_termination: off
          warm start: on, polish: on, time_limit: off

iter   objective    pri res    dua res    rho        time
   1   0.0000e+00   1.00e+00   1.00e+02   1.00e-01   4.84e-05s
 125   1.0310e-05   5.02e-08   1.11e-12   7.82e-05   1.15e-04s
plsh   1.0310e-05   2.22e-16   3.31e-12   --------   1.43e-04s

status:               solved
solution polish:      successful
number of iterations: 125
optimal objective:    0.0000
run time:             1.43e-04s
optimal rho estimate: 1.33e-04

> sqrt(res_osqp$value)
[1] 0.003210968
> res_ecos <- CVXR::solve(prob_cvxr, solver = "ECOS", verbose = TRUE, feas_tol = 1e-6, reltol = 1e-6)

ECOS 2.0.7 - (C) embotech GmbH, Zurich Switzerland, 2012-15. Web: www.embotech.com/ECOS

It     pcost       dcost      gap   pres   dres    k/t    mu     step   sigma     IR    |   BT
 0  +0.000e+00  -1.831e-01  +2e+01  7e-01  8e-01  1e+00  1e+00    ---    ---    1  1  - |  -  - 
 1  +9.353e-04  -1.536e-01  +6e+00  1e-01  1e-01  4e-03  4e-01  0.7220  1e-01   1  1  1 |  0  0
 2  +4.421e-04  -6.040e-03  +1e+00  8e-03  3e-02  9e-03  1e-01  0.9890  2e-01   1  1  1 |  0  0
 3  +1.855e-04  +2.815e-05  +2e-02  2e-04  9e-04  2e-04  2e-03  0.9785  6e-04   1  1  1 |  0  0
 4  +4.881e-05  +2.560e-05  +3e-03  2e-05  1e-04  2e-05  3e-04  0.8755  2e-02   1  1  1 |  0  0
 5  +1.494e-05  +3.380e-06  +1e-03  5e-06  4e-05  3e-06  1e-04  0.9218  3e-01   1  1  1 |  0  0
 6  +1.289e-05  +9.604e-06  +4e-04  1e-06  1e-05  7e-07  3e-05  0.8102  1e-01   1  1  1 |  0  0
 7  +1.095e-05  +1.005e-05  +1e-04  4e-07  3e-06  2e-07  7e-06  0.8434  1e-01   1  1  1 |  0  0
 8  +1.072e-05  +1.037e-05  +4e-05  1e-07  1e-06  5e-08  3e-06  0.8880  3e-01   1  1  1 |  0  0
 9  +1.032e-05  +1.031e-05  +1e-06  5e-09  4e-08  2e-09  1e-07  0.9669  3e-03   1  1  1 |  0  0
10  +1.031e-05  +1.031e-05  +6e-08  2e-10  2e-09  8e-11  4e-09  0.9591  2e-04   2  1  1 |  0  0
11  +1.031e-05  +1.031e-05  +2e-09  8e-12  8e-11  3e-12  2e-10  0.9769  2e-02   2  1  1 |  0  0

OPTIMAL (within feastol=7.7e-11, reltol=2.2e-04, abstol=2.3e-09).
Runtime: 0.000606 seconds.

> sqrt(res_ecos$value)
[1] 0.00321097
> 

Got it. It's my fault. Thanks for help.

Your question is perfectly fine and it always helps to have a reproducible example. I am going to close this issue now.