R/012_utilities_solver_context.R

Defines functions .maybe_warn_soc_approx .solver_supports_cone

#####
## DO NOT EDIT THIS FILE!! EDIT THE SOURCE INSTEAD: rsrc_tree/utilities/solver_context.R
#####

## CVXPY SOURCE: utilities/solver_context.py
##
## SolverInfo carries the chosen solver's name and supported-constraint
## set down through the solving chain so canonicalizers can see what the
## target solver can handle (used today only by the SOC-approximation
## warnings in power/geo_mean/pnorm approx canonicalizers and by auxiliary
## variable bound propagation).
##
## Mirrors CVXPY's `SolverInfo` (lines 18-24).  `solver_supported_constraints`
## holds S7 class objects (e.g. PowCone3D, PowConeND, SOC), matching how
## CVXR stores `@SUPPORTED_CONSTRAINTS` on solver instances.

## `psd_triangle_kind` / `psd_sqrt2_scaling` mirror solver_context.py:27-28 --
## the chosen solver's PSD svec format, carried so the PSD -> svec conversion
## and its dual recovery read it from ONE place instead of each solver
## interface re-deriving it (ADR D_19.6).  NA means the solver takes full PSD
## matrices (CVXPY's `None`).

SolverInfo <- new_class("SolverInfo", package = "CVXR",
  properties = list(
    solver_name                  = class_character,
    solver_supported_constraints = class_list,
    solver_supports_bounds       = class_logical,
    psd_triangle_kind            = class_character,
    psd_sqrt2_scaling            = class_logical
  ),
  constructor = function(solver_name = NA_character_,
                         solver_supported_constraints = list(),
                         solver_supports_bounds = FALSE,
                         psd_triangle_kind = NA_character_,
                         psd_sqrt2_scaling = NA) {
    if (FALSE) new_object(S7_object())  ## S7 static-check guard
    .fast_new(SolverInfo, S7_object(),
      solver_name                  = as.character(solver_name),
      solver_supported_constraints = solver_supported_constraints,
      solver_supports_bounds       = isTRUE(solver_supports_bounds),
      psd_triangle_kind            = as.character(psd_triangle_kind),
      psd_sqrt2_scaling            = as.logical(psd_sqrt2_scaling)
    )
  }
)

## CVXPY SOURCE: settings.py:212-213
.POWERCONE_APPROX_ERROR_THRESHOLD <- 1e-6
.POWERCONE_APPROX_SOC_THRESHOLD   <- 4L

## Predicate: is `target_cone` listed in this solver's supported constraints?
## `solver_supported_constraints` is a list of S7 class objects.
.solver_supports_cone <- function(solver_context, target_cone) {
  if (is.null(solver_context)) return(FALSE)
  supported <- solver_context@solver_supported_constraints
  any(vapply(supported, identical, logical(1L), target_cone))
}

## Emit a UserWarning analogue when the chosen solver supports the
## target power cone yet we are still expanding into an SOC tower.
## Mirrors the warn-emission blocks in CVXPY's power_canon / geo_mean_canon /
## pnorm_canon (lines 84-101, 70-86, 121-137 respectively).
.maybe_warn_soc_approx <- function(solver_context, target_cone,
                                    approx_error, num_soc, msg_head) {
  if (!.solver_supports_cone(solver_context, target_cone)) return(invisible(NULL))
  if (approx_error <= .POWERCONE_APPROX_ERROR_THRESHOLD &&
      num_soc      <= .POWERCONE_APPROX_SOC_THRESHOLD) {
    return(invisible(NULL))
  }
  cli::cli_warn(c(
    "{msg_head} (error: {sprintf('%.2e', approx_error)}) using {num_soc} SOC constraints.",
    "i" = "Consider using {.code approx = FALSE} to use power cones instead."
  ))
  invisible(NULL)
}

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.