Skip to main content

A library to compute gradients for convex optimization problems

Project description

Build Status

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++11-capable compiler to build diffcp.

diffcp requires:

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 primal-dual cone program pair. The primal problem must be expressed as

minimize        c'x + x'Px
subject to      Ax + s = b
                s in K

where x and s are variables, A, b, c and P (optional) are the user-supplied problem data, and K is a user-defined convex cone. The corresponding dual problem is

minimize        b'y + x'Px
subject to      Px + 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, P=None, **kwargs).

This function returns a primal-dual 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, c and P by a vector. The solver argument determines which solver to use; the available solvers are solver="SCS", solver="ECOS", and solver="Clarabel". 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, c and P correspond to the problem data of a cone program.

  • A must be a SciPy sparse CSC matrix.
  • b and c must be NumPy arrays.
  • cone_dict is a dictionary that defines the convex cone K.
  • warm_start is an optional tuple (x, y, s) at which to warm-start. (Note: this is only available for the SCS solver).
  • P is an optional SciPy sparse CSC matrix. (Note: this is currently only available for the Clarabel and SCS solvers, paired with LPGD differentiation mode).
  • **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, and
  • diffcp.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.

To enable Lagrangian Proximal Gradient Descent (LPGD) differentiation of the conic program based on efficient finite-differences, provide one of the mode=[lpgd, lpgd_left, lpgd_right] options along with the argument derivative_kwargs=dict(tau=0.1, rho=0.1) to specify the perturbation and regularization strength. Alternatively, the derivative kwargs can also be passed directly to the returned derivative and adjoint_derivative function.

Return value

The function solve_and_derivative returns a tuple

(x, y, s, derivative, adjoint_derivative)
  • x, y, and s are a primal-dual solution.

  • derivative is a function that applies the derivative at (A, b, c, P) to perturbations dA, db, dc and dP (optional). It has the signature derivative(dA, db, dc, dP=None) -> dx, dy, ds, where dA is a SciPy sparse CSC matrix with the same sparsity pattern as A, db and dc are NumPy arrays, and dP is an optional SciPy sparse CSC matrix with the same sparsity pattern as P (Note: currently only supported for LPGD differentiation mode). dx, dy, and ds are NumPy arrays, approximating the change in the primal-dual solution due to the perturbation.

  • adjoint_derivative is a function that applies the adjoint of the derivative to perturbations dx, dy, ds. It has the signature adjoint_derivative(dx, dy, ds, return_dP=False) -> dA, db, dc, (dP), where dx, dy, and ds are NumPy arrays. dP is only returned when setting return_dP=True (Note: currently only supported for LPGD differentiation mode).

Example

import numpy as np
from scipy import sparse

import diffcp

def random_cone_prog(m, n, cone_dict):
    """Returns the problem data of a random cone program."""
    cone_list = diffcp.cones.parse_cone_dict(cone_dict)
    z = np.random.randn(m)
    s_star = diffcp.cones.pi(z, cone_list, dual=False)
    y_star = s_star - z
    A = sparse.csc_matrix(np.random.randn(m, n))
    x_star = np.random.randn(n)
    b = A @ x_star + s_star
    c = -A.T @ y_star
    return A, b, c

cone_dict = {
    diffcp.ZERO: 3,
    diffcp.POS: 3,
    diffcp.SOC: [5]
}

m = 3 + 3 + 5
n = 5

A, b, c = 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 = 1e-4 * np.random.randn(A.size)
dA = sparse.csc_matrix((data, nonzeros), shape=A.shape)
db = 1e-4 * np.random.randn(m)
dc = 1e-4 * 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, and examples of using LPGD differentiation, 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        = {107--115},
}

@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 Optimization-Based Modeling for Machine Learning}},
  school       = {Carnegie Mellon University},
  year         = 2019,
  month        = May,
}

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

