R/026_expressions_constants_parameter.R

Defines functions is_param_free is_param_affine

Documented in is_param_affine is_param_free

#####
## DO NOT EDIT THIS FILE!! EDIT THE SOURCE INSTEAD: rsrc_tree/expressions/constants/parameter.R
#####

## CVXPY SOURCE: expressions/constants/parameter.py
## Parameter -- a mutable constant whose value can be set after problem creation

#' Create a Parameter
#'
#' Constructs a parameter whose numeric value can be changed without
#' re-canonicalizing the problem. Parameters are treated as constants for
#' DCP purposes but their value can be updated between solves.
#'
#' @param shape Integer vector of length 1 or 2 giving the parameter
#'   dimensions. A scalar \code{n} is interpreted as \code{c(n, 1)}.
#'   Defaults to \code{c(1, 1)} (scalar).
#' @param name Optional character string name. If \code{NULL}, an automatic
#'   name \code{"param<id>"} is generated.
#' @param value Optional initial numeric value.
#' @param id Optional integer ID.
#' @param latex_name Optional character string giving a custom LaTeX name for
#'   use in visualizations. For example, \code{"\\\\gamma"}.
#'   If \code{NULL} (default), visualizations auto-generate a LaTeX name.
#' @param ... Additional attributes: \code{nonneg}, \code{nonpos}, etc.
#' @returns A \code{Parameter} object (inherits from \code{Leaf} and
#'   \code{Expression}).
#'
#' @examples
#' p <- Parameter()
#' value(p) <- 5
#' p_vec <- Parameter(3, nonneg = TRUE)
#' gamma <- Parameter(1, name = "gamma", latex_name = "\\gamma")
#'
#' @export
Parameter <- new_class("Parameter", parent = Leaf, package = "CVXR",
  properties = list(
    .name = new_property(class = class_character),
    .latex_name = new_property(class = class_character)
  ),
  constructor = function(shape = c(1L, 1L), name = NULL, value = NULL,
                         id = NULL, latex_name = NULL, ...) {
    ## Normalize scalar shape
    if (is.numeric(shape) && length(shape) == 1L) {
      shape <- c(as.integer(shape), 1L)
    }
    shape <- validate_shape(shape)

    if (is.null(id)) id <- next_expr_id()

    ## Auto-name deferred: compute lazily in expr_name() to avoid paste0 overhead.
    ## CVXPY SOURCE: parameter.py lines 54-57
    nm <- if (!is.null(name)) name else ""

    ## LaTeX name for visualizations (visualization-only, never touches solver)
    lnm <- if (is.null(latex_name)) "" else as.character(latex_name)

    ## Build leaf attributes from ...
    attrs <- do.call(.build_leaf_attrs, c(list(shape = shape), list(...)))

    obj <- new_object(S7_object(),
      id = as.integer(id),
      .cache = new.env(parent = emptyenv()),
      shape = shape,
      .value = NULL,
      attributes = attrs,
      args = list(),
      .name = nm,
      .latex_name = lnm
    )

    ## Assign value if provided (goes through validation)
    if (!is.null(value)) {
      value(obj) <- value
    }

    obj
  }
)

# -- expr_name ---------------------------------------------------------

method(expr_name, Parameter) <- function(x) {
  nm <- x@.name
  if (nchar(nm) == 0L) {
    nm <- x@.cache$.auto_name
    if (is.null(nm)) {
      nm <- paste0(PARAM_PREFIX, x@id)
      x@.cache$.auto_name <- nm
    }
  }
  nm
}

# -- is_constant: TRUE normally, FALSE in DPP scope --------------------
## CVXPY SOURCE: parameter.py lines 73-76

method(is_constant, Parameter) <- function(x) !dpp_scope_active()

# -- DPP helper functions (module-level, not generics) -----------------
## CVXPY SOURCE: parameter.py lines 24-32

#' Check if Expression is Parameter-Affine
#'
#' Returns \code{TRUE} if the expression is affine in parameters
#' and contains no decision variables.
#'
#' @param expr A CVXR expression.
#' @returns Logical scalar.
#' @keywords internal
is_param_affine <- function(expr) {
  with_dpp_scope({
    length(variables(expr)) == 0L && is_affine(expr)
  })
}

#' Check if Expression is Parameter-Free
#'
#' Returns \code{TRUE} if the expression contains no parameters.
#'
#' @param expr A CVXR expression.
#' @returns Logical scalar.
#' @keywords internal
is_param_free <- function(expr) {
  length(parameters(expr)) == 0L
}

# -- parameters: returns self ------------------------------------------
## CVXPY SOURCE: parameter.py lines 89-92

method(parameters, Parameter) <- function(x) list(x)

# -- value<-: validate, store, and clear cache -------------------------
## CVXPY SOURCE: parameter.py (via Leaf.value setter + cache clear)

method(`value<-`, Parameter) <- function(x, value) {
  validated <- .validate_leaf_value(x, value)
  x@.value <- validated
  cache_clear(x)                     # Clears curvature/sign cache
  x@.cache$leaf_value <- validated   # Restore after clear (reference-semantic)
  x
}

# -- get_data ----------------------------------------------------------
## CVXPY SOURCE: parameter.py lines 65-68

method(get_data, Parameter) <- function(x) {
  list(x@shape, expr_name(x), value(x), x@id, x@attributes)
}

# -- grad: empty (parameters are treated as constants) -----------------
## CVXPY SOURCE: parameter.py lines 78-87

method(grad, Parameter) <- function(x) list()

# -- canonicalize ------------------------------------------------------
## CVXPY SOURCE: parameter.py lines 94-101

method(canonicalize, Parameter) <- function(x) {
  obj <- create_param(x@shape, x@id)
  list(obj, list())
}

# -- print -------------------------------------------------------------

method(print, Parameter) <- function(x, ...) {
  cat(sprintf("Parameter((%s), %s)\n",
              paste(x@shape, collapse = ", "),
              expr_name(x)))
  invisible(x)
}

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.