R/035_atoms_affine_axis_aff_atom.R

#####
## DO NOT EDIT THIS FILE!! EDIT THE SOURCE INSTEAD: rsrc_tree/atoms/affine/axis_aff_atom.R
#####

## CVXPY SOURCE: atoms/affine/sum.py (Sum inherits AxisAtom, AffAtom)
## AxisAffAtom -- resolves multiple inheritance of AxisAtom + AffAtom
##
## In CVXPY, Sum(AxisAtom, AffAtom) uses Python MI with MRO.
## In R/S7, we use single inheritance from AffAtom and compose AxisAtom
## behavior (axis, keepdims, axis-aware shape) directly.
##
## AxisAffAtom = AffAtom + axis/keepdims properties
## Subclasses: SumEntries, Cumsum


AxisAffAtom <- new_class("AxisAffAtom", parent = AffAtom, package = "CVXR",
  properties = list(
    axis     = class_any,     # NULL (reduce all) or integer
    keepdims = class_logical  # whether to keep reduced dimensions
  ),
  constructor = function(expr, axis = NULL, keepdims = FALSE) {
    expr <- as_expr(expr)
    if (!is.null(axis)) axis <- as.integer(axis)
    keepdims <- as.logical(keepdims)

    ## Compute shape using axis-aware reduction (shared with AxisAtom)
    shape <- .axis_shape(expr@shape, axis, keepdims)

    obj <- new_object(S7_object(),
      id       = next_expr_id(),
      .cache   = new.env(parent = emptyenv()),
      args     = list(expr),
      shape    = shape,
      axis     = axis,
      keepdims = keepdims
    )
    validate_arguments(obj)
    obj
  }
)

# -- shape_from_args --------------------------------------------------
## Delegate to same function used by AxisAtom

method(shape_from_args, AxisAffAtom) <- function(x) {
  .axis_shape(x@args[[1L]]@shape, x@axis, x@keepdims)
}

# -- get_data --------------------------------------------------------
## Same as AxisAtom: returns [axis, keepdims]

method(get_data, AxisAffAtom) <- function(x) {
  list(x@axis, x@keepdims)
}

# -- validate_arguments ----------------------------------------------
## Like AxisAtom but allows complex (from AffAtom)

method(validate_arguments, AxisAffAtom) <- function(x) {
  if (!is.null(x@axis)) {
    ndim <- 2L
    axis <- x@axis
    if (axis < 0L) axis <- axis + ndim + 1L
    if (axis < 1L || axis > ndim) {
      .axis_out_of_bounds_error(x@axis, ndim)
    }
  }
  ## AffAtom allows complex -- no further validation needed
  invisible(NULL)
}

# -- expr_name: include axis/keepdims data ---------------------------

method(expr_name, AxisAffAtom) <- function(x) {
  data <- get_data(x)
  data_str <- vapply(data, function(d) {
    if (is.null(d)) "NULL" else as.character(d)
  }, character(1))
  arg_strs <- vapply(x@args, expr_name, character(1))
  sprintf("%s(%s)", class(x)[[1L]], paste(c(arg_strs, data_str), collapse = ", "))
}

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.