Visualization

Author

Anqi Fu, Balasubramanian Narasimhan, Steven Diamond, Stephen Boyd

The visualize() function generates interactive visualizations of CVXR optimization problems, showing the expression tree with DCP curvature annotations. It is useful for understanding how CVXR decomposes a problem and for diagnosing DCP violations.

Function Signature

visualize(
  problem,
  output = c("text", "json", "html", "latex", "tikz"),
  solver = NULL,
  digits = 4L,
  file   = NULL,
  open   = interactive(),
  doc_base = "https://cvxr.rbind.io/reference/"
)

The key arguments:

  • output: format for the visualization. "html" produces a self-contained interactive HTML page; "text" prints to the console
  • solver: solver to use for generating standard form and solver data. Set to TRUE to auto-select a solver, or pass a solver name (e.g., "ECOS", "OSQP"). When specified, the HTML output includes two additional tabs: Standard Form and Solver Data. Omit or set to NULL to show only the expression tree and Smith forms
  • file: path to write the output (used with "html")
  • open: whether to open the file in a browser (default TRUE in interactive sessions)
  • doc_base: base URL for documentation links in the visualization

Two helper features for richer output:

  • latex_name argument in Variable() and Parameter() sets the display name in LaTeX-rendered visualizations
  • set_label(constraint, label) attaches a human-readable label to a constraint

Smith Form Notation

The visualization uses φ (phi) symbols to represent CVXR atoms in the Smith form — the intermediate representation that shows how each expression is decomposed before conic canonicalization. Each atom is written as ti=φtag(args) in the Smith form, and relaxed to an inequality ( for convex, for concave) in the relaxed Smith form.

The table below lists the φ functions that have dedicated annotations. Any atom not listed here uses a generic fallback: φClassName.

Affine Atoms

These atoms preserve curvature (both convex and concave). Their Smith form uses equality (=) since no relaxation is needed.

Symbol CVXR Function Meaning
φ+ + Addition
φ -x Negation
φ× %*% Matrix multiplication
φ * (elementwise) Hadamard (elementwise) product
φ÷ / Division by constant
φ t() Transpose
φvec reshape_expr(), vec() Vectorization / reshape
φΣ sum(), sum_entries() Sum of entries

Convex and Concave Atoms

These atoms have specific curvature. In the relaxed Smith form, convex atoms use tiφ() and concave atoms use tiφ().

Symbol CVXR Function Meaning Curvature
φ|| abs() Absolute value convex
φ2 p_norm(x, 2) Euclidean norm convex
φp p_norm(x, p) General p-norm convex (p1)
φ()2 power(x, 2), x^2 Square convex
φ()p power(x, p), x^p General power varies with p
φqol quad_over_lin() x22/y convex
φquad quad_form(x, P) xPx convex (P0)
φmax max_entries(), maximum() Maximum convex
φmin min_entries(), minimum() Minimum concave

Leaves and Fallback

Symbol Node Type Description
x Variable Optimization variable
θname Parameter Named parameter (value set at solve time)
literal value Constant Numeric constant (shown as value or C(m,n))
φClassName any other Atom Generic fallback for atoms without custom annotation

Atoms that appear in the examples on this page but use the generic fallback include entr(), huber(), log_sum_exp(), lambda_max(), and pos().

DCP-Compliant Examples

The examples below show visualize() output for problems that satisfy the DCP rules. Each tree node is annotated with its curvature and sign using color-coded borders: blue for convex, red for concave, green for affine, and grey for constant. These colors indicate curvature, not validity — a red border on a concave node is expected, not an error. DCP violations are shown differently, with a red background and a banner (see the Non-DCP examples below).

Simple Norm Minimization

minimizex2subject tox1

A basic second-order cone program. The objective p_norm(x, 2) is convex and the constraint is affine, so the problem is DCP-compliant.

x <- Variable(3, name = "x")
prob1 <- Problem(Minimize(p_norm(x, 2)), list(x >= 1))
is_dcp(prob1)
[1] TRUE

Least Squares

minimizeAxb22

The classic unconstrained least squares problem. sum_squares() is a convex atom applied to an affine argument.

set.seed(42)
A <- matrix(rnorm(12), 4, 3)
b <- rnorm(4)
x2 <- Variable(3, name = "x")
prob2 <- Problem(Minimize(sum_squares(A %*% x2 - b)))
is_dcp(prob2)
[1] TRUE

Portfolio Optimization

maximizeμTwγwTΣwsubject towi=1,w0

A Markowitz portfolio problem with a risk-aversion parameter γ. This example demonstrates latex_name for display customization and set_label() for named constraints. Note that parameter values must be set (via value()<-) before calling visualize() with solver = TRUE, so that the problem data matrices can be compiled for the Standard Form and Solver Data tabs.

w <- Variable(4, name = "w", latex_name = "\\mathbf{w}")
mu <- Parameter(4, name = "mu", latex_name = "\\boldsymbol{\\mu}")
gamma <- Parameter(1, name = "gamma", nonneg = TRUE, latex_name = "\\gamma")
Sigma <- matrix(c(1,.5,.3,.1, .5,1,.4,.2, .3,.4,1,.5, .1,.2,.5,1), 4, 4)
## Set parameter values so the solver tabs can compile problem data
value(mu) <- c(0.12, 0.10, 0.07, 0.03)
value(gamma) <- 0.5
prob3 <- Problem(
  Maximize(t(mu) %*% w - gamma * quad_form(w, Sigma)),
  list(
    set_label(sum(w) == 1, "budget"),
    set_label(w >= 0, "long only")
  )
)
is_dcp(prob3)
[1] TRUE

