Dealing with Solver-Specific Parameters

Overview

CVXR 1.0 has now updated how it handles its solver-specific parameters and has diverged slightly from how cvxpy handles it. It now features five standard parameters that are the default parameters for each solve function. Here are the five parameters

  • verbose : A parameter that deals with the verbosity of the solver. It is a boolean variable for all solvers, but it can also take integer values for the MOSEK solver, whose interface deals with an integer verbosity parameter with the default of 10. The default value of verbose for CVXR is set to FALSE.

  • reltol : Deals with the relative tolerance of the solver.

  • abstol : Deals with the absolute tolerance of the solver.

  • feastol : Deals with feasible tolerance of the solver.

  • num_iter : A parameter that specifies the maximum number of iterations for the solver.

The users can also pass in solver-specific parameters to the solve function based on the solver they specify. On the whole, the additional parameters given by the user will override the five values specified above.

For each solver, the tables below show how the five standard parameters are mapped to the solver. Cells with NA values indicate no mapping and any specified value will result in a warning about parameter being ignored.

Solver-Specific Parameters

We will go over some examples for each solvers supported by CVXR, the available parameters for each solver, and where to find the documentation for each solver.

OSQP

The parameters available for OSQP can be found in this link.

Table 1: Default CVXR-OSQP parameter mappings
Standard OSQP Value
verbose verbose FALSE
reltol eps_rel 1e-05
abstol eps_abs 1e-05
feastol eps_{prim/dual}_inf 1e-04
num_iter max_iter 10000

The parameters can be entered individually in the arguments of the solve function or can be passed through as a list. If the user enters in a parameter that is not specified or accepted by OSQP, then the solver will ignore the parameter and proceed to solve the problem. Here is an example.

x <- Variable(1)
obj <- Minimize(x)
prob <- Problem(obj, list(x >= 0))

# Inside Function
result  <- solve(prob, solver = "OSQP", feastol = 1e-2, eps_prim_inf = 1e-5)

# Can also do it by passing in a list
more_params <- list(verbose = TRUE, feastol = 1e-2,
                    eps_prim_inf = 1e-5, eps_prim_inf = 1e-3)
result <- solve(prob, solver = "OSQP", verbose = FALSE, more_params)

In the second case that the verbose in the more_params list overrides the value of verbose listed earlier in the invocation.

SCS

The parameters available for SCS can be found in this link under the scs_control function.

Table 2: Default CVXR-SCS parameter mappings
Standard SCS Value
verbose verbose FALSE
reltol NA NA
abstol NA NA
feastol NA NA
num_iter max_iters 2500

Much like OSQP, the parameters can be entered individually in the arguments of the solve function or can be passed through as a list. If the user enters in a parameter that is not specified or accepted by SCS, then the solver will ignore the parameter and proceed to solve the problem. Here is an example:

n<-3
p<-3
C <- matrix(rnorm(n^2), ncol = n)
A <- list(matrix(rnorm(n*n), nrow = n, ncol = n), matrix(rnorm(n*n), nrow = n, ncol = n), matrix(rnorm(n*n), nrow = n, ncol = n))
b <- matrix(rnorm(p), nrow = p)

X <- Variable(c(n, n), symmetric = TRUE)
constraints <- list(X >= 0)
for(i in 1:p){
  constraints <- c(constraints, list(matrix_trace(A[[i]]%*%X) == b[i] ))
}

obj <- Minimize(matrix_trace(C %*% X))
prob <- Problem(obj, constraints)
result  <- solve(prob, solver = "SCS", verbose = FALSE, feastol = 1e-2, cg_rate = 1.5, scale = 2)

Notice how in this case a warning is thrown: the SCS solver does not support the feasible tolerance parameter, so the solver ignores it.

ECOS/ECOS_BB

The parameters available for ECOS can be found in this link under the ecos.control function.

Table 3: Default CVXR-ECOS parameter mappings
Standard ECOS ECOS Value ECOS_BB ECOS_BB Value
verbose verbose FALSE verbose FALSE
reltol reltol 1e-08 reltol 1e-03
abstol abstol 1e-08 abstol 1e-06
feastol feastol 1e-08 feastol 1e-06
num_iter maxit 100 mi_max_iters 1000

