The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.
CVXR is an R package that provides an object-oriented
modeling language for convex optimization, similar to CVXPY for Python. It allows you to
formulate and solve convex optimization problems in a natural
mathematical syntax.
Consider a simple linear regression problem where we want to estimate parameters using a least squares criterion.
We generate synthetic data where we know the true model:
\[ Y = X\beta + \epsilon \]
where \(Y\) is a \(100 \times 1\) vector, \(X\) is a \(100 \times 10\) matrix, \(\beta = (-4, -3, \ldots, 5)^\top\) is a \(10 \times 1\) vector, and \(\epsilon \sim N(0, 1)\).
set.seed(123)
n <- 100
p <- 10
beta <- -4:5
X <- matrix(rnorm(n * p), nrow = n)
Y <- X %*% beta + rnorm(n)Using base R, we can estimate \(\beta\) via lm:
The same problem can be expressed as:
\[ \underset{\beta}{\text{minimize}} \quad \|Y - X\beta\|_2^2 \]
In CVXR, this translates directly:
library(CVXR)
#>
#> Attaching package: 'CVXR'
#> The following objects are masked from 'package:stats':
#>
#> power, sd, var
#> The following objects are masked from 'package:base':
#>
#> norm, outer
betaHat <- Variable(p)
objective <- Minimize(sum((Y - X %*% betaHat)^2))
problem <- Problem(objective)
result <- psolve(problem, solver = "CLARABEL")The optimal value and estimated coefficients:
cat("Optimal value:", result, "\n")
#> Optimal value: 97.84759
cbind(CVXR = round(value(betaHat), 3),
lm = round(coef(ls.model), 3))
#> lm
#> X1 -3.920 -3.920
#> X2 -3.012 -3.012
#> X3 -2.125 -2.125
#> X4 -0.867 -0.867
#> X5 0.091 0.091
#> X6 0.949 0.949
#> X7 2.076 2.076
#> X8 3.127 3.127
#> X9 3.961 3.961
#> X10 5.135 5.135The real power of CVXR is the ability to add constraints easily.
Suppose we know the \(\beta\)s should be nonnegative:
Now suppose \(\beta_2 + \beta_3 \le 0\) and all other \(\beta\)s are nonnegative:
A <- matrix(c(0, 1, 1, rep(0, 7)), nrow = 1)
B <- diag(c(1, 0, 0, rep(1, 7)))
constraint1 <- A %*% betaHat <= 0
constraint2 <- B %*% betaHat >= 0
problem <- Problem(objective, constraints = list(constraint1, constraint2))
result <- psolve(problem, solver = "CLARABEL", verbose = TRUE) ## verbose = TRUE for details
#> ────────────────────────────────── CVXR v1.8.1 ─────────────────────────────────
#> ℹ Problem: 1 variable, 2 constraints (QP)
#> ℹ Compilation: "CLARABEL" via CVXR::Dcp2Cone -> CVXR::CvxAttr2Constr -> CVXR::ConeMatrixStuffing -> CVXR::Clarabel_Solver
#> ℹ Compile time: 0.013s
#> ─────────────────────────────── Numerical solver ───────────────────────────────
#> ──────────────────────────────────── Summary ───────────────────────────────────
#> ✔ Status: optimal
#> ✔ Optimal value: 1287.63
#> ℹ Compile time: 0.013s
#> ℹ Solver time: 0.001s
round(value(betaHat), 3)
#> [,1]
#> [1,] 0.000
#> [2,] -2.845
#> [3,] -1.711
#> [4,] 0.000
#> [5,] 0.664
#> [6,] 1.178
#> [7,] 2.329
#> [8,] 2.414
#> [9,] 4.212
#> [10,] 4.948This demonstrates the chief advantage of CVXR: flexibility. Users can quickly modify and re-solve a problem, making the package ideal for prototyping new statistical methods. Its syntax is simple and mathematically intuitive.
CVXR supports multiple solvers:
installed_solvers()
#> [1] "CLARABEL" "SCS" "OSQP" "HIGHS" "MOSEK" "GUROBI"
#> [7] "GLPK" "GLPK_MI" "ECOS" "ECOS_BB" "CPLEX" "CVXOPT"
#> [13] "PIQP"You can specify a solver explicitly:
sessionInfo()
#> R version 4.5.2 (2025-10-31)
#> Platform: aarch64-apple-darwin20
#> Running under: macOS Tahoe 26.3.1
#>
#> Matrix products: default
#> BLAS: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRblas.0.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.1
#>
#> locale:
#> [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
#>
#> time zone: America/Los_Angeles
#> tzcode source: internal
#>
#> attached base packages:
#> [1] stats graphics grDevices utils datasets methods base
#>
#> other attached packages:
#> [1] CVXR_1.8.1
#>
#> loaded via a namespace (and not attached):
#> [1] slam_0.1-55 cli_3.6.5 knitr_1.51 ECOSolveR_0.6.1
#> [5] rlang_1.1.7 xfun_0.56 clarabel_0.11.2 gurobi_13.0-1
#> [9] otel_0.2.0 Rglpk_0.6-5.1 highs_1.12.0-3 cccp_0.3-3
#> [13] scs_3.2.7 S7_0.2.1 jsonlite_2.0.0 Rcplex_0.3-8
#> [17] backports_1.5.0 Rmosek_11.1.1 htmltools_0.5.9 sass_0.4.10
#> [21] gmp_0.7-5.1 piqp_0.6.2 rmarkdown_2.30 grid_4.5.2
#> [25] evaluate_1.0.5 jquerylib_0.1.4 fastmap_1.2.0 yaml_2.3.12
#> [29] lifecycle_1.0.5 compiler_4.5.2 codetools_0.2-20 Rcpp_1.1.1
#> [33] osqp_1.0.0 lattice_0.22-9 digest_0.6.39 R6_2.6.1
#> [37] bslib_0.10.0 checkmate_2.3.4 Matrix_1.7-4 tools_4.5.2
#> [41] cachem_1.1.0These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.