No project description provided
Project description
diffcp
diffcp
is a Python package for computing the derivative of a convex cone program, with respect to its problem data. The derivative is implemented as an abstract linear map, with methods for its forward application and its adjoint.
The implementation is based on the calculations in our paper Differentiating through a cone program.
Installation
diffcp
is available on PyPI, as a source distribution. Install it with
pip install diffcp
You will need a C++11capable compiler to build diffcp
.
diffcp
requires:
 NumPy >= 1.15
 SciPy >= 1.10
 SCS >= 2.0.2
 pybind11 >= 2.4
 threadpoolctl >= 1.1
 ECOS >= 2.0.10
 Python >= 3.7
diffcp
uses Eigen; Eigen operations can be automatically vectorized by compilers. To enable vectorization, install with
MARCH_NATIVE=1 pip install diffcp
OpenMP can be enabled by passing extra arguments to your compiler. For example, on linux, you can tell gcc to activate the OpenMP extension by specifying the flag "fopenmp":
OPENMP_FLAG="fopenmp" pip install diffcp
To enable both vectorization and OpenMP (on linux), use
MARCH_NATIVE=1 OPENMP_FLAG="fopenmp" pip install diffcp
Cone programs
diffcp
differentiates through a primaldual cone program pair. The primal problem must be expressed as
minimize c'x
subject to Ax + s = b
s in K
where x
and s
are variables, A
, b
and c
are the usersupplied problem data, and K
is a userdefined convex cone. The corresponding dual problem is
minimize b'y
subject to A'y + c == 0
y in K^*
with dual variable y
.
Usage
diffcp
exposes the function
solve_and_derivative(A, b, c, cone_dict, warm_start=None, solver=None, **kwargs).
This function returns a primaldual solution x
, y
, and s
, along with
functions for evaluating the derivative and its adjoint (transpose).
These functions respectively compute right and left multiplication of the derivative
of the solution map at A
, b
, and c
by a vector.
The solver
argument determines which solver to use; the available solvers
are solver="SCS"
and solver="ECOS"
.
If no solver is specified, diffcp
will choose the solver itself.
In the case that the problem is not solved, i.e. the solver fails for some reason, we will raise
a SolverError
Exception.
Arguments
The arguments A
, b
, and c
correspond to the problem data of a cone program.
A
must be a SciPy sparse CSC matrix.b
andc
must be NumPy arrays.cone_dict
is a dictionary that defines the convex coneK
.warm_start
is an optional tuple(x, y, s)
at which to warmstart. (Note: this is only available for the SCS solver).**kwargs
are keyword arguments to forward to the solver (e.g.,verbose=False
).
These inputs must conform to the SCS convention for problem data. The keys in cone_dict
correspond to the cones, with
diffcp.ZERO
for the zero cone,diffcp.POS
for the positive orthant,diffcp.SOC
for a product of SOC cones,diffcp.PSD
for a product of PSD cones, anddiffcp.EXP
for a product of exponential cones.
The values in cone_dict
denote the sizes of each cone; the values of diffcp.SOC
, diffcp.PSD
, and diffcp.EXP
should be lists. The order of the rows of A
must match the ordering of the cones given above. For more details, consult the SCS documentation.
Return value
The function solve_and_derivative
returns a tuple
(x, y, s, derivative, adjoint_derivative)

