R/142_reductions_dcp2cone_canonicalizers_dotsort_canon.R

Defines functions dotsort_canon

#####
## DO NOT EDIT THIS FILE!! EDIT THE SOURCE INSTEAD: rsrc_tree/reductions/dcp2cone/canonicalizers/dotsort_canon.R
#####

## CVXPY SOURCE: reductions/eliminate_pwl/canonicalizers/dotsort_canon.py
## dotsort(x, w) via LP relaxation:
##   minimize  sum(t) + q %*% w_counts
##   s.t.      outer(vec(x), vec(w_unique)) <= t + q,  t >= 0


dotsort_canon <- function(expr, args, solver_context = NULL) {
  x <- args[[1L]]
  w <- args[[2L]]

  ## W is always Constant (validated in Dotsort constructor)
  w_val <- as.numeric(value(w))
  uw <- unique(sort(w_val))
  w_counts <- as.numeric(table(factor(w_val, levels = uw)))

  n_x <- expr_size(x)
  n_w <- length(uw)

  t <- Variable(c(n_x, 1L))
  q <- Variable(c(1L, n_w))

  obj <- sum_entries(t) + q %*% Constant(matrix(w_counts, ncol = 1L))

  ## outer product: vec(x) %*% t(vec(w_unique))
  x_col <- .cvxr_vec(x)
  w_row <- Constant(matrix(uw, nrow = 1L))
  outer_prod <- x_col %*% w_row

  ## Broadcast t + q: t is (n_x, 1), q is (1, n_w)
  ## Need (n_x, n_w) matrix: t %*% ones(1, n_w) + ones(n_x, 1) %*% q
  ones_row <- Constant(matrix(1, 1L, n_w))
  ones_col <- Constant(matrix(1, n_x, 1L))
  rhs <- t %*% ones_row + ones_col %*% q

  constraints <- list(outer_prod <= rhs, t >= 0)
  list(obj, constraints)
}

method(dcp_canonicalize, Dotsort) <- dotsort_canon
method(has_dcp_canon, Dotsort) <- function(expr) TRUE

Try the CVXR package in your browser

Any scripts or data that you put into this service are public.

CVXR documentation built on March 6, 2026, 9:10 a.m.