Skip to main content

Efficient Interior Point Method solvers for convex optimization

Project description

Cvxium

CI

Cvxium (pronounced "Calcium") is a Python framework for building fast Interior Point Method (IPM) solvers for convex optimization problems of the form:

minimize    f0(x)
subject to  A x = b
            fi(x) <= 0,  i = 1, ..., n

The framework's distinguishing feature is a clean interface for exploiting Hessian structure to accelerate Newton steps. A generic solver inverts an n×n dense matrix at each iteration — O(n³). By encoding the Hessian's structure (diagonal, low-rank update, arrow sparsity pattern, etc.), the same iteration can run in O(n). This allows problems to scale to dimensions in the thousands or even higher.

Why Cvxium?

Most convex optimization needs are well-served by existing tools. Here is how Cvxium compares:

Tool When to use it Why not Cvxium
scipy.optimize General-purpose unconstrained/constrained optimization Handles arbitrary problems with minimal setup; no structural speedups needed
Cvxpy Rapid prototyping of convex programs; standard problem forms Modeling-layer convenience; dispatches to mature solvers (OSQP, SCS, ECOS) under the hood
Gurobi / CPLEX LP, QP, MIP at industrial scale Commercial license; exceptional performance on problems they support, including integers
OSQP / SCS Large-scale QPs and conic programs Fast first-order methods; good default choice when the problem fits their form

Use Cvxium when:

  • Your problem has a custom convex structure that does not map cleanly onto a standard QP/LP/SOCP form — e.g., KL-divergence objectives, Huber loss with non-standard constraints, or specialized barrier functions.
  • The Hessian has exploitable structure (diagonal, diagonal plus low-rank, arrow sparsity) that off-the-shelf solvers cannot leverage.
  • You need predictable, low-overhead performance without a commercial license or a large solver dependency.

Do not use Cvxium when:

  • Your problem fits a standard form that Cvxpy or Gurobi handles well. Those tools are mature, well-tested, and require far less code.
  • You need integer variables. Cvxium is strictly continuous convex optimization.
  • You want a solver you can just call. Cvxium's value is in the framework: you implement the math, it handles the IPM loop. If you are not willing to derive gradients and Hessians (or have an AI agent do this for you), use Cvxpy.

Installation

pip install cvxium

Or with uv:

uv add cvxium

Quick start: ready-made solvers

For the most common problem types, Cvxium ships concrete solvers that require no subclassing.

Find x satisfying Ax = b, x ≥ lb

EqualityWithBoundsSolver finds a feasible point and, if requested, minimizes ‖x‖₂² subject to the constraints:

import numpy as np
from cvxium import EqualityWithBoundsSolver, OptimizationSettings

A = np.random.randn(20, 100)   # p=20 equality constraints, M=100 variables
w_true = np.random.rand(100) + 0.1
b = A @ w_true
lb = 0.01

solver = EqualityWithBoundsSolver(A=A, b=b, lb=lb)

# Feasibility: find any strictly feasible point
result = solver.solve()
assert np.all(result.solution > lb)
assert np.allclose(A @ result.solution, b)

# Optimize: minimize ‖x‖₂²
result = solver.solve(fully_optimize=True)

The solver detects infeasibility via the dual certificate and raises ProblemCertifiablyInfeasibleError when the problem has no solution.

Find x satisfying Ax = b, x ≥ lb, ‖Bx − c‖∞ ≤ ψ

EqualityWithBoundsAndImbalanceConstraintSolver adds an L∞ imbalance constraint, useful when exact balance on a subset of covariates is required alongside a bound on a larger set:

from cvxium import EqualityWithBoundsAndImbalanceConstraintSolver

solver = EqualityWithBoundsAndImbalanceConstraintSolver(
    A=A, b=b, lb=lb,
    B=B, c=c, psi=0.05,  # ‖Bx − c‖∞ ≤ 0.05
)
result = solver.solve()

Solve a quadratic program with equality and bound constraints

QuadraticProgramEqualityBoundsSolver solves:

minimize    x^T Q x + c^T x
subject to  A x = b
            x >= xl

It accepts optional Q_vector_multiply and Q_solve callables to exploit structure in Q:

