blob: b96e3049c9f73ba9132790e40b145bf9a91d9f4d [file] [log] [blame]
Austin Schuh9049e202022-02-20 17:34:16 -08001Update matrices
2===============
3
4
5Consider the following QP
6
7
8.. math::
9 \begin{array}{ll}
10 \mbox{minimize} & \frac{1}{2} x^T \begin{bmatrix}4 & 1\\ 1 & 2 \end{bmatrix} x + \begin{bmatrix}1 \\ 1\end{bmatrix}^T x \\
11 \mbox{subject to} & \begin{bmatrix}1 \\ 0 \\ 0\end{bmatrix} \leq \begin{bmatrix} 1 & 1\\ 1 & 0\\ 0 & 1\end{bmatrix} x \leq \begin{bmatrix}1 \\ 0.7 \\ 0.7\end{bmatrix}
12 \end{array}
13
14
15
16We show below how to setup and solve the problem.
17Then we update the matrices :math:`P` and :math:`A` and solve the updated problem
18
19
20.. math::
21 \begin{array}{ll}
22 \mbox{minimize} & \frac{1}{2} x^T \begin{bmatrix}5 & 1.5\\ 1.5 & 1 \end{bmatrix} x + \begin{bmatrix}1 \\ 1\end{bmatrix}^T x \\
23 \mbox{subject to} & \begin{bmatrix}1 \\ 0 \\ 0\end{bmatrix} \leq \begin{bmatrix} 1.2 & 1.1\\ 1.5 & 0\\ 0 & 0.8\end{bmatrix} x \leq \begin{bmatrix}1 \\ 0.7 \\ 0.7\end{bmatrix}
24 \end{array}
25
26
27
28Python
29------
30
31.. code:: python
32
33 import osqp
34 import numpy as np
35 from scipy import sparse
36
37 # Define problem data
38 P = sparse.csc_matrix([[4, 1], [1, 2]])
39 q = np.array([1, 1])
40 A = sparse.csc_matrix([[1, 1], [1, 0], [0, 1]])
41 l = np.array([1, 0, 0])
42 u = np.array([1, 0.7, 0.7])
43
44 # Create an OSQP object
45 prob = osqp.OSQP()
46
47 # Setup workspace
48 prob.setup(P, q, A, l, u)
49
50 # Solve problem
51 res = prob.solve()
52
53 # Update problem
54 # NB: Update only upper triangular part of P
55 P_new = sparse.csc_matrix([[5, 1.5], [1.5, 1]])
56 A_new = sparse.csc_matrix([[1.2, 1.1], [1.5, 0], [0, 0.8]])
57 prob.update(Px=sparse.triu(P_new).data, Ax=A_new.data)
58
59 # Solve updated problem
60 res = prob.solve()
61
62
63
64Matlab
65------
66
67.. code:: matlab
68
69 % Define problem data
70 P = sparse([4, 1; 1, 2]);
71 q = [1; 1];
72 A = sparse([1, 1; 1, 0; 0, 1]);
73 l = [1; 0; 0];
74 u = [1; 0.7; 0.7];
75
76 % Create an OSQP object
77 prob = osqp;
78
79 % Setup workspace
80 prob.setup(P, q, A, l, u);
81
82 % Solve problem
83 res = prob.solve();
84
85 % Update problem
86 % NB: Update only upper triangular part of P
87 P_new = sparse([5, 1.5; 1.5, 1]);
88 A_new = sparse([1.2, 1.1; 1.5, 0; 0, 0.8]);
89 prob.update('Px', nonzeros(triu(P_new)), 'Ax', nonzeros(A_new));
90
91 % Solve updated problem
92 res = prob.solve();
93
94
95
96Julia
97------
98
99.. code:: julia
100
101 using OSQP
102 using Compat.SparseArrays, Compat.LinearAlgebra
103
104 # Define problem data
105 P = sparse([4. 1.; 1. 2.])
106 q = [1.; 1.]
107 A = sparse([1. 1.; 1. 0.; 0. 1.])
108 l = [1.; 0.; 0.]
109 u = [1.; 0.7; 0.7]
110
111 # Crate OSQP object
112 prob = OSQP.Model()
113
114 # Setup workspace
115 OSQP.setup!(prob; P=P, q=q, A=A, l=l, u=u)
116
117 # Solve problem
118 results = OSQP.solve!(prob)
119
120 # Update problem
121 # NB: Update only upper triangular part of P
122 P_new = sparse([5. 1.5; 1.5 1.])
123 A_new = sparse([1.2 1.1; 1.5 0.; 0. 0.8])
124 OSQP.update!(prob, Px=triu(P_new).nzval, Ax=A_new.nzval)
125
126 # Solve updated problem
127 results = OSQP.solve!(prob)
128
129
130
131R
132-
133
134.. code:: r
135
136 library(osqp)
137 library(Matrix)
138
139 # Define problem data
140 P <- Matrix(c(4., 1.,
141 1., 2.), 2, 2, sparse = TRUE)
142 q <- c(1., 1.)
143 A <- Matrix(c(1., 1., 0.,
144 1., 0., 1.), 3, 2, sparse = TRUE)
145 l <- c(1., 0., 0.)
146 u <- c(1., 0.7, 0.7)
147
148 # Setup workspace
149 model <- osqp(P, q, A, l, u)
150
151 # Solve problem
152 res <- model$Solve()
153
154 # Update problem
155 # NB: Update only upper triangular part of P
156 P_new <- Matrix(c(5., 1.5,
157 1.5, 1.), 2, 2, sparse = TRUE)
158 A_new <- Matrix(c(1.2, 1.5, 0.,
159 1.1, 0., 0.8), 3, 2, sparse = TRUE)
160 model$Update(Px = P_new@x, Ax = A_new@x)
161
162 # Solve updated problem
163 res <- model$Solve()
164
165
166
167C
168-
169
170.. code:: c
171
172 #include "osqp.h"
173
174 int main(int argc, char **argv) {
175 // Load problem data
176 c_float P_x[3] = {4.0, 1.0, 2.0, };
177 c_float P_x_new[3] = {5.0, 1.5, 1.0, };
178 c_int P_nnz = 3;
179 c_int P_i[3] = {0, 0, 1, };
180 c_int P_p[3] = {0, 1, 3, };
181 c_float q[2] = {1.0, 1.0, };
182 c_float q_new[2] = {2.0, 3.0, };
183 c_float A_x[4] = {1.0, 1.0, 1.0, 1.0, };
184 c_float A_x_new[4] = {1.2, 1.5, 1.1, 0.8, };
185 c_int A_nnz = 4;
186 c_int A_i[4] = {0, 1, 0, 2, };
187 c_int A_p[3] = {0, 2, 4, };
188 c_float l[3] = {1.0, 0.0, 0.0, };
189 c_float l_new[3] = {2.0, -1.0, -1.0, };
190 c_float u[3] = {1.0, 0.7, 0.7, };
191 c_float u_new[3] = {2.0, 2.5, 2.5, };
192 c_int n = 2;
193 c_int m = 3;
194
195 // Exitflag
196 c_int exitflag = 0;
197
198 // Workspace structures
199 OSQPWorkspace *work;
200 OSQPSettings *settings = (OSQPSettings *)c_malloc(sizeof(OSQPSettings));
201 OSQPData *data = (OSQPData *)c_malloc(sizeof(OSQPData));
202
203 // Populate data
204 if (data) {
205 data = (OSQPData *)c_malloc(sizeof(OSQPData));
206 data->n = n;
207 data->m = m;
208 data->P = csc_matrix(data->n, data->n, P_nnz, P_x, P_i, P_p);
209 data->q = q;
210 data->A = csc_matrix(data->m, data->n, A_nnz, A_x, A_i, A_p);
211 data->l = l;
212 data->u = u;
213 }
214
215 // Define Solver settings as default
216 if (settings) osqp_set_default_settings(settings);
217
218 // Setup workspace
219 exitflag = osqp_setup(&work, data, settings);
220
221 // Solve problem
222 osqp_solve(work);
223
224 // Update problem
225 // NB: Update only upper triangular part of P
226 osqp_update_P(work, P_x_new, OSQP_NULL, 3);
227 osqp_update_A(work, A_x_new, OSQP_NULL, 4);
228
229 // Solve updated problem
230 osqp_solve(work);
231
232 // Cleanup
233 osqp_cleanup(work);
234 if (data) {
235 if (data->A) c_free(data->A);
236 if (data->P) c_free(data->P);
237 c_free(data);
238 }
239 if (settings) c_free(settings);
240
241 return exitflag;
242 };