Much like OSQP, the parameters can be entered individually in the arguments of the solve function or can be passed through as a list. If the user enters in a parameter that is not specified or accepted by ECOS, then the solver will ignore the parameter and proceed to solve the problem. Here is an example:

x <- Variable(1)
obj <- Minimize(x)
prob <- Problem(obj, list(x >= 0))
result  <- solve(prob, solver = "ECOS", verbose = FALSE, feastol = 1e-2, reltol_inacc = 1e-5)
## as(<dtCMatrix>, "dgCMatrix") is deprecated since Matrix 1.5-0; do as(., "generalMatrix") instead

CPLEX

The parameters available for CPLEX can be found in this link under the details section for the function Rcplex function on page 3.

Table 4: Default CVXR-CPLEX parameter mappings
Standard CPLEX Value
verbose trace FALSE
reltol NA NA
abstol NA NA
feastol NA NA
num_iter itlim 10000

Much like OSQP, the parameters can be entered individually in the arguments of the solve function or can be passed through as a list. If the user enters in a parameter that is not specified or accepted by CPLEX, then the solver will give the user a warning but will proceed to solve the problem. Here is an example:

x <- Variable(1)
obj <- Minimize(x)
prob <- Problem(obj, list(x >= 0))
result  <- solve(prob, solver = "CPLEX", verbose = FALSE, eps_abs_tol = 1e-2, epagap = 1e-5)
## Warning in Rcplex::Rcplex(cvec = q, Amat = Amat, bvec = bvec, Qmat = P, :
## Unknown CPLEX parameter eps_abs_tol. Ignoring it.

As you can see, eps_abs_tol is not one of CPLEX’s specified parameters, so the solver threw a warning.

MOSEK

Table 5: Default CVXR-MOSEK parameter mappings
Standard MOSEK Value
verbose verbose 0
reltol NA NA
abstol NA NA
feastol NA NA
num_iter num_iter 10000

The parameters available for MOSEK can be seen in this link. As you can see, the number of parameters is quite massive. They are also split between three times of parameters in Double, Integer, and String parameters. To pass these into the solver, they must be put in a list beforehand. Moreover, there are also general solver parameters that do not belong in any of the three categories. These parameters can be found in detail in the Rmosek package documentation, but here are the parameters

  • verbose (Another important note here is while the default values of TRUE and FALSE work, MOSEK uses integer values for verbose with the default being 10. The TRUE value for verbose corresponds to 10 in the solver)
  • usesol
  • useparam
  • soldetail
  • getinfo
  • writebefore
  • writeafter

These parameters are passed into the solve function as normal. Here is an example:

x <- Variable(1)
obj <- Minimize(x)
prob <- Problem(obj, list(x >= 0))
iparam <- list()
iparam$AUTO_UPDATE_SOL_INFO <- "OFF"
iparam$BI_IGNORE_NUM_ERROR <- "OFF"
iparam$BI_MAX_ITERATIONS <- 100000

dparam <- list()
dparam$BASIS_REL_TOL_S <- 1.0e-12
dparam$BASIS_TOL_S <- 1.0e-6

result  <- solve(prob, solver = "MOSEK", verbose = FALSE, soldetail = 3, dparam = dparam, iparam = iparam)
## Warning in solve_via_data(object@solver, data, warm_start, verbose, feastol, :
## Solver might not output correct answer depending on the input of the soldetail
## variable. Default is 3

A quick detail in this case is that the solver threw a warning about the soldetail parameter. Both the soldetail and getinfo parameter controls the amount of data the solve returns, and some of them might be needed in order to invert the solution. Therefore, proceed with caution when using these variables as they can cause the solver to not obtain the answer.

GUROBI

Table 6: Default CVXR-GUROBI parameter mappings
Standard GUROBI Value
verbose OutputFlag 0
reltol NA NA
abstol NA NA
feastol {Feasibility/Optimality}Tol 1e-06
num_iter IterationLimit 10000

