Nothing
#####
## DO NOT EDIT THIS FILE!! EDIT THE SOURCE INSTEAD: rsrc_tree/reductions/solvers/conic_solvers/ecos_bb_conif.R
#####
## CVXPY SOURCE: reductions/solvers/conic_solvers/ecos_bb_conif.py
## ECOS_BB (branch-and-bound) solver interface for mixed-integer problems.
##
## Inherits from ECOS_Solver, overrides:
## - MIP_CAPABLE = TRUE
## - solver_name -> "ECOS_BB"
## - solve_via_data: passes boolean/integer variable indices to ECOS_csolve()
## - reduction_invert: skips duals when problem is MIP
##
## R interface: ECOSolveR::ECOS_csolve(bool_vars = ..., int_vars = ...)
# -- ECOS_BB_Solver class ------------------------------------------
## CVXPY SOURCE: ecos_bb_conif.py lines 26-114
ECOS_BB_Solver <- new_class("ECOS_BB_Solver", parent = ECOS_Solver,
package = "CVXR",
constructor = function() {
new_object(S7_object(),
.cache = new.env(parent = emptyenv()),
MIP_CAPABLE = TRUE,
BOUNDED_VARIABLES = FALSE,
SUPPORTED_CONSTRAINTS = list(Zero, NonNeg, SOC, ExpCone),
EXP_CONE_ORDER = c(0L, 2L, 1L),
REQUIRES_CONSTR = FALSE
)
}
)
method(solver_name, ECOS_BB_Solver) <- function(x) ECOS_BB_SOLVER
# -- ECOS_BB solve_via_data ----------------------------------------
## CVXPY SOURCE: ecos_bb_conif.py lines 82-114
## Same as ECOS but additionally passes bool_vars and int_vars.
method(solve_via_data, ECOS_BB_Solver) <- function(x, data, warm_start = FALSE, verbose = FALSE,
solver_opts = list(), ...) {
if (!requireNamespace("ECOSolveR", quietly = TRUE)) {
cli_abort("Package {.pkg ECOSolveR} is required but not installed.")
}
cones <- dims_to_solver_dict_ecos(data[[SD_DIMS]])
## Split solver data into eq (Zero) and ineq parts
zero_dim <- data[[SD_DIMS]]@zero
total_rows <- nrow(data[[SD_A]])
## Equality constraints
if (zero_dim > 0L) {
A_eq <- data[[SD_A]][seq_len(zero_dim), , drop = FALSE]
b_eq <- data[[SD_B]][seq_len(zero_dim)]
} else {
A_eq <- NULL
b_eq <- numeric(0)
}
## Inequality constraints
if (zero_dim < total_rows) {
G <- data[[SD_A]][(zero_dim + 1L):total_rows, , drop = FALSE]
h <- data[[SD_B]][(zero_dim + 1L):total_rows]
} else {
G <- NULL
h <- numeric(0)
}
## Ensure dgCMatrix for ECOSolveR
if (!is.null(G) && !inherits(G, "dgCMatrix")) {
G <- methods::as(G, "dgCMatrix")
}
if (!is.null(A_eq) && !inherits(A_eq, "dgCMatrix")) {
A_eq <- methods::as(A_eq, "dgCMatrix")
}
## Handle mi_verbose option (CVXPY ecos_bb_conif.py lines 93-97)
mi_verbose <- verbose
if ("mi_verbose" %in% names(solver_opts)) {
mi_verbose <- solver_opts[["mi_verbose"]]
solver_opts[["mi_verbose"]] <- NULL
}
## Build control list
## ECOSolveR uses UPPERCASE control names (FEASTOL, MI_MAX_ITERS, ...),
## but CVXPY convention is lowercase (feastol, mi_max_iters, ...).
ctrl <- ECOSolveR::ecos.control()
ctrl[["VERBOSE"]] <- as.integer(verbose)
for (opt_name in names(solver_opts)) {
ctrl[[toupper(opt_name)]] <- solver_opts[[opt_name]]
}
## Integer/boolean variable indices (already 1-based from R pipeline)
bool_vars <- data[["bool_idx"]]
int_vars <- data[["int_idx"]]
if (is.null(bool_vars)) bool_vars <- integer(0)
if (is.null(int_vars)) int_vars <- integer(0)
## Call ECOS with MIP extensions
result <- ECOSolveR::ECOS_csolve(
c = data[[SD_C]],
G = G,
h = h,
dims = cones,
A = A_eq,
b = b_eq,
bool_vars = bool_vars,
int_vars = int_vars,
control = ctrl
)
result
}
# -- ECOS_BB reduction_invert -------------------------------------
## CVXPY SOURCE: ecos_bb_conif.py lines 49-80
## Same as ECOS but no duals for MIP problems.
method(reduction_invert, ECOS_BB_Solver) <- function(x, solution, inverse_data, ...) {
attr_list <- list()
## Extract status from exit flag
exit_flag <- solution$retcodes[["exitFlag"]]
if (is.null(exit_flag)) exit_flag <- solution$retcodes[[1L]]
status <- ECOS_STATUS_MAP[[as.character(exit_flag)]]
if (is.null(status)) status <- SOLVER_ERROR
## Timing attributes
if (!is.null(solution$timing[["tsolve"]]))
attr_list[[RK_SOLVE_TIME]] <- solution$timing[["tsolve"]]
if (!is.null(solution$timing[["tsetup"]]))
attr_list[[RK_SETUP_TIME]] <- solution$timing[["tsetup"]]
iter_val <- solution$retcodes[["iter"]]
if (!is.null(iter_val))
attr_list[[RK_NUM_ITERS]] <- iter_val
if (status %in% SOLUTION_PRESENT) {
primal_val <- solution$summary[["pcost"]]
opt_val <- primal_val + inverse_data[[SD_OFFSET]]
primal_vars <- list()
primal_vars[[as.character(inverse_data[[SOLVER_VAR_ID]])]] <- solution$x
## No duals for MIP problems (CVXPY ecos_bb_conif.py lines 62-76)
dual_vars <- NULL
if (!isTRUE(inverse_data[["is_mip"]])) {
dual_vars <- get_dual_values(
solution$z,
extract_dual_value,
inverse_data[[SOLVER_NEQ_CONSTR]]
)
## Permute ExpCone duals
for (con in inverse_data[[SOLVER_NEQ_CONSTR]]) {
if (S7_inherits(con, ExpCone)) {
cid <- as.character(con@id)
n_cones <- num_cones(con)
perm <- expcone_permutor(n_cones, c(0L, 2L, 1L))
dual_vars[[cid]] <- dual_vars[[cid]][perm]
}
}
eq_duals <- get_dual_values(
solution$y,
extract_dual_value,
inverse_data[[SOLVER_EQ_CONSTR]]
)
dual_vars <- c(dual_vars, eq_duals)
}
## CVXPY passes dual_vars=None for MIP; we use list() for R consistency
if (is.null(dual_vars)) dual_vars <- list()
Solution(status, opt_val, primal_vars, dual_vars, attr_list)
} else {
failure_solution(status, attr_list)
}
}
# -- print ---------------------------------------------------------
method(print, ECOS_BB_Solver) <- function(x, ...) {
cat("ECOS_BB_Solver()\n")
invisible(x)
}
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.