R/185_reductions_dcp2cone_canonicalizers_quad_huber_canon.R

Defines functions huber_quad_canon

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

## CVXPY SOURCE: reductions/dcp2cone/canonicalizers/quad/huber_canon.py
## huber(x, M) = n^2 + 2*M*|s| where x = s + n
## Uses power_quad_canon for n^2 (produces SymbolicQuadForm)
## and abs_canon for |s| (produces linear + constraints)


huber_quad_canon <- function(expr, args, solver_context = NULL) {
  M <- expr@M
  x <- args[[1L]]
  shape <- .shape(expr)
  n <- Variable(shape = shape)
  s <- Variable(shape = shape)

  ## n^2 via power_quad_canon -> SymbolicQuadForm
  power_expr <- power(n, 2)
  n2_result <- power_quad_canon(power_expr, .args(power_expr))
  n2 <- n2_result[[1L]]
  constr_sq <- n2_result[[2L]]

  ## |s| via abs_canon (linear + constraints)
  abs_expr <- Abs(s)
  abs_result <- abs_canon(abs_expr, .args(abs_expr))
  abs_s <- abs_result[[1L]]
  constr_abs <- abs_result[[2L]]

  obj <- n2 + 2 * M * abs_s

  ## x == s + n
  constraints <- c(constr_sq, constr_abs, list(x == s + n))
  list(obj, constraints)
}

method(quad_canonicalize, Huber) <- huber_quad_canon

## Membership marker for the CSE cache: `affine_above` is part of a subtree's
## cache key only when the quad branch could fire inside it
## (`.affine_above_relevant`, dcp2cone.R). CVXPY reads this off its
## `quad_canon_methods` dict; CVXR needs an explicit predicate per class.
method(has_quad_canon, Huber) <- 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 Aug. 24, 2026, 9:10 a.m.