Skip to content

Add ConvexOptimization subpackage (disciplined convex programming backend)#1263

Draft
ChrisRackauckas-Claude wants to merge 2 commits into
SciML:masterfrom
ChrisRackauckas-Claude:add-convexoptimization-subpackage
Draft

Add ConvexOptimization subpackage (disciplined convex programming backend)#1263
ChrisRackauckas-Claude wants to merge 2 commits into
SciML:masterfrom
ChrisRackauckas-Claude:add-convexoptimization-subpackage

Conversation

@ChrisRackauckas-Claude

Copy link
Copy Markdown
Member

Note

Draft / experimental, and blocked on SciML/SciMLBase.jl#1440 (the ConvexOptimizationProblem/ConvexOptimizationSolution types are unreleased). Please ignore until reviewed by @ChrisRackauckas. CI will be red until #1440 merges and SciMLBase releases — the [sources] git-rev is a temporary bridge.

New lib/ConvexOptimization subpackage: the disciplined-convex-programming backend for the SciML optimization stack, and the first vertical slice of the Convex.jl / cvxpy replacement effort (SymbolicAnalysis.jl#121).

What it does

solve(::ConvexOptimizationProblem, ConvexMOI(Clarabel.Optimizer)):

  1. Certifies the objective and constraints convex with SymbolicAnalysis.jl (analyze), erroring (route-to-NLP) if not — a non-convex problem is rejected, never silently mis-solved.
  2. Lowers the affine objective and each ConeConstraint to MathOptInterface via Symbolics.linear_expansion.
  3. Solves with Clarabel (any MOI conic solver via the optimizer_constructor).
  4. Returns a ConvexOptimizationSolution carrying the primal and the dual multipliers — the optimality certificate that OptimizationSolution lacks (OptimizationMOI never surfaces duals).

Purpose of this PR

Primarily to verify the new SciMLBase interface end-to-end — that a ConvexOptimizationProblem constructs, solve routes to a backend, and a ConvexOptimizationSolution with correct duals comes back. It does.

Design notes

  • Routing: ConvexOptimizationProblem <: AbstractOptimizationProblem is a sibling of OptimizationProblem, and OptimizationBase's solve/init dispatch on the concrete OptimizationProblem, so the standard indirection is not inherited. The backend therefore defines SciMLBase.init(::ConvexOptimizationProblem, alg) and SciMLBase.solve!(::ConvexOptimizationCache); solve = solve! ∘ init composes them via CommonSolve.
  • Constraint representation (the opaque ConvexOptimizationProblem.constraints field): a Vector{ConeConstraint}, each ConeConstraint(g, set) pairing a callable affine map g(u,p)->Vector with an MOI cone. This is symmetric with the callable objective (one tracing path), gives exact 1:1 constraint→dual alignment, and fixes the dual sign at construction (>=Nonnegatives, <=Nonpositives, ==Zeros) so the returned ConstraintDual is already in the user's variables — verified to match Convex.jl with no sign flip.

Scope (MVP)

Affine objective + affine-in-cone constraints (LP), plus second-order-cone constraints. A norm2-in-objective epigraph atom (add aux t, [t; Ax+b] ∈ SOC) and the full symbolic atom→cone canonicalizer are the next steps.

Verification

Pkg.test() locally (against the #1440 SciMLBase branch): Core 15/15 pass, covering

  • LP min x₁+2x₂ s.t. x₁+x₂=1, x≥0 → primal [1,0], obj 1, duals [1] (equality) and [0,1] (nonneg cone) — machine-exact vs the analytic values (which equal Convex.jl's);
  • an SOC-constraint solve (min t s.t. ‖(x₁,x₂)‖≤t, x=(3,4)t=5);
  • non-convex objective (x₁x₂) rejected by certification;
  • the solution cache exposing the SciMLBase u0/p glue fields.

An optional Convex.jl cross-check is included (skipped when Convex isn't in the env, since the analytic assertions already pin the same numbers).

🤖 Generated with Claude Code

ChrisRackauckas and others added 2 commits July 12, 2026 17:41
…kend)

New lib/ConvexOptimization: solves a SciMLBase.ConvexOptimizationProblem
by certifying convexity with SymbolicAnalysis.jl, lowering the affine
objective and each ConeConstraint to MathOptInterface via
Symbolics.linear_expansion, and solving with a conic solver (default
Clarabel). Returns a ConvexOptimizationSolution carrying primal AND dual
multipliers — the optimality certificate OptimizationSolution lacks.

Primary purpose: verify the new SciMLBase ConvexOptimizationProblem /
ConvexOptimizationSolution interface (SciML/SciMLBase.jl#1440) end to end.

- Routing: ConvexOptimizationProblem is a sibling of OptimizationProblem,
  so the backend defines SciMLBase.init(::ConvexOptimizationProblem, alg)
  and SciMLBase.solve!(::ConvexOptimizationCache); solve = solve! ∘ init
  via CommonSolve.
- Constraints: Vector{ConeConstraint}, each pairing a callable affine map
  g(u,p)->Vector with an MOI cone, giving 1:1 constraint→dual alignment
  and construction-time dual signs (duals already in user variables).
- Scope: LP + second-order-cone constraints; non-convex objectives are
  rejected by certification, not mis-solved.

Blocked on SciML/SciMLBase.jl#1440 (the problem/solution types are
unreleased); the [sources] git-rev is a temporary bridge until it lands.
Verified locally: Pkg.test() Core 15/15 pass (LP primal+dual machine-exact
vs analytic/Convex.jl, SOC solve, non-convex rejection, cache glue).

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…imizationSolution

SciMLBase v3.36.0 registers ConvexOptimizationProblem and folds the convex
solution into the single OptimizationSolution (with a type-stable `dual` field),
removing ConvexOptimizationSolution. So:

- Drop the temporary [sources] git-rev to the SciMLBase #1440 branch and bump
  the compat floor to SciMLBase = "3.36" (the release carrying the types).
- Use OptimizationSolution instead of ConvexOptimizationSolution in the backend
  and its test; the solve already returns the one struct with duals populated
  (build_convex_solution defaults calculate_dual = Val(true)).

Verified against released SciMLBase 3.36.0: resolves, LP/SOC solves return
correct primal + dual, non-convex objective rejected; all core tests pass.

Co-Authored-By: Chris Rackauckas <accounts@chrisrackauckas.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants