Nothing
## CRAN solver test matrix — core solvers only (Clarabel, SCS, OSQP, HiGHS)
## Extracted from test-standard-solver-matrix.R for CRAN submission.
## These 4 solvers are in Imports and always available — zero skips expected.
##
## Tolerances are solver-documented defaults, NOT empirically fudged:
## Clarabel: 1e-4 (obj), 1e-3 (primal/dual)
## SCS: 1e-2 (obj/primal/dual)
## OSQP: 1e-4 (obj/primal), LP/QP only
## HiGHS: 1e-5 (obj/primal), LP/QP only
##
## NEVER tweak tolerances to get a test to pass.
## If a test fails, the code has a bug — fix the code, not the tolerance.
# ── Helper: verify objective ─────────────────────────────────────
verify_obj <- function(prob, expected, tol, solver_name) {
val <- psolve(prob, solver = solver_name)
if (is.infinite(expected) && expected > 0) {
## Infeasible: psolve returns Inf
expect_true(is.infinite(val) && val > 0,
label = paste(solver_name, "should be infeasible (Inf)"))
} else if (is.infinite(expected) && expected < 0) {
## Unbounded: psolve returns -Inf
expect_true(is.infinite(val) && val < 0,
label = paste(solver_name, "should be unbounded (-Inf)"))
} else {
expect_equal(val, expected, tolerance = tol,
label = paste(solver_name, "objective"))
}
}
# ── Helper: verify primal ────────────────────────────────────────
verify_primal <- function(prob, var, expected, tol, solver_name) {
if (is.null(expected)) return(invisible(NULL))
actual <- value(var)
expect_equal(as.numeric(actual), as.numeric(expected), tolerance = tol,
label = paste(solver_name, "primal"))
}
# ── Helper: verify duals ─────────────────────────────────────────
verify_dual <- function(con, expected, tol, solver_name) {
if (is.null(expected)) return(invisible(NULL))
actual <- dual_value(con)
if (is.list(expected)) {
## SOC / ExpCone / PowCone: list of arrays
for (k in seq_along(expected)) {
expect_equal(as.numeric(actual[[k]]), as.numeric(expected[[k]]),
tolerance = tol,
label = paste(solver_name, "dual component", k))
}
} else {
expect_equal(as.numeric(actual), as.numeric(expected), tolerance = tol,
label = paste(solver_name, "dual"))
}
}
# ══════════════════════════════════════════════════════════════════
# CLARABEL
# ══════════════════════════════════════════════════════════════════
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_lp_0
test_that("Clarabel: lp_0", {
h <- sth_lp_0()
verify_obj(h$prob, h$expect_obj, 1e-4, "CLARABEL")
x_var <- variables(h$prob)[[1]]
verify_primal(h$prob, x_var, h$expect_x, 1e-3, "CLARABEL")
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_lp_1
test_that("Clarabel: lp_1", {
h <- sth_lp_1()
verify_obj(h$prob, h$expect_obj, 1e-4, "CLARABEL")
x_var <- variables(h$prob)[[1]]
verify_primal(h$prob, x_var, h$expect_x, 1e-3, "CLARABEL")
for (i in seq_along(h$con_duals)) {
verify_dual(h$prob@constraints[[i]], h$con_duals[[i]], 1e-3, "CLARABEL")
}
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_lp_2
test_that("Clarabel: lp_2", {
h <- sth_lp_2()
verify_obj(h$prob, h$expect_obj, 1e-4, "CLARABEL")
x_var <- variables(h$prob)[[1]]
verify_primal(h$prob, x_var, h$expect_x, 1e-3, "CLARABEL")
for (i in seq_along(h$con_duals)) {
verify_dual(h$prob@constraints[[i]], h$con_duals[[i]], 1e-3, "CLARABEL")
}
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_lp_3
test_that("Clarabel: lp_3 (unbounded)", {
h <- sth_lp_3()
verify_obj(h$prob, h$expect_obj, 1e-4, "CLARABEL")
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_lp_4
test_that("Clarabel: lp_4 (infeasible)", {
h <- sth_lp_4()
verify_obj(h$prob, h$expect_obj, 1e-4, "CLARABEL")
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_lp_5
test_that("Clarabel: lp_5 (redundant equalities)", {
h <- sth_lp_5()
verify_obj(h$prob, h$expect_obj, 1e-3, "CLARABEL")
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_qp_0
test_that("Clarabel: qp_0", {
h <- sth_qp_0()
verify_obj(h$prob, h$expect_obj, 1e-4, "CLARABEL")
x_var <- variables(h$prob)[[1]]
verify_primal(h$prob, x_var, h$expect_x, 1e-3, "CLARABEL")
for (i in seq_along(h$con_duals)) {
verify_dual(h$prob@constraints[[i]], h$con_duals[[i]], 1e-3, "CLARABEL")
}
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_socp_0
test_that("Clarabel: socp_0", {
h <- sth_socp_0()
verify_obj(h$prob, h$expect_obj, 1e-4, "CLARABEL")
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_socp_1
test_that("Clarabel: socp_1", {
h <- sth_socp_1()
verify_obj(h$prob, h$expect_obj, 1e-4, "CLARABEL")
x_var <- variables(h$prob)[[1]]
verify_primal(h$prob, x_var, h$expect_x, 1e-3, "CLARABEL")
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_socp_2
test_that("Clarabel: socp_2", {
h <- sth_socp_2()
verify_obj(h$prob, h$expect_obj, 1e-4, "CLARABEL")
x_var <- variables(h$prob)[[1]]
verify_primal(h$prob, x_var, h$expect_x, 1e-3, "CLARABEL")
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_socp_3
test_that("Clarabel: socp_3 axis=0", {
h <- sth_socp_3_ax0()
verify_obj(h$prob, h$expect_obj, 1e-4, "CLARABEL")
x_var <- variables(h$prob)[[1]]
verify_primal(h$prob, x_var, h$expect_x, 1e-3, "CLARABEL")
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_socp_3
test_that("Clarabel: socp_3 axis=1", {
h <- sth_socp_3_ax1()
verify_obj(h$prob, h$expect_obj, 1e-4, "CLARABEL")
x_var <- variables(h$prob)[[1]]
verify_primal(h$prob, x_var, h$expect_x, 1e-3, "CLARABEL")
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_sdp_1min
test_that("Clarabel: sdp_1 min", {
h <- sth_sdp_1_min()
verify_obj(h$prob, h$expect_obj, 1e-2, "CLARABEL")
})
## @cvxpy NONE
test_that("Clarabel: sdp_1 max", {
h <- sth_sdp_1_max()
verify_obj(h$prob, h$expect_obj, 1e-2, "CLARABEL")
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_sdp_2
test_that("Clarabel: sdp_2", {
h <- sth_sdp_2()
verify_obj(h$prob, h$expect_obj, 1e-2, "CLARABEL")
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_expcone_1
test_that("Clarabel: expcone_1", {
h <- sth_expcone_1()
verify_obj(h$prob, h$expect_obj, 1e-3, "CLARABEL")
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_exp_soc_1
test_that("Clarabel: exp_soc_1", {
h <- sth_expcone_socp_1()
verify_obj(h$prob, h$expect_obj, 1e-3, "CLARABEL")
})
## @cvxpy NONE
test_that("Clarabel: pcp_1", {
h <- sth_pcp_1()
verify_obj(h$prob, h$expect_obj, 1e-3, "CLARABEL")
})
## @cvxpy NONE
test_that("Clarabel: pcp_2", {
h <- sth_pcp_2()
verify_obj(h$prob, h$expect_obj, 1e-3, "CLARABEL")
})
## @cvxpy NONE
test_that("Clarabel: pcp_3", {
h <- sth_pcp_3()
verify_obj(h$prob, h$expect_obj, 1e-3, "CLARABEL")
})
# ══════════════════════════════════════════════════════════════════
# SCS
# ══════════════════════════════════════════════════════════════════
## @cvxpy NONE
test_that("SCS: lp_0", {
h <- sth_lp_0()
verify_obj(h$prob, h$expect_obj, 1e-2, "SCS")
})
## @cvxpy NONE
test_that("SCS: lp_1", {
h <- sth_lp_1()
verify_obj(h$prob, h$expect_obj, 1e-2, "SCS")
x_var <- variables(h$prob)[[1]]
verify_primal(h$prob, x_var, h$expect_x, 1e-2, "SCS")
})
## @cvxpy NONE
test_that("SCS: lp_2", {
h <- sth_lp_2()
verify_obj(h$prob, h$expect_obj, 1e-1, "SCS")
})
## @cvxpy test_conic_solvers.py::TestSCS::test_scs_lp_3
test_that("SCS: lp_3 (unbounded)", {
h <- sth_lp_3()
verify_obj(h$prob, h$expect_obj, 1e-2, "SCS")
})
## @cvxpy test_conic_solvers.py::TestSCS::test_scs_lp_4
test_that("SCS: lp_4 (infeasible)", {
h <- sth_lp_4()
verify_obj(h$prob, h$expect_obj, 1e-2, "SCS")
})
## @cvxpy test_conic_solvers.py::TestSCS::test_scs_lp_5
test_that("SCS: lp_5 (redundant equalities)", {
h <- sth_lp_5()
verify_obj(h$prob, h$expect_obj, 1e-1, "SCS")
})
## @cvxpy NONE
test_that("SCS: qp_0", {
h <- sth_qp_0()
verify_obj(h$prob, h$expect_obj, 1e-2, "SCS")
})
## @cvxpy NONE
test_that("SCS: socp_0", {
h <- sth_socp_0()
verify_obj(h$prob, h$expect_obj, 1e-2, "SCS")
})
## @cvxpy test_conic_solvers.py::TestSCS::test_scs_socp_1
test_that("SCS: socp_1", {
h <- sth_socp_1()
verify_obj(h$prob, h$expect_obj, 1e-2, "SCS")
})
## @cvxpy NONE
test_that("SCS: socp_2", {
h <- sth_socp_2()
verify_obj(h$prob, h$expect_obj, 1e-2, "SCS")
})
## @cvxpy test_conic_solvers.py::TestSCS::test_scs_socp_3
test_that("SCS: socp_3 axis=0", {
h <- sth_socp_3_ax0()
verify_obj(h$prob, h$expect_obj, 1e-2, "SCS")
})
## @cvxpy test_conic_solvers.py::TestSCS::test_scs_socp_3
test_that("SCS: socp_3 axis=1", {
h <- sth_socp_3_ax1()
verify_obj(h$prob, h$expect_obj, 1e-2, "SCS")
})
## @cvxpy test_conic_solvers.py::TestSCS::test_scs_sdp_1min
test_that("SCS: sdp_1 min", {
h <- sth_sdp_1_min()
verify_obj(h$prob, h$expect_obj, 1e-1, "SCS")
})
## @cvxpy NONE
test_that("SCS: sdp_1 max", {
h <- sth_sdp_1_max()
verify_obj(h$prob, h$expect_obj, 1e-1, "SCS")
})
## @cvxpy test_conic_solvers.py::TestSCS::test_scs_sdp_2
test_that("SCS: sdp_2", {
h <- sth_sdp_2()
verify_obj(h$prob, h$expect_obj, 1e-1, "SCS")
})
## @cvxpy test_conic_solvers.py::TestSCS::test_scs_expcone_1
test_that("SCS: expcone_1", {
h <- sth_expcone_1()
verify_obj(h$prob, h$expect_obj, 1e-2, "SCS")
})
## @cvxpy test_conic_solvers.py::TestSCS::test_scs_exp_soc_1
test_that("SCS: exp_soc_1", {
h <- sth_expcone_socp_1()
verify_obj(h$prob, h$expect_obj, 1e-2, "SCS")
})
## @cvxpy test_conic_solvers.py::TestSCS::test_scs_pcp_1
test_that("SCS: pcp_1", {
h <- sth_pcp_1()
verify_obj(h$prob, h$expect_obj, 1e-2, "SCS")
})
## @cvxpy test_conic_solvers.py::TestSCS::test_scs_pcp_2
test_that("SCS: pcp_2", {
h <- sth_pcp_2()
verify_obj(h$prob, h$expect_obj, 1e-2, "SCS")
})
## @cvxpy test_conic_solvers.py::TestSCS::test_scs_pcp_3
test_that("SCS: pcp_3", {
h <- sth_pcp_3()
verify_obj(h$prob, h$expect_obj, 1e-2, "SCS")
})
# ══════════════════════════════════════════════════════════════════
# OSQP (LP and QP only)
# ══════════════════════════════════════════════════════════════════
## @cvxpy NONE
test_that("OSQP: lp_0", {
h <- sth_lp_0()
verify_obj(h$prob, h$expect_obj, 1e-4, "OSQP")
})
## @cvxpy NONE
test_that("OSQP: lp_1", {
h <- sth_lp_1()
verify_obj(h$prob, h$expect_obj, 1e-4, "OSQP")
x_var <- variables(h$prob)[[1]]
verify_primal(h$prob, x_var, h$expect_x, 1e-3, "OSQP")
})
## @cvxpy NONE
test_that("OSQP: lp_2", {
h <- sth_lp_2()
verify_obj(h$prob, h$expect_obj, 1e-4, "OSQP")
x_var <- variables(h$prob)[[1]]
verify_primal(h$prob, x_var, h$expect_x, 1e-3, "OSQP")
})
## @cvxpy NONE
test_that("OSQP: lp_3 (unbounded)", {
h <- sth_lp_3()
verify_obj(h$prob, h$expect_obj, 1e-4, "OSQP")
})
## @cvxpy NONE
test_that("OSQP: lp_4 (infeasible)", {
h <- sth_lp_4()
verify_obj(h$prob, h$expect_obj, 1e-4, "OSQP")
})
## @cvxpy NONE
test_that("OSQP: qp_0", {
h <- sth_qp_0()
verify_obj(h$prob, h$expect_obj, 1e-4, "OSQP")
x_var <- variables(h$prob)[[1]]
verify_primal(h$prob, x_var, h$expect_x, 1e-3, "OSQP")
})
# ══════════════════════════════════════════════════════════════════
# HiGHS (LP and QP only)
# ══════════════════════════════════════════════════════════════════
## @cvxpy test_conic_solvers.py::TestHIGHS::test_highs_solving
test_that("HiGHS: lp_0", {
h <- sth_lp_0()
verify_obj(h$prob, h$expect_obj, 1e-5, "HIGHS")
})
## @cvxpy test_conic_solvers.py::TestHIGHS::test_highs_solving
test_that("HiGHS: lp_1", {
h <- sth_lp_1()
verify_obj(h$prob, h$expect_obj, 1e-5, "HIGHS")
x_var <- variables(h$prob)[[1]]
verify_primal(h$prob, x_var, h$expect_x, 1e-5, "HIGHS")
## NOTE: HiGHS dual signs are negated vs CVXPY convention (known issue)
})
## @cvxpy test_conic_solvers.py::TestHIGHS::test_highs_solving
test_that("HiGHS: lp_2", {
h <- sth_lp_2()
verify_obj(h$prob, h$expect_obj, 1e-5, "HIGHS")
x_var <- variables(h$prob)[[1]]
verify_primal(h$prob, x_var, h$expect_x, 1e-5, "HIGHS")
})
## @cvxpy test_conic_solvers.py::TestHIGHS::test_highs_solving
test_that("HiGHS: lp_3 (unbounded)", {
h <- sth_lp_3()
verify_obj(h$prob, h$expect_obj, 1e-5, "HIGHS")
})
## @cvxpy test_conic_solvers.py::TestHIGHS::test_highs_solving
test_that("HiGHS: lp_4 (infeasible)", {
h <- sth_lp_4()
verify_obj(h$prob, h$expect_obj, 1e-5, "HIGHS")
})
## @cvxpy test_conic_solvers.py::TestHIGHS::test_highs_solving
test_that("HiGHS: lp_5 (redundant equalities)", {
h <- sth_lp_5()
verify_obj(h$prob, h$expect_obj, 1e-4, "HIGHS")
})
## @cvxpy NONE
test_that("HiGHS: qp_0", {
h <- sth_qp_0()
verify_obj(h$prob, h$expect_obj, 1e-5, "HIGHS")
x_var <- variables(h$prob)[[1]]
verify_primal(h$prob, x_var, h$expect_x, 1e-5, "HIGHS")
})
# ══════════════════════════════════════════════════════════════════
# Cross-solver consistency checks
# ══════════════════════════════════════════════════════════════════
## @cvxpy NONE
test_that("Cross-solver: LP objectives agree across solvers", {
h <- sth_lp_1()
obj_clarabel <- psolve(h$prob, solver = "CLARABEL")
h2 <- sth_lp_1()
obj_scs <- psolve(h2$prob, solver = "SCS")
h3 <- sth_lp_1()
obj_osqp <- psolve(h3$prob, solver = "OSQP")
h4 <- sth_lp_1()
obj_highs <- psolve(h4$prob, solver = "HIGHS")
expect_equal(obj_clarabel, obj_scs, tolerance = 1e-2)
expect_equal(obj_clarabel, obj_osqp, tolerance = 1e-3)
expect_equal(obj_clarabel, obj_highs, tolerance = 1e-4)
})
## @cvxpy NONE
test_that("Cross-solver: QP objectives agree across solvers", {
h <- sth_qp_0()
obj_clarabel <- psolve(h$prob, solver = "CLARABEL")
h2 <- sth_qp_0()
obj_scs <- psolve(h2$prob, solver = "SCS")
h3 <- sth_qp_0()
obj_osqp <- psolve(h3$prob, solver = "OSQP")
h4 <- sth_qp_0()
obj_highs <- psolve(h4$prob, solver = "HIGHS")
expect_equal(obj_clarabel, obj_scs, tolerance = 1e-2)
expect_equal(obj_clarabel, obj_osqp, tolerance = 1e-3)
expect_equal(obj_clarabel, obj_highs, tolerance = 1e-4)
})
## @cvxpy NONE
test_that("Cross-solver: SOCP objectives agree (Clarabel vs SCS)", {
h1 <- sth_socp_1()
obj_clarabel <- psolve(h1$prob, solver = "CLARABEL")
h2 <- sth_socp_1()
obj_scs <- psolve(h2$prob, solver = "SCS")
expect_equal(obj_clarabel, obj_scs, tolerance = 1e-2)
})
# ══════════════════════════════════════════════════════════════════
# Solver option tests
# ══════════════════════════════════════════════════════════════════
## @cvxpy NONE
test_that("Clarabel: solver options accepted", {
h <- sth_lp_1()
val <- psolve(h$prob, solver = "CLARABEL", max_iter = 50)
expect_equal(val, h$expect_obj, tolerance = 1e-4)
})
## @cvxpy NONE
test_that("SCS: solver options accepted", {
h <- sth_lp_1()
val <- psolve(h$prob, solver = "SCS", max_iters = 5000)
expect_equal(val, h$expect_obj, tolerance = 1e-2)
})
## @cvxpy NONE
test_that("OSQP: solver options accepted", {
h <- sth_qp_0()
val <- psolve(h$prob, solver = "OSQP", max_iter = 5000)
expect_equal(val, h$expect_obj, tolerance = 1e-4)
})
## @cvxpy NONE
test_that("HiGHS: solver options accepted", {
h <- sth_lp_1()
val <- psolve(h$prob, solver = "HIGHS", time_limit = 60)
expect_equal(val, h$expect_obj, tolerance = 1e-5)
})
# ══════════════════════════════════════════════════════════════════
# Invalid solver for problem type
# ══════════════════════════════════════════════════════════════════
## @cvxpy test_qp_solvers.py::TestQpSolverValidation::test_qp_solver_rejects_soc_cones
test_that("OSQP rejects SOCP problem", {
h <- sth_socp_1()
expect_error(psolve(h$prob, solver = "OSQP"))
})
## @cvxpy NONE
test_that("HiGHS rejects SOCP problem", {
h <- sth_socp_1()
expect_error(psolve(h$prob, solver = "HIGHS"))
})
## @cvxpy test_qp_solvers.py::TestQpSolverValidation::test_qp_solver_rejects_psd_cones
test_that("OSQP rejects SDP problem", {
h <- sth_sdp_1_min()
expect_error(psolve(h$prob, solver = "OSQP"))
})
## @cvxpy NONE
test_that("HiGHS rejects SDP problem", {
h <- sth_sdp_1_min()
expect_error(psolve(h$prob, solver = "HIGHS"))
})
# ══════════════════════════════════════════════════════════════════
# TestAllSolvers — infrastructure tests
# ══════════════════════════════════════════════════════════════════
## @cvxpy test_conic_solvers.py::TestAllSolvers::test_installed_solvers
test_that("AllSolvers: installed_solvers returns character vector of known solvers", {
solvers <- installed_solvers()
expect_type(solvers, "character")
## At minimum, Clarabel is always available (bundled)
expect_true("CLARABEL" %in% solvers)
## All returned names must be valid solver constants
known <- c("CLARABEL", "SCS", "OSQP", "HIGHS", "MOSEK", "GUROBI",
"GLPK", "GLPK_MI", "ECOS", "ECOS_BB", "CPLEX", "CVXOPT", "PIQP")
expect_true(all(solvers %in% known))
})
# ══════════════════════════════════════════════════════════════════
# Clarabel (gap tests)
# ══════════════════════════════════════════════════════════════════
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_nonstandard_name
test_that("Clarabel: nonstandard variable name", {
## Variables with unusual names still solve correctly
x <- Variable(2, name = "my var with spaces")
prob <- Problem(Minimize(sum_entries(x)), list(x >= 1))
val <- psolve(prob, solver = "CLARABEL")
expect_equal(val, 2.0, tolerance = 1e-4)
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_pcp_0
test_that("Clarabel: pcp_0 (socp_0 via power cone path)", {
## CVXPY maps test_clarabel_pcp_0 -> StandardTestSOCPs.test_socp_0('CLARABEL')
h <- sth_socp_0()
verify_obj(h$prob, h$expect_obj, 1e-4, "CLARABEL")
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_pcp_1
test_that("Clarabel: pcp_1 (gap closure)", {
## Already covered as "Clarabel: pcp_1" but annotated differently
h <- sth_pcp_1()
verify_obj(h$prob, h$expect_obj, 1e-3, "CLARABEL")
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_pcp_2
test_that("Clarabel: pcp_2 (gap closure)", {
## Already covered as "Clarabel: pcp_2" but annotated differently
h <- sth_pcp_2()
verify_obj(h$prob, h$expect_obj, 1e-3, "CLARABEL")
})
## @cvxpy test_conic_solvers.py::TestClarabel::test_clarabel_qp_0_linear_obj
test_that("Clarabel: qp_0 with linear objective", {
h <- sth_qp_0_linear_obj()
verify_obj(h$prob, h$expect_obj, 1e-4, "CLARABEL")
x_var <- variables(h$prob)[[1]]
verify_primal(h$prob, x_var, h$expect_x, 1e-3, "CLARABEL")
})
# ══════════════════════════════════════════════════════════════════
# HiGHS (gap tests)
# ══════════════════════════════════════════════════════════════════
## @cvxpy test_conic_solvers.py::TestHIGHS::test_highs_nonstandard_name
test_that("HiGHS: nonstandard variable name", {
x <- Variable(2, name = "my var with spaces")
prob <- Problem(Minimize(sum_entries(x)), list(x >= 1))
val <- psolve(prob, solver = "HIGHS")
expect_equal(val, 2.0, tolerance = 1e-5)
})
## @cvxpy test_conic_solvers.py::TestHIGHS::test_highs_options
test_that("HiGHS: options (CVXPY parity)", {
h <- sth_lp_1()
val <- psolve(h$prob, solver = "HIGHS", time_limit = 60)
expect_equal(val, h$expect_obj, tolerance = 1e-5)
})
## @cvxpy test_conic_solvers.py::TestHIGHS::test_highs_validate_column_name
test_that("HiGHS: validate_column_name", {
skip("HiGHS column name validation not exposed in R highs package")
})
## @cvxpy test_conic_solvers.py::TestHIGHS::test_highs_warm_start
test_that("HiGHS: warm_start", {
skip("HiGHS warm-start blocked: R highs package lacks setSolution()")
})
## @cvxpy test_conic_solvers.py::TestHIGHS::test_highs_written_model_contains_variable_names
test_that("HiGHS: written_model_contains_variable_names", {
skip("HiGHS model export not exposed in R highs package")
})
# ══════════════════════════════════════════════════════════════════
# SCS (gap tests)
# ══════════════════════════════════════════════════════════════════
## @cvxpy test_conic_solvers.py::TestSCS::test_complex_matrices
test_that("SCS: complex matrices", {
## Trace norm of a complex matrix via SDP dual formulation
## CVXPY SOURCE: test_conic_solvers.py TestSCS::test_complex_matrices
## K is a fixed 2x2 complex matrix (np.random.seed(0))
K <- matrix(c(0.5488135+0.4236548i, 0.60276338+0.43758721i,
0.71518937+0.64589411i, 0.54488318+0.891773i), nrow = 2)
## Expected: sum of singular values of K
expected_n1 <- 1.8740804548294105
X <- Variable(c(2, 2), complex = TRUE)
Y <- Variable(c(2, 2), complex = TRUE)
objective <- Minimize(Re(0.5 * matrix_trace(X) + 0.5 * matrix_trace(Y)))
constraints <- list(
PSD(bmat(list(list(X, -Conj(t(K))), list(-K, Y)))),
PSD(X),
PSD(Y)
)
prob <- Problem(objective, constraints)
val <- psolve(prob, solver = "SCS")
expect_equal(val, expected_n1, tolerance = 0.05)
})
## @cvxpy test_conic_solvers.py::TestSCS::test_psd_constraint
test_that("SCS: psd_constraint", {
X <- Variable(c(3, 3), symmetric = TRUE)
prob <- Problem(Minimize(matrix_trace(X)),
list(PSD(X), X[1, 1] >= 1, X[2, 2] >= 1, X[3, 3] >= 1))
val <- psolve(prob, solver = "SCS")
expect_equal(val, 3.0, tolerance = 1e-1)
})
## @cvxpy test_conic_solvers.py::TestSCS::test_quad_obj
test_that("SCS: quad_obj", {
x <- Variable(2)
prob <- Problem(Minimize(sum_squares(x)), list(x[1] >= 1))
val <- psolve(prob, solver = "SCS")
expect_equal(val, 1.0, tolerance = 1e-2)
expect_equal(as.numeric(value(x)), c(1, 0), tolerance = 1e-1)
})
## @cvxpy test_conic_solvers.py::TestSCS::test_quad_obj_with_power
test_that("SCS: quad_obj_with_power", {
x <- Variable(2)
prob <- Problem(Minimize(power(x[1], 2) + power(x[2], 2)),
list(x[1] >= 1))
val <- psolve(prob, solver = "SCS")
expect_equal(val, 1.0, tolerance = 1e-2)
expect_equal(as.numeric(value(x)), c(1, 0), tolerance = 1e-1)
})
## @cvxpy test_conic_solvers.py::TestSCS::test_scs_options
test_that("SCS: solver options (max_iters, eps_abs)", {
h <- sth_lp_1()
val <- psolve(h$prob, solver = "SCS", max_iters = 10000)
expect_equal(val, h$expect_obj, tolerance = 1e-2)
})
## @cvxpy test_conic_solvers.py::TestSCS::test_scs_retry
test_that("SCS: retry on inaccurate solution", {
## SCS can retry with different settings when it gets inaccurate results.
## Use a problem that converges easily to show the mechanism works.
h <- sth_lp_1()
val <- psolve(h$prob, solver = "SCS")
expect_true(status(h$prob) %in% c("optimal", "optimal_inaccurate"))
expect_equal(val, h$expect_obj, tolerance = 1e-1)
})
## @cvxpy test_conic_solvers.py::TestSCS::test_scs_sdp_pcp_1
test_that("SCS: sdp_pcp_1 (mixed SDP + power cone)", {
h <- sth_sdp_pcp_1()
val <- psolve(h$prob, solver = "SCS")
expect_true(is.finite(val))
expect_true(status(h$prob) %in% c("optimal", "optimal_inaccurate"))
})
## @cvxpy test_conic_solvers.py::TestSCS::test_sdp_var
test_that("SCS: sdp_var", {
## SDP variable (symmetric, PSD constrained)
X <- Variable(c(2, 2), PSD = TRUE)
prob <- Problem(Minimize(matrix_trace(X)),
list(X[1, 1] >= 2))
val <- psolve(prob, solver = "SCS")
expect_equal(val, 2.0, tolerance = 1e-1)
})
## @cvxpy test_conic_solvers.py::TestSCS::test_sigma_max
test_that("SCS: sigma_max", {
## Minimize sigma_max (largest singular value)
Y <- Variable(c(2, 3))
prob <- Problem(Minimize(sigma_max(Y)),
list(Y[1, 1] >= 1, Y[2, 2] >= 1))
val <- psolve(prob, solver = "SCS")
expect_true(is.finite(val))
expect_equal(val, 1.0, tolerance = 1e-1)
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.