CVXPY: Convex optimization, for everyone#

cvxpy logo

CVXPY is an open-source Python tool tailored for convex optimization problems. Unlike many platforms which require you to express your problem in strict formats determined by optimization solvers, CVXPY allows users to lay out their problem in a way that follows the maths.

A significant benefit of this is that CVXPY decouples the problem’s formulation from the solver used to tackle it. This means that once a problem is defined within CVXPY, one can seamlessly switch between or experiment with different solvers without the need to adjust the problem’s representation. Additionally, CVXPY supports an extensive range of both commercial and open-source solvers, providing users with the flexibility to choose the most appropriate tool for their specific challenges, be it for experimentation or scalability. This versatility simplifies the optimization process, making it more accessible and efficient.

import corneto as cn

cn.info()
Installed version:v1.0.0.dev3 (latest stable: v1.0.0-alpha)
Available backends:CVXPY v1.6.0, PICOS v2.5.1
Default backend (corneto.opt):CVXPY
Installed solvers:CVXOPT, GLPK, GLPK_MI, HIGHS, SCIP, SCIPY
Graphviz version:v0.20.3
Installed path:/home/runner/work/corneto/corneto/corneto
Repository:https://github.com/saezlab/corneto
import numpy as np

from corneto.backend import CvxpyBackend

backend = CvxpyBackend()
P = backend.Problem()
A = np.array([[0.12, 0.92, 0.76, 0.98, 0.79], [0.58, 0.57, 0.53, 0.71, 0.55]])
b = np.array([1, 0])
x = backend.Variable("x", A.shape[1])
P += sum(x) == 1, x >= 0

P.add_objectives(sum(A @ x - b))
cvxpy_model = P.solve(solver="osqp", verbosity=1)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[2], line 13
     10 P += sum(x) == 1, x >= 0
     12 P.add_objectives(sum(A @ x - b))
---> 13 cvxpy_model = P.solve(solver="osqp", verbosity=1)

File ~/work/corneto/corneto/corneto/backend/_base.py:579, in ProblemDef.solve(self, solver, max_seconds, warm_start, verbosity, **options)
    577 if self._backend is None:
    578     raise ValueError("No backend assigned.")
--> 579 return self._backend.solve(
    580     self,
    581     solver=solver,
    582     max_seconds=max_seconds,
    583     warm_start=warm_start,
    584     verbosity=verbosity,
    585     **options,
    586 )

File ~/work/corneto/corneto/corneto/backend/_base.py:840, in Backend.solve(self, p, solver, max_seconds, warm_start, verbosity, **options)
    834 else:
    835     o = (
    836         p.weights[0] * p.objectives[0]
    837         if p.objectives and p.weights[0] != 0
    838         else None
    839     )
--> 840 return self._solve(
    841     p,
    842     objective=o,
    843     solver=solver,
    844     max_seconds=max_seconds,
    845     warm_start=warm_start,
    846     verbosity=verbosity,
    847     **options,
    848 )

File ~/work/corneto/corneto/corneto/backend/_cvxpy_backend.py:170, in CvxpyBackend._solve(self, p, objective, solver, max_seconds, warm_start, verbosity, **options)
    168 solvers = cp.installed_solvers()
    169 if s is not None and s not in solvers:
--> 170     raise ValueError(
    171         f"Solver {s} is not installed/supported, supported solvers are: {solvers}"
    172     )
    173 # TODO: Implement parameter mapping for solvers and backends
    174 if max_seconds is not None:

ValueError: Solver OSQP is not installed/supported, supported solvers are: ['CVXOPT', 'GLPK', 'GLPK_MI', 'HIGHS', 'SCIP', 'SCIPY']
P.objectives[0].value
-0.30000000000000004
type(P)
corneto.backend._base.ProblemDef
type(cvxpy_model)
cvxpy.problems.problem.Problem
cvxpy_model.status
'optimal'