INSTALLED_SOLVERS <- installed_solvers()
TOL <- 1e-4
x <- Variable(2, name = "x")
slope <- Variable(1, name = "slope")
offset <- Variable(1, name = "offset")
quadratic_coeff <- Variable(1, name = "quadratic_coeff")
#LP, QP, SOCP, SDP, MIP, GP
test_that("Test a basic LP with all solvers", {
skip_on_cran()
# Example from
# http://cvxopt.org/userguide/coneprog.html?highlight=solvers.lp#cvxopt.solvers.lp
objective <- Minimize(-4*x[1] - 5*x[2])
constraints <- list(2*x[1] + x[2] <= 3, x[1] + 2*x[2] <= 3, x[1] >= 0, x[2] >= 0)
prob <- Problem(objective, constraints)
## scs3.0 fix for tol have to be more lenient...
for(solver in INSTALLED_SOLVERS){
result <- solve(prob, solver = solver)
expect_equal(result$value, -9, tolerance = 10 * TOL)
expect_equal(result$getValue(x), as.matrix(c(1, 1)), tolerance = 10 * TOL)
}
#Example from
# https://www.cvxpy.org/examples/basic/linear_program.html
m <- 15
n <- 10
set.seed(1)
s0 <- rnorm(m)
lamb0 <- pmax(-s0, 0)
s0 <- pmax(s0, 0)
x0 <- rnorm(n)
A <- matrix(rnorm(m * n), nrow = m, ncol = n)
b <- A %*% x0 + s0
c <- -t(A) %*% lamb0
x_var <- Variable(n)
prob <- Problem(Minimize(t(c) %*% x_var), list(A %*% x_var <= b))
for(solver in INSTALLED_SOLVERS){
suppressWarnings(
result <- solve(prob, solver = solver, abstol = 1e-6, verbose = TRUE)
)
expect_equal(result$value, -7.83446, tolerance = TOL)
}
})
#QP
test_that("Test a basic QP with all solvers", {
skip_on_cran()
set.seed(0)
#Regression 1 test-g01-qp.R
n <- 100
# Specify the true value of the variable
true_coeffs <- matrix(c(2, -2, 0.5), ncol = 1)
# Generate data
x_data <- 5*rnorm(n)
x_data_expanded <- sapply(1:3, function(i) { x_data^i })
y_data <- x_data_expanded %*% true_coeffs + 0.5*runif(n)
line <- offset + slope*x_data
residuals <- line - y_data
fit_error <- sum_squares(residuals)
p <- Problem(Minimize(fit_error), list())
model <- lm(y_data ~ x_data)
##CBC, ECOS_BB, GLPK_MI, GLPK don't support QPs
applicable_solvers <- setdiff(INSTALLED_SOLVERS, list("CBC", "ECOS_BB", "GLPK_MI", "GLPK"))
## SCS is known to cause problems
## Works sometimes if we set rho_x = 1e-2, but too problematic
applicable_solvers <- setdiff(applicable_solvers, c("SCS", "CVXOPT"))
for(solver in applicable_solvers) {
result <- solve(p, solver)
print(sprintf("Solver: %s status: %s\n", solver, result$status))
expect_equal(sum((model$residuals)^2), result$value, tolerance = TOL)
expect_equal(as.numeric(model$coefficients[1]), result$getValue(offset), tolerance = TOL)
expect_equal(as.numeric(model$coefficients[2]), result$getValue(slope), tolerance = TOL)
}
##Regression 2 test-g01-qp.R
quadratic <- offset + slope*x_data + quadratic_coeff*x_data^2
residuals <- quadratic - y_data
fit_error <- sum_squares(residuals)
p <- Problem(Minimize(fit_error), list())
x_data_sq <- x_data^2
model <- lm(y_data ~ x_data + x_data_sq)
for(solver in applicable_solvers) {
##cat(sprintf("Doing %s\n", solver))
result <- solve(p, solver)
expect_equal(sum((model$residuals)^2), result$value, tolerance = TOL)
expect_equal(as.numeric(model$coefficients[1]), result$getValue(offset), tolerance = TOL)
expect_equal(as.numeric(model$coefficients[2]), result$getValue(slope), tolerance = TOL)
expect_equal(as.numeric(model$coefficients[3]), result$getValue(quadratic_coeff), tolerance = TOL)
}
})
test_that("Test a basic SOCP with solvers", {
skip_on_cran()
applicable_solvers <- setdiff(INSTALLED_SOLVERS, list("CBC", "ECOS_BB", "GLPK_MI", "GLPK", "OSQP"))
# Example from
# http://cvxopt.org/userguide/coneprog.html?highlight=solvers.lp#cvxopt.solvers.lp
objective <- Minimize(-4*x[1] - 5*x[2])
constraints <- list(2*x[1] + x[2] <= 3, (x[1] + 2*x[2])^2 <= 9, x[1] >= 0, x[2] >= 0)
prob <- Problem(objective, constraints)
for(solver in applicable_solvers) {
result <- solve(prob, solver = solver)
print(sprintf("Solver: %s status: %s\n", solver, result$status))
expect_equal(result$value, -9, tolerance = TOL)
expect_equal(result$getValue(x), as.matrix(c(1, 1)), tolerance = TOL)
}
# Example from
# https://www.cvxpy.org/examples/basic/socp.html
set.seed(1)
m <- 3
n <- 10
p <- 5
n_i <- 5
f = rnorm(n)
A <- vector(mode="list", m)
b <- vector(mode="list", m)
c <- vector(mode="list", m)
d <- vector(mode="list", m)
x0 <- rnorm(n)
soc_constraints <- vector(mode="list", m+1)
x_var <- Variable(n)
for(i in 1:m){
A[[i]] <- matrix(rnorm(n_i * n), nrow = n_i, ncol = n)
b[[i]] <- rnorm(n_i)
c[[i]] <- rnorm(n)
d[[i]] <- norm(A[[i]] %*% x0 + b[[i]], "f")
soc_constraints[[i]] <- CVXR:::SOC(t(c[[i]]) %*% x_var + d[[i]], A[[i]] %*% x_var + b[[i]])
}
Fmat <- matrix(rnorm(p * n), nrow = p, ncol = n)
g <- Fmat %*% x0
soc_constraints[[m+1]] <- Fmat %*% x_var == g
prob <- Problem(Minimize(t(f)%*%x_var), soc_constraints)
for(solver in applicable_solvers) {
result <- solve(prob, solver=solver)
print(sprintf("Solver: %s status: %s\n", solver, result$status))
expect_equal(result$value, -10.13341, tolerance=TOL)
}
})
test_that("Test a basic SDP with all solvers", {
skip_on_cran()
# Example from
# https://www.cvxpy.org/examples/basic/sdp.html
n <- 3
p <- 3
set.seed(4)
C <- matrix(rnorm(n^2), nrow = n)
A <- vector(mode="list", p)
b <- numeric(p)
X <- Variable(n, n, PSD=T)
constraints <- list()
for(i in 1:p){
A[[i]] <- matrix(rnorm(n^2), nrow = n)
b[i] <- rnorm(1)
constraints <- c(constraints, matrix_trace(A[[i]] %*% X) == b[i])
}
prob <- Problem(Minimize(matrix_trace(C %*% X)), constraints)
check_matrix <- matrix(c(.3771707, -.5692205, .1166577, -.5692205,
.8590441, -.1760618, .11665767,
-.17606183, .03608155), nrow = n)
# SCS and MOSEK and CVXOPT, CLARABEL are the only solvers that support SDPs
## Not adding clarabel for now
for(solver in intersect(INSTALLED_SOLVERS, c("SCS", "MOSEK", "CVXOPT"))) {
result <- solve(prob, solver = solver)
print(sprintf("Solver: %s status: %s\n", solver, result$status))
expect_equal(result$value, 1.395479, tolerance=TOL)
expect_equal(result$getValue(X), check_matrix, tolerance=TOL)
}
})
test_that("Test a mixed-integer quadratic program",{
skip_on_cran()
# Example from
# https://www.cvxpy.org/examples/basic/mixed_integer_quadratic_program.html
m <- 40
n <- 25
set.seed(1)
A <- matrix(runif(m*n), nrow = m)
b <- rnorm(m)
x <- Variable(n, integer=T)
obj <- Minimize(sum_squares(A %*% x - b))
prob <- Problem(obj)
applicable_solvers <- intersect(INSTALLED_SOLVERS, c("ECOS_BB", "CPLEX", "GUROBI", "MOSEK"))
for(solver in applicable_solvers) {
result <- solve(prob, solver=solver)
expect_equal(result$value, 13.34086, tolerance=TOL)
}
})
test_that("Test a simple geometric program", {
skip_on_cran()
# Example from
# https://www.cvxpy.org/examples/dgp/dgp_fundamentals.html
x <- Variable(pos=TRUE)
y <- Variable(pos=TRUE)
z <- Variable(pos=TRUE)
obj <- x * y * z
constraints <- list(4*x*y*z + 2*x*z <= 10,
x <= 2*y,
y <= 2*x,
z >=1)
prob <- Problem(Maximize(obj), constraints)
## Leave out CLARABEL for now
for(solver in c("ECOS", "SCS")){
result <- solve(prob, solver=solver, gp=TRUE)
expect_equal(result$value, 2, tolerance=TOL)
expect_equal(result$getValue(x), 1, tolerance=TOL)
expect_equal(result$getValue(y), 2, tolerance=TOL)
expect_equal(result$getValue(z), 1, tolerance=TOL)
}
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.