diffcp-1.1.8.tar.gz (2.1 MB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

diffcp-1.1.8-cp313-cp313-musllinux_1_2_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ x86-64

diffcp-1.1.8-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (248.3 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

diffcp-1.1.8-cp313-cp313-macosx_11_0_arm64.whl (218.2 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

diffcp-1.1.8-cp313-cp313-macosx_10_13_x86_64.whl (231.3 kB view details)

Uploaded CPython 3.13macOS 10.13+ x86-64

diffcp-1.1.8-cp312-cp312-musllinux_1_2_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ x86-64

diffcp-1.1.8-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (248.6 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

diffcp-1.1.8-cp312-cp312-macosx_11_0_arm64.whl (218.2 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

diffcp-1.1.8-cp312-cp312-macosx_10_13_x86_64.whl (231.3 kB view details)

Uploaded CPython 3.12macOS 10.13+ x86-64

diffcp-1.1.8-cp311-cp311-musllinux_1_2_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ x86-64

diffcp-1.1.8-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (247.5 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

diffcp-1.1.8-cp311-cp311-macosx_11_0_arm64.whl (216.7 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

diffcp-1.1.8-cp311-cp311-macosx_10_9_x86_64.whl (229.5 kB view details)

Uploaded CPython 3.11macOS 10.9+ x86-64

diffcp-1.1.8-cp310-cp310-musllinux_1_2_x86_64.whl (1.2 MB view details)

Uploaded CPython 3.10musllinux: musl 1.2+ x86-64

diffcp-1.1.8-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl (246.5 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.27+ x86-64manylinux: glibc 2.28+ x86-64

diffcp-1.1.8-cp310-cp310-macosx_11_0_arm64.whl (215.3 kB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

diffcp-1.1.8-cp310-cp310-macosx_10_9_x86_64.whl (228.3 kB view details)

Uploaded CPython 3.10macOS 10.9+ x86-64

File details

Details for the file diffcp-1.1.8.tar.gz.

File metadata

  • Download URL: diffcp-1.1.8.tar.gz
  • Upload date:
  • Size: 2.1 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for diffcp-1.1.8.tar.gz
Algorithm Hash digest
SHA256 364f999530314730eff003719779da31b2824d7c1acce4af03fb0aaceb82400b
MD5 10be3bffd108b72a737e68f3a9a02768
BLAKE2b-256 a75fbabbc6849504364503b95abfb058360c6ce46617b0b6de0fc3f71582dc20

See more details on using hashes here.

File details

Details for the file diffcp-1.1.8-cp313-cp313-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for diffcp-1.1.8-cp313-cp313-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 86dbf0258b27ef5361be25e084d8e5d515cd149c86007908f282df60a4baf928
MD5 d50c6d034cd78bb57c9b9b31a4f8e434
BLAKE2b-256 dc17d18190d157ac89ed526ced50a7b220038d1baf7e1eba77c9ff6015943785

See more details on using hashes here.

File details

Details for the file diffcp-1.1.8-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for diffcp-1.1.8-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 7427eacec2e7d9e7d5b5046db76288c1b1ab03dc30382175bb77d2757cb9047a
MD5 9d4d5ef34f3bf6d87838739b883df4d6
BLAKE2b-256 c1c692a43578fd74906c9d0f98680f49ab0b146696e886a0a0bd05cf7a8199e8

See more details on using hashes here.

File details

Details for the file diffcp-1.1.8-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for diffcp-1.1.8-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f4f239a691335d1cd8fadfe13238fbd37968c44e46ec68c962380c0a81977ba6
MD5 53c804a96e4f68ac3b8c2e7b11b24657
BLAKE2b-256 58b8479af15d70509ab9538af0dcdae0d49593950c778fdf1b2b800c2796cedc

See more details on using hashes here.

File details

Details for the file diffcp-1.1.8-cp313-cp313-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for diffcp-1.1.8-cp313-cp313-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 5cedfdefcf53d7a667455e0731c76383d2a2648f4ebb62dc1a79c3e55aeeadd9
MD5 4fa2b534f507a38e7c448f111145d56f
BLAKE2b-256 60fdeb43abe8e2e2c2ffb1569af8366ea3106690cc456ca207cb5a7eda7e7815

See more details on using hashes here.

File details

Details for the file diffcp-1.1.8-cp312-cp312-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for diffcp-1.1.8-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 be96fc2165ba2c13d6d50169aa581865ece481433bbc716207d223c57bb0e3b5
MD5 8034c0a095ec641214c3adb6896e70a8
BLAKE2b-256 55b7faecc9eea389b3886131d62948dbb94047a0f521cd158070ffcfa53a90d4

See more details on using hashes here.

File details

Details for the file diffcp-1.1.8-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for diffcp-1.1.8-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 0f8a1e807b48ee3cf33e208cb7eab8a867ded2c3f90ecb7dea2c371c3b01e6d3
MD5 56577a616a8278756251ccdf01e80d7f
BLAKE2b-256 a802f74c4c20de45014b008608093e2a3b42948623e3429e49918cb4c8726d92

See more details on using hashes here.

File details

Details for the file diffcp-1.1.8-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for diffcp-1.1.8-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b30c3cf0983bab975cc00a4104624bfb2706ea9f435ca0c958b26641594c9c05
MD5 3efd3fec3962892ef92e27ee3e8093bf
BLAKE2b-256 b9c9e3bc97b9028fa29e120a2bfe52811007192c0531f0aaaa16163c2a53d4e3

See more details on using hashes here.

File details

Details for the file diffcp-1.1.8-cp312-cp312-macosx_10_13_x86_64.whl.

File metadata

File hashes

Hashes for diffcp-1.1.8-cp312-cp312-macosx_10_13_x86_64.whl
Algorithm Hash digest
SHA256 ca7e2bf7d7e3a958850a2d7cbcc50ffc0a1b61e15ab61b044f2113205fbe726b
MD5 f8b0671ee4e95b04e5e752fcc6c0b540
BLAKE2b-256 7e55f937aeb3437635f3da3e1ff47c68949b17740b3b517ac510d160b5ad7a10

See more details on using hashes here.

File details

Details for the file diffcp-1.1.8-cp311-cp311-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for diffcp-1.1.8-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 3c181d54ca6ed792371511df0e1dba78401e6a14a53b06a9368460dc471ed65f
MD5 f38f13044068fb7d19f95ac8e662deb0
BLAKE2b-256 927160e856464bd3028886f61f0455ed7adb122e711ecd9e90b7344ddbb18438

See more details on using hashes here.

File details

Details for the file diffcp-1.1.8-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for diffcp-1.1.8-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 4bea8fea47f066b460cf2e775547020dda855178988de0c139aaa79aab1f92b5
MD5 78383ffa02a30b4e72e6bd6341551728
BLAKE2b-256 1004868107be3032a9a663d8c0c7821d8160e8656587d548249ed72c8279ea30

See more details on using hashes here.

File details

Details for the file diffcp-1.1.8-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for diffcp-1.1.8-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a31f6adc9ca564be749e6d7ea0007b209c1c67ce94a912bcae580cdc6aad9bd9
MD5 d76983b84ff48f6b718f3b487f09b958
BLAKE2b-256 cb9f6b9ab59ec71833a1f5909247c512d5688314b7a5f2602d0ef771b760b585

See more details on using hashes here.

File details

Details for the file diffcp-1.1.8-cp311-cp311-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for diffcp-1.1.8-cp311-cp311-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 7c06e559d534d3e4a0bbf86c488587e1e0bc5a6bff7fd50a8c3bfe0626314865
MD5 521001a0abf5386f07ec53322deaca33
BLAKE2b-256 02570958764cd14cc7c4eb6e6a439911490e657216be109c859f10f286e1d0f6

See more details on using hashes here.

File details

Details for the file diffcp-1.1.8-cp310-cp310-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for diffcp-1.1.8-cp310-cp310-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 a330944c1dd0633d66552c638af22eda320448130e49c133a39df6693b65d8cb
MD5 9dbea683d8e89591131baddcd9f69a0c
BLAKE2b-256 d453e8613dc72f74544176f4d599a8bed10bc46f7059bf3b1441679053929087

See more details on using hashes here.

File details

Details for the file diffcp-1.1.8-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for diffcp-1.1.8-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 eb5166eb8ef168b390a5da4470082b49519518e9b09ededb3247cd495f38b568
MD5 b287cb505ba584be4f990c794e59ebd7
BLAKE2b-256 baa91c2618cc898dc6923ca51b7b89652e5649aee5b78feb3a5f6a8a410798f2

See more details on using hashes here.

File details

Details for the file diffcp-1.1.8-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for diffcp-1.1.8-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 e9ab4ed935dd76e3b0522772d696c19a7f01d4c245b5d012d017195e77759de4
MD5 e80bafe838f1a4160d4f8bcb2be17d18
BLAKE2b-256 ab07b8ff20a8af42067e9ce9b9538213cba15006b65e610ecaa7bdbf40e8621b

See more details on using hashes here.

File details

Details for the file diffcp-1.1.8-cp310-cp310-macosx_10_9_x86_64.whl.

File metadata

File hashes

Hashes for diffcp-1.1.8-cp310-cp310-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 d923ba97d17c60997eb96a78fbacbf4b6a9b05871f1ac1f5994db3913c0d3c38
MD5 c5605ed28cee9b2f98f336bd78a47904
BLAKE2b-256 b4adb1c2772fc47ca378ea47f62d7f4eb19a37fc285ff83d67873af91d5ae3c2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page