R/152_reductions_dcp2cone_canonicalizers_cumsum_canon.R

Defines functions cumsum_canon

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

## CVXPY SOURCE: reductions/eliminate_pwl/canonicalizers/cumsum_canon.py
## cumsum(X) -> Y where Y[first] == X[first], X[rest] == Y[rest] - Y[prev]


cumsum_canon <- function(expr, args, solver_context = NULL) {
  X <- args[[1L]]
  axis <- expr@axis
  shape <- .shape(expr)

  ## Handle axis=NULL: flatten to a column, then treat as axis=2.
  ## R deviation (1.9.3 plan decision D2): flatten COLUMN-MAJOR to match the
  ## atom (.cumsum_shape, numeric_value); CVXPY flattens in C order.
  ## CVXPY v1.9.3 fix: #3398 -- an X that is already a column is not reshaped.
  if (is.null(axis)) {
    if (.shape(X)[2L] != 1L) {
      X <- Reshape(X, c(expr_size(X), 1L), order = "F")
    }
    shape <- c(expr_size(X), 1L)
    axis <- 2L
  }

  ## If only one element along this axis, cumsum is identity
  if (shape[3L - axis] == 1L) {
    return(list(X, list()))
  }

  ## CVXPY v1.9.3 fix: #3398 -- X constant or parameter-affine: an auxiliary
  ## Variable would make cumsum(p) %*% x a Variable product and break DPP.
  ## Apply the cumsum operator to the column-major vec instead
  ## (cumsum_canon.py:45-55, _cumsum_axis_op at cumsum.py:41-57).
  if (length(variables(X)) == 0L) {
    op <- .cumsum_axis_op(shape, axis)
    if (shape[2L] == 1L) {
      return(list(Constant(op) %*% X, list()))
    }
    flat <- Reshape(X, c(expr_size(X), 1L), order = "F")
    return(list(Reshape(Constant(op) %*% flat, shape, order = "F"), list()))
  }

  Y <- Variable(shape = shape)

  ## Build index slices for the axis
  n <- shape[3L - axis]
  if (axis == 2L) {
    ## axis=0: slice along rows
    ## Y[1, ] == X[1, ]
    ## X[2:n, ] == Y[2:n, ] - Y[1:(n-1), ]
    constr <- list(
      X[2L:n, ] == Y[2L:n, ] - Y[1L:(n - 1L), ],
      Y[1L, ] == X[1L, ]
    )
  } else {
    ## axis=1: slice along columns
    ## Y[, 1] == X[, 1]
    ## X[, 2:n] == Y[, 2:n] - Y[, 1:(n-1)]
    constr <- list(
      X[, 2L:n] == Y[, 2L:n] - Y[, 1L:(n - 1L)],
      Y[, 1L] == X[, 1L]
    )
  }

  list(Y, constr)
}

method(dcp_canonicalize, Cumsum) <- cumsum_canon
method(has_dcp_canon, Cumsum) <- 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.