| Crates.io | cvxrust |
| lib.rs | cvxrust |
| version | 0.1.0 |
| created_at | 2025-12-14 23:24:08.250393+00 |
| updated_at | 2025-12-14 23:24:08.250393+00 |
| description | A Rust implementation of Disciplined Convex Programming |
| homepage | |
| repository | https://github.com/cvxpy/cvxrust |
| max_upload_size | |
| id | 1985270 |
| size | 330,476 |
A Disciplined Convex Programming (DCP) library for Rust, inspired by CVXPY.
cvxrust provides a domain-specific language for specifying convex optimization problems with automatic convexity verification and solving via the Clarabel solver.
constraint! macro for natural >=, <=, == notationAdd to your Cargo.toml:
[dependencies]
cvxrust = "0.1"
use cvxrust::prelude::*;
// Minimize ||x||_2 subject to sum(x) = 1, x >= 0
let x = variable(5);
let solution = Problem::minimize(norm2(&x))
.subject_to([
constraint!((sum(&x)) == 1.0),
constraint!(x >= 0.0),
])
.solve()
.unwrap();
println!("Optimal value: {}", solution.value.unwrap());
println!("x = {:?}", &solution[&x]);
# Build the library
cargo build
# Run all tests (159 tests)
cargo test
# Run a specific test
cargo test test_name
# Run tests with output visible
cargo test -- --nocapture
# Run examples
cargo run --example portfolio
cargo run --example least_squares
cargo run --example quadratic_program
# Lint with clippy
cargo clippy
# Generate documentation
cargo doc --open
| Problem Type | Objective | Constraints |
|---|---|---|
| LP | Linear | Linear equality/inequality |
| QP | Quadratic (convex) | Linear equality/inequality |
| SOCP | Linear | Second-order cone |
| Exp Cone | Exponential/log | Exponential cone |
| Mixed | Any convex | Combination of above |
+, -, * (scalar), / (scalar)sum, sum_axis, cumsumreshape, flatten, vstack, hstack, transpose, diagmatmul, dot, traceindex, slicenorm1, norm2, norm_inf, normabs, pos, neg_part, expmaximum, max2quad_form (PSD), sum_squares, quad_over_linpower (p >= 1 or p < 0)minimum, min2quad_form (NSD)log, entropypower (0 < p < 1), sqrt// Simple vector variable
let x = variable(5);
// Matrix variable
let X = variable((3, 4));
// Scalar variable
let t = variable(());
// Named variable with bounds
let x = VariableBuilder::vector(5)
.name("x")
.nonneg() // x >= 0
.build();
cvxrust provides the constraint! macro for natural constraint syntax:
use cvxrust::prelude::*;
let x = variable(5);
// Using constraint! macro (recommended)
let constraints = [
constraint!(x >= 0.0), // x >= 0
constraint!(x <= 10.0), // x <= 10
constraint!((sum(&x)) == 1.0), // sum(x) = 1
];
// Method syntax also available
let c1 = x.ge(0.0); // x >= 0
let c2 = x.le(10.0); // x <= 10
let c3 = sum(&x).eq(1.0);
// Second-order cone constraint: ||x||_2 <= t
let t = variable(());
let soc = Constraint::soc(t, x);
let solution = problem.solve()?;
// Check status
assert_eq!(solution.status, SolveStatus::Optimal);
// Get optimal objective value
let value = solution.value.unwrap();
// Get variable values using indexing
let x_val = &solution[&x];
// Get scalar value
let t_val = solution.value(&t);
// Access dual variables (shadow prices)
let duals = solution.duals();
let dual_0 = solution.constraint_dual(0); // Dual for first constraint
let x = variable(n);
let residual = &A * &x - &b;
let solution = Problem::minimize(sum_squares(&residual)).solve()?;
let x = variable(n);
let loss = sum_squares(&(&A * &x - &b));
let reg = norm1(&x);
let solution = Problem::minimize(loss + lambda * reg).solve()?;
let w = variable(n);
let risk = quad_form(&w, &sigma); // w' * Sigma * w
let solution = Problem::minimize(risk)
.subject_to([
constraint!((dot(&mu, &w)) >= target_return),
constraint!((sum(&w)) == 1.0),
constraint!(w >= 0.0),
])
.solve()?;
// Access dual variable for return constraint (shadow price)
if let Some(dual) = solution.constraint_dual(0) {
println!("Marginal cost of increasing return: {}", dual);
}
let theta = variable(n);
// log(1 + exp(-y * X @ theta)) using log-sum-exp
let solution = Problem::minimize(log_sum_exp_loss)
.subject_to([constraint!((norm2(&theta)) <= C)])
.solve()?;
cvxrust enforces Disciplined Convex Programming rules:
Objective:
minimize(convex) or maximize(concave)Constraints:
convex <= concaveconcave >= convexaffine == affineCurvature is determined by DCP composition rules - for example, convex + convex = convex, and nonneg * convex = convex. See dcp.stanford.edu for a complete reference.
Problems that violate DCP rules will return a DcpError.
Expression -> DCP Verification -> Canonicalization -> Matrix Stuffing -> Clarabel -> Solution
Apache 2.0