Nothing
#####
## DO NOT EDIT THIS FILE!! EDIT THE SOURCE INSTEAD: rsrc_tree/lin_ops/lin_utils.R
#####
## CVXPY SOURCE: lin_ops/lin_op.py + lin_ops/lin_utils.py
## R-level LinOp constructors for canonicalize methods
##
## NOTE: These are the "old-style" LinOp objects (plain R lists).
## They are used by canonicalize() methods on Variable/Constant/Parameter.
## The C++ LinOp objects (from LinOp.R) are separate and used by the canon backend.
# -- LinOp type constants ----------------------------------------------
## CVXPY SOURCE: lin_ops/lin_op.py lines 39-119
LINOP_VARIABLE <- "variable"
LINOP_PARAM <- "param"
LINOP_SCALAR_CONST <- "scalar_const"
LINOP_DENSE_CONST <- "dense_const"
LINOP_SPARSE_CONST <- "sparse_const"
LINOP_NO_OP <- "no_op"
LINOP_CONSTANT_ID <- -1L
# -- R-level LinOp constructor -----------------------------------------
## CVXPY SOURCE: lin_ops/lin_op.py::LinOp class
#' Create an R-level LinOp (plain list)
#' @param type Character: one of the LINOP_* constants
#' @param shape Integer vector: dimensions
#' @param args List of child LinOps
#' @param data LinOp data (varies by type)
#' @returns A list with class "LinOp_R"
#' @noRd
LinOp_R <- function(type, shape, args = list(), data = NULL) {
structure(
list(type = type, shape = as.integer(shape), args = args, data = data),
class = "LinOp_R"
)
}
# -- Factory functions -------------------------------------------------
## CVXPY SOURCE: lin_ops/lin_utils.py
#' Create a LinOp for a variable
#' @param shape Integer vector c(nrow, ncol)
#' @param var_id Integer variable id
#' @returns A LinOp_R
#' @noRd
create_var <- function(shape, var_id) {
LinOp_R(LINOP_VARIABLE, shape, args = list(), data = var_id)
}
#' Create a LinOp for a parameter
#' @param shape Integer vector c(nrow, ncol)
#' @param param_id Integer parameter id
#' @returns A LinOp_R
#' @noRd
create_param <- function(shape, param_id) {
LinOp_R(LINOP_PARAM, shape, args = list(), data = param_id)
}
#' Create a LinOp for a constant
#' @param value Numeric value (scalar, matrix, or sparse)
#' @param shape Integer vector c(nrow, ncol)
#' @param sparse Logical: is the value sparse?
#' @returns A LinOp_R
#' @noRd
create_const <- function(value, shape, sparse = FALSE) {
if (all(shape == c(1L, 1L))) {
## Scalar constant -- always extract to plain numeric
op_type <- LINOP_SCALAR_CONST
if (is.matrix(value) || inherits(value, "Matrix")) {
value <- value[1L, 1L]
} else if (length(value) != 1L) {
value <- value[1L]
}
} else if (sparse) {
op_type <- LINOP_SPARSE_CONST
} else {
op_type <- LINOP_DENSE_CONST
}
LinOp_R(op_type, shape, args = list(), data = value)
}
# -- LinOp type constants (operations) --------------------------------
## CVXPY SOURCE: lin_ops/lin_op.py lines 41-102
## These complement the leaf-type constants above (VARIABLE, PARAM, etc.)
## IMPORTANT: These strings must match the operatorType vector in LinOp.R
## after toupper(). LinOp.R has: VARIABLE, PROMOTE, MUL_EXPR, RMUL_EXPR,
## MUL_ELEM, DIV, SUM, NEG, INDEX, TRANSPOSE, SUM_ENTRIES, TRACE,
## RESHAPE_EXPR, DIAG_VEC, DIAG_MAT, UPPER_TRI, CONV, HSTACK, VSTACK,
## SCALAR_CONST, DENSE_CONST, SPARSE_CONST, NO_OP, KRON.
LINOP_PROMOTE <- "promote"
LINOP_MUL <- "mul_expr" # C++ ENUM: MUL_EXPR (not "MUL")
LINOP_RMUL <- "rmul_expr" # C++ ENUM: RMUL_EXPR (not "RMUL")
LINOP_MUL_ELEM <- "mul_elem"
LINOP_DIV <- "div"
LINOP_SUM <- "sum"
LINOP_NEG <- "neg"
LINOP_INDEX <- "index"
LINOP_TRANSPOSE <- "transpose"
LINOP_SUM_ENTRIES <- "sum_entries"
LINOP_RESHAPE <- "reshape_expr" # C++ ENUM: RESHAPE_EXPR (not "RESHAPE")
LINOP_TRACE <- "trace"
LINOP_DIAG_VEC <- "diag_vec"
LINOP_DIAG_MAT <- "diag_mat"
LINOP_UPPER_TRI <- "upper_tri"
LINOP_CONV <- "conv"
LINOP_KRON_R <- "kron" # C++ ENUM: KRON (constant on left)
LINOP_KRON_L <- "kron_l" # C++ ENUM: KRON_L (variable on left)
LINOP_HSTACK <- "hstack"
LINOP_VSTACK <- "vstack"
LINOP_BROADCAST_TO <- "broadcast_to"
# -- LinOp operation functions ----------------------------------------
## CVXPY SOURCE: lin_ops/lin_utils.py
## These create compound LinOp trees used by graph_implementation() methods.
## Named with _linop suffix to avoid collision with atom class names.
#' Test if a LinOp is scalar
#' @param operator A LinOp_R object
#' @returns Logical
#' @noRd
is_scalar_linop <- function(operator) {
## CVXPY: is_scalar(operator) in lin_utils.py line 127-139
prod(operator$shape) == 1L
}
#' Test if a LinOp is a constant type
#' @param operator A LinOp_R object
#' @returns Logical
#' @noRd
is_const_linop <- function(operator) {
## CVXPY: is_const(operator) in lin_utils.py line 142-157
operator$type %in% c(LINOP_SCALAR_CONST, LINOP_SPARSE_CONST,
LINOP_DENSE_CONST, LINOP_PARAM)
}
#' Sum LinOps
#' @param operators List of LinOp_R objects
#' @returns A LinOp_R representing the sum
#' @noRd
sum_expr_linop <- function(operators) {
## CVXPY: sum_expr(operators) in lin_utils.py line 160-173
LinOp_R(LINOP_SUM, operators[[1L]]$shape, operators, NULL)
}
#' Negate a LinOp
#' @param operator A LinOp_R object
#' @returns A LinOp_R representing the negation
#' @noRd
neg_expr_linop <- function(operator) {
## CVXPY: neg_expr(operator) in lin_utils.py line 176-189
LinOp_R(LINOP_NEG, operator$shape, list(operator), NULL)
}
#' Left-multiply by constant: const %*% expr
#' @param lh_op LinOp_R for the constant (left operand, stored as data)
#' @param rh_op LinOp_R for the expression (right operand, stored as arg)
#' @param shape Integer(2) result shape
#' @returns A LinOp_R representing the product
#' @noRd
mul_expr_linop <- function(lh_op, rh_op, shape) {
## CVXPY: mul_expr(lh_op, rh_op, shape) in lin_utils.py line 238-253
## Convention: args = [rh_op], data = lh_op (constant on left)
LinOp_R(LINOP_MUL, shape, list(rh_op), lh_op)
}
#' Right-multiply by constant: expr %*% const
#' @param lh_op LinOp_R for the expression (left operand, stored as arg)
#' @param rh_op LinOp_R for the constant (right operand, stored as data)
#' @param shape Integer(2) result shape
#' @returns A LinOp_R representing the product
#' @noRd
rmul_expr_linop <- function(lh_op, rh_op, shape) {
## CVXPY: rmul_expr(lh_op, rh_op, shape) in lin_utils.py line 256-273
## Convention: args = [lh_op], data = rh_op (constant on right)
LinOp_R(LINOP_RMUL, shape, list(lh_op), rh_op)
}
#' Elementwise multiply: const * expr
#' @param lh_op LinOp_R for the constant (stored as data)
#' @param rh_op LinOp_R for the expression (stored as arg)
#' @returns A LinOp_R representing the elementwise product
#' @noRd
multiply_linop <- function(lh_op, rh_op) {
## CVXPY: multiply(lh_op, rh_op) in lin_utils.py line 276-292
## Shape: max of both operand shapes (broadcasting)
shape <- pmax(lh_op$shape, rh_op$shape)
LinOp_R(LINOP_MUL_ELEM, shape, list(rh_op), lh_op)
}
#' Divide by scalar constant: expr / const
#' @param lh_op LinOp_R for the numerator (stored as arg)
#' @param rh_op LinOp_R for the divisor (stored as data)
#' @returns A LinOp_R representing the quotient
#' @noRd
div_expr_linop <- function(lh_op, rh_op) {
## CVXPY: div_expr(lh_op, rh_op) in lin_utils.py line 331-350
LinOp_R(LINOP_DIV, lh_op$shape, list(lh_op), rh_op)
}
#' Promote scalar to given shape
#' @param operator A scalar LinOp_R
#' @param shape Integer(2) target shape
#' @returns A LinOp_R representing the promotion
#' @noRd
promote_linop <- function(operator, shape) {
## CVXPY: promote(operator, shape) in lin_utils.py line 353-368
LinOp_R(LINOP_PROMOTE, shape, list(operator), NULL)
}
#' Transpose a LinOp
#' @param operator A LinOp_R to transpose
#' @returns A LinOp_R representing the transpose
#' @noRd
transpose_linop <- function(operator) {
## CVXPY: transpose(operator) in lin_utils.py line 451-475
shape <- rev(operator$shape)
LinOp_R(LINOP_TRANSPOSE, shape, list(operator), NULL)
}
#' Index/slice into a LinOp
#' @param operator A LinOp_R to index
#' @param shape Integer(2) result shape after indexing
#' @param keys List containing row and column index information
#' @returns A LinOp_R representing the index operation
#' @noRd
index_linop <- function(operator, shape, keys) {
## CVXPY: index(operator, shape, keys) in lin_utils.py line 411-428
## C++ bridge (set_slice_data) expects data = list(row_idx, col_idx, "key")
## where the trailing "key" marker identifies this as slice data.
LinOp_R(LINOP_INDEX, shape, list(operator), c(keys, list("key")))
}
#' Sum entries of an expression
#' @param operator A LinOp_R to sum
#' @param shape Integer(2) result shape
#' @param axis NULL (sum all), 0 (columns), or 1 (rows)
#' @param keepdims Logical: keep reduced dimensions?
#' @returns A LinOp_R representing the sum of entries
#' @noRd
sum_entries_linop <- function(operator, shape, axis = NULL, keepdims = NULL) {
## CVXPY: sum_entries(operator, shape, axis, keepdims) in lin_utils.py line 377-392
## NOTE: axis/keepdims are resolved at R level (different LinOp structures for
## axis=0/1 vs NULL). C++ SUM_ENTRIES handler doesn't use data, so pass NULL.
LinOp_R(LINOP_SUM_ENTRIES, shape, list(operator), data = NULL)
}
#' Reshape a LinOp
#' @param operator A LinOp_R to reshape
#' @param shape Integer(2) target shape
#' @returns A LinOp_R representing the reshaped expression
#' @noRd
reshape_linop <- function(operator, shape) {
## CVXPY: reshape(operator, shape) in lin_utils.py line 478-493
LinOp_R(LINOP_RESHAPE, shape, list(operator), NULL)
}
# -- Phase 3 LinOp constructors ------------------------------------
## CVXPY SOURCE: lin_ops/lin_utils.py
#' Sum the diagonal entries of a matrix (trace)
#' @param operator A LinOp_R (square matrix)
#' @returns A LinOp_R of shape (1,1) representing the trace
#' @noRd
trace_linop <- function(operator) {
## CVXPY: trace(operator) in lin_utils.py line 395-408
LinOp_R(LINOP_TRACE, c(1L, 1L), list(operator), NULL)
}
#' Convert a vector to a diagonal matrix
#' @param operator A LinOp_R (vector)
#' @param k Integer diagonal offset (0 = main diagonal)
#' @returns A LinOp_R representing the diagonal matrix
#' @noRd
diag_vec_linop <- function(operator, k = 0L) {
## CVXPY: diag_vec(operator, k) in lin_utils.py line 496-513
rows <- operator$shape[1L] + abs(k)
shape <- c(rows, rows)
LinOp_R(LINOP_DIAG_VEC, as.integer(shape), list(operator), as.integer(k))
}
#' Extract the diagonal of a matrix as a vector
#' @param operator A LinOp_R (square matrix)
#' @param k Integer diagonal offset (0 = main diagonal)
#' @returns A LinOp_R representing the diagonal vector
#' @noRd
diag_mat_linop <- function(operator, k = 0L) {
## CVXPY: diag_mat(operator, k) in lin_utils.py line 516-532
shape <- c(operator$shape[1L] - abs(k), 1L)
LinOp_R(LINOP_DIAG_MAT, as.integer(shape), list(operator), as.integer(k))
}
#' Vectorized strict upper triangle of a square matrix
#' @param operator A LinOp_R (square matrix)
#' @returns A LinOp_R representing the vectorized upper triangle
#' @noRd
upper_tri_linop <- function(operator) {
## CVXPY: upper_tri(operator) in lin_utils.py line 535-550
entries <- operator$shape[1L] * operator$shape[2L]
shape <- c((entries - operator$shape[1L]) %/% 2L, 1L)
LinOp_R(LINOP_UPPER_TRI, as.integer(shape), list(operator), NULL)
}
#' Concatenate operators horizontally
#' @param operators List of LinOp_R objects
#' @param shape Integer(2) resulting shape
#' @returns A LinOp_R representing horizontal concatenation
#' @noRd
hstack_linop <- function(operators, shape) {
## CVXPY: hstack(operators, shape) in lin_utils.py line 553-568
LinOp_R(LINOP_HSTACK, as.integer(shape), operators, NULL)
}
#' Concatenate operators vertically
#' @param operators List of LinOp_R objects
#' @param shape Integer(2) resulting shape
#' @returns A LinOp_R representing vertical concatenation
#' @noRd
vstack_linop <- function(operators, shape) {
## CVXPY: vstack(operators, shape) in lin_utils.py line 571-586
LinOp_R(LINOP_VSTACK, as.integer(shape), operators, NULL)
}
#' Kronecker product (right operand is variable)
#' @param lh_op LinOp_R for the constant (stored as data)
#' @param rh_op LinOp_R for the variable (stored as arg)
#' @param shape Integer(2) resulting shape
#' @returns A LinOp_R representing the Kronecker product
#' @noRd
kron_r_linop <- function(lh_op, rh_op, shape) {
## CVXPY: kron_r(lh_op, rh_op, shape) in lin_utils.py line 295-310
LinOp_R(LINOP_KRON_R, as.integer(shape), list(rh_op), lh_op)
}
#' Kronecker product (left operand is variable)
#' @param lh_op LinOp_R for the variable (stored as arg)
#' @param rh_op LinOp_R for the constant (stored as data)
#' @param shape Integer(2) resulting shape
#' @returns A LinOp_R representing the Kronecker product
#' @noRd
kron_l_linop <- function(lh_op, rh_op, shape) {
## CVXPY: kron_l(lh_op, rh_op, shape) in lin_utils.py line 313-328
LinOp_R(LINOP_KRON_L, as.integer(shape), list(lh_op), rh_op)
}
#' 1D discrete convolution
#' @param lh_op LinOp_R for the constant (stored as data)
#' @param rh_op LinOp_R for the variable (stored as arg)
#' @param shape Integer(2) resulting shape
#' @returns A LinOp_R representing the convolution
#' @noRd
conv_linop <- function(lh_op, rh_op, shape) {
## CVXPY: conv(lh_op, rh_op, shape) in lin_utils.py line 431-448
LinOp_R(LINOP_CONV, as.integer(shape), list(rh_op), lh_op)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.