Nothing
#####
## DO NOT EDIT THIS FILE!! EDIT THE SOURCE INSTEAD: rsrc_tree/reductions/discrete2mixedint/valinvec2mixedint.R
#####
## CVXPY SOURCE: reductions/discrete2mixedint/valinvec2mixedint.py
## Valinvec2mixedint -- canonicalize FiniteSet constraints to MIP form
##
## Two formulations:
## 1. Inequality form: sorted differences + binary ordering variables
## 2. Equality form (default): one-hot binary indicators (MOSEK cookbook)
# -- Inequality formulation --------------------------------------
## CVXPY SOURCE: valinvec2mixedint.py lines 27-41
.exprval_in_vec_ineq <- function(expr_flat, vec_val) {
n_entries <- expr_size(expr_flat)
vec_sorted <- sort(vec_val)
d <- diff(vec_sorted)
len_d <- length(d)
## repeated_d: (n_entries, len_d) matrix -- each row is d
repeated_d <- matrix(rep(d, each = n_entries), nrow = n_entries, ncol = len_d)
z <- Variable(c(n_entries, len_d), boolean = TRUE)
## main: expr == vec_sorted[1] + sum_per_row(d * z)
main_con <- expr_flat == vec_sorted[1L] + sum_entries(multiply(Constant(repeated_d), z), axis = 1L)
## aux: z[, 2:] <= z[, 1:(end-1)] (ordering constraint)
if (len_d > 1L) {
aux_cons <- list(z[, 2:len_d] <= z[, 1:(len_d - 1L)])
} else {
aux_cons <- list()
}
list(main_con = main_con, aux_cons = aux_cons)
}
# -- Equality formulation ----------------------------------------
## CVXPY SOURCE: valinvec2mixedint.py lines 44-54
## Reference: https://docs.mosek.com/modeling-cookbook/mio.html#fixed-set-of-values
.exprval_in_vec_eq <- function(expr_flat, vec_val) {
n_entries <- expr_size(expr_flat)
len_vec <- length(vec_val)
## repeated_vec: (n_entries, len_vec) matrix -- each row is vec_val
repeated_vec <- matrix(rep(vec_val, each = n_entries), nrow = n_entries, ncol = len_vec)
z <- Variable(c(n_entries, len_vec), boolean = TRUE)
## main: sum_per_row(vec * z) == expr
main_con <- sum_entries(multiply(Constant(repeated_vec), z), axis = 1L) == expr_flat
## aux: sum_per_row(z) == 1 (exactly one selected)
aux_cons <- list(sum_entries(z, axis = 1L) == 1)
list(main_con = main_con, aux_cons = aux_cons)
}
# -- Canonicalizer -----------------------------------------------
## CVXPY SOURCE: valinvec2mixedint.py lines 64-73
.finite_set_canon <- function(expr, args, ...) {
vec_val <- as.numeric(value(expr@vec))
## Deduplicate
vec_val <- unique(vec_val)
if (length(vec_val) == 1L) {
## Single element: simple equality
return(list(expr@expre == vec_val[1L], list()))
}
## Flatten expression
expr_flat <- Reshape(expr@expre, c(expr_size(expr@expre), 1L))
## Choose formulation
formulation_fn <- if (expr@.ineq_form) .exprval_in_vec_ineq else .exprval_in_vec_eq
result <- formulation_fn(expr_flat, vec_val)
list(result$main_con, result$aux_cons)
}
# -- Valinvec2mixedint class -------------------------------------
## CVXPY SOURCE: valinvec2mixedint.py lines 76-87
## Register FiniteSet canonicalizer via S7 dispatch.
## FiniteSet is NOT a DCP atom, so has_dcp_canon remains FALSE.
method(dcp_canonicalize, FiniteSet) <- .finite_set_canon
Valinvec2mixedint <- new_class("Valinvec2mixedint", parent = Canonicalization, package = "CVXR",
constructor = function(problem = NULL) {
id <- as.integer(next_expr_id())
new_object(S7_object(),
id = id,
.cache = new.env(parent = emptyenv()),
problem = problem
)
}
)
## accepts: TRUE if any FiniteSet constraint present
## CVXPY SOURCE: valinvec2mixedint.py lines 77-78
method(reduction_accepts, Valinvec2mixedint) <- function(x, problem, ...) {
any(vapply(problem@constraints, function(c) S7_inherits(c, FiniteSet), logical(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.