update time #249
-
Hello, and thanks for a great open-sourced solver! I'm benchmarking ProxQP against OSQP; the results have been impressive so far. I also noticed that updating problem data takes a long time, even if only the vectors are updated. For example, on a problem size 1000, OSQP takes ~ microseconds to update the model, whereas (dense) ProxQP takes ~milliseconds (timed by adapting the Does the update() method in ProxQP trigger some routine that could slow things down? Perhaps I'm missing a setting somewhere? Many thanks in advance! |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
Dear @johnzhang3, Thanks for your feedback. We are happy that ProxQP helps you in your work. Best, |
Beta Was this translation helpful? Give feedback.
-
Thanks for the quick response. Here is simple python script. import proxsuite
import numpy as np
import scipy.sparse as spa
import time
def generate_mixed_qp(n, seed=1):
# A function for generating sparse random convex qps in dense format
np.random.seed(seed)
n_eq = int(n / 4)
n_in = int(n / 4)
m = n_eq + n_in
P = spa.random(
n, n, density=0.075, data_rvs=np.random.randn, format="csc"
).toarray()
P = (P + P.T) / 2.0
s = max(np.absolute(np.linalg.eigvals(P)))
P += (abs(s) + 1e-02) * spa.eye(n)
P = spa.coo_matrix(P)
q = np.random.randn(n)
A = spa.random(m, n, density=0.15, data_rvs=np.random.randn, format="csc").toarray()
v = np.random.randn(n) # Fictitious solution
delta = np.random.rand(m) # To get inequality
u = A @ v
l = -1.0e20 * np.ones(m)
return P.toarray(), q, A[:n_eq, :], u[:n_eq], A[n_in:, :], u[n_in:], l[n_in:]
# load a qp object using qp problem dimensions
n = 1000
n_eq = int(n / 4)
n_in = int(n / 4)
qp = proxsuite.proxqp.dense.QP(n, n_eq, n_in)
qp.settings.compute_timings = True
# generate a random QP
H, g, A, b, C, u, l = generate_mixed_qp(n)
# initialize the model of the problem to solve
t1 = time.time_ns()/1e9
qp.init(H, g, A, b, C, l, u)
t2 = time.time_ns()/1e9
print("init time: {} seconds".format(t2 - t1))
# solve without warm start
t1 = time.time_ns()/1e9
qp.solve()
t2 = time.time_ns()/1e9
print("solve time (no warmstart): {} seconds".format(t2 - t1))
qp.settings.initial_guess = proxsuite.proxqp.WARM_START_WITH_PREVIOUS_RESULT
t1 = time.time_ns()/1e9
qp.update(b=b, l=l, u=u)
# qp.update(b=b)
#
t2 = time.time_ns()/1e9
print("update time (vector only): {} seconds".format(t2 - t1))
# t1 = time.time_ns()/1e9
# qp.update(H=H, A=A, C=C)
# t2 = time.time_ns()/1e9
# print("update time (matrix only): {} seconds".format(t2 - t1))
# t1 = time.time_ns()/1e9
# qp.update(H=H, A=A, g=g, C=C, b=b, l=l, u=u)
# t2 = time.time_ns()/1e9
# print("update time (all): {} seconds".format(t2 - t1))
t1 = time.time_ns()/1e9
qp.solve()
t2 = time.time_ns()/1e9
print("solve time (warmstart): {} seconds".format(t2 - t1))
print("run time: {} seconds".format(qp.results.info.run_time/1e6)) For me (on an Intel i7-12700k), the outputs are |
Beta Was this translation helpful? Give feedback.
We have checked with @Bambade, and should change the line:
with:
We will change the default parameters accordingly.