scs 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/README.md +34 -5
  4. data/lib/scs/matrix.rb +72 -0
  5. data/lib/scs/solver.rb +19 -26
  6. data/lib/scs/version.rb +1 -1
  7. data/lib/scs.rb +1 -0
  8. data/vendor/scs/CITATION.cff +1 -1
  9. data/vendor/scs/CMakeLists.txt +2 -2
  10. data/vendor/scs/README.md +3 -1
  11. data/vendor/scs/include/cones.h +5 -3
  12. data/vendor/scs/include/glbopts.h +4 -5
  13. data/vendor/scs/include/normalize.h +1 -0
  14. data/vendor/scs/include/rw.h +3 -3
  15. data/vendor/scs/include/scs.h +45 -22
  16. data/vendor/scs/include/scs_work.h +15 -18
  17. data/vendor/scs/include/util.h +3 -1
  18. data/vendor/scs/linsys/external/amd/LICENSE.txt +0 -897
  19. data/vendor/scs/linsys/external/amd/SuiteSparse_config.c +4 -2
  20. data/vendor/scs/linsys/external/amd/SuiteSparse_config.h +0 -5
  21. data/vendor/scs/linsys/scs_matrix.c +38 -67
  22. data/vendor/scs/linsys/scs_matrix.h +4 -3
  23. data/vendor/scs/scs.mk +0 -4
  24. data/vendor/scs/src/aa.c +0 -4
  25. data/vendor/scs/src/cones.c +63 -25
  26. data/vendor/scs/src/normalize.c +49 -0
  27. data/vendor/scs/src/rw.c +48 -40
  28. data/vendor/scs/src/scs.c +212 -170
  29. data/vendor/scs/src/util.c +26 -12
  30. data/vendor/scs/test/problem_utils.h +3 -3
  31. data/vendor/scs/test/problems/degenerate.h +1 -0
  32. data/vendor/scs/test/problems/hs21_tiny_qp.h +1 -0
  33. data/vendor/scs/test/problems/hs21_tiny_qp_rw.h +5 -1
  34. data/vendor/scs/test/problems/infeasible_tiny_qp.h +1 -0
  35. data/vendor/scs/test/problems/qafiro_tiny_qp.h +2 -1
  36. data/vendor/scs/test/problems/random_prob.h +5 -1
  37. data/vendor/scs/test/problems/rob_gauss_cov_est.h +8 -1
  38. data/vendor/scs/test/problems/small_lp.h +4 -1
  39. data/vendor/scs/test/problems/small_qp.h +42 -7
  40. data/vendor/scs/test/problems/test_validation.h +4 -1
  41. data/vendor/scs/test/problems/unbounded_tiny_qp.h +3 -3
  42. data/vendor/scs/test/random_socp_prob.c +3 -1
  43. data/vendor/scs/test/run_from_file.c +15 -3
  44. metadata +5 -4
@@ -50,7 +50,9 @@
50
50
 
51
51
  struct SuiteSparse_config_struct SuiteSparse_config =