The parameters available for GUROBI can be seen in this link. If an unaccepted parameter is passed into the solve function, then the function will not run to completion. The solver will also not let you know which parameter is at fault unless the parameter is continuous. Here is an example.

x <- Variable(1)
obj <- Minimize(x)
prob <- Problem(obj, list(x >= 0))
result  <- solve(prob, solver = "GUROBI", verbose = FALSE, BarIterLimit = 20, Quad = 1)

GLPK

Table 7: Default CVXR-GLPK parameter mappings
Standard GLPK Value
verbose verbose 0
reltol NA NA
abstol NA NA
feastol NA NA
num_iter NA NA

The parameters available for GLPK can be seen in this link under the Details section in page 4. There are only four parameters in verbose, presolve, tm_limit, canonicalize_status. Here is an example

x <- Variable(1)
obj <- Minimize(x)
prob <- Problem(obj, list(x >= 0))
result  <- solve(prob, solver = "GLPK", verbose = FALSE, presolve = FALSE, tm_limit = 10, canonicalize_status = TRUE)

CBC

Table 8: Default CVXR-CBC parameter mappings
Standard CBC Value
verbose verbose 0
reltol NA NA
abstol NA NA
feastol NA NA
num_iter NA NA

The parameters available for CBC can be seen in this link. Much like most of the solvers outlined above, if the user passes in a unspecified parameter into the solver, then the solver just ignores the parameter and proceeds to solve the problem. Here is an example

x <- Variable(1)
obj <- Minimize(x)
prob <- Problem(obj, list(x >= 0))
result  <- solve(prob, solver = "CBC", verbose = FALSE, sec = 5, maxn = 10)

Session Info

sessionInfo()
## R version 4.2.1 (2022-06-23)
## Platform: x86_64-apple-darwin21.6.0 (64-bit)
## Running under: macOS Ventura 13.0
## 
## Matrix products: default
## BLAS:   /usr/local/Cellar/openblas/0.3.21/lib/libopenblasp-r0.3.21.dylib
## LAPACK: /usr/local/Cellar/r/4.2.1_4/lib/R/lib/libRlapack.dylib
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## attached base packages:
## [1] stats     graphics  grDevices datasets  utils     methods   base     
## 
## other attached packages:
## [1] kableExtra_1.3.4 tibble_3.1.8     CVXR_1.0-11     
## 
## loaded via a namespace (and not attached):
##  [1] xfun_0.34         bslib_0.4.0       slam_0.1-50       lattice_0.20-45  
##  [5] Rmosek_10.0.25    colorspace_2.0-3  vctrs_0.5.0       htmltools_0.5.3  
##  [9] viridisLite_0.4.1 yaml_2.3.6        gmp_0.6-6         utf8_1.2.2       
## [13] rlang_1.0.6       jquerylib_0.1.4   pillar_1.8.1      glue_1.6.2       
## [17] Rmpfr_0.8-9       Rcplex_0.3-5      bit64_4.0.5       scs_3.0-1        
## [21] lifecycle_1.0.3   stringr_1.4.1     munsell_0.5.0     blogdown_1.13    
## [25] gurobi_9.5-2      rvest_1.0.3       codetools_0.2-18  evaluate_0.17    
## [29] knitr_1.40        fastmap_1.1.0     cccp_0.2-9        fansi_1.0.3      
## [33] highr_0.9         Rcpp_1.0.9        scales_1.2.1      cachem_1.0.6     
## [37] osqp_0.6.0.5      webshot_0.5.4     jsonlite_1.8.3    systemfonts_1.0.4
## [41] bit_4.0.4         digest_0.6.30     stringi_1.7.8     bookdown_0.29    
## [45] Rglpk_0.6-4       grid_4.2.1        ECOSolveR_0.5.4   cli_3.4.1        
## [49] tools_4.2.1       magrittr_2.0.3    sass_0.4.2        pkgconfig_2.0.3  
## [53] rcbc_0.1.0.9001   Matrix_1.5-1      xml2_1.3.3        assertthat_0.2.1 
## [57] rmarkdown_2.17    svglite_2.1.0     httr_1.4.4        rstudioapi_0.14  
## [61] R6_2.5.1          compiler_4.2.1

Source

R Markdown