Entropy Maximization

maximizeentr(xi)subject toxi=1

Maximum entropy distribution. The entr() atom is concave, so maximizing a sum of concave atoms is DCP-compliant.

x4 <- Variable(5, name = "x")
prob4 <- Problem(Maximize(sum(entr(x4))), list(sum(x4) == 1))
is_dcp(prob4)
[1] TRUE

Huber Loss

minimizehuber(xi)

The Huber function is convex; minimizing its sum is DCP-compliant. This is an unconstrained problem.

x5 <- Variable(3, name = "x")
prob5 <- Problem(Minimize(sum(huber(x5))))
is_dcp(prob5)
[1] TRUE

Log-Sum-Exp

minimizelogexisubject tox1

log_sum_exp() is a convex atom. The constraint is affine.

x6 <- Variable(4, name = "x")
prob6 <- Problem(Minimize(log_sum_exp(x6)), list(x6 >= -1))
is_dcp(prob6)
[1] TRUE

Semidefinite Program

minimizeλmax(X)subject toX11=1

An SDP with a symmetric matrix variable. lambda_max() is convex and the equality constraint is affine.

X7 <- Variable(c(3, 3), name = "X", symmetric = TRUE)
prob7 <- Problem(Minimize(lambda_max(X7)), list(X7[1, 1] == 1))
is_dcp(prob7)
[1] TRUE

Mixed Atoms

minimizemaxi|xi|+pos(xi)

A combination of max_entries(abs(x)) (convex) and sum_entries(pos(x)) (convex). The sum of convex functions is convex.

x8 <- Variable(3, name = "x")
prob8 <- Problem(Minimize(max_entries(abs(x8)) + sum_entries(pos(x8))))
is_dcp(prob8)
[1] TRUE

Non-DCP Examples

The following problems violate the DCP rules. The visualization highlights the offending nodes in red, making it easy to pinpoint where the violation occurs.

Bilinear Objective

minimizex1x2subject tox0

Warning

DCP violation: The product x1x2 is neither convex nor concave — it is bilinear. visualize() marks the objective node in red.

x9 <- Variable(2, name = "x")
prob9 <- Problem(Minimize(x9[1] * x9[2]), list(x9 >= 0))
is_dcp(prob9)
[1] FALSE

Nonaffine Equality Constraint

minimize1Txsubject tox2=1

Warning

DCP violation: Equality constraints must be affine. Here x2 is convex, so the equality x2=1 is not DCP-compliant. The constraint node is highlighted in red.

x10 <- Variable(3, name = "x")
prob10 <- Problem(Minimize(sum(x10)), list(p_norm(x10, 2) == 1))
is_dcp(prob10)
[1] FALSE

Text Output

For quick inspection in the console, use output = "text" (the default):

visualize(prob1, output = "text")
## ── Expression Tree (MINIMIZE) ──────────────────────────────────────────────────
## t_1 = PnormApprox(...)  [convex, \mathbb{R}_+, 1x1]
## \-- x  [affine, 3x1]
## ── Constraints ─────────────────────────────────────────────────────────────────
## ✓ [1] Inequality 3x1
##       1  [constant, 1x1]
##       x  [affine, 3x1]
## ── SMITH FORM ──────────────────────────────────────────────────────────────────
##   t_{1} = phi^{||.||_2}({x})
## ── RELAXED SMITH FORM ──────────────────────────────────────────────────────────
##   t_{1} >= phi^{||.||_2}({x})
## ── CONIC FORM ──────────────────────────────────────────────────────────────────
##   (t_{1}, {x}) in Q^{n+1}

Practical Considerations

visualize() is designed for small to moderate problems — the kind you build during modeling and debugging. Problems with many variables, large data matrices, or hundreds of constraints will produce unwieldy expression trees and oversized conic forms that obscure rather than illuminate. Keep the problem small and representative when using this tool.

Session Info

sessionInfo()
R version 4.5.2 (2025-10-31)
Platform: aarch64-apple-darwin20
Running under: macOS Tahoe 26.3

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRblas.0.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.1

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: America/Los_Angeles
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] CVXR_1.8.1

loaded via a namespace (and not attached):
 [1] slam_0.1-55       cli_3.6.5         knitr_1.51        ECOSolveR_0.6.1  
 [5] rlang_1.1.7       xfun_0.56         clarabel_0.11.2   otel_0.2.0       
 [9] gurobi_13.0-1     Rglpk_0.6-5.1     highs_1.12.0-3    cccp_0.3-3       
[13] scs_3.2.7         S7_0.2.1          jsonlite_2.0.0    Rcplex_0.3-8     
[17] backports_1.5.0   rprojroot_2.1.1   htmltools_0.5.9   Rmosek_11.1.1    
[21] gmp_0.7-5.1       piqp_0.6.2        rmarkdown_2.30    grid_4.5.2       
[25] evaluate_1.0.5    fastmap_1.2.0     yaml_2.3.12       compiler_4.5.2   
[29] codetools_0.2-20  htmlwidgets_1.6.4 Rcpp_1.1.1        here_1.0.2       
[33] osqp_1.0.0        lattice_0.22-9    digest_0.6.39     checkmate_2.3.4  
[37] Matrix_1.7-4      tools_4.5.2