R/153_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]]

  ## CVXPY dotsort_canon.py:30-33 -- a Constant W is grouped by unique value; a
  ## parametric W (a Parameter, or parameter-affine such as 2 * p) cannot be
  ## grouped, so it stays symbolic with unit counts and the compiled tensor
  ## depends on the parameter (DPP fast path). Reading value(w) here instead
  ## baked the number in: correct answers, but no parameter in the compiled
  ## problem, so no cached tensor and a full re-canonicalization per solve.
  if (.s7_is(w, Constant)) {
    w_val <- as.numeric(value(w))
    uw <- unique(sort(w_val))
    w_counts <- as.numeric(table(factor(w_val, levels = uw)))
    n_w <- length(uw)
    w_row <- Constant(matrix(uw, nrow = 1L))
  } else {
    n_w <- expr_size(w)
    w_counts <- rep(1, n_w)
    w_row <- t(.cvxr_vec(w))
  }

  n_x <- expr_size(x)

  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)
  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 Oct. 19, 2026, 5:07 p.m.