R/123_constraints_nonpos.R

#####
## DO NOT EDIT THIS FILE!! EDIT THE SOURCE INSTEAD: rsrc_tree/constraints/nonpos.R
#####

## CVXPY SOURCE: constraints/nonpos.py
## NonPos (x <= 0), NonNeg (x >= 0), Inequality (x <= y) constraints

# ===================================================================
# NonPos -- constraint of the form x <= 0
# ===================================================================

#' Create a Non-Positive Constraint
#'
#' Constrains an expression to be non-positive elementwise: \eqn{x \le 0}.
#'
#' @param expr A CVXR expression.
#' @param constr_id Optional integer constraint ID.
#' @returns A \code{NonPos} constraint object.
#' @seealso \code{\link{NonNeg}}, \code{\link{Inequality}}
#' @export
NonPos <- new_class("NonPos", parent = Constraint, package = "CVXR",
  constructor = function(expr, constr_id = NULL) {
    expr <- as_expr(expr)
    if (is.null(constr_id)) constr_id <- next_expr_id()
    shape <- expr@shape
    dvars <- list(Variable(shape))
    obj <- new_object(S7_object(),
      id    = as.integer(constr_id),
      .cache = new.env(parent = emptyenv()),
      args  = list(expr),
      dual_variables = dvars,
      shape = shape,
      .label = ""
    )
    ## CVXPY SOURCE: nonpos.py lines 55-59
    if (!is_real(obj@args[[1L]])) {
      cli_abort("Input to {.cls NonPos} must be real.")
    }
    obj
  }
)

# -- expr_name ----------------------------------------------------
## CVXPY SOURCE: nonpos.py line 61-62

method(expr_name, NonPos) <- function(x) {
  sprintf("%s <= 0", expr_name(x@args[[1L]]))
}

# -- is_dcp -------------------------------------------------------
## CVXPY SOURCE: nonpos.py lines 64-69
## A NonPos constraint is DCP if its argument is convex.

method(is_dcp, NonPos) <- function(x) is_convex(x@args[[1L]])

# -- is_dqcp ------------------------------------------------------
## CVXPY SOURCE: nonpos.py lines 74-75

method(is_dqcp, NonPos) <- function(x) is_quasiconvex(x@args[[1L]])

# -- residual -----------------------------------------------------
## CVXPY SOURCE: nonpos.py lines 77-87
## Returns max(expr.value, 0) or NULL.

method(residual, NonPos) <- function(x) {
  val <- value(x@args[[1L]])
  if (is.null(val)) return(NULL)
  pmax(val, 0)
}

# -- violation: L2 norm of residual -------------------------------
## CVXPY SOURCE: nonpos.py lines 89-95

method(violation, NonPos) <- function(x) {
  res <- residual(x)
  if (is.null(res)) {
    cli_abort("Cannot compute the violation of a constraint whose expression has no value.")
  }
  sqrt(sum(res^2))
}


# ===================================================================
# NonNeg -- constraint of the form x >= 0
# ===================================================================
## CVXPY SOURCE: nonpos.py lines 98-154

#' Create a Non-Negative Constraint
#'
#' Constrains an expression to be non-negative elementwise: \eqn{x \ge 0}.
#'
#' @param expr A CVXR expression.
#' @param constr_id Optional integer constraint ID.
#' @returns A \code{NonNeg} constraint object.
#' @seealso \code{\link{NonPos}}, \code{\link{Inequality}}
#' @export
NonNeg <- new_class("NonNeg", parent = Constraint, package = "CVXR",
  constructor = function(expr, constr_id = NULL) {
    expr <- as_expr(expr)
    if (is.null(constr_id)) constr_id <- next_expr_id()
    shape <- expr@shape
    dvars <- list(Variable(shape))
    obj <- new_object(S7_object(),
      id    = as.integer(constr_id),
      .cache = new.env(parent = emptyenv()),
      args  = list(expr),
      dual_variables = dvars,
      shape = shape,
      .label = ""
    )
    ## CVXPY SOURCE: nonpos.py lines 115-118
    if (!is_real(obj@args[[1L]])) {
      cli_abort("Input to {.cls NonNeg} must be real.")
    }
    obj
  }
)

# -- expr_name ----------------------------------------------------
## CVXPY SOURCE: nonpos.py lines 120-121

method(expr_name, NonNeg) <- function(x) {
  sprintf("%s >= 0", expr_name(x@args[[1L]]))
}

# -- is_dcp -------------------------------------------------------
## CVXPY SOURCE: nonpos.py lines 123-128
## A NonNeg constraint is DCP if its argument is concave.

