Nothing
#####
## DO NOT EDIT THIS FILE!! EDIT THE SOURCE INSTEAD: rsrc_tree/zzz_R_specific/visualize_annotations.R
#####
## R-SPECIFIC: Smith form annotations for visualize()
##
## Each atom class provides a smith_annotation() method that returns LaTeX-math
## descriptions for the Smith form pipeline stages. The null object pattern
## ensures every atom returns something -- atoms without custom annotations
## get an auto-generated stub.
##
## Architecture:
## smith_annotation(expr) -> list(
## latex_name, # atom symbol: $\varphi^{|\cdot|}$
## latex_definition, # what it computes: $|x|$
## conic, # list of LaTeX conic constraints, or NULL (stub)
## doc_topic, # for clickable doc links
## developer # implementation anatomy (files, DCP props, etc.)
## )
# ==========================================================================
# S7 generic
# ==========================================================================
#' Smith Form Annotation for an Expression Node
#'
#' Returns LaTeX-math annotation data for visualizing the canonicalization
#' pipeline. Each atom class can override this to provide a custom LaTeX name,
#' definition, and conic form. The default stub auto-generates from class
#' metadata.
#'
#' @param expr An Expression, Atom, or Leaf.
#' @param aux_var Character: the auxiliary variable name assigned to this node (e.g., "t_3").
#' @param child_vars Character vector: auxiliary variable names of the children.
#' @param ... Reserved for future use.
#' @returns A list with components: latex_name, latex_definition, conic, doc_topic, developer.
#' @keywords internal
smith_annotation <- new_generic("smith_annotation", "expr",
function(expr, aux_var = "t", child_vars = character(0), ...) {
S7_dispatch()
}
)
# ==========================================================================
# Helpers
# ==========================================================================
## Clean class name: strip CVXR:: prefix
.clean_class_name <- function(expr) {
sub("^CVXR::", "", class(expr)[[1L]])
}
## LaTeX-safe class name: strip prefix, escape underscores
.latex_class_name <- function(expr) {
gsub("_", "\\\\_", .clean_class_name(expr))
}
## Build shape string like "(m, 1)"
.latex_shape <- function(expr) {
paste0("(", paste(expr@shape, collapse = ", "), ")")
}
## Curvature as LaTeX-friendly string
.latex_curvature <- function(expr) {
if (is_constant(expr)) return("constant")
if (is_affine(expr)) return("affine")
if (is_convex(expr)) return("convex")
if (is_concave(expr)) return("concave")
"unknown"
}
## Sign as LaTeX-friendly string
.latex_sign <- function(expr) {
if (is_zero(expr)) return("zero")
if (is_nonneg(expr)) return("\\mathbb{R}_+")
if (is_nonpos(expr)) return("\\mathbb{R}_-")
"?"
}
## Relation symbol for relaxed Smith form based on curvature
.smith_relation <- function(expr) {
if (is_constant(expr) || is_affine(expr)) return("=")
if (is_convex(expr)) return("\\geq")
if (is_concave(expr)) return("\\leq")
"="
}
## Auto-generate developer info from introspection
.auto_developer <- function(expr) {
cls_name <- .clean_class_name(expr)
parent_name <- tryCatch(
sub("^CVXR::", "", class(S7_class(expr)@parent)[[1L]]),
error = function(e) "unknown"
)
has_canon <- tryCatch(has_dcp_canon(expr), error = function(e) FALSE)
list(
class_file = NULL,
canon_file = if (has_canon) "(registered)" else "(none \\textemdash\\ affine atom)",
parent_class = parent_name,
dcp_properties = list(
is_atom_convex = tryCatch(is_atom_convex(expr), error = function(e) NA),
is_atom_concave = tryCatch(is_atom_concave(expr), error = function(e) NA),
sign = .latex_sign(expr)
),
canon_pattern = if (has_canon) "custom" else "identity (affine)",
canon_summary = NULL
)
}
# ==========================================================================
# Default: Atom (null object stub)
# ==========================================================================
method(smith_annotation, Atom) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
cls_latex <- .latex_class_name(expr)
args_str <- paste(child_vars, collapse = ", ")
list(
latex_name = sprintf("\\varphi^{\\texttt{%s}}", cls_latex),
latex_definition = sprintf("\\texttt{%s}(%s)", cls_latex, args_str),
smith = sprintf("$%s = \\varphi^{\\texttt{%s}}(%s)$", aux_var, cls_latex, args_str),
relaxed = sprintf("$%s %s \\varphi^{\\texttt{%s}}(%s)$",
aux_var, .smith_relation(expr), cls_latex, args_str),
conic = NULL,
doc_topic = class(expr)[[1L]],
developer = .auto_developer(expr)
)
}
# ==========================================================================
# Leaves: Variable, Constant, Parameter
# ==========================================================================
method(smith_annotation, Variable) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
vname <- expr_name(expr)
shape_str <- .latex_shape(expr)
list(
latex_name = sprintf("\\mathbf{%s}", vname),
latex_definition = sprintf("\\mathbf{%s} \\in \\mathbb{R}^{%s}",
vname, paste(expr@shape, collapse = " \\times ")),
smith = sprintf("$\\mathbf{%s}$", vname),
relaxed = sprintf("$\\mathbf{%s}$", vname),
conic = NULL,
doc_topic = "Variable",
developer = list(
class_file = "expressions/variable.R",
canon_file = "(terminal \\textemdash\\ no canonicalizer)",
parent_class = "Leaf",
dcp_properties = list(is_atom_convex = TRUE, is_atom_concave = TRUE, sign = "?"),
canon_pattern = "terminal",
canon_summary = "Variables are leaf nodes; no canonicalization needed"
)
)
}
method(smith_annotation, Constant) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
## Try to show small constants literally
val <- tryCatch(value(expr), error = function(e) NULL)
if (!is.null(val) && length(val) == 1L) {
val_str <- format(val, digits = 4)
} else {
val_str <- sprintf("C_{%s}", .latex_shape(expr))
}
list(
latex_name = val_str,
latex_definition = val_str,
smith = sprintf("$%s$", val_str),
relaxed = sprintf("$%s$", val_str),
conic = NULL,
doc_topic = "Constant",
developer = list(
class_file = "expressions/constants/constant.R",
canon_file = "(terminal \\textemdash\\ constant)",
parent_class = "Leaf",
dcp_properties = list(is_atom_convex = TRUE, is_atom_concave = TRUE, sign = .latex_sign(expr)),
canon_pattern = "terminal",
canon_summary = "Constants are leaf nodes; folded into affine data"
)
)
}
method(smith_annotation, Parameter) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
pname <- expr_name(expr)
list(
latex_name = sprintf("\\theta_{\\text{%s}}", pname),
latex_definition = sprintf("\\theta_{\\text{%s}} \\in \\mathbb{R}^{%s}",
pname, paste(expr@shape, collapse = " \\times ")),
smith = sprintf("$\\theta_{\\text{%s}}$", pname),
relaxed = sprintf("$\\theta_{\\text{%s}}$", pname),
conic = NULL,
doc_topic = "Parameter",
developer = list(
class_file = "expressions/constants/parameter.R",
canon_file = "(terminal \\textemdash\\ parameter)",
parent_class = "Leaf",
dcp_properties = list(is_atom_convex = TRUE, is_atom_concave = TRUE, sign = .latex_sign(expr)),
canon_pattern = "terminal",
canon_summary = "Parameters are leaf nodes; values substituted at solve time"
)
)
}
# ==========================================================================
# P0 Affine Atoms
# ==========================================================================
method(smith_annotation, AddExpression) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
## Smart joining: if a term starts with "- " or "-\\", use subtraction
if (length(child_vars) == 0L) {
args_str <- ""
} else {
parts <- child_vars[[1L]]
for (j in seq_along(child_vars)[-1L]) {
cv <- child_vars[[j]]
if (grepl("^-\\s", cv) || grepl("^-\\\\", cv)) {
## Already negated: use " - rest" instead of " + -rest"
parts <- paste0(parts, " ", cv)
} else {
parts <- paste0(parts, " + ", cv)
}
}
args_str <- parts
}
list(
latex_name = "\\varphi^{+}",
latex_definition = sprintf("%s", args_str),
smith = sprintf("$%s = %s$", aux_var, args_str),
relaxed = sprintf("$%s = %s$", aux_var, args_str),
conic = list(sprintf("$%s = %s$", aux_var, args_str)),
doc_topic = "AddExpression",
developer = list(
class_file = "atoms/affine/add_expr.R",
canon_file = "(none \\textemdash\\ affine atom)",
parent_class = "AffAtom",
dcp_properties = list(is_atom_convex = TRUE, is_atom_concave = TRUE, sign = "?"),
canon_pattern = "identity (affine)",
canon_summary = "Affine: passed through to LinOp tree as \\texttt{LINOP\\_SUM}"
)
)
}
method(smith_annotation, NegExpression) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
x <- if (length(child_vars) >= 1L) child_vars[[1L]] else "x"
list(
latex_name = "\\varphi^{-}",
latex_definition = sprintf("-%s", x),
smith = sprintf("$%s = -%s$", aux_var, x),
relaxed = sprintf("$%s = -%s$", aux_var, x),
conic = list(sprintf("$%s = -%s$", aux_var, x)),
doc_topic = "NegExpression",
developer = list(
class_file = "atoms/affine/unary_operators.R",
canon_file = "(none \\textemdash\\ affine atom)",
parent_class = "AffAtom",
dcp_properties = list(is_atom_convex = TRUE, is_atom_concave = TRUE, sign = "?"),
canon_pattern = "identity (affine)",
canon_summary = "Affine: passed through to LinOp tree as \\texttt{LINOP\\_NEG}"
)
)
}
method(smith_annotation, MulExpression) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
lhs <- if (length(child_vars) >= 1L) child_vars[[1L]] else "A"
rhs <- if (length(child_vars) >= 2L) child_vars[[2L]] else "\\mathbf{x}"
list(
latex_name = "\\varphi^{\\times}",
latex_definition = sprintf("%s %s", lhs, rhs),
smith = sprintf("$%s = %s %s$", aux_var, lhs, rhs),
relaxed = sprintf("$%s = %s %s$", aux_var, lhs, rhs),
conic = list(sprintf("$%s = %s %s$", aux_var, lhs, rhs)),
doc_topic = "MulExpression",
developer = list(
class_file = "atoms/affine/binary_operators.R",
canon_file = "(none \\textemdash\\ affine atom)",
parent_class = "AffAtom",
dcp_properties = list(is_atom_convex = TRUE, is_atom_concave = TRUE, sign = "?"),
canon_pattern = "identity (affine)",
canon_summary = "Affine: passed through to LinOp tree as \\texttt{LINOP\\_MUL}"
)
)
}
method(smith_annotation, Multiply) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
lhs <- if (length(child_vars) >= 1L) child_vars[[1L]] else "a"
rhs <- if (length(child_vars) >= 2L) child_vars[[2L]] else "x"
list(
latex_name = "\\varphi^{\\odot}",
latex_definition = sprintf("%s \\odot %s", lhs, rhs),
smith = sprintf("$%s = %s \\odot %s$", aux_var, lhs, rhs),
relaxed = sprintf("$%s = %s \\odot %s$", aux_var, lhs, rhs),
conic = list(sprintf("$%s = %s \\odot %s$", aux_var, lhs, rhs)),
doc_topic = "Multiply",
developer = list(
class_file = "atoms/affine/binary_operators.R",
canon_file = "(none \\textemdash\\ affine atom)",
parent_class = "AffAtom",
dcp_properties = list(is_atom_convex = TRUE, is_atom_concave = TRUE, sign = "?"),
canon_pattern = "identity (affine)",
canon_summary = "Elementwise multiply: affine when one arg is constant"
)
)
}
method(smith_annotation, DivExpression) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
lhs <- if (length(child_vars) >= 1L) child_vars[[1L]] else "x"
rhs <- if (length(child_vars) >= 2L) child_vars[[2L]] else "a"
list(
latex_name = "\\varphi^{\\div}",
latex_definition = sprintf("%s / %s", lhs, rhs),
smith = sprintf("$%s = %s / %s$", aux_var, lhs, rhs),
relaxed = sprintf("$%s = %s / %s$", aux_var, lhs, rhs),
conic = list(sprintf("$%s = %s / %s$", aux_var, lhs, rhs)),
doc_topic = "DivExpression",
developer = list(
class_file = "atoms/affine/binary_operators.R",
canon_file = "(none \\textemdash\\ affine atom)",
parent_class = "AffAtom",
dcp_properties = list(is_atom_convex = TRUE, is_atom_concave = TRUE, sign = "?"),
canon_pattern = "identity (affine)",
canon_summary = "Division by positive constant: affine"
)
)
}
method(smith_annotation, Transpose) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
x <- if (length(child_vars) >= 1L) child_vars[[1L]] else "X"
list(
latex_name = "\\varphi^{\\top}",
latex_definition = sprintf("%s^\\top", x),
smith = sprintf("$%s = %s^\\top$", aux_var, x),
relaxed = sprintf("$%s = %s^\\top$", aux_var, x),
conic = list(sprintf("$%s = %s^\\top$", aux_var, x)),
doc_topic = "Transpose",
developer = list(
class_file = "atoms/affine/transpose.R",
canon_file = "(none \\textemdash\\ affine atom)",
parent_class = "AffAtom",
dcp_properties = list(is_atom_convex = TRUE, is_atom_concave = TRUE, sign = "?"),
canon_pattern = "identity (affine)",
canon_summary = "Affine: passed through to LinOp tree as \\texttt{LINOP\\_TRANSPOSE}"
)
)
}
method(smith_annotation, Reshape) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
x <- if (length(child_vars) >= 1L) child_vars[[1L]] else "X"
list(
latex_name = "\\varphi^{\\text{vec}}",
latex_definition = sprintf("\\operatorname{vec}(%s)", x),
smith = sprintf("$%s = \\operatorname{vec}(%s)$", aux_var, x),
relaxed = sprintf("$%s = \\operatorname{vec}(%s)$", aux_var, x),
conic = list(sprintf("$%s = \\operatorname{vec}(%s)$", aux_var, x)),
doc_topic = "Reshape",
developer = list(
class_file = "atoms/affine/reshape.R",
canon_file = "(none \\textemdash\\ affine atom)",
parent_class = "AffAtom",
dcp_properties = list(is_atom_convex = TRUE, is_atom_concave = TRUE, sign = "?"),
canon_pattern = "identity (affine)",
canon_summary = "Affine: passed through to LinOp tree as \\texttt{LINOP\\_RESHAPE}"
)
)
}
method(smith_annotation, SumEntries) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
x <- if (length(child_vars) >= 1L) child_vars[[1L]] else "\\mathbf{x}"
list(
latex_name = "\\varphi^{\\Sigma}",
latex_definition = sprintf("\\mathbf{1}^\\top %s", x),
smith = sprintf("$%s = \\varphi^{\\Sigma}(%s)$", aux_var, x),
relaxed = sprintf("$%s = \\mathbf{1}^\\top %s$", aux_var, x),
conic = list(sprintf("$%s = \\mathbf{1}^\\top %s$", aux_var, x)),
doc_topic = "SumEntries",
developer = list(
class_file = "atoms/affine/sum.R",
canon_file = "(none \\textemdash\\ affine atom)",
parent_class = "AxisAffAtom",
dcp_properties = list(is_atom_convex = TRUE, is_atom_concave = TRUE, sign = "?"),
canon_pattern = "identity (affine)",
canon_summary = "Affine sum: $\\mathbf{1}^\\top \\mathbf{x}$"
)
)
}
# ==========================================================================
# P0 Convex Atoms (with full conic annotations)
# ==========================================================================
## -- Abs ------------------------------------------------------------------
method(smith_annotation, Abs) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
x <- if (length(child_vars) >= 1L) child_vars[[1L]] else "x"
list(
latex_name = "\\varphi^{|\\cdot|}",
latex_definition = sprintf("|%s|", x),
smith = sprintf("$%s = \\varphi^{|\\cdot|}(%s)$", aux_var, x),
relaxed = sprintf("$%s \\geq \\varphi^{|\\cdot|}(%s)$", aux_var, x),
conic = list(sprintf("$(%s, %s) \\in \\mathcal{Q}^2$", aux_var, x)),
doc_topic = "Abs",
developer = list(
class_file = "atoms/elementwise/abs.R",
canon_file = "reductions/dcp2cone/canonicalizers/abs_canon.R",
parent_class = "Elementwise",
dcp_properties = list(is_atom_convex = TRUE, is_atom_concave = FALSE,
sign = "\\mathbb{R}_+"),
canon_pattern = "new_variable_plus_constraints",
canon_summary = "Introduces $t$ with $t \\geq x$ and $t \\geq -x$"
)
)
}
## -- Pnorm (p=2 special case, general p) ---------------------------------
method(smith_annotation, Pnorm) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
x <- if (length(child_vars) >= 1L) child_vars[[1L]] else "\\mathbf{x}"
p <- expr@p
if (p == 2) {
list(
latex_name = "\\varphi^{\\lVert\\cdot\\rVert_2}",
latex_definition = sprintf("\\lVert %s \\rVert_2", x),
smith = sprintf("$%s = \\varphi^{\\lVert\\cdot\\rVert_2}(%s)$", aux_var, x),
relaxed = sprintf("$%s \\geq \\varphi^{\\lVert\\cdot\\rVert_2}(%s)$", aux_var, x),
conic = list(sprintf("$(%s, %s) \\in \\mathcal{Q}^{n+1}$", aux_var, x)),
doc_topic = "Pnorm",
developer = list(
class_file = "atoms/pnorm.R",
canon_file = "reductions/dcp2cone/canonicalizers/pnorm_canon.R",
parent_class = "AxisAtom",
dcp_properties = list(is_atom_convex = TRUE, is_atom_concave = FALSE,
sign = "\\mathbb{R}_+"),
canon_pattern = "new_variable_plus_SOC",
canon_summary = sprintf("SOC constraint: $(%s, %s) \\in \\mathcal{Q}^{n+1}$", aux_var, x)
)
)
} else {
p_str <- format(p, digits = 4)
rel <- if (p >= 1) "\\geq" else "\\leq"
list(
latex_name = sprintf("\\varphi^{\\lVert\\cdot\\rVert_{%s}}", p_str),
latex_definition = sprintf("\\lVert %s \\rVert_{%s}", x, p_str),
smith = sprintf("$%s = \\varphi^{\\lVert\\cdot\\rVert_{%s}}(%s)$", aux_var, p_str, x),
relaxed = sprintf("$%s %s \\varphi^{\\lVert\\cdot\\rVert_{%s}}(%s)$",
aux_var, rel, p_str, x),
conic = list(sprintf("$\\text{PowCone3D constraints for } p = %s$", p_str)),
doc_topic = "Pnorm",
developer = list(
class_file = "atoms/pnorm.R",
canon_file = "reductions/dcp2cone/canonicalizers/pnorm_canon.R",
parent_class = "AxisAtom",
dcp_properties = list(is_atom_convex = (p >= 1), is_atom_concave = (p < 1),
sign = "\\mathbb{R}_+"),
canon_pattern = "new_variable_plus_PowCone",
canon_summary = sprintf("Power cone decomposition for $p = %s$", p_str)
)
)
}
}
## -- Power (covers square as p=2 special case) ---------------------------
method(smith_annotation, Power) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
x <- if (length(child_vars) >= 1L) child_vars[[1L]] else "x"
p <- expr@p_used
if (!is.null(p) && p == 2) {
## Square: x^2, convex
list(
latex_name = "\\varphi^{(\\cdot)^2}",
latex_definition = sprintf("%s^2", x),
smith = sprintf("$%s = \\varphi^{(\\cdot)^2}(%s)$", aux_var, x),
relaxed = sprintf("$%s \\geq \\varphi^{(\\cdot)^2}(%s)$", aux_var, x),
conic = list(
sprintf("$\\left(\\frac{1+%s}{2},\\; \\frac{1-%s}{2},\\; %s\\right) \\in \\mathcal{Q}^3$",
aux_var, aux_var, x)
),
doc_topic = "Power",
developer = list(
class_file = "atoms/elementwise/power.R",
canon_file = "reductions/dcp2cone/canonicalizers/power_canon.R",
parent_class = "Elementwise",
dcp_properties = list(is_atom_convex = TRUE, is_atom_concave = FALSE,
sign = "\\mathbb{R}_+"),
canon_pattern = "delegating",
canon_summary = "$x^2$ canonicalized via $\\varphi^{\\text{qol}}(x, 1)$ (quad\\_over\\_lin)"
)
)
} else {
## General power
p_str <- if (!is.null(p)) format(p, digits = 4) else "p"
curv <- .latex_curvature(expr)
rel <- .smith_relation(expr)
list(
latex_name = sprintf("\\varphi^{(\\cdot)^{%s}}", p_str),
latex_definition = sprintf("%s^{%s}", x, p_str),
smith = sprintf("$%s = \\varphi^{(\\cdot)^{%s}}(%s)$", aux_var, p_str, x),
relaxed = sprintf("$%s %s \\varphi^{(\\cdot)^{%s}}(%s)$", aux_var, rel, p_str, x),
conic = NULL,
doc_topic = "Power",
developer = list(
class_file = "atoms/elementwise/power.R",
canon_file = "reductions/dcp2cone/canonicalizers/power_canon.R",
parent_class = "Elementwise",
dcp_properties = list(is_atom_convex = is_atom_convex(expr),
is_atom_concave = is_atom_concave(expr),
sign = .latex_sign(expr)),
canon_pattern = "power_cone",
canon_summary = sprintf("Power $p = %s$: %s, uses power cone decomposition", p_str, curv)
)
)
}
}
## -- QuadOverLin ---------------------------------------------------------
method(smith_annotation, QuadOverLin) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
x <- if (length(child_vars) >= 1L) child_vars[[1L]] else "\\mathbf{x}"
y <- if (length(child_vars) >= 2L) child_vars[[2L]] else "y"
list(
latex_name = "\\varphi^{\\text{qol}}",
latex_definition = sprintf("\\frac{\\lVert %s \\rVert_2^2}{%s}", x, y),
smith = sprintf("$%s = \\varphi^{\\text{qol}}(%s, %s)$", aux_var, x, y),
relaxed = sprintf("$%s \\geq \\varphi^{\\text{qol}}(%s, %s)$", aux_var, x, y),
conic = list(
sprintf("$\\left(\\frac{%s+%s}{2},\\; \\frac{%s-%s}{2},\\; %s\\right) \\in \\mathcal{Q}^{n+2}$",
y, aux_var, y, aux_var, x),
sprintf("$%s \\in \\mathcal{Q}^1$", y)
),
doc_topic = "QuadOverLin",
developer = list(
class_file = "atoms/quad_over_lin.R",
canon_file = "reductions/dcp2cone/canonicalizers/quad_over_lin_canon.R",
parent_class = "AxisAtom",
dcp_properties = list(is_atom_convex = TRUE, is_atom_concave = FALSE,
sign = "\\mathbb{R}_+"),
canon_pattern = "new_variable_plus_SOC",
canon_summary = "Rotated SOC: $\\lVert\\mathbf{x}\\rVert_2^2 \\leq t \\cdot y$"
)
)
}
## -- QuadForm ------------------------------------------------------------
method(smith_annotation, QuadForm) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
x <- if (length(child_vars) >= 1L) child_vars[[1L]] else "\\mathbf{x}"
P <- if (length(child_vars) >= 2L) child_vars[[2L]] else "P"
curv <- .latex_curvature(expr)
rel <- .smith_relation(expr)
list(
latex_name = "\\varphi^{\\text{quad}}",
latex_definition = sprintf("%s^\\top %s %s", x, P, x),
smith = sprintf("$%s = \\varphi^{\\text{quad}}(%s, %s)$", aux_var, x, P),
relaxed = sprintf("$%s %s \\varphi^{\\text{quad}}(%s, %s)$", aux_var, rel, x, P),
conic = list(
sprintf("$%s %s \\lVert P^{1/2} %s \\rVert_2^2 \\text{ via eigendecomposition} \\to \\text{SOC}$",
aux_var, rel, x)
),
doc_topic = "QuadForm",
developer = list(
class_file = "atoms/quad_form.R",
canon_file = "reductions/dcp2cone/canonicalizers/quad_form_canon.R",
parent_class = "Atom",
dcp_properties = list(is_atom_convex = is_atom_convex(expr),
is_atom_concave = is_atom_concave(expr),
sign = .latex_sign(expr)),
canon_pattern = "delegating",
canon_summary = "Eigendecomposes $P$, then delegates to $\\varphi^{\\text{qol}}$"
)
)
}
## -- MaxEntries ----------------------------------------------------------
method(smith_annotation, MaxEntries) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
x <- if (length(child_vars) >= 1L) child_vars[[1L]] else "\\mathbf{x}"
list(
latex_name = "\\varphi^{\\max}",
latex_definition = sprintf("\\max\\{%s_1, \\ldots, %s_n\\}", x, x),
smith = sprintf("$%s = \\varphi^{\\max}(%s)$", aux_var, x),
relaxed = sprintf("$%s \\geq \\varphi^{\\max}(%s)$", aux_var, x),
conic = list(
sprintf("$%s - %s_i \\in \\mathcal{Q}^1,\\; i = 1, \\ldots, n$", aux_var, x)
),
doc_topic = "MaxEntries",
developer = list(
class_file = "atoms/max.R",
canon_file = "reductions/dcp2cone/canonicalizers/max_canon.R",
parent_class = "AxisAtom",
dcp_properties = list(is_atom_convex = TRUE, is_atom_concave = FALSE, sign = "?"),
canon_pattern = "new_variable_plus_constraints",
canon_summary = "$n$ nonneg constraints: $t \\geq x_i$ for all $i$"
)
)
}
## -- MinEntries ----------------------------------------------------------
method(smith_annotation, MinEntries) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
x <- if (length(child_vars) >= 1L) child_vars[[1L]] else "\\mathbf{x}"
list(
latex_name = "\\varphi^{\\min}",
latex_definition = sprintf("\\min\\{%s_1, \\ldots, %s_n\\}", x, x),
smith = sprintf("$%s = \\varphi^{\\min}(%s)$", aux_var, x),
relaxed = sprintf("$%s \\leq \\varphi^{\\min}(%s)$", aux_var, x),
conic = list(
sprintf("$%s_i - %s \\in \\mathcal{Q}^1,\\; i = 1, \\ldots, n$", x, aux_var)
),
doc_topic = "MinEntries",
developer = list(
class_file = "atoms/min.R",
canon_file = "reductions/dcp2cone/canonicalizers/min_canon.R",
parent_class = "AxisAtom",
dcp_properties = list(is_atom_convex = FALSE, is_atom_concave = TRUE, sign = "?"),
canon_pattern = "new_variable_plus_constraints",
canon_summary = "$n$ nonneg constraints: $x_i \\geq t$ for all $i$"
)
)
}
## -- Maximum (elementwise max of two expressions) ------------------------
method(smith_annotation, Maximum) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
x <- if (length(child_vars) >= 1L) child_vars[[1L]] else "x"
y <- if (length(child_vars) >= 2L) child_vars[[2L]] else "y"
list(
latex_name = "\\varphi^{\\max}",
latex_definition = sprintf("\\max(%s, %s)", x, y),
smith = sprintf("$%s = \\varphi^{\\max}(%s, %s)$", aux_var, x, y),
relaxed = sprintf("$%s \\geq \\varphi^{\\max}(%s, %s)$", aux_var, x, y),
conic = list(
sprintf("$%s \\geq %s,\\; %s \\geq %s$", aux_var, x, aux_var, y)
),
doc_topic = "Maximum",
developer = list(
class_file = "atoms/elementwise/maximum.R",
canon_file = "reductions/dcp2cone/canonicalizers/max_elemwise_canon.R",
parent_class = "Elementwise",
dcp_properties = list(is_atom_convex = TRUE, is_atom_concave = FALSE, sign = "?"),
canon_pattern = "new_variable_plus_constraints",
canon_summary = "Introduces $t$ with $t \\geq x$ and $t \\geq y$"
)
)
}
## -- Minimum (elementwise min of two expressions) ------------------------
method(smith_annotation, Minimum) <- function(expr, aux_var = "t", child_vars = character(0), ...) {
x <- if (length(child_vars) >= 1L) child_vars[[1L]] else "x"
y <- if (length(child_vars) >= 2L) child_vars[[2L]] else "y"
list(
latex_name = "\\varphi^{\\min}",
latex_definition = sprintf("\\min(%s, %s)", x, y),
smith = sprintf("$%s = \\varphi^{\\min}(%s, %s)$", aux_var, x, y),
relaxed = sprintf("$%s \\leq \\varphi^{\\min}(%s, %s)$", aux_var, x, y),
conic = list(
sprintf("$%s \\leq %s,\\; %s \\leq %s$", aux_var, x, aux_var, y)
),
doc_topic = "Minimum",
developer = list(
class_file = "atoms/elementwise/minimum.R",
canon_file = "reductions/dcp2cone/canonicalizers/min_elemwise_canon.R",
parent_class = "Elementwise",
dcp_properties = list(is_atom_convex = FALSE, is_atom_concave = TRUE, sign = "?"),
canon_pattern = "new_variable_plus_constraints",
canon_summary = "Introduces $t$ with $t \\leq x$ and $t \\leq y$"
)
)
}
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.