52
52
  {
53
- scs_malloc, scs_calloc, scs_realloc, scs_free, _scs_printf,
53
+ scs_malloc, scs_calloc, scs_realloc, scs_free,
54
+ /* Disable printing */
55
+ SCS_NULL,
54
56
  SuiteSparse_hypot,
55
57
  SuiteSparse_divcomplex
56
58
 
@@ -79,7 +81,7 @@ void SuiteSparse_start ( void )
79
81
  SuiteSparse_config.calloc_func = scs_calloc ;
80
82
  SuiteSparse_config.realloc_func = scs_realloc ;
81
83
  SuiteSparse_config.free_func = scs_free ;
82
- SuiteSparse_config.printf_func = _scs_printf ;
84
+ SuiteSparse_config.printf_func = SCS_NULL;
83
85
  /* math functions */
84
86
  SuiteSparse_config.hypot_func = SuiteSparse_hypot ;
85
87
  SuiteSparse_config.divcomplex_func = SuiteSparse_divcomplex ;
@@ -71,11 +71,6 @@ extern "C" {
71
71
  #define SuiteSparse_long_id "%" SuiteSparse_long_idd
72
72
  #endif
73
73
 
74
- #ifndef _scs_printf
75
- #define _scs_printf scs_printf
76
- #endif
77
-
78
-
79
74
  /* ========================================================================== */
80
75
  /* === SuiteSparse_config parameters and functions ========================== */
81
76
  /* ========================================================================== */
@@ -10,6 +10,10 @@
10
10
  #define NUM_L2_PASSES (1) /* do one or zero, not more since not stable */
11
11
 
12
12
  scs_int SCS(copy_matrix)(ScsMatrix **dstp, const ScsMatrix *src) {
13
+ if (!src) {
14
+ *dstp = SCS_NULL;
15
+ return 1;
16
+ }
13
17
  scs_int Anz = src->p[src->n];
14
18
  ScsMatrix *A = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
15
19
  if (!A) {
@@ -41,6 +45,8 @@ scs_int SCS(validate_lin_sys)(const ScsMatrix *A, const ScsMatrix *P) {
41
45
  }
42
46
  /* detects some errors in A col ptrs: */
43
47
  Anz = A->p[A->n];
48
+ /* Disable this check which is slowish and typically just produces noise. */
49
+ /*
44
50
  if (Anz > 0) {
45
51
  for (i = 0; i < A->n; ++i) {
46
52
  if (A->p[i] == A->p[i + 1]) {
@@ -53,6 +59,7 @@ scs_int SCS(validate_lin_sys)(const ScsMatrix *A, const ScsMatrix *P) {
53
59
  }
54
60
  }
55
61
  }
62
+ */
56
63
  if (((scs_float)Anz / A->m > A->n) || (Anz < 0)) {
57
64
  scs_printf("Anz (nonzeros in A) = %li, outside of valid range\n",
58
65
  (long)Anz);
@@ -106,9 +113,8 @@ static inline scs_float apply_limit(scs_float x) {
106
113
  return x;
107
114
  }
108
115
 
109
- static void compute_ruiz_mats(ScsMatrix *P, ScsMatrix *A, scs_float *b,
110
- scs_float *c, scs_float *Dt, scs_float *Et,
111
- scs_float *s, ScsConeWork *cone) {
116
+ static void compute_ruiz_mats(ScsMatrix *P, ScsMatrix *A, scs_float *Dt,
117
+ scs_float *Et, ScsConeWork *cone) {
112
118
  scs_int i, j, kk;
113
119
  scs_float wrk;
114
120
 
@@ -116,8 +122,8 @@ static void compute_ruiz_mats(ScsMatrix *P, ScsMatrix *A, scs_float *b,
116
122
 
117
123
  /* initialize D */
118
124
  for (i = 0; i < A->m; ++i) {
119
- /* Dt[i] = 0.; */
120
- Dt[i] = ABS(b[i]);
125
+ Dt[i] = 0.;
126
+ /* Dt[i] = ABS(b[i]); */
121
127
  }
122
128
 
123
129
  /* calculate row norms */
@@ -139,8 +145,8 @@ static void compute_ruiz_mats(ScsMatrix *P, ScsMatrix *A, scs_float *b,
139
145
 
140
146
  /* initialize E */
141
147
  for (i = 0; i < A->n; ++i) {
142
- /* Et[i] = 0.; */
143
- Et[i] = ABS(c[i]);
148
+ Et[i] = 0.;
149
+ /* Et[i] = ABS(c[i]); */
144
150
  }
145
151
 
146
152
  /* TODO: test not using P to determine scaling */
@@ -166,24 +172,19 @@ static void compute_ruiz_mats(ScsMatrix *P, ScsMatrix *A, scs_float *b,
166
172
  Et[i] = MAX(Et[i], SCS(norm_inf)(&(A->x[A->p[i]]), A->p[i + 1] - A->p[i]));
167
173
  Et[i] = SAFEDIV_POS(1.0, SQRTF(apply_limit(Et[i])));
168
174
  }
169
-
170
- /* calculate s value */
171
- *s = MAX(SCS(norm_inf)(c, A->n), SCS(norm_inf)(b, A->m));
172
- *s = SAFEDIV_POS(1.0, SQRTF(apply_limit(*s)));
173
175
  }
174
176
 
175
- static void compute_l2_mats(ScsMatrix *P, ScsMatrix *A, scs_float *b,
176
- scs_float *c, scs_float *Dt, scs_float *Et,
177
- scs_float *s, ScsConeWork *cone) {
177
+ static void compute_l2_mats(ScsMatrix *P, ScsMatrix *A, scs_float *Dt,
178
+ scs_float *Et, ScsConeWork *cone) {
178
179
  scs_int i, j, kk;
179
- scs_float wrk, norm_c, norm_b;
180
+ scs_float wrk;
180
181
 
181
182
  /**************************** D ****************************/
182
183
 
183
184
  /* initialize D */
184
185
  for (i = 0; i < A->m; ++i) {
185
- /* Dt[i] = 0.; */
186
- Dt[i] = b[i] * b[i];
186
+ Dt[i] = 0.;
187
+ /* Dt[i] = b[i] * b[i]; */
187
188
  }
188
189
 
189
190
  /* calculate row norms */
@@ -207,8 +208,8 @@ static void compute_l2_mats(ScsMatrix *P, ScsMatrix *A, scs_float *b,
207
208
 
208
209
  /* initialize E */
209
210
  for (i = 0; i < A->n; ++i) {
210
- /* Et[i] = 0.; */
211
- Et[i] = c[i] * c[i];
211
+ Et[i] = 0.;
212
+ /* Et[i] = c[i] * c[i]; */
212
213
  }
213
214
 
214
215
  /* TODO: test not using P to determine scaling */
@@ -234,17 +235,10 @@ static void compute_l2_mats(ScsMatrix *P, ScsMatrix *A, scs_float *b,
234
235
  Et[i] += SCS(norm_sq)(&(A->x[A->p[i]]), A->p[i + 1] - A->p[i]);
235
236
  Et[i] = SAFEDIV_POS(1.0, SQRTF(apply_limit(SQRTF(Et[i]))));
236
237
  }
237
-
238
- /* calculate s value */
239
- norm_c = SCS(norm_2)(c, A->n);
240
- norm_b = SCS(norm_2)(b, A->m);
241
- *s = SQRTF(norm_c * norm_c + norm_b * norm_b);
242
- *s = SAFEDIV_POS(1.0, SQRTF(apply_limit(*s)));
243
238
  }
244
239
 
245
- static void rescale(ScsMatrix *P, ScsMatrix *A, scs_float *b, scs_float *c,
246
- scs_float *Dt, scs_float *Et, scs_float s, ScsScaling *scal,
247
- ScsConeWork *cone) {
240
+ static void rescale(ScsMatrix *P, ScsMatrix *A, scs_float *Dt, scs_float *Et,
241
+ ScsScaling *scal, ScsConeWork *cone) {
248
242
  scs_int i, j;
249
243
  /* scale the rows of A with D */
250
244
  for (i = 0; i < A->n; ++i) {
@@ -271,15 +265,6 @@ static void rescale(ScsMatrix *P, ScsMatrix *A, scs_float *b, scs_float *c,
271
265
  }
272
266
  }
273
267
 
274
- /* scale c */
275
- for (i = 0; i < A->n; ++i) {
276
- c[i] *= Et[i];
277
- }
278
- /* scale b */
279
- for (i = 0; i < A->m; ++i) {
280
- b[i] *= Dt[i];
281
- }
282
-
283
268
  /* Accumulate scaling */
284
269
  for (i = 0; i < A->m; ++i) {
285
270
  scal->D[i] *= Dt[i];
@@ -288,53 +273,39 @@ static void rescale(ScsMatrix *P, ScsMatrix *A, scs_float *b, scs_float *c,
288
273
  scal->E[i] *= Et[i];
289
274
  }
290
275
 
291
- /* Apply scaling */
292
- SCS(scale_array)(c, s, A->n);
293
- SCS(scale_array)(b, s, A->m);
294
- /* no need to scale P since primal_scale = dual_scale */
276
+ /* no need to scale P since later primal_scale = dual_scale */
295
277
  /*
296
278
  if (P) {
297
279
  SCS(scale_array)(P->x, primal_scale, P->p[P->n]);
298
280
  SCS(scale_array)(P->x, 1.0 / dual_scale, P->p[P->n]);
299
281
  }
300
282
  */
301
-
302
- /* Accumulate scaling */
303
- scal->primal_scale *= s;
304
- scal->dual_scale *= s;
305
283
  }
306
284
 
307
- /* Will rescale as P -> EPE, A -> DAE, c -> sEc, b -> sDb, in-place.
285
+ /* Will rescale as P -> EPE, A -> DAE in-place.
308
286
  * Essentially trying to rescale this matrix:
309
287
  *
310
- * [P A' c] with [E 0 0] on both sides (D, E diagonal)
311
- * [A 0 b] [0 D 0]
312
- * [c' b' 0] [0 0 s]
288
+ * [P A'] with [E 0 ] on both sides (D, E diagonal)
289
+ * [A 0 ] [0 D ]
313
290
  *
314
291
  * which results in:
315
292
  *
316
- * [ EPE EA'D sEc ]
317
- * [ DAE 0 sDb ]
318
- * [ sc'E sb'D 0 ]
293
+ * [ EPE EA'D ]
294
+ * [ DAE 0 ]
319
295
  *
320
- * In other words D rescales the rows of A, b
321
- * E rescales the cols of A and rows/cols of P, c'
296
+ * In other words D rescales the rows of A
297
+ * E rescales the cols of A and rows/cols of P
322
298
  *
323
- * will repeatedly set: D^-1 ~ norm of rows of [ A b ]
299
+ * will repeatedly set: D^-1 ~ norm of rows of [ A ]
324
300
  *
325
301
  * E^-1 ~ norm of cols of [ P ]
326
302
  * [ A ]
327
- * [ c']
328
- *
329
- * `s` is incorporated into dual_scale and primal_scale
330
303
  *
331
304
  * The main complication is that D has to respect cone boundaries.
332
305
  *
333
306
  */
334
- ScsScaling *SCS(normalize_a_p)(ScsMatrix *P, ScsMatrix *A, scs_float *b,
335
- scs_float *c, ScsConeWork *cone) {
307
+ ScsScaling *SCS(normalize_a_p)(ScsMatrix *P, ScsMatrix *A, ScsConeWork *cone) {
336
308
  scs_int i;
337
- scs_float s;
338
309
  ScsScaling *scal = (ScsScaling *)scs_calloc(1, sizeof(ScsScaling));
339
310
  scs_float *Dt = (scs_float *)scs_calloc(A->m, sizeof(scs_float));
340
311
  scs_float *Et = (scs_float *)scs_calloc(A->n, sizeof(scs_float));
@@ -359,12 +330,12 @@ ScsScaling *SCS(normalize_a_p)(ScsMatrix *P, ScsMatrix *A, scs_float *b,
359
330
  scal->primal_scale = 1.;
360
331
  scal->dual_scale = 1.;
361
332
  for (i = 0; i < NUM_RUIZ_PASSES; ++i) {
362
- compute_ruiz_mats(P, A, b, c, Dt, Et, &s, cone);
363
- rescale(P, A, b, c, Dt, Et, s, scal, cone);
333
+ compute_ruiz_mats(P, A, Dt, Et, cone);
334
+ rescale(P, A, Dt, Et, scal, cone);
364
335
  }
365
336
  for (i = 0; i < NUM_L2_PASSES; ++i) {
366
- compute_l2_mats(P, A, b, c, Dt, Et, &s, cone);
367
- rescale(P, A, b, c, Dt, Et, s, scal, cone);
337
+ compute_l2_mats(P, A, Dt, Et, cone);
338
+ rescale(P, A, Dt, Et, scal, cone);
368
339
  }
369
340
  scs_free(Dt);
370
341
  scs_free(Et);
@@ -378,14 +349,13 @@ ScsScaling *SCS(normalize_a_p)(ScsMatrix *P, ScsMatrix *A, scs_float *b,
378
349
  }
379
350
  scs_printf("primal_scale %g\n", scal->primal_scale);
380
351
  scs_printf("dual_scale %g\n", scal->dual_scale);
381
- scs_printf("norm_b %g\n", SCS(norm_inf)(b, A->m));
382
- scs_printf("norm_c %g\n", SCS(norm_inf)(c, A->n));
383
352
  scs_printf("norm D %g\n", SCS(norm_inf)(scal->D, A->m));
384
353
  scs_printf("norm E %g\n", SCS(norm_inf)(scal->E, A->n));
385
354
  #endif
386
355
  return scal;
387
356
  }
388
357
 
358
+ /*
389
359
  void SCS(un_normalize_a_p)(ScsMatrix *A, ScsMatrix *P, const ScsScaling *scal) {
390
360
  scs_int i, j;
391
361
  scs_float *D = scal->D;
@@ -411,6 +381,7 @@ void SCS(un_normalize_a_p)(ScsMatrix *A, ScsMatrix *P, const ScsScaling *scal) {
411
381
  }
412
382
  }
413
383
  }
384
+ */
414
385
 
415
386
  void SCS(accum_by_atrans)(const ScsMatrix *A, const scs_float *x,
416
387
  scs_float *y) {
@@ -13,11 +13,12 @@ extern "C" {
13
13
  /* normalizes A matrix, sets scal->E and scal->D diagonal scaling matrices,
14
14
  * A -> D*A*E. D and E must be all positive entries, D must satisfy cone
15
15
  * boundaries */
16
- ScsScaling *SCS(normalize_a_p)(ScsMatrix *P, ScsMatrix *A, scs_float *b,
17
- scs_float *c, ScsConeWork *cone);
16
+ ScsScaling *SCS(normalize_a_p)(ScsMatrix *P, ScsMatrix *A, ScsConeWork *cone);
18
17
 
19
18
  /* unnormalizes A matrix, unnormalizes by w->D and w->E */
20
- void SCS(un_normalize_a_p)(ScsMatrix *A, ScsMatrix *P, const ScsScaling *scal);
19
+ /* void SCS(un_normalize_a_p)(ScsMatrix *A, ScsMatrix *P, const ScsScaling
20
+ * *scal);
21
+ */
21
22
 
22
23
  /* to free the memory allocated in a ScsMatrix (called on A and P at finish) */
23
24
  void SCS(free_scs_matrix)(ScsMatrix *A);
data/vendor/scs/scs.mk CHANGED
@@ -103,10 +103,6 @@ NOTIMER = 0
103
103
  ifneq ($(NOTIMER), 0)
104
104
  OPT_FLAGS += -DNOTIMER=$(NOTIMER) # no timing, times reported as nan
105
105
  endif
106
- COPYAMATRIX = 1
107
- ifneq ($(COPYAMATRIX), 0)
108
- OPT_FLAGS += -DCOPYAMATRIX=$(COPYAMATRIX) # if normalize, copy A
109
- endif
110
106
  GPU_TRANSPOSE_MAT = 1
111
107
  ifneq ($(GPU_TRANSPOSE_MAT), 0)
112
108
  OPT_FLAGS += -DGPU_TRANSPOSE_MAT=$(GPU_TRANSPOSE_MAT) # tranpose A mat in GPU memory
data/vendor/scs/src/aa.c CHANGED
@@ -199,7 +199,6 @@ static void set_m(AaWork *a, aa_int len) {
199
199
  }
200
200
  }
201
201
  TIME_TOC
202
- return;
203
202
  }
204
203
 
205
204
  /* initialize accel params, in particular x_prev, f_prev, g_prev */
@@ -278,7 +277,6 @@ static void update_accel_params(const aa_float *x, const aa_float *f, AaWork *a,
278
277
  a->norm_g = BLAS(nrm2)(&bdim, a->g, &one);
279
278
 
280
279
  TIME_TOC
281
- return;
282
280
  }
283
281
 
284
282
  /* f = (1-relaxation) * \sum_i a_i x_i + relaxation * \sum_i a_i f_i */
@@ -493,7 +491,6 @@ void aa_finish(AaWork *a) {
493
491
  }
494
492
  free(a);
495
493
  }
496
- return;
497
494
  }
498
495
 
499
496
  void aa_reset(AaWork *a) {
@@ -502,7 +499,6 @@ void aa_reset(AaWork *a) {
502
499
  printf("AA reset.\n");
503
500
  }
504
501
  a->iter = 0;
505
- return;
506
502
  }
507
503
 
508
504
  #endif
@@ -35,6 +35,57 @@ void BLAS(scal)(const blas_int *n, const scs_float *sa, scs_float *sx,
35
35
 
36
36
  #endif
37
37
 
38
+ void SCS(free_cone)(ScsCone *k) {
39
+ if (k) {
40
+ if (k->bu)
41
+ scs_free(k->bu);
42
+ if (k->bl)
43
+ scs_free(k->bl);
44
+ if (k->q)
45
+ scs_free(k->q);
46
+ if (k->s)
47
+ scs_free(k->s);
48
+ if (k->p)
49
+ scs_free(k->p);
50
+ scs_free(k);
51
+ }
52
+ }
53
+
54
+ void SCS(deep_copy_cone)(ScsCone *dest, const ScsCone *src) {
55
+ memcpy(dest, src, sizeof(ScsCone));
56
+ /* copy bu, bl */
57
+ if (src->bsize > 1) {
58
+ dest->bu = (scs_float *)scs_calloc(src->bsize - 1, sizeof(scs_float));
59
+ memcpy(dest->bu, src->bu, (src->bsize - 1) * sizeof(scs_float));
60
+ dest->bl = (scs_float *)scs_calloc(src->bsize - 1, sizeof(scs_float));
61
+ memcpy(dest->bl, src->bl, (src->bsize - 1) * sizeof(scs_float));
62
+ } else {
63
+ dest->bu = SCS_NULL;
64
+ dest->bl = SCS_NULL;
65
+ }
66
+ /* copy SOC */
67
+ if (src->qsize > 0) {
68
+ dest->q = (scs_int *)scs_calloc(src->qsize, sizeof(scs_int));
69
+ memcpy(dest->q, src->q, src->qsize * sizeof(scs_int));
70
+ } else {
71
+ dest->q = SCS_NULL;
72
+ }
73
+ /* copy PSD cone */
74
+ if (src->ssize > 0) {
75
+ dest->s = (scs_int *)scs_calloc(src->ssize, sizeof(scs_int));
76
+ memcpy(dest->s, src->s, src->ssize * sizeof(scs_int));
77
+ } else {
78
+ dest->s = SCS_NULL;
79
+ }
80
+ /* copy power cone */
81
+ if (src->psize > 0) {
82
+ dest->p = (scs_float *)scs_calloc(src->psize, sizeof(scs_float));
83
+ memcpy(dest->p, src->p, src->psize * sizeof(scs_float));
84
+ } else {
85
+ dest->p = SCS_NULL;
86
+ }
87
+ }
88
+
38
89
  /* set the vector of rho y terms, based on scale and cones */
39
90
  void SCS(set_r_y)(const ScsConeWork *c, scs_float scale, scs_float *r_y) {
40
91
  scs_int i;
@@ -228,12 +279,6 @@ void SCS(finish_cone)(ScsConeWork *c) {
228
279
  if (c->s) {
229
280
  scs_free(c->s);
230
281
  }
231
- if (c->bu) {
232
- scs_free(c->bu);
233
- }
234
- if (c->bl) {
235
- scs_free(c->bl);
236
- }
237
282
  if (c) {
238
283
  scs_free(c);
239
284
  }
@@ -580,18 +625,18 @@ static scs_float pow_calc_fp(scs_float x, scs_float y, scs_float dxdr,
580
625
  * { (t', s') | t' * l' <= s' <= t' u', t >= 0 } = K'
581
626
  * where l' = D l / d0, u' = D u / d0.
582
627
  */
583
- static void normalize_box_cone(ScsConeWork *c, scs_float *D, scs_int bsize) {
628
+ static void normalize_box_cone(ScsCone *k, scs_float *D, scs_int bsize) {
584
629
  scs_int j;
585
630
  for (j = 0; j < bsize - 1; j++) {
586
- if (c->bu[j] >= MAX_BOX_VAL) {
587
- c->bu[j] = INFINITY;
631
+ if (k->bu[j] >= MAX_BOX_VAL) {
632
+ k->bu[j] = INFINITY;
588
633
  } else {
589
- c->bu[j] = D ? D[j + 1] * c->bu[j] / D[0] : c->bu[j];
634
+ k->bu[j] = D ? D[j + 1] * k->bu[j] / D[0] : k->bu[j];
590
635
  }
591
- if (c->bl[j] <= -MAX_BOX_VAL) {
592
- c->bl[j] = -INFINITY;
636
+ if (k->bl[j] <= -MAX_BOX_VAL) {
637
+ k->bl[j] = -INFINITY;
593
638
  } else {
594
- c->bl[j] = D ? D[j + 1] * c->bl[j] / D[0] : c->bl[j];
639
+ k->bl[j] = D ? D[j + 1] * k->bl[j] / D[0] : k->bl[j];
595
640
  }
596
641
  }
597
642
  }
@@ -740,7 +785,6 @@ static scs_int proj_cone(scs_float *x, const ScsCone *k, ScsConeWork *c,
740
785
  scs_int i, status;
741
786
  scs_int count = 0;
742
787
  scs_float *r_box = SCS_NULL;
743
- scs_float *bu, *bl;
744
788
 
745
789
  if (k->z) { /* doesn't use r_y */
746
790
  /* project onto primal zero / dual free cone */
@@ -761,9 +805,7 @@ static scs_int proj_cone(scs_float *x, const ScsCone *k, ScsConeWork *c,
761
805
  r_box = &(r_y[count]);
762
806
  }
763
807
  /* project onto box cone */
764
- bu = normalize ? c->bu : k->bu;
765
- bl = normalize ? c->bl : k->bl;
766
- c->box_t_warm_start = proj_box_cone(&(x[count]), bl, bu, k->bsize,
808
+ c->box_t_warm_start = proj_box_cone(&(x[count]), k->bl, k->bu, k->bsize,
767
809
  c->box_t_warm_start, r_box);
768
810
  count += k->bsize; /* since b = (t,s), len(s) = bsize - 1 */
769
811
  }
@@ -864,7 +906,7 @@ static scs_int proj_cone(scs_float *x, const ScsCone *k, ScsConeWork *c,
864
906
  return 0;
865
907
  }
866
908
 
867
- ScsConeWork *SCS(init_cone)(const ScsCone *k, scs_int m) {
909
+ ScsConeWork *SCS(init_cone)(ScsCone *k, scs_int m) {
868
910
  ScsConeWork *c = (ScsConeWork *)scs_calloc(1, sizeof(ScsConeWork));
869
911
  c->k = k;
870
912
  c->m = m;
@@ -880,16 +922,12 @@ ScsConeWork *SCS(init_cone)(const ScsCone *k, scs_int m) {
880
922
  return c;
881
923
  }
882
924
 
883
- void scale_box_cone(const ScsCone *k, ScsConeWork *c, ScsScaling *scal) {
925
+ void scale_box_cone(ScsCone *k, ScsConeWork *c, ScsScaling *scal) {
884
926
  if (k->bsize && k->bu && k->bl) {
885
927
  c->box_t_warm_start = 1.;
886
928
  if (scal) {
887
- c->bu = (scs_float *)scs_calloc(k->bsize - 1, sizeof(scs_float));
888
- c->bl = (scs_float *)scs_calloc(k->bsize - 1, sizeof(scs_float));
889
- memcpy(c->bu, k->bu, (k->bsize - 1) * sizeof(scs_float));
890
- memcpy(c->bl, k->bl, (k->bsize - 1) * sizeof(scs_float));
891
929
  /* also does some sanitizing */
892
- normalize_box_cone(c, &(scal->D[k->z + k->l]), k->bsize);
930
+ normalize_box_cone(k, &(scal->D[k->z + k->l]), k->bsize);
893
931
  }
894
932
  }
895
933
  }
@@ -909,7 +947,7 @@ void scale_box_cone(const ScsCone *k, ScsConeWork *c, ScsScaling *scal) {
909
947
  scs_int SCS(proj_dual_cone)(scs_float *x, ScsConeWork *c, ScsScaling *scal,
910
948
  scs_float *r_y) {
911
949
  scs_int status, i;
912
- const ScsCone *k = c->k;
950
+ ScsCone *k = c->k;
913
951
 
914
952
  if (!c->scaled_cones) {
915
953
  scale_box_cone(k, c, scal);
@@ -3,6 +3,55 @@
3
3
  #include "linalg.h"
4
4
  #include "scs.h"
5
5
 
6
+ /* copied from linsys/scs_matrix.c */
7
+ #define MIN_NORMALIZATION_FACTOR (1e-4)
8
+ #define MAX_NORMALIZATION_FACTOR (1e4)
9
+
10
+ /* Given D, E in scaling normalize b, c and compute primal / dual scales.
11
+ *
12
+ * Recall that the normalization routine is performing:
13
+ *
14
+ * [P A' c] with [E 0 0] on both sides (D, E diagonal)
15
+ * [A 0 b] [0 D 0]
16
+ * [c' b' 0] [0 0 s]
17
+ *
18
+ * which results in:
19
+ *
20
+ * [ EPE EA'D sEc ]
21
+ * [ DAE 0 sDb ]
22
+ * [ sc'E sb'D 0 ]
23
+ *
24
+ * `s` is incorporated into dual_scale and primal_scale
25
+ *
26
+ */
27
+ void SCS(normalize_b_c)(ScsScaling *scal, scs_float *b, scs_float *c) {
28
+ scs_int i;
29
+ scs_float sigma;
30
+
31
+ /* scale c */
32
+ for (i = 0; i < scal->n; ++i) {
33
+ c[i] *= scal->E[i];
34
+ }
35
+ /* scale b */
36
+ for (i = 0; i < scal->m; ++i) {
37
+ b[i] *= scal->D[i];
38
+ }
39
+
40
+ /* calculate primal and dual scales */
41
+ sigma = MAX(SCS(norm_inf)(c, scal->n), SCS(norm_inf)(b, scal->m));
42
+ sigma = sigma < MIN_NORMALIZATION_FACTOR ? 1.0 : sigma;
43
+ sigma = sigma > MAX_NORMALIZATION_FACTOR ? MAX_NORMALIZATION_FACTOR : sigma;
44
+ sigma = SAFEDIV_POS(1.0, sigma);
45
+
46
+ /* Scale b, c */
47
+ SCS(scale_array)(c, sigma, scal->n);
48
+ SCS(scale_array)(b, sigma, scal->m);
49
+
50
+ /* We assume that primal_scale = dual_scale, otherwise need to refactorize */
51
+ scal->primal_scale = sigma;
52
+ scal->dual_scale = sigma;
53
+ }
54
+
6
55
  /* needed for normalizing the warm-start */
7
56
  void SCS(normalize_sol)(ScsScaling *scal, ScsSolution *sol) {
8
57
  scs_int i;
data/vendor/scs/src/rw.c CHANGED
@@ -33,21 +33,29 @@ static ScsCone *read_scs_cone(FILE *fin) {
33
33
  fread(&(k->z), sizeof(scs_int), 1, fin);
34
34
  fread(&(k->l), sizeof(scs_int), 1, fin);
35
35
  fread(&(k->bsize), sizeof(scs_int), 1, fin);
36
- k->bl = (scs_float *)scs_calloc(MAX(k->bsize - 1, 0), sizeof(scs_float));
37
- k->bu = (scs_float *)scs_calloc(MAX(k->bsize - 1, 0), sizeof(scs_float));
38
- fread(k->bl, sizeof(scs_float), MAX(k->bsize - 1, 0), fin);
39
- fread(k->bu, sizeof(scs_float), MAX(k->bsize - 1, 0), fin);
36
+ if (k->bsize > 1) {
37
+ k->bl = (scs_float *)scs_calloc(MAX(k->bsize - 1, 0), sizeof(scs_float));
38
+ k->bu = (scs_float *)scs_calloc(MAX(k->bsize - 1, 0), sizeof(scs_float));
39
+ fread(k->bl, sizeof(scs_float), MAX(k->bsize - 1, 0), fin);
40
+ fread(k->bu, sizeof(scs_float), MAX(k->bsize - 1, 0), fin);
41
+ }
40
42
  fread(&(k->qsize), sizeof(scs_int), 1, fin);
41
- k->q = (scs_int *)scs_calloc(k->qsize, sizeof(scs_int));
42
- fread(k->q, sizeof(scs_int), k->qsize, fin);
43
+ if (k->qsize) {
44
+ k->q = (scs_int *)scs_calloc(k->qsize, sizeof(scs_int));
45
+ fread(k->q, sizeof(scs_int), k->qsize, fin);
46
+ }
43
47
  fread(&(k->ssize), sizeof(scs_int), 1, fin);
44
- k->s = (scs_int *)scs_calloc(k->ssize, sizeof(scs_int));
45
- fread(k->s, sizeof(scs_int), k->ssize, fin);
48
+ if (k->ssize) {
49
+ k->s = (scs_int *)scs_calloc(k->ssize, sizeof(scs_int));
50
+ fread(k->s, sizeof(scs_int), k->ssize, fin);
51
+ }
46
52
  fread(&(k->ep), sizeof(scs_int), 1, fin);
47
53
  fread(&(k->ed), sizeof(scs_int), 1, fin);
48
54
  fread(&(k->psize), sizeof(scs_int), 1, fin);
49
- k->p = (scs_float *)scs_calloc(k->psize, sizeof(scs_float));
50
- fread(k->p, sizeof(scs_float), k->psize, fin);
55
+ if (k->psize) {
56
+ k->p = (scs_float *)scs_calloc(k->psize, sizeof(scs_float));
57
+ fread(k->p, sizeof(scs_float), k->psize, fin);
58
+ }
51
59
  return k;
52
60
  }
53
61
 
@@ -208,9 +216,9 @@ scs_int SCS(read_data)(const char *filename, ScsData **d, ScsCone **k,
208
216
  return 0;
209
217
  }
210
218
 
211
- void SCS(log_data_to_csv)(const ScsData *d, const ScsCone *k,
212
- const ScsSettings *stgs, const ScsWork *w,
213
- scs_int iter, SCS(timer) * solve_timer) {
219
+ void SCS(log_data_to_csv)(const ScsCone *k, const ScsSettings *stgs,
220
+ const ScsWork *w, scs_int iter,
221
+ SCS(timer) * solve_timer) {
214
222
  ScsResiduals *r = w->r_orig;
215
223
  ScsResiduals *r_n = w->r_normalized;
216
224
  ScsSolution *sol = w->xys_orig;
@@ -222,7 +230,7 @@ void SCS(log_data_to_csv)(const ScsData *d, const ScsCone *k,
222
230
  stgs->log_csv_filename);
223
231
  return;
224
232
  }
225
- scs_int l = w->m + w->n + 1;
233
+ scs_int l = w->d->m + w->d->n + 1;
226
234
  if (iter == 0) {
227
235
  /* need to end in comma so that csv parsing is correct */
228
236
  fprintf(fout, "iter,"
@@ -286,22 +294,22 @@ void SCS(log_data_to_csv)(const ScsData *d, const ScsCone *k,
286
294
  fprintf(fout, "%.16e,", r->res_pri);
287
295
  fprintf(fout, "%.16e,", r->res_dual);
288
296
  fprintf(fout, "%.16e,", r->gap);
289
- fprintf(fout, "%.16e,", SCS(norm_inf)(sol->x, w->n));
290
- fprintf(fout, "%.16e,", SCS(norm_inf)(sol->y, w->m));
291
- fprintf(fout, "%.16e,", SCS(norm_inf)(sol->s, w->m));
292
- fprintf(fout, "%.16e,", SCS(norm_2)(sol->x, w->n));
293
- fprintf(fout, "%.16e,", SCS(norm_2)(sol->y, w->m));
294
- fprintf(fout, "%.16e,", SCS(norm_2)(sol->s, w->m));
295
- fprintf(fout, "%.16e,", SCS(norm_inf)(sol_n->x, w->n));
296
- fprintf(fout, "%.16e,", SCS(norm_inf)(sol_n->y, w->m));
297
- fprintf(fout, "%.16e,", SCS(norm_inf)(sol_n->s, w->m));
298
- fprintf(fout, "%.16e,", SCS(norm_2)(sol_n->x, w->n));
299
- fprintf(fout, "%.16e,", SCS(norm_2)(sol_n->y, w->m));
300
- fprintf(fout, "%.16e,", SCS(norm_2)(sol_n->s, w->m));
301
- fprintf(fout, "%.16e,", SCS(norm_inf)(r->ax_s_btau, w->m));
302
- fprintf(fout, "%.16e,", SCS(norm_inf)(r->px_aty_ctau, w->n));
303
- fprintf(fout, "%.16e,", SCS(norm_2)(r->ax_s_btau, w->m));
304
- fprintf(fout, "%.16e,", SCS(norm_2)(r->px_aty_ctau, w->n));
297
+ fprintf(fout, "%.16e,", SCS(norm_inf)(sol->x, w->d->n));
298
+ fprintf(fout, "%.16e,", SCS(norm_inf)(sol->y, w->d->m));
299
+ fprintf(fout, "%.16e,", SCS(norm_inf)(sol->s, w->d->m));
300
+ fprintf(fout, "%.16e,", SCS(norm_2)(sol->x, w->d->n));
301
+ fprintf(fout, "%.16e,", SCS(norm_2)(sol->y, w->d->m));
302
+ fprintf(fout, "%.16e,", SCS(norm_2)(sol->s, w->d->m));
303
+ fprintf(fout, "%.16e,", SCS(norm_inf)(sol_n->x, w->d->n));
304
+ fprintf(fout, "%.16e,", SCS(norm_inf)(sol_n->y, w->d->m));
305
+ fprintf(fout, "%.16e,", SCS(norm_inf)(sol_n->s, w->d->m));
306
+ fprintf(fout, "%.16e,", SCS(norm_2)(sol_n->x, w->d->n));
307
+ fprintf(fout, "%.16e,", SCS(norm_2)(sol_n->y, w->d->m));
308
+ fprintf(fout, "%.16e,", SCS(norm_2)(sol_n->s, w->d->m));
309
+ fprintf(fout, "%.16e,", SCS(norm_inf)(r->ax_s_btau, w->d->m));
310
+ fprintf(fout, "%.16e,", SCS(norm_inf)(r->px_aty_ctau, w->d->n));
311
+ fprintf(fout, "%.16e,", SCS(norm_2)(r->ax_s_btau, w->d->m));
312
+ fprintf(fout, "%.16e,", SCS(norm_2)(r->px_aty_ctau, w->d->n));
305
313
  fprintf(fout, "%.16e,", r->res_infeas);
306
314
  fprintf(fout, "%.16e,", r->res_unbdd_a);
307
315
  fprintf(fout, "%.16e,", r->res_unbdd_p);
@@ -312,10 +320,10 @@ void SCS(log_data_to_csv)(const ScsData *d, const ScsCone *k,
312
320
  fprintf(fout, "%.16e,", r_n->res_pri);
313
321
  fprintf(fout, "%.16e,", r_n->res_dual);
314
322
  fprintf(fout, "%.16e,", r_n->gap);
315
- fprintf(fout, "%.16e,", SCS(norm_inf)(r_n->ax_s_btau, w->m));
316
- fprintf(fout, "%.16e,", SCS(norm_inf)(r_n->px_aty_ctau, w->n));
317
- fprintf(fout, "%.16e,", SCS(norm_2)(r_n->ax_s_btau, w->m));
318
- fprintf(fout, "%.16e,", SCS(norm_2)(r_n->px_aty_ctau, w->n));
323
+ fprintf(fout, "%.16e,", SCS(norm_inf)(r_n->ax_s_btau, w->d->m));
324
+ fprintf(fout, "%.16e,", SCS(norm_inf)(r_n->px_aty_ctau, w->d->n));
325
+ fprintf(fout, "%.16e,", SCS(norm_2)(r_n->ax_s_btau, w->d->m));
326
+ fprintf(fout, "%.16e,", SCS(norm_2)(r_n->px_aty_ctau, w->d->n));
319
327
  fprintf(fout, "%.16e,", r_n->res_infeas);
320
328
  fprintf(fout, "%.16e,", r_n->res_unbdd_a);
321
329
  fprintf(fout, "%.16e,", r_n->res_unbdd_p);
@@ -323,12 +331,12 @@ void SCS(log_data_to_csv)(const ScsData *d, const ScsCone *k,
323
331
  fprintf(fout, "%.16e,", r_n->dobj);
324
332
  fprintf(fout, "%.16e,", r_n->tau);
325
333
  fprintf(fout, "%.16e,", r_n->kap);
326
- fprintf(fout, "%.16e,", SCS(norm_inf)(r->ax, w->m));
327
- fprintf(fout, "%.16e,", SCS(norm_inf)(r->px, w->n));
328
- fprintf(fout, "%.16e,", SCS(norm_inf)(r->aty, w->n));
329
- fprintf(fout, "%.16e,", SCS(norm_inf)(w->b_orig, w->m));
330
- fprintf(fout, "%.16e,", SCS(norm_inf)(w->c_orig, w->n));
331
- fprintf(fout, "%.16e,", w->scale);
334
+ fprintf(fout, "%.16e,", SCS(norm_inf)(r->ax, w->d->m));
335
+ fprintf(fout, "%.16e,", SCS(norm_inf)(r->px, w->d->n));
336
+ fprintf(fout, "%.16e,", SCS(norm_inf)(r->aty, w->d->n));
337
+ fprintf(fout, "%.16e,", SCS(norm_inf)(w->b_orig, w->d->m));
338
+ fprintf(fout, "%.16e,", SCS(norm_inf)(w->c_orig, w->d->n));
339
+ fprintf(fout, "%.16e,", w->stgs->scale);
332
340
  fprintf(fout, "%.16e,", SCS(norm_diff)(w->u, w->u_t, l));
333
341
  fprintf(fout, "%.16e,", SCS(norm_diff)(w->v, w->v_prev, l));
334
342
  fprintf(fout, "%.16e,", SCS(norm_inf_diff)(w->u, w->u_t, l));