from cvxium import QuadraticProgramEqualityBoundsSolver

solver = QuadraticProgramEqualityBoundsSolver(Q=Q, c=c, A=A, b=b, xl=xl)
result = solver.solve()

print(result.solution)        # optimal x
print(result.objective_value) # primal objective
print(result.dual_value)      # dual lower bound (duality gap = objective - dual)
print(result.nits)            # outer IPM iterations
print(result.inner_nits)      # Newton iterations per centering step

When Q has structure (e.g., diagonal plus rank-one), passing Q_vector_multiply and Q_solve callables can yield a further ~12× speedup over the dense path. See USAGE.md for the full pattern.

Building a custom solver

Cvxium's real power is its framework for new problem types. You subclass one of the base classes, implement a handful of methods (objective, gradient, Hessian multiply, Newton step, dual), and the IPM loop is handled for you. A library of composable structured linear system solvers (solve_diagonal, solve_rank_one_update, solve_rank_p_update, solve_kkt_system, etc.) makes it straightforward to go from a mathematical description of the Hessian to a fast Newton step.

Full guidance — including worked examples, the class hierarchy, and the numerical helpers reference — is in USAGE.md and can be retrieved at runtime:

import cvxium
cvxium.usage()

An AI agent can implement a custom solver from an existing codebase with a prompt like:

Look at the optimization problem being solved in <function>. Learn how to use Cvxium by running python -c 'import cvxium; print(cvxium.usage())'. Make a plan to refactor <function> using Cvxium.

Exception hierarchy

BacktrackingLineSearchError
├── ConstraintBoundaryError       — step would violate a constraint
├── InvalidDescentDirectionError  — Newton step is not a descent direction
└── SevereCurvatureError          — backtracking condition never satisfied

OptimizationError
├── CenteringStepError            — inner Newton loop failed
└── InteriorPointMethodError      — outer IPM loop failed

ProblemInfeasibleError            — no feasible point exists
ProblemCertifiablyInfeasibleError — dual certificate proves infeasibility
ProblemMarginallyFeasibleError    — feasible set is non-empty but has no interior

Optimization settings

OptimizationSettings controls the IPM:

from cvxium import OptimizationSettings

settings = OptimizationSettings(
    barrier_multiplier=10.0,    # factor by which t increases each outer iteration
    outer_tolerance=1e-8,       # duality gap threshold for convergence
    outer_tolerance_soft=None,  # looser threshold for feasibility-only problems
    max_outer_iterations=100,
    max_inner_iterations=100,
    verbose=False,
)

References

  • Boyd, Stephen and Vandenberghe, Lieven. Convex Optimization. Cambridge University Press, 2004.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cvxium-0.3.0.tar.gz (51.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cvxium-0.3.0-py3-none-any.whl (58.3 kB view details)

Uploaded Python 3

File details

Details for the file cvxium-0.3.0.tar.gz.

File metadata

  • Download URL: cvxium-0.3.0.tar.gz
  • Upload date:
  • Size: 51.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for cvxium-0.3.0.tar.gz
Algorithm Hash digest
SHA256 65de0ad695daf7f42bd0a21a92719778db50a71ffd5c8811765d02a59ecec215
MD5 c5d590d352a95e9df2b29ed9de2fd099
BLAKE2b-256 56e0c70a396d56cdc06f6c144dc1b762141ef25423f86db4014bbeb65ae463ee

See more details on using hashes here.

Provenance

The following attestation bundles were made for cvxium-0.3.0.tar.gz:

Publisher: publish.yml on rwilson4/Cvxium

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cvxium-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: cvxium-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 58.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for cvxium-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b68f620042344cf3a9a5efdb4abe2ed8b6e3361d49c8ec6ddc114c1c0c39244f
MD5 0f3000304f08f56798409d586070ff34
BLAKE2b-256 59740050f1344aefa31649dcd6a3e0ef9a7dfef242cb757edc88214a718e3517

See more details on using hashes here.

Provenance

The following attestation bundles were made for cvxium-0.3.0-py3-none-any.whl:

Publisher: publish.yml on rwilson4/Cvxium

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page