Nothing
#####
## DO NOT EDIT THIS FILE!! EDIT THE SOURCE INSTEAD: rsrc_tree/atoms/elementwise/elementwise.R
#####
## CVXPY SOURCE: atoms/elementwise/elementwise.py
## Elementwise -- abstract base class for elementwise atoms
##
## Elementwise atoms operate on each element independently and produce
## output with the same shape as the broadcasted arguments.
Elementwise <- new_class("Elementwise", parent = Atom, package = "CVXR",
constructor = function(args, id = NULL) {
if (FALSE) new_object(S7_object()) ## S7 static-check guard
if (is.null(id)) id <- next_expr_id()
args <- lapply(args, as_expr)
if (length(args) == 0L) {
cli_abort("No arguments given to {.cls Elementwise}.")
}
## shape_from_args: elementwise uses sum_shapes (broadcasting)
shape <- sum_shapes(lapply(args, function(a) .shape(a)))
obj <- .fast_new(Elementwise, S7_object(),
id = as.integer(id),
.cache = new.env(parent = emptyenv()),
args = args,
shape = shape
)
validate_arguments(obj)
obj
}
)
# -- shape_from_args: broadcasting ---------------------------------
## CVXPY SOURCE: elementwise.py lines 30-33
method(shape_from_args, Elementwise) <- function(x) {
sum_shapes(lapply(.args(x), function(a) .shape(a)))
}
# -- validate_arguments: check broadcastable shapes ----------------
## CVXPY SOURCE: elementwise.py lines 35-41
method(validate_arguments, Elementwise) <- function(x) {
## Verify shapes are broadcastable (sum_shapes will abort on mismatch)
sum_shapes(lapply(.args(x), function(a) .shape(a)))
## Call Atom's validate_arguments (rejects complex arguments)
## NOTE: Can't use NextMethod() with S7 generics -- call Atom's method directly
if (.any_args(x, is_complex)) {
cli_abort("Arguments to {.cls {class(x)[[1L]]}} cannot be complex.")
}
invisible(NULL)
}
# -- is_symmetric --------------------------------------------------
## CVXPY SOURCE: elementwise.py:44-48 (CVXPY 1.9.2)
## 1.9.2 guarded this with `if self.ndim == 2 and shape[0] == shape[1]`,
## falling back to the Expression default otherwise, because indexing
## `shape[1]` raised IndexError on a scalar or 1-D argument. CVXR needs no
## such guard and is left as-is: an R shape is ALWAYS length 2 (a scalar is
## c(1,1), a vector c(n,1)), so the subscript cannot go out of range, and
## the non-square branch already returns FALSE, which is what the upstream
## fallback yields for every non-scalar. Verified against all five
## assertions of test_elementwise_is_symmetric.
method(is_symmetric, Elementwise) <- function(x) {
symm_args <- .all_args(x, is_symmetric)
.shape(x)[1L] == .shape(x)[2L] && symm_args
}
# -- Helper: promote LinOp if needed ------------------------------
## CVXPY SOURCE: elementwise.py lines 63-82
## Used by graph_implementation in subclasses
.elemwise_promote <- function(arg, shape) {
if (!identical(arg$shape, as.integer(shape))) {
promote_linop(arg, shape)
} else {
arg
}
}
# -- Helper: elementwise grad to diagonal sparse matrix -----------
## CVXPY SOURCE: elementwise.py:50-61 (elementwise.elemwise_grad_to_diag).
## Takes a same-shape derivative array `value`, ravels it in column-major
## order, and embeds it as the diagonal of a (rows x cols) sparse matrix.
## Used by every elementwise atom's .grad hook.
.elemwise_grad_to_diag <- function(value, rows, cols) {
## Column-major ravel: as.numeric() on a base-R array/matrix flattens
## by column, matching numpy's ravel(order='F').
v <- as.numeric(value)
n <- length(v)
Matrix::sparseMatrix(
i = seq_len(n),
j = seq_len(n),
x = v,
dims = c(as.integer(rows), as.integer(cols)),
repr = "C"
)
}
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.