R/167_reductions_dcp2cone_canonicalizers_quad_over_lin_canon.R

Defines functions quad_over_lin_canon

#####
## DO NOT EDIT THIS FILE!! EDIT THE SOURCE INSTEAD: rsrc_tree/reductions/dcp2cone/canonicalizers/quad_over_lin_canon.R
#####

## CVXPY SOURCE: reductions/dcp2cone/canonicalizers/quad_over_lin_canon.py
## quad_over_lin(x, y) = ||x||^2 / y -> t via SOC
## Phase 5a: axis=NULL case only


quad_over_lin_canon <- function(expr, args, solver_context = NULL) {
  x <- args[[1L]]
  y <- args[[2L]]
  axis <- expr@axis

  if (is.null(axis)) {
    ## Scalar output -- single SOC constraint
    ## ||[y-t, 2*vec(x)]||_2 <= y+t  ==>  ||x||^2 <= t*y
    ## CVXPY: hstack([y-t, 2*x.flatten()]) -> 1D concat, axis=0 -> single cone
    ## In R (always 2D): VStack to get column vector c(1+n, 1) for 1 cone
    t <- Variable(shape = c(1L, 1L))
    y_flat <- reshape_expr(y, c(1L, 1L))
    x_flat <- .cvxr_vec(x)  # c(n, 1) column vector
    lhs <- VStack(y_flat - t, 2 * x_flat)  # c(1+n, 1)
    constraints <- list(SOC(t = y_flat + t, X = lhs, axis = 2L))
    list(t, constraints)
  } else {
    ## Axis-aware case -- defer to Phase 5b
    cli_abort("quad_over_lin with axis != NULL not yet supported in canonicalization.")
  }
}

method(dcp_canonicalize, QuadOverLin) <- quad_over_lin_canon
method(has_dcp_canon, QuadOverLin) <- function(expr) TRUE

Try the CVXR package in your browser

Any scripts or data that you put into this service are public.

CVXR documentation built on March 6, 2026, 9:10 a.m.