No project description provided
Project description
coneref
coneref
is a Python package for iteratively refining an approximate solution to a conic linear program. It has an interface to cvxpy
and is easy to use.
Installation
coneref
is available on PyPI. Install it with
pip install coneref
coneref
uses Eigen
for linear algebra. Eigen has a built-in support for vectorization. To enable vectorization, install coneref
from the source distribution using the command (on Linux)
MARCH_NATIVE=1 pip install coneref --no-binary=coneref
Enabling vectorization typically decreases the refinement time by a factor of 2 for problems with matrix variables and by 10% for problems with vector variables.
Building coneref
from the source distribution requires a compiler that supports C++11.
Refinement
The basic idea of the refinement procedure is to reduce the problem of solving a conic linear program to the problem of finding a zero of a nonlinear map. A Newton-based method is then applied to solve the root-finding problem. For more details, see the paper Solution Refinement at Regular Points of Conic Problems. Also see the note refinement_theory_note.pdf.
Basic example
coneref
can be used in combination with cvxpy
. The following optimization problem arises in the context of sparse inverse covariance estimation:
$$\begin{equation*} \begin{array}{ll} \text{minimize} & \text{log det} (S) + \text{Tr} (S Q) + \alpha \left\lVert S\right\rVert_1 \end{array} \end{equation*},$$
where the optimization variable is $S \in \bf{S}^n$. The following code snippet generates a problem instance, solves it using SCS
, takes two refinement steps and then two additional refinement steps.
import numpy as np
import scipy
from sklearn.datasets import make_sparse_spd_matrix
import cvxpy as cp
import coneref
# Generate problem data.
q = 40
p = (7 + np.random.randint(0, 6))*q
ratio = 0.9
S_true = make_sparse_spd_matrix(q, alpha = ratio)
Sigma = np.linalg.inv(S_true)
z_sample = scipy.linalg.sqrtm(Sigma).dot(np.random.randn(q,p))
Q = np.cov(z_sample)
mask = np.ones(Q.shape, dtype=bool)
np.fill_diagonal(mask, 0)
alpha_max = np.max(np.abs(Q)[mask])
alpha = 0.005*alpha_max
# Build optimization model using cvxpy.
S = cp.Variable((q, q), PSD = True)
obj = -cp.log_det(S) + cp.trace(S @ Q) + alpha*cp.sum(cp.abs(S))
problem = cp.Problem(objective = cp.Minimize(obj))
# Solve problem using SCS, take two refinement steps.
print("Solve problem with SCS and take two refinement steps.")
coneref.cvxpy_solve(problem, verbose_scs=False)
# Refine again.
print("Take two additional refinement steps.")
coneref.cvxpy_solve(problem)
# Retrieve the solution.
estimated_covariance_matrix = S.value
Running this code snippet produces the following output.
Solve problem with SCS and take two refinement steps.
After SCS (total time = 8.74e+02s):
Primal residual/dual residual/duality_gap: 4.7324e-05 1.7722e-02 -7.7714e-04
After refinement (ref time = 5.68e+00s):
Primal residual/dual residual/duality_gap: 1.6998e-05 6.8185e-07 1.4947e-07
Take two additional refinement steps.
After refinement (ref time = 5.16e+00s):
Primal residual/dual residual/duality_gap: 6.5164e-06 3.5763e-07 -3.4035e-08
Interface
The package exposes the function
cvxpy_solve(prob, ref_iter=2, lsqr_iter=300, verbose_scs=True, scs_opts={}, warmstart=False, verbose_ref1=True, verbose_ref2=True).
Here the arguments are defined as follows.
prob
- The problem you want to solve in CVXPY-format.ref-iter
- number of refinement steps.lsqr_iter
- each refinement step requires solving a sparse linear system approximately. This parameter determines the maximum number of LSQR iterations.verbose_scs
- verbose parameter sent to SCS. If true, SCS outputs its progress.warm_start
- Whether to warm-start SCS or not.verbose_ref1
- If true the refinement algorithm outputs the norm of the KKT-residuals/infeasibility certificates.verbose_ref2
- If true the refinement algorithm outputs the norm of the normalized residual map. This option is mainly for developers.
The function modifies the object prob
in the following way: TODO
How well does it work?
The refinement algorithm can often produce a more accurate solution with just a small additional cost, see Section 4 of refinement_theory_note.pdf for empirical results.
Acknowledgements
TODO
Some code has been modified from ...
Also add tests.
Citing
If you find this package useful, consider citing the following works.
@misc{cpr,
author = {Cederberg, D. and Boyd, S.},
title = {{coneref}: conic LP refinement, version 0.1},
howpublished = {\url{https://github.com/dance858/coneref}},
year = 2022
}
@article{cpr2019,
author = {Busseti, E. and Moursi, W. and Boyd, S.},
title = {Solution refinement at regular points of conic problems},
journal = {Computational Optimization and Applications},
year = {2019},
volume = {74},
number = {3},
pages = {627--643},
}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
File details
Details for the file coneref-0.2.2.tar.gz
.
File metadata
- Download URL: coneref-0.2.2.tar.gz
- Upload date:
- Size: 2.7 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.8.14
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 47f5feea32a5438a542cd62261539c9c60d0fa1d20e51564bed506fbad955107 |
|
MD5 | d2f9cedc1ab51c65714da9c41fa1c612 |
|
BLAKE2b-256 | 1833578c34092ce2c7e9dcde306017ef373d5891a5de28c989979c65844fde23 |
File details
Details for the file coneref-0.2.2-cp38-cp38-win_amd64.whl
.
File metadata
- Download URL: coneref-0.2.2-cp38-cp38-win_amd64.whl
- Upload date:
- Size: 203.3 kB
- Tags: CPython 3.8, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.8.10
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | cff98202654b7d39b79eef2ace049813dc06d6c301826ed5a0601b7c94505985 |
|
MD5 | 4de2a9ed46fc6c163f4e2c7f395c271f |
|
BLAKE2b-256 | f6c978e4e53a4069182a3dfe16a7580bafb28838b9a5f77c49effd1b589880ae |
File details
Details for the file coneref-0.2.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
.
File metadata
- Download URL: coneref-0.2.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 7.1 MB
- Tags: CPython 3.8, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.8.14
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 69d47dd252b89f2e680e7f520808c3c031848e79f619e75f4aaecaeabfbfe14f |
|
MD5 | 5e5126c9e1f8666fb8dc4dcec272c52b |
|
BLAKE2b-256 | a8bb31763c35fb3db8d9c757fd93c375fc65414bcc401498d40f494bf0243900 |
File details
Details for the file coneref-0.2.2-cp38-cp38-macosx_10_9_x86_64.whl
.
File metadata
- Download URL: coneref-0.2.2-cp38-cp38-macosx_10_9_x86_64.whl
- Upload date:
- Size: 318.0 kB
- Tags: CPython 3.8, macOS 10.9+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/4.0.1 CPython/3.8.14
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 2a1884b84c56eba669a96bc87b4ccda7d8b4aa9ca1ece5b59900c9785c860b44 |
|
MD5 | 48147129a01248b49bcd9fa2a5d4fbb1 |
|
BLAKE2b-256 | 651c0f3e76e9979eb4541f87b67cbd2408e4d66ff7ea914f251a56cb9460911e |