R/126_constraints_psd.R

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

## CVXPY SOURCE: constraints/psd.py
## PSD -- Positive Semidefinite constraint

#' Create a Positive Semidefinite Constraint
#'
#' Constrains a square matrix expression to be positive semidefinite (PSD):
#' \eqn{X \succeq 0}. The expression must be square.
#'
#' @param expr A CVXR expression representing a square matrix.
#' @param constr_id Optional integer constraint ID.
#' @returns A \code{PSD} constraint object.
#' @export
PSD <- new_class("PSD", parent = Cone, package = "CVXR",
  constructor = function(expr, constr_id = NULL) {
    expr <- as_expr(expr)

    ## CVXPY SOURCE: psd.py lines 49-54
    ## Must be square matrix
    if (length(expr@shape) != 2L || expr@shape[1L] != expr@shape[2L]) {
      cli_abort("Non-square matrix in positive semidefinite constraint.")
    }

    if (is.null(constr_id)) constr_id <- next_expr_id()
    shape <- expr@shape

    args <- list(expr)
    dvars <- list(Variable(expr@shape))

    new_object(S7_object(),
      id    = as.integer(constr_id),
      .cache = new.env(parent = emptyenv()),
      args  = args,
      dual_variables = dvars,
      shape = shape,
      .label = ""
    )
  }
)

# -- expr_name ----------------------------------------------------
## CVXPY SOURCE: psd.py lines 57-58

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

# -- is_dcp -------------------------------------------------------
## CVXPY SOURCE: psd.py lines 60-66

method(is_dcp, PSD) <- function(x) {
  is_affine(x@args[[1L]])
}

# -- is_dgp -------------------------------------------------------
## CVXPY SOURCE: psd.py lines 68-69

method(is_dgp, PSD) <- function(x) FALSE

# -- num_cones ----------------------------------------------------

method(num_cones, PSD) <- function(x) 1L

# -- cone_sizes ---------------------------------------------------
## Returns n (the matrix dimension) -- used by solvers for PSD cone

method(cone_sizes, PSD) <- function(x) {
  x@args[[1L]]@shape[1L]
}

# -- residual -----------------------------------------------------
## CVXPY SOURCE: psd.py lines 74-86
## Returns -min(0, eigenvalues of symmetric part)

method(residual, PSD) <- function(x) {
  X_val <- value(x@args[[1L]])
  if (is.null(X_val)) return(NULL)

  ## Symmetric part
  sym <- (X_val + t(X_val)) / 2
  min_eig <- min(.eigvalsh(sym, only_values = TRUE)$values)
  max(0, -min_eig)
}

# -- dual_cone ----------------------------------------------------
## CVXPY SOURCE: psd.py lines 87-98
## PSD is self-dual

method(dual_cone, PSD) <- function(x, ...) {
  args <- list(...)
  if (length(args) == 0L) {
    PSD(x@dual_variables[[1L]])
  } else {
    PSD(args[[1L]])
  }
}

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.