R/022_expressions_expression.R

Defines functions is_log_log_constant expr_H

Documented in expr_H

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

## CVXPY SOURCE: expressions/expression.py
## Expression -- base class for mathematical expressions


Expression <- new_class("Expression", parent = Canonical, package = "CVXR",
  properties = list(
    shape = new_property(class = class_integer, default = c(1L, 1L))
  )
)

## Register with S4 so that method([, Expression) and similar primitives work.
## Required before using S7::method() for S4 generics like `[`.
S4_register(Expression)

# -- Curvature methods (cached) ----------------------------------------
## CVXPY SOURCE: expression.py line 318-322

## is_constant(): 0 in shape OR all args constant
## Uses .dpp_key() so DPP-scope results are cached separately.
method(is_constant, Expression) <- function(x) {
  key <- .dpp_key("is_constant")
  cached <- cache_get(x, key)
  if (!cache_miss(cached)) return(cached)
  result <- (0L %in% x@shape) || .all_args(x, is_constant)
  cache_set(x, key, result)
  result
}

## is_affine(): constant OR (convex AND concave)
## CVXPY SOURCE: expression.py line 325-328
method(is_affine, Expression) <- function(x) {
  key <- .dpp_key("is_affine")
  cached <- cache_get(x, key)
  if (!cache_miss(cached)) return(cached)
  result <- is_constant(x) || (is_convex(x) && is_concave(x))
  cache_set(x, key, result)
  result
}

## is_convex() / is_concave() -- abstract on Expression, concrete on Leaf/Atom
## Default implementation: FALSE (subclasses override)
method(is_convex, Expression) <- function(x) FALSE
method(is_concave, Expression) <- function(x) FALSE

## is_dcp(): convex OR concave
## CVXPY SOURCE: expression.py line 343-360
method(is_dcp, Expression) <- function(x) {
  key <- .dpp_key("is_dcp")
  cached <- cache_get(x, key)
  if (!cache_miss(cached)) return(cached)
  result <- is_convex(x) || is_concave(x)
  cache_set(x, key, result)
  result
}

## is_dpp(): check DPP compliance (DCP context + atom-level compatibility)
## CVXPY SOURCE: atom.py lines 229-237
## Extended: recursively checks all child atoms are DPP-compatible too.
## This catches atoms like Kron/Conv whose C++ handlers can't process
## PARAM LinOp nodes even though the expression is structurally DCP.
method(is_dpp, Expression) <- function(x) {
  if (!with_dpp_scope(is_dcp(x))) return(FALSE)
  for (arg in x@args) {
    if (!is_dpp(arg)) return(FALSE)
  }
  TRUE
}

# -- Sign methods (cached) --------------------------------------------
## is_nonneg() / is_nonpos() -- abstract, defaults FALSE
method(is_nonneg, Expression) <- function(x) FALSE
method(is_nonpos, Expression) <- function(x) FALSE

## is_zero(): nonneg AND nonpos
## CVXPY SOURCE: expression.py line 503-506
method(is_zero, Expression) <- function(x) {
  cached <- cache_get(x, "is_zero")
  if (!cache_miss(cached)) return(cached)
  result <- is_nonneg(x) && is_nonpos(x)
  cache_set(x, "is_zero", result)
  result
}

## expr_sign(): returns sign string
## CVXPY SOURCE: expression.py::sign property
method(expr_sign, Expression) <- function(x) {
  expr_sign_str(x)
}

# -- Matrix property defaults -----------------------------------------

## is_symmetric: default -> scalar only
## CVXPY SOURCE: expression.py line 464-468
method(is_symmetric, Expression) <- function(x) expr_is_scalar(x)

## is_psd / is_nsd: default FALSE
## CVXPY SOURCE: expression.py lines 436-446
method(is_psd, Expression) <- function(x) FALSE
method(is_nsd, Expression) <- function(x) FALSE

## is_pos: default FALSE (overridden by Leaf and Constant)
method(is_pos, Expression) <- function(x) FALSE

## is_complex / is_imag: default FALSE
## CVXPY SOURCE: expression.py (abstract on Expression, concrete on Leaf)
method(is_complex, Expression) <- function(x) FALSE
method(is_imag, Expression) <- function(x) FALSE