method(is_dcp, NonNeg) <- function(x) is_concave(x@args[[1L]])

# -- is_dqcp ------------------------------------------------------
## CVXPY SOURCE: nonpos.py lines 133-134

method(is_dqcp, NonNeg) <- function(x) is_quasiconcave(x@args[[1L]])

# -- residual -----------------------------------------------------
## CVXPY SOURCE: nonpos.py lines 136-146
## Returns abs(min(expr.value, 0)) or NULL.

method(residual, NonNeg) <- function(x) {
  val <- value(x@args[[1L]])
  if (is.null(val)) return(NULL)
  abs(pmin(val, 0))
}

# -- violation: L2 norm of residual -------------------------------
## CVXPY SOURCE: nonpos.py lines 148-154

method(violation, NonNeg) <- function(x) {
  res <- residual(x)
  if (is.null(res)) {
    cli_abort("Cannot compute the violation of a constraint whose expression has no value.")
  }
  sqrt(sum(res^2))
}


# ===================================================================
# Inequality -- constraint of the form lhs <= rhs
# ===================================================================
## CVXPY SOURCE: nonpos.py lines 157-246

#' Create an Inequality Constraint
#'
#' Constrains the left-hand side to be less than or equal to the
#' right-hand side elementwise: \eqn{lhs \le rhs}. Typically created
#' via the \code{<=} operator on CVXR expressions.
#'
#' @param lhs A CVXR expression (left-hand side).
#' @param rhs A CVXR expression (right-hand side).
#' @param constr_id Optional integer constraint ID.
#' @returns An \code{Inequality} constraint object.
#' @seealso \code{\link{Equality}}, \code{\link{NonPos}}, \code{\link{NonNeg}}
#' @export
Inequality <- new_class("Inequality", parent = Constraint, package = "CVXR",
  properties = list(
    .expr = new_property(class = class_any, default = NULL)
  ),
  constructor = function(lhs, rhs, constr_id = NULL) {
    lhs <- as_expr(lhs)
    rhs <- as_expr(rhs)
    expr_diff <- lhs - rhs  ## Uses Phase 2D operator dispatch
    ## CVXPY SOURCE: nonpos.py lines 182-183
    if (is_complex(expr_diff)) {
      cli_abort("Inequality constraints cannot be complex.")
    }
    if (is.null(constr_id)) constr_id <- next_expr_id()
    shape <- expr_diff@shape
    ## Dual variables based on expr shape (not individual args)
    ## CVXPY SOURCE: nonpos.py lines 186-187
    dvars <- list(Variable(shape))
    new_object(S7_object(),
      id    = as.integer(constr_id),
      .cache = new.env(parent = emptyenv()),
      args  = list(lhs, rhs),
      dual_variables = dvars,
      shape = shape,
      .label = "",
      .expr = expr_diff
    )
  }
)

# -- expr_name ----------------------------------------------------
## CVXPY SOURCE: nonpos.py lines 193-194

method(expr_name, Inequality) <- function(x) {
  sprintf("%s <= %s", expr_name(x@args[[1L]]), expr_name(x@args[[2L]]))
}

# -- is_dcp -------------------------------------------------------
## CVXPY SOURCE: nonpos.py lines 206-211
## An inequality is DCP if (lhs - rhs) is convex.

method(is_dcp, Inequality) <- function(x) is_convex(x@.expr)

# -- is_dqcp ------------------------------------------------------
## CVXPY SOURCE: nonpos.py lines 229-233

method(is_dqcp, Inequality) <- function(x) {
  is_dcp(x) ||
    (is_quasiconvex(x@args[[1L]]) && is_constant(x@args[[2L]])) ||
    (is_constant(x@args[[1L]]) && is_quasiconcave(x@args[[2L]]))
}

# -- residual -----------------------------------------------------
## CVXPY SOURCE: nonpos.py lines 235-245
## Returns max(expr.value, 0) or NULL where expr = lhs - rhs.

## is_dgp: lhs is log-log convex AND rhs is log-log concave
## CVXPY SOURCE: nonpos.py lines 213-219
## G9: Must use x@args, NOT x@.expr
method(is_dgp, Inequality) <- function(x) {
  is_log_log_convex(x@args[[1L]]) && is_log_log_concave(x@args[[2L]])
}

method(residual, Inequality) <- function(x) {
  val <- value(x@.expr)
  if (is.null(val)) return(NULL)
  pmax(val, 0)
}

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.