Metadata-Version: 2.3
Name: cvqp
Version: 0.1.0
Summary: A Python implementation of the CVQP solver for CVaR-constrained quadratic programs
License: MIT
Author: David Perez Pineiro
Requires-Python: >=3.11,<4.0
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Scientific/Engineering :: Mathematics
Requires-Dist: cvxpy (>=1.6.0,<2.0.0)
Requires-Dist: matplotlib (>=3.9.2,<4.0.0)
Requires-Dist: numpy (>=2.1.3,<3.0.0)
Requires-Dist: scipy (>=1.14.1,<2.0.0)
Requires-Dist: tqdm (>=4.67.1,<5.0.0)
Project-URL: Repository, https://github.com/davidper/cvqp
Description-Content-Type: text/markdown

# CVQP

A Python implementation of the CVQP solver, as described in our paper "An Operator
Splitting Method for Large-Scale CVaR-Constrained Quadratic Programs."

This solver handles CVaR-constrained quadratic programs (CVQPs) of the form:

$$
\begin{align*}
\underset{x}{\text{minimize}} & \quad \frac{1}{2}x^TPx + q^Tx \\
\text{subject to} & \quad \phi_\beta(Ax) \leq \kappa, \\
                  & \quad l \leq Bx \leq u
\end{align*}
$$

The variable $x$ is a vector of length $n$. The objective has a positive
semidefinite matrix $P$ and a vector $q$. The function $\phi_\beta$ is the
Conditional Value-at-Risk (CVaR) with parameter $\beta \in (0,1)$, applied to
$Ax$ where $A$ is an $m \times n$ matrix. Box constraints are defined by matrix
$B$ and bounds $l$, $u$ that can include infinity.

## Installation

### From PyPI (recommended)

```bash
pip install cvqp
```

### From Source

Clone the repository and install using Poetry:

```bash
# Clone the repository
git clone https://github.com/davidper/cvqp.git
cd cvqp

# Install dependencies
poetry install

# Compile C++ extensions
poetry run pip install -e .
```

## Usage

```python
import numpy as np
from cvqp import CVQP, CVQPParams, CVQPConfig

# Define problem parameters
params = CVQPParams(
    P=np.eye(10),              # Quadratic cost matrix
    q=np.ones(10) * -0.1,      # Linear cost vector
    A=np.random.randn(100, 10) * 0.2 + 0.1,  # CVaR constraint matrix
    B=np.eye(10),              # Box constraint matrix
    l=-np.ones(10),            # Lower bounds
    u=np.ones(10),             # Upper bounds
    beta=0.9,                  # CVaR confidence level
    kappa=0.1,                 # CVaR limit
)

# Create solver with custom configuration
config = CVQPConfig(
    verbose=True,              # Print detailed progress
    max_iter=1000,             # Maximum iterations
    abstol=1e-4,               # Absolute tolerance
    reltol=1e-3,               # Relative tolerance
)

# Initialize and solve
solver = CVQP(params, config)
results = solver.solve()

# Access solution
print(f"Optimal value: {results.objval[-1]:.6f}")
print(f"Solver status: {results.problem_status}")
print(f"Solve time: {results.solve_time:.2f} seconds")
print(f"Iterations: {results.iter_count}")
```

## Sum-k-Largest Projection

The package also provides a function for projecting onto the set where the sum of k largest elements is at most alpha:

```python
from cvqp import proj_sum_largest

# Project a vector
z = np.array([6.0, 2.0, 5.0, 4.0, 1.0])
k = 2  # Number of largest elements to constraint
alpha = 7.0  # Upper bound on sum

# Apply projection
result = proj_sum_largest(z, k, alpha)
print(f"Sum of {k} largest elements after projection: {sum(sorted(result, reverse=True)[:k]):.6f}")
```

## Examples

See the `examples/` directory for notebooks demonstrating:
- Portfolio optimization with CVaR constraints
- Quantile regression with CVaR formulation

## Benchmarks

To reproduce the benchmark results shown in the paper, run these scripts in the `examples/` directory:

```bash
# For sum-k-largest projection benchmarks
python benchmark_proj.py

# For CVQP solver benchmarks
python benchmark_cvqp.py
```

Results are saved in the `examples/data/` directory and can be visualized using the
`examples/benchmarks.ipynb` notebook.

> **Note**: Our benchmarks compare against MOSEK, which requires a license.
Academic licenses are available at no cost, and commercial trial licenses can be
obtained from the [MOSEK website](https://www.mosek.com/products/trial/).
