scs 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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));