Nothing
#####
## DO NOT EDIT THIS FILE!! EDIT THE SOURCE INSTEAD: rsrc_tree/atoms/perspective.R
#####
## CVXPY SOURCE: atoms/perspective.py
## Perspective -- perspective transform of convex/concave scalar expression
##
## Given a scalar expression f and nonneg variable s, the perspective is
## the function t >= s*f(x/s). This exploits the cone representation of
## f's epigraph to build a lifted conic program.
# -- Perspective class --------------------------------------------
## CVXPY SOURCE: perspective.py lines 30-153
Perspective <- new_class("Perspective", parent = Atom, package = "CVXR",
properties = list(
.f = class_any, # The scalar expression being transformed
.f_recession = class_any # Optional recession function for s=0
),
constructor = function(f, s, f_recession = NULL) {
id <- next_expr_id()
f <- as_expr(f)
args <- c(list(s), variables(f))
shape <- f@shape
obj <- new_object(S7_object(),
id = as.integer(id),
.cache = new.env(parent = emptyenv()),
args = args,
shape = shape,
.f = f,
.f_recession = f_recession
)
validate_arguments(obj)
obj
}
)
# -- validate_arguments -------------------------------------------
## CVXPY SOURCE: perspective.py lines 56-61
method(validate_arguments, Perspective) <- function(x) {
if (expr_size(x@.f) != 1L) {
cli_abort("Perspective requires a scalar function f, got size {expr_size(x@.f)}.")
}
s <- x@args[[1L]]
if (expr_size(s) != 1L) {
cli_abort("Perspective requires scalar s, got size {expr_size(s)}.")
}
if (!S7_inherits(s, Variable)) {
cli_abort("s must be a {.cls Variable}.")
}
if (!is_nonneg(s)) {
cli_abort("s must be a nonnegative variable.")
}
}
# -- sign ---------------------------------------------------------
## CVXPY SOURCE: perspective.py lines 97-107
method(sign_from_args, Perspective) <- function(x) {
f_pos <- is_nonneg(x@.f)
f_neg <- is_nonpos(x@.f)
s_pos <- is_nonneg(x@args[[1L]])
list(is_nonneg = f_pos && s_pos,
is_nonpos = f_neg && s_pos)
}
# -- curvature ----------------------------------------------------
## CVXPY SOURCE: perspective.py lines 109-123
## With DPP scope: non-param-free f -> not convex/concave (forces EvalParams)
method(is_atom_convex, Perspective) <- function(x) {
if (dpp_scope_active() && !is_param_free(x@.f)) return(FALSE)
is_convex(x@.f) && is_nonneg(x@args[[1L]])
}
method(is_atom_concave, Perspective) <- function(x) {
if (dpp_scope_active() && !is_param_free(x@.f)) return(FALSE)
is_concave(x@.f) && is_nonneg(x@args[[1L]])
}
# -- monotonicity -------------------------------------------------
## CVXPY SOURCE: perspective.py lines 125-133
method(is_incr, Perspective) <- function(x, idx, ...) FALSE
method(is_decr, Perspective) <- function(x, idx, ...) FALSE
# -- shape --------------------------------------------------------
## CVXPY SOURCE: perspective.py lines 135-138
method(shape_from_args, Perspective) <- function(x) x@.f@shape
# -- numeric ------------------------------------------------------
## CVXPY SOURCE: perspective.py lines 63-95
## Compute s * f(x / s) numerically.
method(numeric_value, Perspective) <- function(x, values, ...) {
s_val <- as.numeric(values[[1L]])
if (s_val < 0) cli_abort("s must be nonneg, got {s_val}.")
f <- x@.f
if (abs(s_val) < .Machine$double.eps) {
## Handle s = 0 with recession function
if (is.null(x@.f_recession)) {
cli_abort("To handle s = 0, pass in a recession function f_recession.")
}
f <- x@.f_recession
s_val <- 1.0
}
## Save old variable values, set x/s, compute, restore
f_vars <- variables(f)
old_vals <- lapply(f_vars, function(v) value(v))
for (i in seq_along(f_vars)) {
value(f_vars[[i]]) <- values[[i + 1L]] / s_val
}
ret <- value(f) * s_val
## Restore
for (i in seq_along(f_vars)) {
value(f_vars[[i]]) <- old_vals[[i]]
}
as.numeric(ret)
}
# -- graph_implementation stub ------------------------------------
method(graph_implementation, Perspective) <- function(x, arg_objs, shape, data = NULL, ...) {
cli_abort("graph_implementation for {.cls Perspective} not implemented; use Dcp2Cone.")
}
# -- User-facing constructor --------------------------------------
#' Perspective Transform
#'
#' Creates the perspective transform of a scalar convex or concave expression.
#' Given a scalar expression \code{f(x)} and a nonneg variable \code{s},
#' the perspective is \code{s * f(x/s)}.
#'
#' @param f A scalar convex or concave Expression.
#' @param s A nonneg Variable (scalar).
#' @param f_recession Optional recession function for handling \code{s = 0}.
#' @returns A \code{Perspective} expression.
#' @export
perspective <- function(f, s, f_recession = NULL) {
Perspective(f, s, f_recession)
}
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.