Nothing
#####
## DO NOT EDIT THIS FILE!! EDIT THE SOURCE INSTEAD: rsrc_tree/atoms/sign.R
#####
## CVXPY SOURCE: atoms/sign.py
## Sign -- sign of a scalar variable: -1 if x <= 0, +1 if x > 0.
## A DQCP atom (both quasiconvex AND quasiconcave) on scalar input;
## not DQCP on vector input. Numerically a step function with zero
## subgradient on each plateau; CVXPY returns _grad = [None] and we
## mirror via .grad returning list(NULL).
##
## User-facing dispatch: base R's `sign()` on a CVXR Expression is
## routed through the Math group handler in
## rsrc_tree/zzz_R_specific/operators.R, which delegates here.
## `expr_sign(x)` is the unrelated *curvature-query* generic and is
## not changed by this atom (see CLAUDE.md note about the rename).
# ===================================================================
# Sign -- DQCP atom (scalar): step function sign of an Expression
# ===================================================================
Sign <- new_class("Sign", parent = Atom, package = "CVXR",
constructor = function(x) {
if (FALSE) new_object(S7_object()) ## S7 static-check guard
x <- as_expr(x)
id <- next_expr_id()
obj <- .fast_new(Sign, S7_object(),
id = as.integer(id),
.cache = new.env(parent = emptyenv()),
args = list(x),
shape = .shape(x) ## mirrors CVXPY shape_from_args: same as arg
)
validate_arguments(obj)
obj
}
)
## shape_from_args mirrors CVXPY:36-38: returns the argument's shape.
method(shape_from_args, Sign) <- function(x) .arg_shape(x)
## sign_from_args mirrors CVXPY:41-44: the atom's own sign is the
## argument's sign (nonneg if arg is nonneg; nonpos if arg is nonpos).
method(sign_from_args, Sign) <- function(x) {
list(is_nonneg = is_nonneg(.args(x)[[1L]]),
is_nonpos = is_nonpos(.args(x)[[1L]]))
}
## Sign is neither convex nor concave (CVXPY:46-54).
method(is_atom_convex, Sign) <- function(x) FALSE
method(is_atom_concave, Sign) <- function(x) FALSE
## Sign is not log-log either.
method(is_atom_log_log_convex, Sign) <- function(x) FALSE
method(is_atom_log_log_concave, Sign) <- function(x) FALSE
## DQCP only when the argument is scalar (CVXPY:56-63).
## For vector input, is_dqcp() on the containing Problem will
## correctly return FALSE because both flags are FALSE here.
method(is_atom_quasiconvex, Sign) <- function(x) is_scalar(.args(x)[[1L]])
method(is_atom_quasiconcave, Sign) <- function(x) is_scalar(.args(x)[[1L]])
## Step function: neither monotone increasing nor decreasing globally
## (CVXPY:65-73).
method(is_incr, Sign) <- function(x, idx, ...) FALSE
method(is_decr, Sign) <- function(x, idx, ...) FALSE
## CVXPY:31-35 numeric: +1 where val > 0, -1 elsewhere (including 0).
method(numeric_value, Sign) <- function(x, values, ...) {
val <- values[[1L]]
out <- val
out[val > 0] <- 1.0
out[val <= 0] <- -1.0
out
}
## Subgradient: undefined. Mirrors CVXPY:75-76 (_grad returns [None]).
## Returning list(NULL) propagates NULL up the chain rule for every
## variable that flows through Sign.
method(.grad, Sign) <- function(x, values, ...) {
list(NULL)
}
method(get_data, Sign) <- function(x) NULL
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.