Nothing
context("ECOS Lifecycle API")
## Helper: load a test problem and construct sparse G matrix
load_problem <- function(name) {
d <- readRDS(system.file("testdata", name, package = "ECOSolveR"))
G <- Matrix::sparseMatrix(x = d$Gpr, i = d$Gir, p = d$Gjc,
dims = c(d$m, d$n), index1 = FALSE)
dims <- lapply(list(l = d$l, q = d$q, e = d$e), as.integer)
if (!is.null(d$Apr) && length(d$Apr) > 0) {
A <- Matrix::sparseMatrix(x = d$Apr, i = d$Air, p = d$Ajc,
dims = c(d$p, d$n), index1 = FALSE)
b <- d$b
} else {
A <- NULL
b <- numeric(0)
}
list(c = d$c, G = G, h = d$h, dims = dims, A = A, b = b, raw = d)
}
## -----------------------------------------------------------------
## 1. Basic lifecycle: setup -> solve -> cleanup
## -----------------------------------------------------------------
test_that("basic lifecycle works", {
prob <- load_problem("update_data_1.RDS")
ws <- ECOS_setup(c = prob$c, G = prob$G, h = prob$h,
dims = prob$dims, A = prob$A, b = prob$b)
on.exit(ECOS_cleanup(ws), add = TRUE)
expect_s3_class(ws, "ecos_workspace")
res <- ECOS_solve(ws)
expect_equal(res$retcodes[["exitFlag"]], 0L)
expect_equal(res$infostring, "Optimal solution found")
})
## -----------------------------------------------------------------
## 2. Results match ECOS_csolve
## -----------------------------------------------------------------
test_that("lifecycle results match ECOS_csolve", {
prob <- load_problem("update_data_1.RDS")
ws <- ECOS_setup(c = prob$c, G = prob$G, h = prob$h,
dims = prob$dims, A = prob$A, b = prob$b)
on.exit(ECOS_cleanup(ws), add = TRUE)
res_lc <- ECOS_solve(ws)
res_ref <- ECOS_csolve(c = prob$c, G = prob$G, h = prob$h,
dims = prob$dims, A = prob$A, b = prob$b)
expect_equal(res_lc$x, res_ref$x, tolerance = 1e-8)
expect_equal(res_lc$y, res_ref$y, tolerance = 1e-8)
expect_equal(res_lc$s, res_ref$s, tolerance = 1e-8)
expect_equal(res_lc$z, res_ref$z, tolerance = 1e-8)
expect_equal(res_lc$retcodes, res_ref$retcodes)
})
## -----------------------------------------------------------------
## 3. Update + re-solve produces different solution
## -----------------------------------------------------------------
test_that("update and re-solve works", {
prob <- load_problem("update_data_1.RDS")
ws <- ECOS_setup(c = prob$c, G = prob$G, h = prob$h,
dims = prob$dims, A = prob$A, b = prob$b)
on.exit(ECOS_cleanup(ws), add = TRUE)
res1 <- ECOS_solve(ws)
expect_equal(res1$retcodes[["exitFlag"]], 0L)
## Perturb h and update
new_h <- prob$h + 0.5
ECOS_update(ws, h = new_h)
res2 <- ECOS_solve(ws)
expect_equal(res2$retcodes[["exitFlag"]], 0L)
## Solutions should differ
expect_false(isTRUE(all.equal(res1$x, res2$x)))
## Compare with a fresh ECOS_csolve using perturbed h
res_ref <- ECOS_csolve(c = prob$c, G = prob$G, h = new_h,
dims = prob$dims, A = prob$A, b = prob$b)
expect_equal(res2$x, res_ref$x, tolerance = 1e-6)
})
## -----------------------------------------------------------------
## 4. Wrong-length update errors
## -----------------------------------------------------------------
test_that("wrong-length update vectors error", {
prob <- load_problem("update_data_1.RDS")
ws <- ECOS_setup(c = prob$c, G = prob$G, h = prob$h,
dims = prob$dims, A = prob$A, b = prob$b)
on.exit(ECOS_cleanup(ws), add = TRUE)
expect_error(ECOS_update(ws, h = numeric(1)), "h length")
expect_error(ECOS_update(ws, c = numeric(1)), "c length")
expect_error(ECOS_update(ws, b = numeric(1)), "b length")
expect_error(ECOS_update(ws, Gpr = numeric(1)), "Gpr length")
expect_error(ECOS_update(ws, Apr = numeric(1)), "Apr length")
})
## -----------------------------------------------------------------
## 5. Use-after-cleanup errors
## -----------------------------------------------------------------
test_that("use after cleanup errors", {
prob <- load_problem("update_data_1.RDS")
ws <- ECOS_setup(c = prob$c, G = prob$G, h = prob$h,
dims = prob$dims, A = prob$A, b = prob$b)
ECOS_cleanup(ws)
expect_error(ECOS_solve(ws), "cleaned up")
expect_error(ECOS_update(ws, h = prob$h), "cleaned up")
## Double cleanup should be safe (no error)
expect_silent(ECOS_cleanup(ws))
})
## -----------------------------------------------------------------
## 6. GC finalizer doesn't crash
## -----------------------------------------------------------------
test_that("GC finalizer does not crash", {
prob <- load_problem("update_data_1.RDS")
ws <- ECOS_setup(c = prob$c, G = prob$G, h = prob$h,
dims = prob$dims, A = prob$A, b = prob$b)
rm(ws)
expect_silent(gc())
})
## -----------------------------------------------------------------
## 7. Per-solve control override
## -----------------------------------------------------------------
test_that("per-solve control override works", {
prob <- load_problem("update_data_1.RDS")
ws <- ECOS_setup(c = prob$c, G = prob$G, h = prob$h,
dims = prob$dims, A = prob$A, b = prob$b)
on.exit(ECOS_cleanup(ws), add = TRUE)
## Solve with maxit=1 -> should hit MAXIT
res_maxit <- ECOS_solve(ws, control = ecos.control(maxit = 1L))
expect_equal(res_maxit$retcodes[["exitFlag"]], -1L)
## Re-solve with default settings -> should find optimal
res_opt <- ECOS_solve(ws, control = ecos.control())
expect_equal(res_opt$retcodes[["exitFlag"]], 0L)
})
## -----------------------------------------------------------------
## 8. Partial updates (update only c, only h)
## -----------------------------------------------------------------
test_that("partial updates work correctly", {
prob <- load_problem("update_data_1.RDS")
ws <- ECOS_setup(c = prob$c, G = prob$G, h = prob$h,
dims = prob$dims, A = prob$A, b = prob$b)
on.exit(ECOS_cleanup(ws), add = TRUE)
res_orig <- ECOS_solve(ws)
## Update only c
new_c <- prob$c * 2
ECOS_update(ws, c = new_c)
res_c <- ECOS_solve(ws)
## Optimal value should roughly double since c is scaled
expect_false(isTRUE(all.equal(res_orig$summary[["pcost"]],
res_c$summary[["pcost"]])))
## Update only h back to original, keeping scaled c
ECOS_update(ws, h = prob$h)
res_h <- ECOS_solve(ws)
expect_equal(res_h$retcodes[["exitFlag"]], 0L)
})
## -----------------------------------------------------------------
## 9. Problem without A (no equality constraints)
## -----------------------------------------------------------------
test_that("lifecycle works without equality constraints", {
prob <- load_problem("MPC01_1.RDS")
ws <- ECOS_setup(c = prob$c, G = prob$G, h = prob$h,
dims = prob$dims)
on.exit(ECOS_cleanup(ws), add = TRUE)
res <- ECOS_solve(ws)
expect_equal(res$retcodes[["exitFlag"]], 0L)
ref <- ECOS_csolve(c = prob$c, G = prob$G, h = prob$h,
dims = prob$dims)
expect_equal(res$x, ref$x, tolerance = 1e-6)
## Update h and re-solve
new_h <- prob$h + 0.01
ECOS_update(ws, h = new_h)
res2 <- ECOS_solve(ws)
expect_false(isTRUE(all.equal(res$x, res2$x)))
})
## -----------------------------------------------------------------
## 10. Print method
## -----------------------------------------------------------------
test_that("print method works", {
prob <- load_problem("MPC01_1.RDS")
ws <- ECOS_setup(c = prob$c, G = prob$G, h = prob$h,
dims = prob$dims)
on.exit(ECOS_cleanup(ws), add = TRUE)
expect_output(print(ws), "ecos_workspace")
})
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.