R/134_reductions_reduction.R

Defines functions reduction_retrieve reduction_reduce

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

## CVXPY SOURCE: reductions/reduction.py
## Reduction -- abstract base class for reductions
## Also: InverseData -- stores data for solution retrieval


# -- InverseData -----------------------------------------------------
## CVXPY SOURCE: reductions/inverse_data.py
## Stores variable/constraint ID mappings for inverting a reduction.

InverseData <- new_class("InverseData", package = "CVXR",
  properties = list(
    id_map       = class_list,    # var.id -> (offset, size)
    var_offsets  = class_list,    # var.id -> offset
    x_length     = class_integer, # total variable length
    var_shapes   = class_list,    # var.id -> shape
    param_shapes = class_list,    # param.id -> shape
    param_to_size = class_list,   # param.id -> size (includes CONSTANT_ID -> 1)
    param_id_map = class_list,    # param.id -> column offset in tensor
    cons_id_map  = class_environment, # orig constraint id -> canon constraint id
    .extra       = class_environment  # mutable store for ConeMatrixStuffing etc.
  ),
  constructor = function(problem) {
    vars_ <- variables(problem)

    ## CVXPY SOURCE: inverse_data.py lines 45-56
    id_map <- list()
    var_offsets <- list()
    var_shapes <- list()
    vert_offset <- 0L
    for (v in vars_) {
      vid <- as.character(v@id)
      sz <- expr_size(v)
      var_shapes[[vid]] <- v@shape
      var_offsets[[vid]] <- vert_offset
      id_map[[vid]] <- c(vert_offset, sz)
      vert_offset <- vert_offset + sz
    }

    ## CVXPY SOURCE: inverse_data.py lines 31-43
    ## Build parameter mappings for DPP tensor construction.
    ## param_to_size always starts with CONSTANT_ID -> 1.
    ## param_id_map: parameter columns are first, CONSTANT_ID is last.
    param_shapes <- list()
    param_to_size <- list()
    param_id_map <- list()
    param_to_size[[as.character(LINOP_CONSTANT_ID)]] <- 1L
    offset <- 0L
    for (p in parameters(problem)) {
      pid <- as.character(p@id)
      param_shapes[[pid]] <- p@shape
      param_to_size[[pid]] <- expr_size(p)
      param_id_map[[pid]] <- offset
      offset <- offset + expr_size(p)
    }
    param_id_map[[as.character(LINOP_CONSTANT_ID)]] <- offset

    new_object(S7_object(),
      id_map        = id_map,
      var_offsets   = var_offsets,
      x_length      = as.integer(vert_offset),
      var_shapes    = var_shapes,
      param_shapes  = param_shapes,
      param_to_size = param_to_size,
      param_id_map  = param_id_map,
      cons_id_map   = new.env(hash = TRUE, parent = emptyenv()),
      .extra        = new.env(hash = TRUE, parent = emptyenv())
    )
  }
)

# -- Reduction base class --------------------------------------------
## CVXPY SOURCE: reductions/reduction.py lines 20-253

Reduction <- new_class("Reduction", package = "CVXR",
  properties = list(
    .cache = class_environment
  ),
  constructor = function() {
    new_object(S7_object(),
      .cache = new.env(parent = emptyenv())
    )
  }
)

## accepts: subclasses must override
method(reduction_accepts, Reduction) <- function(x, problem, ...) {
  cli_abort("Class {.cls {class(x)[[1L]]}} must implement {.fn reduction_accepts}.")
}

## apply: subclasses must override
method(reduction_apply, Reduction) <- function(x, problem, ...) {
  cli_abort("Class {.cls {class(x)[[1L]]}} must implement {.fn reduction_apply}.")
}

## invert: subclasses must override
method(reduction_invert, Reduction) <- function(x, solution, inverse_data, ...) {
  cli_abort("Class {.cls {class(x)[[1L]]}} must implement {.fn reduction_invert}.")
}

## update_parameters: default no-op (overridden by Dgp2Dcp for DGP+DPP)
## CVXPY SOURCE: reduction.py -- base class does nothing
method(update_parameters, Reduction) <- function(x, problem, ...) {
  invisible(NULL)
}

## DEFERRED: Derivative chain-rule methods (reduction.py lines 87-167)
## These 4 methods enable backward()/derivative() on Problem via chain rule
## through the reduction pipeline. Deferred because the derivative API depends
## on diffcp (no R equivalent). See notes/derivative_api_deferred.md.
##
## param_backward(x, param, dparams) -- gradient chain rule (backward pass)
## param_forward(x, param, delta) -- delta chain rule (forward pass)
## var_backward(x, var, value) -- transform variable gradient (default: identity)
## var_forward(x, var, value) -- transform variable delta (default: identity)

## reduce: convenience -- apply and cache result
## CVXPY SOURCE: reduction.py lines 169-192
reduction_reduce <- function(x, problem) {
  if (!is.null(x@.cache$emitted_problem)) {
    return(x@.cache$emitted_problem)
  }
  result <- reduction_apply(x, problem)
  x@.cache$emitted_problem <- result[[1L]]
  x@.cache$retrieval_data <- result[[2L]]
  result[[1L]]
}

## retrieve: convenience -- invert cached result
## CVXPY SOURCE: reduction.py lines 194-215
reduction_retrieve <- function(x, solution) {
  if (is.null(x@.cache$retrieval_data)) {
    cli_abort("{.fn reduction_reduce} must be called before {.fn reduction_retrieve}.")
  }
  reduction_invert(x, solution, x@.cache$retrieval_data)
}

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.