Nothing
#####
## DO NOT EDIT THIS FILE!! EDIT THE SOURCE INSTEAD: rsrc_tree/reductions/dqcp2dcp/sets.R
#####
## CVXPY SOURCE: reductions/dqcp2dcp/sets.py
## Sublevel and superlevel set registries for DQCP atoms
## Sublevel set: x such that f(x) <= t
## Superlevel set: x such that f(x) >= t
## Returns a list of constraints (some may be lazy closures)
## CVXPY SOURCE: sets.py mul_sub
## CVXPY uses: [y <= t * inv_pos(x)] -- NOT t/x (DivExpression is not DCP)
.mul_sub <- function(expr, t) {
x <- expr@args[[1L]]
y <- expr@args[[2L]]
if (is_nonneg(x) && is_nonpos(y)) {
list(Inequality(y, t * inv_pos(x)))
} else if (is_nonpos(x) && is_nonneg(y)) {
list(Inequality(x, t * inv_pos(y)))
} else {
cli_abort("Incorrect signs for multiply sublevel set.")
}
}
## CVXPY SOURCE: sets.py mul_sup
## CVXPY uses: [x >= t * inv_pos(y)] -- NOT t/y
.mul_sup <- function(expr, t) {
x <- expr@args[[1L]]
y <- expr@args[[2L]]
if (is_nonneg(x) && is_nonneg(y)) {
list(Inequality(t * inv_pos(y), x))
} else if (is_nonpos(x) && is_nonpos(y)) {
list(Inequality(t * inv_pos(-y), -x))
} else {
cli_abort("Incorrect signs for multiply superlevel set.")
}
}
## CVXPY SOURCE: sets.py ratio_sub
## CVXPY uses: [x <= t * y] -- elementwise Multiply, not MulExpression
.ratio_sub <- function(expr, t) {
x <- expr@args[[1L]]
y <- expr@args[[2L]]
if (is_nonneg(y)) {
list(Inequality(x, t * y))
} else if (is_nonpos(y)) {
list(Inequality(t * y, x))
} else {
cli_abort("The denominator's sign must be known.")
}
}
## CVXPY SOURCE: sets.py ratio_sup
## CVXPY uses: [x >= t * y] -- elementwise Multiply, not MulExpression
.ratio_sup <- function(expr, t) {
x <- expr@args[[1L]]
y <- expr@args[[2L]]
if (is_nonneg(y)) {
list(Inequality(t * y, x))
} else if (is_nonpos(y)) {
list(Inequality(x, t * y))
} else {
cli_abort("The denominator's sign must be known.")
}
}
## CVXPY SOURCE: sets.py length_sub
## Sublevel set: {x : length(x) <= t} <=> x[floor(t):] == 0
.length_sub <- function(expr, t) {
arg <- expr@args[[1L]]
if (S7_inherits(t, Parameter)) {
## Lazy constraint: evaluated at bisection time when t has a value
sublevel_set <- function() {
tv <- value(t)
if (tv < 0) return(FALSE)
n <- prod(arg@shape)
if (tv >= n) return(TRUE)
idx_start <- as.integer(floor(tv)) + 1L # 1-based, first zero position
if (idx_start > n) return(TRUE)
arg[idx_start:n] == 0
}
return(list(sublevel_set))
} else {
idx_start <- as.integer(floor(value(t))) + 1L
n <- prod(arg@shape)
if (idx_start > n) return(list())
return(list(arg[idx_start:n] == 0))
}
}
## CVXPY SOURCE: sets.py gen_lambda_max_sub
## Sublevel set: {(A,B) : lambda_max(A,B) <= t} <=> A == A^T, B >> 0, t*B - A >> 0
.gen_lambda_max_sub <- function(expr, t) {
A <- expr@args[[1L]]
B <- expr@args[[2L]]
list(
Equality(A, t(A)),
PSD(B),
PSD(t * B - A)
)
}
## CVXPY SOURCE: sets.py condition_number_sub
## Sublevel set: {A : cond(A) <= t} uses auxiliary scalar u > 0
## with u*I <= A <= u*t*I (both semidefinite)
.condition_number_sub <- function(expr, t) {
A <- expr@args[[1L]]
n <- A@shape[1L]
u <- Variable(pos = TRUE)
prom_ut <- cvxr_promote(u * t, c(n, 1L))
prom_u <- cvxr_promote(u, c(n, 1L))
tmp_expr1 <- A - DiagVec(prom_u)
tmp_expr2 <- DiagVec(prom_ut) - A
list(
Equality(upper_tri(A), upper_tri(t(A))),
PSD(A),
PSD(tmp_expr1),
PSD(tmp_expr2)
)
}
## CVXPY SOURCE: sets.py dist_ratio_sub
## Sublevel set: {x : dist_ratio(x,a,b) <= t}
## Lazy closure -- evaluated at bisection time when t has a value.
.dist_ratio_sub <- function(expr, t) {
x <- expr@args[[1L]]
a <- expr@a
b <- expr@b
sublevel_set <- function() {
tv <- as.numeric(value(t))
if (tv > 1) return(FALSE)
tsq <- tv^2
## (1 - tsq^2)*||x||^2 - 2*(a - tsq*b)^T x + ||a||^2 - tsq*||b||^2 <= 0
coeff <- as.numeric(2 * (as.numeric(a) - tsq * as.numeric(b)))
(1 - tsq^2) * sum_squares(x) -
Constant(matrix(coeff, nrow = 1L)) %*% x +
sum(as.numeric(a)^2) - tsq * sum(as.numeric(b)^2) <= 0
}
list(sublevel_set)
}
## Dispatch sublevel/superlevel via S7_inherits
## CVXPY SOURCE: sets.py sublevel()
.dqcp_sublevel <- function(expr, t) {
if (S7_inherits(expr, MulExpression)) {
return(.mul_sub(expr, t))
} else if (S7_inherits(expr, DivExpression)) {
return(.ratio_sub(expr, t))
} else if (S7_inherits(expr, Length)) {
return(.length_sub(expr, t))
} else if (S7_inherits(expr, GenLambdaMax)) {
return(.gen_lambda_max_sub(expr, t))
} else if (S7_inherits(expr, ConditionNumber)) {
return(.condition_number_sub(expr, t))
} else if (S7_inherits(expr, DistRatio)) {
return(.dist_ratio_sub(expr, t))
}
cls <- class(expr)[[1L]]
cli_abort("The {.cls {cls}} atom is not yet supported in DQCP sublevel sets.")
}
## CVXPY SOURCE: sets.py superlevel()
.dqcp_superlevel <- function(expr, t) {
if (S7_inherits(expr, MulExpression)) {
return(.mul_sup(expr, t))
} else if (S7_inherits(expr, DivExpression)) {
return(.ratio_sup(expr, t))
}
cls <- class(expr)[[1L]]
cli_abort("The {.cls {cls}} atom is not yet supported in DQCP superlevel sets.")
}
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.