x
,y
, ands
are a primaldual solution. 
derivative
is a function that applies the derivative at(A, b, c)
to perturbationsdA
,db
,dc
. It has the signaturederivative(dA, db, dc) > dx, dy, ds
, wheredA
is a SciPy sparse CSC matrix with the same sparsity pattern asA
, anddb
anddc
are NumPy arrays.dx
,dy
, andds
are NumPy arrays, approximating the change in the primaldual solution due to the perturbation. 
adjoint_derivative
is a function that applies the adjoint of the derivative to perturbationsdx
,dy
,ds
. It has the signatureadjoint_derivative(dx, dy, ds) > dA, db, dc
, wheredx
,dy
, andds
are NumPy arrays.
Example
import numpy as np
from scipy import sparse
import diffcp
cone_dict = {
diffcp.ZERO: 3,
diffcp.POS: 3,
diffcp.SOC: [5]
}
m = 3 + 3 + 5
n = 5
A, b, c = diffcp.utils.random_cone_prog(m, n, cone_dict)
x, y, s, D, DT = diffcp.solve_and_derivative(A, b, c, cone_dict)
# evaluate the derivative
nonzeros = A.nonzero()
data = 1e4 * np.random.randn(A.size)
dA = sparse.csc_matrix((data, nonzeros), shape=A.shape)
db = 1e4 * np.random.randn(m)
dc = 1e4 * np.random.randn(n)
dx, dy, ds = D(dA, db, dc)
# evaluate the adjoint of the derivative
dx = c
dy = np.zeros(m)
ds = np.zeros(m)
dA, db, dc = DT(dx, dy, ds)
For more examples, including the SDP example described in the paper, see the examples
directory.
Citing
If you wish to cite diffcp
, please use the following BibTex:
@article{diffcp2019,
author = {Agrawal, A. and Barratt, S. and Boyd, S. and Busseti, E. and Moursi, W.},
title = {Differentiating through a Cone Program},
journal = {Journal of Applied and Numerical Optimization},
year = {2019},
volume = {1},
number = {2},
pages = {107115},
}
@misc{diffcp,
author = {Agrawal, A. and Barratt, S. and Boyd, S. and Busseti, E. and Moursi, W.},
title = {{diffcp}: differentiating through a cone program, version 1.0},
howpublished = {\url{https://github.com/cvxgrp/diffcp}},
year = 2019
}
The following thesis concurrently derived the mathematics behind differentiating cone programs.
@phdthesis{amos2019differentiable,
author = {Brandon Amos},
title = {{Differentiable OptimizationBased Modeling for Machine Learning}},
school = {Carnegie Mellon University},
year = 2019,
month = May,
}
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
Hashes for diffcp1.0.23cp311cp311win_amd64.whl
Algorithm  Hash digest  

SHA256  276312a5cb150a185a25592cd5e2cb8f9b72d1f02093b2234ff96d0b03bd3ad5 

MD5  ab7c28282f311a2568967cb6bbcf999f 

BLAKE2b256  43f173c389ecd7c1f1eeaeaf1cffd69e40012bda554da494c88ef3e36cfe6593 
Hashes for diffcp1.0.23cp311cp311manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm  Hash digest  

SHA256  d1643ad17f568efd0875a5436d1c5b19ba984cbbb9e57f0a20ad1d5d21d967b7 

MD5  c77b706903d9b69cd61273b05b9e99d5 

BLAKE2b256  0ee6058e534fc03ff182ac625dc9d2b6922564f42780b15bfe09f550f8ddd27e 
Hashes for diffcp1.0.23cp311cp311macosx_10_9_x86_64.whl
Algorithm  Hash digest  

SHA256  b7d01435cac21103443f72905885b7216ec8336829c227feb5291b32381f6612 

MD5  fa2436596483efa44bd0a7f4ca64316e 

BLAKE2b256  a7199fedd52a2b5f2ac350e194dd42ace800685d73f8ac10a7951b9b685c84a5 
Hashes for diffcp1.0.23cp310cp310win_amd64.whl
Algorithm  Hash digest  

SHA256  100b31fd99099bbf2767b023adffa8c60647d5c11a5ed3f145134eb28cc0bc12 

MD5  2aec164ad482b2afaf1bbffade4519e8 

BLAKE2b256  c79f2b6a25552523f928a0c85c983f141bedccf4b3dc7525ec0f278d75c9e7c4 
Hashes for diffcp1.0.23cp310cp310manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm  Hash digest  

SHA256  e2a20f8ab11172fadfc1b47033f568b238d668fafe74c0622c485c404e237c8e 

MD5  e5b92b46e12ed3cfaf3014fecbc3b5c9 

BLAKE2b256  b8a9d00b2cb69df2b0952491c7dd74859b56e8704fe203cee1d09e232bf1c8da 
Hashes for diffcp1.0.23cp310cp310macosx_10_9_x86_64.whl
Algorithm  Hash digest  

SHA256  f22fbbf8ff7bc3446cb9f2d16323331dff7db8e93fac392d6b57f35a630948f3 

MD5  c6bb9e2fe9ce2c69db2b2179f2ebdc32 

BLAKE2b256  1cb1069c285db05b10ba12511a0e05223af37d3a336a8e88c440b4e618a0127e 
Hashes for diffcp1.0.23cp39cp39win_amd64.whl
Algorithm  Hash digest  

SHA256  26d26ce0a8269b1368d26a3e1ea39ef56e0fb1dc0ac7ba0643ee292be5cd0bc4 

MD5  bcde3b0a13ebae825312b12e7e79b671 

BLAKE2b256  478bd17b07f78e5b00a4f55039355a0fd41e4ebed29e7aba1ffefd1213908628 
Hashes for diffcp1.0.23cp39cp39manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm  Hash digest  

SHA256  3227f01ce5fe78bff10e852c4f012248ece0a597312a946557b615953d4cc716 

MD5  c97327ce8ac5c2afc9ae58eb2a50faaa 

BLAKE2b256  116e03a94b626429aff194ef75c90d88f9ed815cc02483019debfac3164883d1 
Hashes for diffcp1.0.23cp39cp39macosx_10_9_x86_64.whl
Algorithm  Hash digest  

SHA256  029b4e40197ad005edca734a37284173f6e460d77ff312f6b17a699d2bcdfa8a 

MD5  3b3c01baeaf09531dd346d8a6ed87459 

BLAKE2b256  f67ff36bc379c96b0d41f0c5897e62890299c5d14e2a6e02583c7d7d23d0a068 
Hashes for diffcp1.0.23cp38cp38win_amd64.whl
Algorithm  Hash digest  

SHA256  c6acf85acc0569f959d98043d8c631b8f06081bebe4b6bfb6d27a56ca633a583 

MD5  e3d93052156e7d193676b1c77a11ed60 

BLAKE2b256  02d8d96a3078aac85e834e99982ee56da96066a8b0cd3ec5b758b6d64cd79bb8 
Hashes for diffcp1.0.23cp38cp38manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm  Hash digest  

SHA256  5dedca409c4f1e398a4a9150d53b3d85852da097b9ff103f7f4690c042b5c054 

MD5  00836499f6af0e4d5fa784621010f122 

BLAKE2b256  18a912bd36155e0d8f95cbac5bfdff0dcd43ead254d1aadcb2ef426caa4209e9 
Hashes for diffcp1.0.23cp38cp38macosx_10_9_x86_64.whl
Algorithm  Hash digest  

SHA256  9674f84dbc338f1d9b9ed5b7641ed3376f2c4df041adfbc0ee987704b42d4a7e 

MD5  cdbe224754b5c515ccacf54bd382a946 

BLAKE2b256  471026ebe85e557b2e3694bdc09556cc20d14ae8440ef534af6688e353d338f9 
Hashes for diffcp1.0.23cp37cp37mwin_amd64.whl
Algorithm  Hash digest  

SHA256  d7060c59e313d5153d8383b7e8242918f55a9cfff2525d4de552b561d547075b 

MD5  2e549b4d5759a172bb49bff33ff604ff 

BLAKE2b256  2629403f95836070253d1910661fe2e23c326caab66beeabd168758bc2ce2585 
Hashes for diffcp1.0.23cp37cp37mmanylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm  Hash digest  

SHA256  cc32b5b36cdd7c8301e2109fc2bdd81f17c690a39272fe32c812090982caeb24 

MD5  4fefd90ead1674ec44d72938054dc677 

BLAKE2b256  3d7d83198e457eca24d691df696038700af4feaee0fb79ebe0fdf4ad836cfa91 
Hashes for diffcp1.0.23cp37cp37mmacosx_10_9_x86_64.whl
Algorithm  Hash digest  

SHA256  25bde418ebf8cc4af3a7601e6bd555c6206f667224e759b83a2b29a71563b553 

MD5  ab63759b58bc7a1f0090851c294a6c82 

BLAKE2b256  df6e9c99c0d126d464668d115eefa66e029cdf4e50781eab1c87f40056ae6981 