Generate code for Variable derivative
a-latyshev opened this issue · comments
Dear cvxpygen developers,
First of all I would like to thank the developers for cvxpygen
, it's a really fantastic extension, which can potentially accelerate any cvxpy
code!
I'm wondering how I can generate C code for the derivate
function of a cvxpy
problem. I leave here the example, which I would like to convert completely into C code:
import cvxpy as cp
import numpy as np
# We can solve plasticity problems of solid mechanics with the help of cvxpy
# There is a simple example of the vonMises perfect plasticity
sig0 = 1
E = 1
nu = 0.3
lmbda = E*nu/(1+nu)/(1-2*nu)
mu = E/2/(1+nu)
l, m = lmbda, mu
C = np.array([[l+2*m, l, l, 0],
[l, l+2*m, l, 0],
[l, l, l+2*m, 0],
[0, 0, 0, 2*m]])
deps = cp.Parameter((4,), name='deps')
sig_old = cp.Parameter((4,), name='sig_old')
sig_elas = sig_old + C @ deps
sig = cp.Variable((4, ), name='sig')
obj = cp.quad_form(sig - sig_elas, np.linalg.inv(C))
problem = cp.Problem(cp.Minimize(obj), [np.sqrt(3/2)*cp.norm(sig) <= sig0])
N = 100
theta = np.linspace(0, 2*np.pi, N+1)
Eps = 0.1*np.vstack((np.cos(theta), np.sin(theta), 0*theta, 0*theta)).T
Sig = np.zeros_like(Eps)
for i in range(N + 1):
sig_old.value = np.zeros((4, ))
deps.value = Eps[i,:]
# We can generate the corresponded C code of this solve function
# But how can I take into account a `requires_grad` argument in cvxpygen?
problem.solve(solver='SCS', requires_grad=True)
Sig[i,:] = sig.value
C_tang = np.zeros((4, 4))
for i in range(4):
z = np.zeros((4,))
z[i] = 1
# It would be a great advantage to generate appropriate C functions and variables for the following lines
deps.delta = z
problem.derivative()
C_tang[i, :] = sig.delta
# Here `C_tang` should be the same as `C`
assert np.max(np.abs(C_tang - C)) < 1e-4
Is it possible to generate C code for this kind of problem? Can you please give some advice about how I can do it in cvxpygen?
About context. I'm interested in embedding a cvxpy
solver into JIT compilable code, such as numba
functions are, for instance. I considered cvxcore
wrapping to implement this, but it's time-consuming and I didn’t find any C++ API… So it’s much faster with cvxpygen
, which automatically generates the C-code! I wrote some kind of wrapper via the cffi
library and could solve a convex problem inside a numba
function. Here you can find a simple example.
If I could get a C analog of the problem.derivate()
function and related cvxpy
features, I would dramatically accelerate the performance of my code!
Thank you for your work!
This is the library for computing the derivatives: https://github.com/cvxgrp/diffcp
The core is in C++ I believe, wrapped with pybind.