scs 0.3.2 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +34 -5
- data/lib/scs/matrix.rb +72 -0
- data/lib/scs/solver.rb +19 -26
- data/lib/scs/version.rb +1 -1
- data/lib/scs.rb +1 -0
- data/vendor/scs/CITATION.cff +1 -1
- data/vendor/scs/CMakeLists.txt +2 -2
- data/vendor/scs/README.md +3 -1
- data/vendor/scs/include/cones.h +5 -3
- data/vendor/scs/include/glbopts.h +4 -5
- data/vendor/scs/include/normalize.h +1 -0
- data/vendor/scs/include/rw.h +3 -3
- data/vendor/scs/include/scs.h +45 -22
- data/vendor/scs/include/scs_work.h +15 -18
- data/vendor/scs/include/util.h +3 -1
- data/vendor/scs/linsys/external/amd/LICENSE.txt +0 -897
- data/vendor/scs/linsys/external/amd/SuiteSparse_config.c +4 -2
- data/vendor/scs/linsys/external/amd/SuiteSparse_config.h +0 -5
- data/vendor/scs/linsys/scs_matrix.c +38 -67
- data/vendor/scs/linsys/scs_matrix.h +4 -3
- data/vendor/scs/scs.mk +0 -4
- data/vendor/scs/src/aa.c +0 -4
- data/vendor/scs/src/cones.c +63 -25
- data/vendor/scs/src/normalize.c +49 -0
- data/vendor/scs/src/rw.c +48 -40
- data/vendor/scs/src/scs.c +212 -170
- data/vendor/scs/src/util.c +26 -12
- data/vendor/scs/test/problem_utils.h +3 -3
- data/vendor/scs/test/problems/degenerate.h +1 -0
- data/vendor/scs/test/problems/hs21_tiny_qp.h +1 -0
- data/vendor/scs/test/problems/hs21_tiny_qp_rw.h +5 -1
- data/vendor/scs/test/problems/infeasible_tiny_qp.h +1 -0
- data/vendor/scs/test/problems/qafiro_tiny_qp.h +2 -1
- data/vendor/scs/test/problems/random_prob.h +5 -1
- data/vendor/scs/test/problems/rob_gauss_cov_est.h +8 -1
- data/vendor/scs/test/problems/small_lp.h +4 -1
- data/vendor/scs/test/problems/small_qp.h +42 -7
- data/vendor/scs/test/problems/test_validation.h +4 -1
- data/vendor/scs/test/problems/unbounded_tiny_qp.h +3 -3
- data/vendor/scs/test/random_socp_prob.c +3 -1
- data/vendor/scs/test/run_from_file.c +15 -3
- metadata +5 -4
data/vendor/scs/src/scs.c
CHANGED
@@ -40,21 +40,34 @@ static void free_work(ScsWork *w) {
|
|
40
40
|
scs_free(w->rsk);
|
41
41
|
scs_free(w->h);
|
42
42
|
scs_free(w->g);
|
43
|
-
scs_free(w->
|
44
|
-
scs_free(w->
|
43
|
+
scs_free(w->b_orig);
|
44
|
+
scs_free(w->c_orig);
|
45
45
|
scs_free(w->lin_sys_warm_start);
|
46
46
|
scs_free(w->diag_r);
|
47
|
+
SCS(free_sol)(w->xys_orig);
|
47
48
|
if (w->scal) {
|
48
49
|
scs_free(w->scal->D);
|
49
50
|
scs_free(w->scal->E);
|
50
51
|
scs_free(w->scal);
|
51
52
|
}
|
52
|
-
SCS(free_sol)(w->xys_orig);
|
53
53
|
free_residuals(w->r_orig);
|
54
54
|
if (w->stgs && w->stgs->normalize) {
|
55
55
|
SCS(free_sol)(w->xys_normalized);
|
56
56
|
free_residuals(w->r_normalized);
|
57
57
|
}
|
58
|
+
if (w->stgs) {
|
59
|
+
if (w->stgs->log_csv_filename)
|
60
|
+
scs_free((char *)w->stgs->log_csv_filename);
|
61
|
+
if (w->stgs->write_data_filename)
|
62
|
+
scs_free((char *)w->stgs->write_data_filename);
|
63
|
+
scs_free(w->stgs);
|
64
|
+
}
|
65
|
+
if (w->k) { /* deep copy */
|
66
|
+
SCS(free_cone)(w->k);
|
67
|
+
}
|
68
|
+
if (w->d) { /* deep copy */
|
69
|
+
SCS(free_data)(w->d);
|
70
|
+
}
|
58
71
|
scs_free(w);
|
59
72
|
}
|
60
73
|
}
|
@@ -87,12 +100,11 @@ static void print_init_header(const ScsData *d, const ScsCone *k,
|
|
87
100
|
scs_free(cone_str);
|
88
101
|
scs_printf("settings: eps_abs: %.1e, eps_rel: %.1e, eps_infeas: %.1e\n"
|
89
102
|
"\t alpha: %.2f, scale: %.2e, adaptive_scale: %i\n"
|
90
|
-
"\t max_iters: %i, normalize: %i,
|
91
|
-
/*, rho_x: %.2e\n", */
|
103
|
+
"\t max_iters: %i, normalize: %i, rho_x: %.2e\n",
|
92
104
|
stgs->eps_abs, stgs->eps_rel, stgs->eps_infeas, stgs->alpha,
|
93
105
|
stgs->scale, (int)stgs->adaptive_scale, (int)stgs->max_iters,
|
94
|
-
(int)stgs->normalize,
|
95
|
-
/*
|
106
|
+
(int)stgs->normalize, stgs->rho_x);
|
107
|
+
/* (int)stgs->warm_start); */
|
96
108
|
if (stgs->acceleration_lookback != 0) {
|
97
109
|
scs_printf("\t acceleration_lookback: %i, acceleration_interval: %i\n",
|
98
110
|
(int)acceleration_lookback, (int)acceleration_interval);
|
@@ -154,18 +166,26 @@ static scs_int failure(ScsWork *w, scs_int m, scs_int n, ScsSolution *sol,
|
|
154
166
|
return status;
|
155
167
|
}
|
156
168
|
|
169
|
+
static inline scs_int _is_nan(scs_float x) {
|
170
|
+
return x != x;
|
171
|
+
}
|
172
|
+
|
157
173
|
/* given x,y,s warm start, set v = [x; s / R + y; 1]
|
174
|
+
* check for nans and set to zero if present
|
158
175
|
*/
|
159
176
|
static void warm_start_vars(ScsWork *w, ScsSolution *sol) {
|
160
|
-
scs_int n = w->n, m = w->m, i;
|
177
|
+
scs_int n = w->d->n, m = w->d->m, i;
|
161
178
|
scs_float *v = w->v;
|
162
179
|
/* normalize the warm-start */
|
163
180
|
if (w->stgs->normalize) {
|
164
181
|
SCS(normalize_sol)(w->scal, sol);
|
165
182
|
}
|
166
|
-
|
183
|
+
for (i = 0; i < n; ++i) {
|
184
|
+
v[i] = _is_nan(sol->x[i]) ? 0. : sol->x[i];
|
185
|
+
}
|
167
186
|
for (i = 0; i < m; ++i) {
|
168
187
|
v[i + n] = sol->y[i] + sol->s[i] / w->diag_r[i + n];
|
188
|
+
v[i + n] = _is_nan(v[i + n]) ? 0. : v[i + n];
|
169
189
|
}
|
170
190
|
v[n + m] = 1.0; /* tau = 1 */
|
171
191
|
/* un-normalize so sol unchanged */
|
@@ -199,12 +219,12 @@ static void unnormalize_residuals(ScsWork *w) {
|
|
199
219
|
r->tau = r_n->tau;
|
200
220
|
|
201
221
|
/* mem copy arrays */
|
202
|
-
memcpy(r->ax, r_n->ax, w->m * sizeof(scs_float));
|
203
|
-
memcpy(r->ax_s, r_n->ax_s, w->m * sizeof(scs_float));
|
204
|
-
memcpy(r->ax_s_btau, r_n->ax_s_btau, w->m * sizeof(scs_float));
|
205
|
-
memcpy(r->aty, r_n->aty, w->n * sizeof(scs_float));
|
206
|
-
memcpy(r->px, r_n->px, w->n * sizeof(scs_float));
|
207
|
-
memcpy(r->px_aty_ctau, r_n->px_aty_ctau, w->n * sizeof(scs_float));
|
222
|
+
memcpy(r->ax, r_n->ax, w->d->m * sizeof(scs_float));
|
223
|
+
memcpy(r->ax_s, r_n->ax_s, w->d->m * sizeof(scs_float));
|
224
|
+
memcpy(r->ax_s_btau, r_n->ax_s_btau, w->d->m * sizeof(scs_float));
|
225
|
+
memcpy(r->aty, r_n->aty, w->d->n * sizeof(scs_float));
|
226
|
+
memcpy(r->px, r_n->px, w->d->n * sizeof(scs_float));
|
227
|
+
memcpy(r->px_aty_ctau, r_n->px_aty_ctau, w->d->n * sizeof(scs_float));
|
208
228
|
|
209
229
|
/* unnormalize */
|
210
230
|
r->kap = r_n->kap / pd;
|
@@ -225,13 +245,13 @@ static void unnormalize_residuals(ScsWork *w) {
|
|
225
245
|
SCS(un_normalize_dual)(w->scal, r->px);
|
226
246
|
SCS(un_normalize_dual)(w->scal, r->px_aty_ctau);
|
227
247
|
|
228
|
-
compute_residuals(r, w->m, w->n);
|
248
|
+
compute_residuals(r, w->d->m, w->d->n);
|
229
249
|
}
|
230
250
|
|
231
251
|
/* calculates un-normalized residual quantities */
|
232
252
|
/* this is somewhat slow but not a bottleneck */
|
233
253
|
static void populate_residual_struct(ScsWork *w, scs_int iter) {
|
234
|
-
scs_int n = w->n, m = w->m;
|
254
|
+
scs_int n = w->d->n, m = w->d->m;
|
235
255
|
/* normalized x,y,s terms */
|
236
256
|
scs_float *x = w->xys_normalized->x;
|
237
257
|
scs_float *y = w->xys_normalized->y;
|
@@ -254,7 +274,7 @@ static void populate_residual_struct(ScsWork *w, scs_int iter) {
|
|
254
274
|
/**************** PRIMAL *********************/
|
255
275
|
memset(r->ax, 0, m * sizeof(scs_float));
|
256
276
|
/* ax = Ax */
|
257
|
-
SCS(accum_by_a)(w->A, x, r->ax);
|
277
|
+
SCS(accum_by_a)(w->d->A, x, r->ax);
|
258
278
|
|
259
279
|
memcpy(r->ax_s, r->ax, m * sizeof(scs_float));
|
260
280
|
/* ax_s = Ax + s */
|
@@ -262,13 +282,13 @@ static void populate_residual_struct(ScsWork *w, scs_int iter) {
|
|
262
282
|
|
263
283
|
memcpy(r->ax_s_btau, r->ax_s, m * sizeof(scs_float));
|
264
284
|
/* ax_s_btau = Ax + s - b * tau */
|
265
|
-
SCS(add_scaled_array)(r->ax_s_btau, w->
|
285
|
+
SCS(add_scaled_array)(r->ax_s_btau, w->d->b, m, -r->tau);
|
266
286
|
|
267
287
|
/**************** DUAL *********************/
|
268
288
|
memset(r->px, 0, n * sizeof(scs_float));
|
269
|
-
if (w->P) {
|
289
|
+
if (w->d->P) {
|
270
290
|
/* px = Px */
|
271
|
-
SCS(accum_by_p)(w->P, x, r->px);
|
291
|
+
SCS(accum_by_p)(w->d->P, x, r->px);
|
272
292
|
r->xt_p_x_tau = SCS(dot)(r->px, x, n);
|
273
293
|
} else {
|
274
294
|
r->xt_p_x_tau = 0.;
|
@@ -276,18 +296,18 @@ static void populate_residual_struct(ScsWork *w, scs_int iter) {
|
|
276
296
|
|
277
297
|
memset(r->aty, 0, n * sizeof(scs_float));
|
278
298
|
/* aty = A'y */
|
279
|
-
SCS(accum_by_atrans)(w->A, y, r->aty);
|
299
|
+
SCS(accum_by_atrans)(w->d->A, y, r->aty);
|
280
300
|
|
281
301
|
/* r->px_aty_ctau = Px */
|
282
302
|
memcpy(r->px_aty_ctau, r->px, n * sizeof(scs_float));
|
283
303
|
/* r->px_aty_ctau = Px + A'y */
|
284
304
|
SCS(add_scaled_array)(r->px_aty_ctau, r->aty, n, 1.);
|
285
305
|
/* r->px_aty_ctau = Px + A'y + c * tau */
|
286
|
-
SCS(add_scaled_array)(r->px_aty_ctau, w->
|
306
|
+
SCS(add_scaled_array)(r->px_aty_ctau, w->d->c, n, r->tau);
|
287
307
|
|
288
308
|
/**************** OTHERS *****************/
|
289
|
-
r->bty_tau = SCS(dot)(y, w->
|
290
|
-
r->ctx_tau = SCS(dot)(x, w->
|
309
|
+
r->bty_tau = SCS(dot)(y, w->d->b, m);
|
310
|
+
r->ctx_tau = SCS(dot)(x, w->d->c, n);
|
291
311
|
|
292
312
|
r->bty = SAFEDIV_POS(r->bty_tau, r->tau);
|
293
313
|
r->ctx = SAFEDIV_POS(r->ctx_tau, r->tau);
|
@@ -309,7 +329,7 @@ static void populate_residual_struct(ScsWork *w, scs_int iter) {
|
|
309
329
|
}
|
310
330
|
|
311
331
|
static void cold_start_vars(ScsWork *w) {
|
312
|
-
scs_int l = w->n + w->m + 1;
|
332
|
+
scs_int l = w->d->n + w->d->m + 1;
|
313
333
|
memset(w->v, 0, l * sizeof(scs_float));
|
314
334
|
w->v[l - 1] = 1.;
|
315
335
|
}
|
@@ -319,7 +339,7 @@ static inline scs_float dot_r(ScsWork *w, const scs_float *x,
|
|
319
339
|
const scs_float *y) {
|
320
340
|
scs_int i;
|
321
341
|
scs_float ip = 0.0;
|
322
|
-
for (i = 0; i < w->n + w->m; ++i) {
|
342
|
+
for (i = 0; i < w->d->n + w->d->m; ++i) {
|
323
343
|
ip += x[i] * y[i] * w->diag_r[i];
|
324
344
|
}
|
325
345
|
return ip;
|
@@ -327,7 +347,7 @@ static inline scs_float dot_r(ScsWork *w, const scs_float *x,
|
|
327
347
|
|
328
348
|
static scs_float root_plus(ScsWork *w, scs_float *p, scs_float *mu,
|
329
349
|
scs_float eta) {
|
330
|
-
scs_float a, b, c, tau_scale = w->diag_r[w->n + w->m];
|
350
|
+
scs_float a, b, c, tau_scale = w->diag_r[w->d->n + w->d->m];
|
331
351
|
a = tau_scale + dot_r(w, w->g, w->g);
|
332
352
|
b = dot_r(w, mu, w->g) - 2 * dot_r(w, p, w->g) - eta * tau_scale;
|
333
353
|
c = dot_r(w, p, p) - dot_r(w, p, mu);
|
@@ -336,7 +356,7 @@ static scs_float root_plus(ScsWork *w, scs_float *p, scs_float *mu,
|
|
336
356
|
|
337
357
|
/* status < 0 indicates failure */
|
338
358
|
static scs_int project_lin_sys(ScsWork *w, scs_int iter) {
|
339
|
-
scs_int n = w->n, m = w->m, l = n + m + 1, status, i;
|
359
|
+
scs_int n = w->d->n, m = w->d->m, l = n + m + 1, status, i;
|
340
360
|
scs_float *warm_start = SCS_NULL;
|
341
361
|
scs_float tol = -1.0; /* only used for indirect methods, overridden later */
|
342
362
|
memcpy(w->u_t, w->v, l * sizeof(scs_float));
|
@@ -350,12 +370,12 @@ static scs_int project_lin_sys(ScsWork *w, scs_int iter) {
|
|
350
370
|
/* warm_start = u[:n] + tau * g[:n] */
|
351
371
|
SCS(add_scaled_array)(warm_start, w->g, l - 1, w->u[l - 1]);
|
352
372
|
/* use normalized residuals to compute tolerance */
|
353
|
-
tol = MIN(CG_NORM(w->r_normalized->ax_s_btau, w->m),
|
354
|
-
CG_NORM(w->r_normalized->px_aty_ctau, w->n));
|
373
|
+
tol = MIN(CG_NORM(w->r_normalized->ax_s_btau, w->d->m),
|
374
|
+
CG_NORM(w->r_normalized->px_aty_ctau, w->d->n));
|
355
375
|
/* tol ~ O(1/k^(1+eps)) guarantees convergence */
|
356
376
|
/* use warm-start to calculate tolerance rather than w->u_t, since warm_start
|
357
377
|
* should be approximately equal to the true solution */
|
358
|
-
tol = CG_TOL_FACTOR * MIN(tol, CG_NORM(warm_start, w->n) /
|
378
|
+
tol = CG_TOL_FACTOR * MIN(tol, CG_NORM(warm_start, w->d->n) /
|
359
379
|
POWF((scs_float)iter + 1, CG_RATE));
|
360
380
|
tol = MAX(CG_BEST_TOL, tol);
|
361
381
|
#endif
|
@@ -378,14 +398,14 @@ static scs_int project_lin_sys(ScsWork *w, scs_int iter) {
|
|
378
398
|
* (no effect of w->stgs->alpha here).
|
379
399
|
*/
|
380
400
|
static void compute_rsk(ScsWork *w) {
|
381
|
-
scs_int i, l = w->m + w->n + 1;
|
401
|
+
scs_int i, l = w->d->m + w->d->n + 1;
|
382
402
|
for (i = 0; i < l; ++i) {
|
383
403
|
w->rsk[i] = (w->v[i] + w->u[i] - 2 * w->u_t[i]) * w->diag_r[i];
|
384
404
|
}
|
385
405
|
}
|
386
406
|
|
387
407
|
static void update_dual_vars(ScsWork *w) {
|
388
|
-
scs_int i, l = w->n + w->m + 1;
|
408
|
+
scs_int i, l = w->d->n + w->d->m + 1;
|
389
409
|
for (i = 0; i < l; ++i) {
|
390
410
|
w->v[i] += w->stgs->alpha * (w->u[i] - w->u_t[i]);
|
391
411
|
}
|
@@ -393,7 +413,7 @@ static void update_dual_vars(ScsWork *w) {
|
|
393
413
|
|
394
414
|
/* status < 0 indicates failure */
|
395
415
|
static scs_int project_cones(ScsWork *w, const ScsCone *k, scs_int iter) {
|
396
|
-
scs_int i, n = w->n, l = w->n + w->m + 1, status;
|
416
|
+
scs_int i, n = w->d->n, l = w->d->n + w->d->m + 1, status;
|
397
417
|
for (i = 0; i < l; ++i) {
|
398
418
|
w->u[i] = 2 * w->u_t[i] - w->v[i];
|
399
419
|
}
|
@@ -410,30 +430,30 @@ static scs_int project_cones(ScsWork *w, const ScsCone *k, scs_int iter) {
|
|
410
430
|
|
411
431
|
static void sety(const ScsWork *w, ScsSolution *sol) {
|
412
432
|
if (!sol->y) {
|
413
|
-
sol->y = (scs_float *)scs_calloc(w->m, sizeof(scs_float));
|
433
|
+
sol->y = (scs_float *)scs_calloc(w->d->m, sizeof(scs_float));
|
414
434
|
}
|
415
|
-
memcpy(sol->y, &(w->u[w->n]), w->m * sizeof(scs_float));
|
435
|
+
memcpy(sol->y, &(w->u[w->d->n]), w->d->m * sizeof(scs_float));
|
416
436
|
}
|
417
437
|
|
418
438
|
/* s is contained in rsk */
|
419
439
|
static void sets(const ScsWork *w, ScsSolution *sol) {
|
420
440
|
if (!sol->s) {
|
421
|
-
sol->s = (scs_float *)scs_calloc(w->m, sizeof(scs_float));
|
441
|
+
sol->s = (scs_float *)scs_calloc(w->d->m, sizeof(scs_float));
|
422
442
|
}
|
423
|
-
memcpy(sol->s, &(w->rsk[w->n]), w->m * sizeof(scs_float));
|
443
|
+
memcpy(sol->s, &(w->rsk[w->d->n]), w->d->m * sizeof(scs_float));
|
424
444
|
}
|
425
445
|
|
426
446
|
static void setx(const ScsWork *w, ScsSolution *sol) {
|
427
447
|
if (!sol->x) {
|
428
|
-
sol->x = (scs_float *)scs_calloc(w->n, sizeof(scs_float));
|
448
|
+
sol->x = (scs_float *)scs_calloc(w->d->n, sizeof(scs_float));
|
429
449
|
}
|
430
|
-
memcpy(sol->x, w->u, w->n * sizeof(scs_float));
|
450
|
+
memcpy(sol->x, w->u, w->d->n * sizeof(scs_float));
|
431
451
|
}
|
432
452
|
|
433
453
|
static void set_solved(const ScsWork *w, ScsSolution *sol, ScsInfo *info) {
|
434
|
-
SCS(scale_array)(sol->x, SAFEDIV_POS(1.0, w->r_orig->tau), w->n);
|
435
|
-
SCS(scale_array)(sol->y, SAFEDIV_POS(1.0, w->r_orig->tau), w->m);
|
436
|
-
SCS(scale_array)(sol->s, SAFEDIV_POS(1.0, w->r_orig->tau), w->m);
|
454
|
+
SCS(scale_array)(sol->x, SAFEDIV_POS(1.0, w->r_orig->tau), w->d->n);
|
455
|
+
SCS(scale_array)(sol->y, SAFEDIV_POS(1.0, w->r_orig->tau), w->d->m);
|
456
|
+
SCS(scale_array)(sol->s, SAFEDIV_POS(1.0, w->r_orig->tau), w->d->m);
|
437
457
|
info->gap = w->r_orig->gap;
|
438
458
|
info->res_pri = w->r_orig->res_pri;
|
439
459
|
info->res_dual = w->r_orig->res_dual;
|
@@ -444,9 +464,9 @@ static void set_solved(const ScsWork *w, ScsSolution *sol, ScsInfo *info) {
|
|
444
464
|
}
|
445
465
|
|
446
466
|
static void set_infeasible(const ScsWork *w, ScsSolution *sol, ScsInfo *info) {
|
447
|
-
SCS(scale_array)(sol->y, -1 / w->r_orig->bty_tau, w->m);
|
448
|
-
SCS(scale_array)(sol->x, NAN, w->n);
|
449
|
-
SCS(scale_array)(sol->s, NAN, w->m);
|
467
|
+
SCS(scale_array)(sol->y, -1 / w->r_orig->bty_tau, w->d->m);
|
468
|
+
SCS(scale_array)(sol->x, NAN, w->d->n);
|
469
|
+
SCS(scale_array)(sol->s, NAN, w->d->m);
|
450
470
|
info->gap = NAN;
|
451
471
|
info->res_pri = NAN;
|
452
472
|
info->res_dual = NAN;
|
@@ -457,9 +477,9 @@ static void set_infeasible(const ScsWork *w, ScsSolution *sol, ScsInfo *info) {
|
|
457
477
|
}
|
458
478
|
|
459
479
|
static void set_unbounded(const ScsWork *w, ScsSolution *sol, ScsInfo *info) {
|
460
|
-
SCS(scale_array)(sol->x, -1 / w->r_orig->ctx_tau, w->n);
|
461
|
-
SCS(scale_array)(sol->s, -1 / w->r_orig->ctx_tau, w->m);
|
462
|
-
SCS(scale_array)(sol->y, NAN, w->m);
|
480
|
+
SCS(scale_array)(sol->x, -1 / w->r_orig->ctx_tau, w->d->n);
|
481
|
+
SCS(scale_array)(sol->s, -1 / w->r_orig->ctx_tau, w->d->m);
|
482
|
+
SCS(scale_array)(sol->y, NAN, w->d->m);
|
463
483
|
info->gap = NAN;
|
464
484
|
info->res_pri = NAN;
|
465
485
|
info->res_dual = NAN;
|
@@ -506,13 +526,13 @@ static void finalize(ScsWork *w, ScsSolution *sol, ScsInfo *info,
|
|
506
526
|
info->res_infeas = w->r_orig->res_infeas;
|
507
527
|
info->res_unbdd_a = w->r_orig->res_unbdd_a;
|
508
528
|
info->res_unbdd_p = w->r_orig->res_unbdd_p;
|
509
|
-
info->scale = w->scale;
|
529
|
+
info->scale = w->stgs->scale;
|
510
530
|
info->scale_updates = w->scale_updates;
|
511
531
|
info->rejected_accel_steps = w->rejected_accel_steps;
|
512
532
|
info->accepted_accel_steps = w->accepted_accel_steps;
|
513
|
-
info->comp_slack = ABS(SCS(dot)(sol->s, sol->y, w->m));
|
514
|
-
if (info->comp_slack >
|
515
|
-
|
533
|
+
info->comp_slack = ABS(SCS(dot)(sol->s, sol->y, w->d->m));
|
534
|
+
if (info->comp_slack > 1e-5 * MAX(SCS(norm_inf)(sol->s, w->d->m),
|
535
|
+
SCS(norm_inf)(sol->y, w->d->m))) {
|
516
536
|
scs_printf("WARNING - large complementary slackness residual: %f\n",
|
517
537
|
info->comp_slack);
|
518
538
|
}
|
@@ -542,23 +562,23 @@ static void print_summary(ScsWork *w, scs_int i, SCS(timer) * solve_timer) {
|
|
542
562
|
scs_printf("%*.2e ", (int)HSPACE, r->gap);
|
543
563
|
/* report mid point of primal and dual objective values */
|
544
564
|
scs_printf("%*.2e ", (int)HSPACE, 0.5 * (r->pobj + r->dobj));
|
545
|
-
scs_printf("%*.2e ", (int)HSPACE, w->scale);
|
565
|
+
scs_printf("%*.2e ", (int)HSPACE, w->stgs->scale);
|
546
566
|
scs_printf("%*.2e ", (int)HSPACE, SCS(tocq)(solve_timer) / 1e3);
|
547
567
|
scs_printf("\n");
|
548
568
|
|
549
569
|
#if VERBOSITY > 0
|
550
|
-
scs_printf("Norm u = %4f, ", SCS(norm_2)(w->u, w->n + w->m + 1));
|
551
|
-
scs_printf("Norm u_t = %4f, ", SCS(norm_2)(w->u_t, w->n + w->m + 1));
|
552
|
-
scs_printf("Norm v = %4f, ", SCS(norm_2)(w->v, w->n + w->m + 1));
|
553
|
-
scs_printf("Norm rsk = %4f, ", SCS(norm_2)(w->rsk, w->n + w->m + 1));
|
554
|
-
scs_printf("Norm x = %4f, ", SCS(norm_2)(w->xys_orig->x, w->n));
|
555
|
-
scs_printf("Norm y = %4f, ", SCS(norm_2)(w->xys_orig->y, w->m));
|
556
|
-
scs_printf("Norm s = %4f, ", SCS(norm_2)(w->xys_orig->s, w->m));
|
557
|
-
scs_printf("Norm |Ax + s| = %1.2e, ", SCS(norm_2)(r->ax_s, w->m));
|
558
|
-
scs_printf("tau = %4f, ", w->u[w->n + w->m]);
|
559
|
-
scs_printf("kappa = %4f, ", w->rsk[w->n + w->m]);
|
570
|
+
scs_printf("Norm u = %4f, ", SCS(norm_2)(w->u, w->d->n + w->d->m + 1));
|
571
|
+
scs_printf("Norm u_t = %4f, ", SCS(norm_2)(w->u_t, w->d->n + w->d->m + 1));
|
572
|
+
scs_printf("Norm v = %4f, ", SCS(norm_2)(w->v, w->d->n + w->d->m + 1));
|
573
|
+
scs_printf("Norm rsk = %4f, ", SCS(norm_2)(w->rsk, w->d->n + w->d->m + 1));
|
574
|
+
scs_printf("Norm x = %4f, ", SCS(norm_2)(w->xys_orig->x, w->d->n));
|
575
|
+
scs_printf("Norm y = %4f, ", SCS(norm_2)(w->xys_orig->y, w->d->m));
|
576
|
+
scs_printf("Norm s = %4f, ", SCS(norm_2)(w->xys_orig->s, w->d->m));
|
577
|
+
scs_printf("Norm |Ax + s| = %1.2e, ", SCS(norm_2)(r->ax_s, w->d->m));
|
578
|
+
scs_printf("tau = %4f, ", w->u[w->d->n + w->d->m]);
|
579
|
+
scs_printf("kappa = %4f, ", w->rsk[w->d->n + w->d->m]);
|
560
580
|
scs_printf("|u - u_t| = %1.2e, ",
|
561
|
-
SCS(norm_diff)(w->u, w->u_t, w->n + w->m + 1));
|
581
|
+
SCS(norm_diff)(w->u, w->u_t, w->d->n + w->d->m + 1));
|
562
582
|
scs_printf("res_infeas = %1.2e, ", r->res_infeas);
|
563
583
|
scs_printf("res_unbdd_a = %1.2e, ", r->res_unbdd_a);
|
564
584
|
scs_printf("res_unbdd_p = %1.2e, ", r->res_unbdd_p);
|
@@ -643,10 +663,11 @@ static scs_int has_converged(ScsWork *w, scs_int iter) {
|
|
643
663
|
/* xt_p_x, ctx, bty already have tau divided out */
|
644
664
|
grl = MAX(MAX(ABS(r->xt_p_x), ABS(r->ctx)), ABS(r->bty));
|
645
665
|
/* s, ax, px, aty do *not* have tau divided out, so need to divide */
|
646
|
-
prl = MAX(MAX(NORM(b, w->m) * r->tau, NORM(s, w->m)),
|
666
|
+
prl = MAX(MAX(NORM(b, w->d->m) * r->tau, NORM(s, w->d->m)),
|
667
|
+
NORM(r->ax, w->d->m)) /
|
647
668
|
r->tau;
|
648
|
-
drl = MAX(MAX(NORM(c, w->n) * r->tau, NORM(r->px, w->n)),
|
649
|
-
NORM(r->aty, w->n)) /
|
669
|
+
drl = MAX(MAX(NORM(c, w->d->n) * r->tau, NORM(r->px, w->d->n)),
|
670
|
+
NORM(r->aty, w->d->n)) /
|
650
671
|
r->tau;
|
651
672
|
if (isless(r->res_pri, eps_abs + eps_rel * prl) &&
|
652
673
|
isless(r->res_dual, eps_abs + eps_rel * drl) &&
|
@@ -722,7 +743,6 @@ static scs_int validate(const ScsData *d, const ScsCone *k,
|
|
722
743
|
|
723
744
|
static ScsResiduals *init_residuals(const ScsData *d) {
|
724
745
|
ScsResiduals *r = (ScsResiduals *)scs_calloc(1, sizeof(ScsResiduals));
|
725
|
-
r->last_iter = -1;
|
726
746
|
r->ax = (scs_float *)scs_calloc(d->m, sizeof(scs_float));
|
727
747
|
r->ax_s = (scs_float *)scs_calloc(d->m, sizeof(scs_float));
|
728
748
|
r->ax_s_btau = (scs_float *)scs_calloc(d->m, sizeof(scs_float));
|
@@ -732,16 +752,44 @@ static ScsResiduals *init_residuals(const ScsData *d) {
|
|
732
752
|
return r;
|
733
753
|
}
|
734
754
|
|
755
|
+
scs_int scs_update(ScsWork *w, scs_float *b, scs_float *c) {
|
756
|
+
SCS(timer) update_timer;
|
757
|
+
SCS(tic)(&update_timer);
|
758
|
+
|
759
|
+
if (b) {
|
760
|
+
memcpy(w->b_orig, b, w->d->m * sizeof(scs_float));
|
761
|
+
memcpy(w->d->b, b, w->d->m * sizeof(scs_float));
|
762
|
+
} else {
|
763
|
+
memcpy(w->d->b, w->b_orig, w->d->m * sizeof(scs_float));
|
764
|
+
}
|
765
|
+
if (c) {
|
766
|
+
memcpy(w->c_orig, c, w->d->n * sizeof(scs_float));
|
767
|
+
memcpy(w->d->c, c, w->d->n * sizeof(scs_float));
|
768
|
+
} else {
|
769
|
+
memcpy(w->d->c, w->c_orig, w->d->n * sizeof(scs_float));
|
770
|
+
}
|
771
|
+
|
772
|
+
/* normalize */
|
773
|
+
if (w->scal) {
|
774
|
+
SCS(normalize_b_c)(w->scal, w->d->b, w->d->c);
|
775
|
+
}
|
776
|
+
|
777
|
+
/* override setup time with update time, since the update is the 'setup' */
|
778
|
+
w->setup_time = SCS(tocq)(&update_timer);
|
779
|
+
return 0;
|
780
|
+
}
|
781
|
+
|
735
782
|
/* Sets the diag_r vector, given the scale parameters in work */
|
736
783
|
static void set_diag_r(ScsWork *w) {
|
737
784
|
scs_int i;
|
738
|
-
for (i = 0; i < w->n; ++i) {
|
785
|
+
for (i = 0; i < w->d->n; ++i) {
|
739
786
|
w->diag_r[i] = w->stgs->rho_x;
|
740
787
|
}
|
741
788
|
/* use cone information to set R_y */
|
742
|
-
SCS(set_r_y)(w->cone_work, w->scale, &(w->diag_r[w->n]));
|
789
|
+
SCS(set_r_y)(w->cone_work, w->stgs->scale, &(w->diag_r[w->d->n]));
|
743
790
|
/* if modified need to SCS(enforce_cone_boundaries)(...) */
|
744
|
-
w->diag_r[w->n + w->m] =
|
791
|
+
w->diag_r[w->d->n + w->d->m] =
|
792
|
+
TAU_FACTOR; /* TODO: is this the best choice? */
|
745
793
|
}
|
746
794
|
|
747
795
|
static ScsWork *init_work(const ScsData *d, const ScsCone *k,
|
@@ -755,18 +803,21 @@ static ScsWork *init_work(const ScsData *d, const ScsCone *k,
|
|
755
803
|
scs_printf("ERROR: allocating work failure\n");
|
756
804
|
return SCS_NULL;
|
757
805
|
}
|
758
|
-
/*
|
759
|
-
w->d =
|
760
|
-
w->
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
w->
|
765
|
-
w->
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
w->
|
806
|
+
/* deep copy data */
|
807
|
+
w->d = (ScsData *)scs_calloc(1, sizeof(ScsData));
|
808
|
+
SCS(deep_copy_data)(w->d, d);
|
809
|
+
d = SCS_NULL; /* for safety */
|
810
|
+
|
811
|
+
/* deep copy cone */
|
812
|
+
w->k = (ScsCone *)scs_calloc(1, sizeof(ScsCone));
|
813
|
+
SCS(deep_copy_cone)(w->k, k);
|
814
|
+
k = SCS_NULL; /* for safety */
|
815
|
+
|
816
|
+
/* deep copy settings */
|
817
|
+
w->stgs = (ScsSettings *)scs_calloc(1, sizeof(ScsSettings));
|
818
|
+
SCS(deep_copy_stgs)(w->stgs, stgs);
|
819
|
+
stgs = SCS_NULL; /* for safety */
|
820
|
+
|
770
821
|
/* allocate workspace: */
|
771
822
|
w->u = (scs_float *)scs_calloc(l, sizeof(scs_float));
|
772
823
|
w->u_t = (scs_float *)scs_calloc(l, sizeof(scs_float));
|
@@ -779,64 +830,44 @@ static ScsWork *init_work(const ScsData *d, const ScsCone *k,
|
|
779
830
|
w->diag_r = (scs_float *)scs_calloc(l, sizeof(scs_float));
|
780
831
|
/* x,y,s struct */
|
781
832
|
w->xys_orig = (ScsSolution *)scs_calloc(1, sizeof(ScsSolution));
|
782
|
-
w->xys_orig->x = (scs_float *)scs_calloc(d->n, sizeof(scs_float));
|
783
|
-
w->xys_orig->s = (scs_float *)scs_calloc(d->m, sizeof(scs_float));
|
784
|
-
w->xys_orig->y = (scs_float *)scs_calloc(d->m, sizeof(scs_float));
|
785
|
-
w->r_orig = init_residuals(d);
|
786
|
-
|
787
|
-
w->
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
w->c_orig = d->c;
|
792
|
-
w->b_normalized = (scs_float *)scs_calloc(d->m, sizeof(scs_float));
|
793
|
-
w->c_normalized = (scs_float *)scs_calloc(d->n, sizeof(scs_float));
|
794
|
-
memcpy(w->b_normalized, w->b_orig, w->m * sizeof(scs_float));
|
795
|
-
memcpy(w->c_normalized, w->c_orig, w->n * sizeof(scs_float));
|
796
|
-
|
797
|
-
if (!(w->cone_work = SCS(init_cone)(k, w->m))) {
|
798
|
-
scs_printf("ERROR: init_cone failure\n");
|
833
|
+
w->xys_orig->x = (scs_float *)scs_calloc(w->d->n, sizeof(scs_float));
|
834
|
+
w->xys_orig->s = (scs_float *)scs_calloc(w->d->m, sizeof(scs_float));
|
835
|
+
w->xys_orig->y = (scs_float *)scs_calloc(w->d->m, sizeof(scs_float));
|
836
|
+
w->r_orig = init_residuals(w->d);
|
837
|
+
w->b_orig = (scs_float *)scs_calloc(w->d->m, sizeof(scs_float));
|
838
|
+
w->c_orig = (scs_float *)scs_calloc(w->d->n, sizeof(scs_float));
|
839
|
+
|
840
|
+
if (!w->c_orig) {
|
841
|
+
scs_printf("ERROR: work memory allocation failure\n");
|
799
842
|
return SCS_NULL;
|
800
843
|
}
|
801
|
-
set_diag_r(w);
|
802
844
|
|
803
|
-
if (!w->
|
804
|
-
scs_printf("ERROR:
|
845
|
+
if (!(w->cone_work = SCS(init_cone)(w->k, w->d->m))) {
|
846
|
+
scs_printf("ERROR: init_cone failure\n");
|
805
847
|
return SCS_NULL;
|
806
848
|
}
|
849
|
+
set_diag_r(w);
|
807
850
|
|
808
851
|
if (w->stgs->normalize) {
|
809
852
|
w->xys_normalized = (ScsSolution *)scs_calloc(1, sizeof(ScsSolution));
|
810
|
-
w->xys_normalized->x = (scs_float *)scs_calloc(d->n, sizeof(scs_float));
|
811
|
-
w->xys_normalized->s = (scs_float *)scs_calloc(d->m, sizeof(scs_float));
|
812
|
-
w->xys_normalized->y = (scs_float *)scs_calloc(d->m, sizeof(scs_float));
|
813
|
-
w->r_normalized = init_residuals(d);
|
814
|
-
|
815
|
-
#ifdef COPYAMATRIX
|
816
|
-
if (!SCS(copy_matrix)(&(w->A), d->A)) {
|
817
|
-
scs_printf("ERROR: copy A matrix failed\n");
|
818
|
-
return SCS_NULL;
|
819
|
-
}
|
820
|
-
if (w->P && !SCS(copy_matrix)(&(w->P), d->P)) {
|
821
|
-
scs_printf("ERROR: copy P matrix failed\n");
|
822
|
-
return SCS_NULL;
|
823
|
-
}
|
824
|
-
#endif
|
853
|
+
w->xys_normalized->x = (scs_float *)scs_calloc(w->d->n, sizeof(scs_float));
|
854
|
+
w->xys_normalized->s = (scs_float *)scs_calloc(w->d->m, sizeof(scs_float));
|
855
|
+
w->xys_normalized->y = (scs_float *)scs_calloc(w->d->m, sizeof(scs_float));
|
856
|
+
w->r_normalized = init_residuals(w->d);
|
825
857
|
/* this allocates memory that must be freed */
|
826
|
-
w->scal = SCS(normalize_a_p)(w->P, w->A, w->
|
827
|
-
w->cone_work);
|
858
|
+
w->scal = SCS(normalize_a_p)(w->d->P, w->d->A, w->cone_work);
|
828
859
|
} else {
|
829
860
|
w->xys_normalized = w->xys_orig;
|
830
861
|
w->r_normalized = w->r_orig;
|
831
862
|
w->scal = SCS_NULL;
|
832
863
|
}
|
833
|
-
|
864
|
+
/* set w->*_orig and performs normalization if appropriate */
|
865
|
+
scs_update(w, w->d->b, w->d->c);
|
866
|
+
|
867
|
+
if (!(w->p = SCS(init_lin_sys_work)(w->d->A, w->d->P, w->diag_r))) {
|
834
868
|
scs_printf("ERROR: init_lin_sys_work failure\n");
|
835
869
|
return SCS_NULL;
|
836
870
|
}
|
837
|
-
/* Acceleration */
|
838
|
-
w->rejected_accel_steps = 0;
|
839
|
-
w->accepted_accel_steps = 0;
|
840
871
|
if (w->stgs->acceleration_lookback) {
|
841
872
|
/* TODO(HACK!) negative acceleration_lookback interpreted as type-II */
|
842
873
|
if (!(w->accel = aa_init(l, ABS(w->stgs->acceleration_lookback),
|
@@ -858,16 +889,31 @@ static ScsWork *init_work(const ScsData *d, const ScsCone *k,
|
|
858
889
|
|
859
890
|
static void update_work_cache(ScsWork *w) {
|
860
891
|
/* g = (I + M)^{-1} h */
|
861
|
-
memcpy(w->g, w->h, (w->n + w->m) * sizeof(scs_float));
|
862
|
-
SCS(scale_array)(&(w->g[w->n]), -1., w->m);
|
892
|
+
memcpy(w->g, w->h, (w->d->n + w->d->m) * sizeof(scs_float));
|
893
|
+
SCS(scale_array)(&(w->g[w->d->n]), -1., w->d->m);
|
863
894
|
SCS(solve_lin_sys)(w->p, w->g, SCS_NULL, CG_BEST_TOL);
|
864
895
|
return;
|
865
896
|
}
|
866
897
|
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
898
|
+
/* Reset quantities specific to current solve */
|
899
|
+
static void reset_tracking(ScsWork *w) {
|
900
|
+
w->last_scale_update_iter = 0;
|
901
|
+
w->sum_log_scale_factor = 0.;
|
902
|
+
w->n_log_scale_factor = 0;
|
903
|
+
w->scale_updates = 0;
|
904
|
+
w->time_limit_reached = 0;
|
905
|
+
/* Acceleration */
|
906
|
+
w->rejected_accel_steps = 0;
|
907
|
+
w->accepted_accel_steps = 0;
|
908
|
+
w->aa_norm = 0.;
|
909
|
+
/* Need this to force residual calc if previous solve solved at iter 0 */
|
910
|
+
w->r_normalized->last_iter = -1;
|
911
|
+
w->r_orig->last_iter = -1;
|
912
|
+
}
|
913
|
+
|
914
|
+
static scs_int update_work(ScsWork *w, ScsSolution *sol) {
|
915
|
+
reset_tracking(w);
|
916
|
+
|
871
917
|
if (w->stgs->warm_start) {
|
872
918
|
warm_start_vars(w, sol);
|
873
919
|
} else {
|
@@ -875,8 +921,8 @@ static scs_int update_work(const ScsData *d, ScsWork *w, ScsSolution *sol) {
|
|
875
921
|
}
|
876
922
|
|
877
923
|
/* h = [c;b] */
|
878
|
-
memcpy(w->h, w->
|
879
|
-
memcpy(&(w->h[n]), w->
|
924
|
+
memcpy(w->h, w->d->c, w->d->n * sizeof(scs_float));
|
925
|
+
memcpy(&(w->h[w->d->n]), w->d->b, w->d->m * sizeof(scs_float));
|
880
926
|
update_work_cache(w);
|
881
927
|
return 0;
|
882
928
|
}
|
@@ -897,15 +943,15 @@ static void update_scale(ScsWork *w, const ScsCone *k, scs_int iter) {
|
|
897
943
|
|
898
944
|
scs_int iters_since_last_update = iter - w->last_scale_update_iter;
|
899
945
|
/* ||Ax + s - b * tau|| */
|
900
|
-
scs_float relative_res_pri =
|
901
|
-
|
902
|
-
|
903
|
-
|
946
|
+
scs_float relative_res_pri = SAFEDIV_POS(
|
947
|
+
SCALE_NORM(r->ax_s_btau, w->d->m),
|
948
|
+
MAX(MAX(SCALE_NORM(r->ax, w->d->m), SCALE_NORM(xys->s, w->d->m)),
|
949
|
+
SCALE_NORM(b, w->d->m) * r->tau));
|
904
950
|
/* ||Px + A'y + c * tau|| */
|
905
|
-
scs_float relative_res_dual =
|
906
|
-
|
907
|
-
|
908
|
-
|
951
|
+
scs_float relative_res_dual = SAFEDIV_POS(
|
952
|
+
SCALE_NORM(r->px_aty_ctau, w->d->n),
|
953
|
+
MAX(MAX(SCALE_NORM(r->px, w->d->n), SCALE_NORM(r->aty, w->d->n)),
|
954
|
+
SCALE_NORM(c, w->d->n) * r->tau));
|
909
955
|
|
910
956
|
/* higher scale makes res_pri go down faster, so increase if res_pri larger */
|
911
957
|
w->sum_log_scale_factor += log(relative_res_pri) - log(relative_res_dual);
|
@@ -919,8 +965,9 @@ static void update_scale(ScsWork *w, const ScsCone *k, scs_int iter) {
|
|
919
965
|
if (iters_since_last_update < RESCALING_MIN_ITERS) {
|
920
966
|
return;
|
921
967
|
}
|
922
|
-
new_scale =
|
923
|
-
|
968
|
+
new_scale =
|
969
|
+
MIN(MAX(w->stgs->scale * factor, MIN_SCALE_VALUE), MAX_SCALE_VALUE);
|
970
|
+
if (new_scale == w->stgs->scale) {
|
924
971
|
return;
|
925
972
|
}
|
926
973
|
if (should_update_r(factor, iters_since_last_update)) {
|
@@ -928,7 +975,7 @@ static void update_scale(ScsWork *w, const ScsCone *k, scs_int iter) {
|
|
928
975
|
w->sum_log_scale_factor = 0;
|
929
976
|
w->n_log_scale_factor = 0;
|
930
977
|
w->last_scale_update_iter = iter;
|
931
|
-
w->scale = new_scale;
|
978
|
+
w->stgs->scale = new_scale;
|
932
979
|
|
933
980
|
/* update diag r vector */
|
934
981
|
set_diag_r(w);
|
@@ -947,7 +994,7 @@ static void update_scale(ScsWork *w, const ScsCone *k, scs_int iter) {
|
|
947
994
|
/* solve: R^+ (v^+ + u - 2u_t) = rsk = R(v + u - 2u_t)
|
948
995
|
* => v^+ = R+^-1 rsk + 2u_t - u
|
949
996
|
*/
|
950
|
-
for (i = 0; i < w->n + w->m + 1; i++) {
|
997
|
+
for (i = 0; i < w->d->n + w->d->m + 1; i++) {
|
951
998
|
w->v[i] = w->rsk[i] / w->diag_r[i] + 2 * w->u_t[i] - w->u[i];
|
952
999
|
}
|
953
1000
|
}
|
@@ -959,7 +1006,8 @@ static inline void normalize_v(scs_float *v, scs_int len) {
|
|
959
1006
|
SCS(scale_array)(v, SQRTF((scs_float)len) * ITERATE_NORM / v_norm, len);
|
960
1007
|
}
|
961
1008
|
|
962
|
-
scs_int scs_solve(ScsWork *w, ScsSolution *sol, ScsInfo *info
|
1009
|
+
scs_int scs_solve(ScsWork *w, ScsSolution *sol, ScsInfo *info,
|
1010
|
+
scs_int warm_start) {
|
963
1011
|
scs_int i;
|
964
1012
|
SCS(timer) solve_timer, lin_sys_timer, cone_timer, accel_timer;
|
965
1013
|
scs_float total_accel_time = 0.0, total_cone_time = 0.0,
|
@@ -968,16 +1016,18 @@ scs_int scs_solve(ScsWork *w, ScsSolution *sol, ScsInfo *info) {
|
|
968
1016
|
scs_printf("ERROR: missing ScsWork, ScsSolution or ScsInfo input\n");
|
969
1017
|
return SCS_FAILED;
|
970
1018
|
}
|
971
|
-
scs_int l = w->m + w->n + 1;
|
972
|
-
const ScsData *d = w->d;
|
1019
|
+
scs_int l = w->d->m + w->d->n + 1;
|
973
1020
|
const ScsCone *k = w->k;
|
974
|
-
|
1021
|
+
ScsSettings *stgs = w->stgs;
|
1022
|
+
/* set warm start */
|
1023
|
+
stgs->warm_start = warm_start;
|
1024
|
+
|
975
1025
|
/* initialize ctrl-c support */
|
976
1026
|
scs_start_interrupt_listener();
|
977
1027
|
SCS(tic)(&solve_timer);
|
978
1028
|
strcpy(info->lin_sys_solver, SCS(get_lin_sys_method)());
|
979
1029
|
info->status_val = SCS_UNFINISHED; /* not yet converged */
|
980
|
-
update_work(
|
1030
|
+
update_work(w, sol);
|
981
1031
|
|
982
1032
|
if (w->stgs->verbose) {
|
983
1033
|
print_header(w, k);
|
@@ -1008,7 +1058,7 @@ scs_int scs_solve(ScsWork *w, ScsSolution *sol, ScsInfo *info) {
|
|
1008
1058
|
/******************* linear system solve ********************/
|
1009
1059
|
SCS(tic)(&lin_sys_timer);
|
1010
1060
|
if (project_lin_sys(w, i) < 0) {
|
1011
|
-
return failure(w, w->m, w->n, sol, info, SCS_FAILED,
|
1061
|
+
return failure(w, w->d->m, w->d->n, sol, info, SCS_FAILED,
|
1012
1062
|
"error in project_lin_sys", "failure");
|
1013
1063
|
}
|
1014
1064
|
total_lin_sys_time += SCS(tocq)(&lin_sys_timer);
|
@@ -1016,7 +1066,7 @@ scs_int scs_solve(ScsWork *w, ScsSolution *sol, ScsInfo *info) {
|
|
1016
1066
|
/****************** project onto the cones ******************/
|
1017
1067
|
SCS(tic)(&cone_timer);
|
1018
1068
|
if (project_cones(w, k, i) < 0) {
|
1019
|
-
return failure(w, w->m, w->n, sol, info, SCS_FAILED,
|
1069
|
+
return failure(w, w->d->m, w->d->n, sol, info, SCS_FAILED,
|
1020
1070
|
"error in project_cones", "failure");
|
1021
1071
|
}
|
1022
1072
|
total_cone_time += SCS(tocq)(&cone_timer);
|
@@ -1027,8 +1077,8 @@ scs_int scs_solve(ScsWork *w, ScsSolution *sol, ScsInfo *info) {
|
|
1027
1077
|
|
1028
1078
|
if (i % CONVERGED_INTERVAL == 0) {
|
1029
1079
|
if (scs_is_interrupted()) {
|
1030
|
-
return failure(w, w->m, w->n, sol, info, SCS_SIGINT,
|
1031
|
-
"interrupted");
|
1080
|
+
return failure(w, w->d->m, w->d->n, sol, info, SCS_SIGINT,
|
1081
|
+
"interrupted", "interrupted");
|
1032
1082
|
}
|
1033
1083
|
populate_residual_struct(w, i);
|
1034
1084
|
if ((info->status_val = has_converged(w, i)) != 0) {
|
@@ -1076,14 +1126,14 @@ scs_int scs_solve(ScsWork *w, ScsSolution *sol, ScsInfo *info) {
|
|
1076
1126
|
if (w->stgs->log_csv_filename) {
|
1077
1127
|
/* calc residuals every iter if logging to csv */
|
1078
1128
|
populate_residual_struct(w, i);
|
1079
|
-
SCS(log_data_to_csv)(
|
1129
|
+
SCS(log_data_to_csv)(k, stgs, w, i, &solve_timer);
|
1080
1130
|
}
|
1081
1131
|
}
|
1082
1132
|
|
1083
1133
|
/* Final logging after full run */
|
1084
1134
|
if (w->stgs->log_csv_filename) {
|
1085
1135
|
populate_residual_struct(w, i);
|
1086
|
-
SCS(log_data_to_csv)(
|
1136
|
+
SCS(log_data_to_csv)(k, stgs, w, i, &solve_timer);
|
1087
1137
|
}
|
1088
1138
|
|
1089
1139
|
if (w->stgs->verbose) {
|
@@ -1111,14 +1161,6 @@ scs_int scs_solve(ScsWork *w, ScsSolution *sol, ScsInfo *info) {
|
|
1111
1161
|
void scs_finish(ScsWork *w) {
|
1112
1162
|
if (w) {
|
1113
1163
|
SCS(finish_cone)(w->cone_work);
|
1114
|
-
if (w->stgs && w->stgs->normalize) {
|
1115
|
-
#ifndef COPYAMATRIX
|
1116
|
-
SCS(un_normalize_a_p)(w->A, w->P, w->scal);
|
1117
|
-
#else
|
1118
|
-
SCS(free_scs_matrix)(w->A);
|
1119
|
-
SCS(free_scs_matrix)(w->P);
|
1120
|
-
#endif
|
1121
|
-
}
|
1122
1164
|
if (w->p) {
|
1123
1165
|
SCS(free_lin_sys_work)(w->p);
|
1124
1166
|
}
|
@@ -1142,6 +1184,10 @@ ScsWork *scs_init(const ScsData *d, const ScsCone *k, const ScsSettings *stgs) {
|
|
1142
1184
|
scs_printf("ERROR: Validation returned failure\n");
|
1143
1185
|
return SCS_NULL;
|
1144
1186
|
}
|
1187
|
+
#endif
|
1188
|
+
#if VERBOSITY > 0
|
1189
|
+
scs_printf("size of scs_int = %lu, size of scs_float = %lu\n",
|
1190
|
+
sizeof(scs_int), sizeof(scs_float));
|
1145
1191
|
#endif
|
1146
1192
|
SCS(tic)(&init_timer);
|
1147
1193
|
if (stgs->write_data_filename) {
|
@@ -1160,12 +1206,8 @@ scs_int scs(const ScsData *d, const ScsCone *k, const ScsSettings *stgs,
|
|
1160
1206
|
ScsSolution *sol, ScsInfo *info) {
|
1161
1207
|
scs_int status;
|
1162
1208
|
ScsWork *w = scs_init(d, k, stgs);
|
1163
|
-
#if VERBOSITY > 0
|
1164
|
-
scs_printf("size of scs_int = %lu, size of scs_float = %lu\n",
|
1165
|
-
sizeof(scs_int), sizeof(scs_float));
|
1166
|
-
#endif
|
1167
1209
|
if (w) {
|
1168
|
-
scs_solve(w, sol, info);
|
1210
|
+
scs_solve(w, sol, info, stgs->warm_start);
|
1169
1211
|
status = info->status_val;
|
1170
1212
|
} else {
|
1171
1213
|
status = failure(SCS_NULL, d ? d->m : -1, d ? d->n : -1, sol, info,
|