## is_hermitian: default -> real AND symmetric
## CVXPY SOURCE: expression.py line 431-434
method(is_hermitian, Expression) <- function(x) is_real(x) && is_symmetric(x)

## is_skew_symmetric: default -> FALSE
## CVXPY SOURCE: expression.py line 470-473
method(is_skew_symmetric, Expression) <- function(x) FALSE

## is_real: default -> not complex
## CVXPY SOURCE: expression.py
method(is_real, Expression) <- function(x) !is_complex(x)

# -- Conjugate-transpose (.H in CVXPY) ------------------------------
## CVXPY SOURCE: expression.py lines 604-611
## In Python: expr.H property. In R: expr_H(x) function.
## For real expressions, this is just t(x).
## For complex expressions, this is Conj(t(x)).

#' Conjugate-Transpose of an Expression
#'
#' Equivalent to CVXPY's \code{.H} property. For real expressions, returns
#' \code{t(x)}. For complex expressions, returns \code{Conj(t(x))}.
#'
#' @param x A CVXR Expression.
#' @returns The conjugate-transpose expression.
#' @export
expr_H <- function(x) {
  if (is_real(x)) t(x) else Conj_(t(x))
}

## is_quasiconvex / is_quasiconcave / is_quasilinear / is_dqcp: defaults
## CVXPY SOURCE: expression.py lines 411-429
method(is_quasiconvex, Expression) <- function(x) is_convex(x)
method(is_quasiconcave, Expression) <- function(x) is_concave(x)
method(is_quasilinear, Expression) <- function(x) is_quasiconvex(x) && is_quasiconcave(x)
method(is_dqcp, Expression) <- function(x) {
  cached <- cache_get(x, "is_dqcp")
  if (!cache_miss(cached)) return(cached)
  result <- is_quasiconvex(x) || is_quasiconcave(x)
  cache_set(x, "is_dqcp", result)
  result
}

## is_quadratic / has_quadratic_term / is_pwl / is_qpwa: defaults
## CVXPY SOURCE: expression.py lines 448-484
method(is_quadratic, Expression) <- function(x) is_constant(x)
method(has_quadratic_term, Expression) <- function(x) is_constant(x)
method(is_pwl, Expression) <- function(x) is_constant(x)
method(is_qpwa, Expression) <- function(x) is_quadratic(x) || is_pwl(x)

## is_log_log_constant: elementwise strictly positive constant
## CVXPY SOURCE: expression.py lines 362-371
## NOT a generic -- same logic for all Expression types.
is_log_log_constant <- function(x) {
  if (!is_constant(x)) return(FALSE)
  ## Constant and Parameter: use is_pos() (attribute-based)
  if (S7_inherits(x, Constant) || S7_inherits(x, Parameter)) {
    return(is_pos(x))
  }
  ## Other constant expressions: check actual value > 0
  v <- value(x)
  !is.null(v) && all(v > 0)
}

## is_log_log_*: default FALSE (overridden by atoms)
## CVXPY SOURCE: expression.py lines 380-415
method(is_log_log_convex, Expression) <- function(x) FALSE
method(is_log_log_concave, Expression) <- function(x) FALSE
method(is_log_log_affine, Expression) <- function(x) {
  is_log_log_constant(x) || (is_log_log_convex(x) && is_log_log_concave(x))
}

## is_dgp: checks whether the expression is log-log DCP
## CVXPY SOURCE: expression.py lines 392-403
method(is_dgp, Expression) <- function(x) {
  is_log_log_convex(x) || is_log_log_concave(x)
}

# -- value / grad / domain -- abstract defaults ------------------------

method(value, Expression) <- function(x) {
  cli_abort("value() not implemented for this expression type.")
}

method(grad, Expression) <- function(x) {
  cli_abort("grad() not implemented for this expression type.")
}

method(domain, Expression) <- function(x) list()

# -- expr_name default ------------------------------------------------

method(expr_name, Expression) <- function(x) {
  sprintf("Expression(%s, %s, (%s))",
          expr_curvature(x), expr_sign_str(x),
          paste(x@shape, collapse = ", "))
}

# -- print method -----------------------------------------------------

method(print, Expression) <- function(x, ...) {
  cat(sprintf("%s\n", 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.