scs 0.2.2 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/LICENSE.txt +18 -18
  4. data/README.md +19 -14
  5. data/lib/scs/ffi.rb +31 -20
  6. data/lib/scs/solver.rb +32 -9
  7. data/lib/scs/version.rb +1 -1
  8. data/vendor/scs/CITATION.cff +39 -0
  9. data/vendor/scs/CMakeLists.txt +320 -0
  10. data/vendor/scs/Makefile +32 -23
  11. data/vendor/scs/README.md +9 -218
  12. data/vendor/scs/include/aa.h +67 -23
  13. data/vendor/scs/include/cones.h +22 -19
  14. data/vendor/scs/include/glbopts.h +107 -79
  15. data/vendor/scs/include/linalg.h +3 -4
  16. data/vendor/scs/include/linsys.h +58 -44
  17. data/vendor/scs/include/normalize.h +6 -5
  18. data/vendor/scs/include/rw.h +8 -2
  19. data/vendor/scs/include/scs.h +257 -141
  20. data/vendor/scs/include/scs_types.h +34 -0
  21. data/vendor/scs/include/scs_work.h +83 -0
  22. data/vendor/scs/include/util.h +3 -15
  23. data/vendor/scs/linsys/cpu/direct/private.c +241 -232
  24. data/vendor/scs/linsys/cpu/direct/private.h +13 -7
  25. data/vendor/scs/linsys/cpu/indirect/private.c +194 -118
  26. data/vendor/scs/linsys/cpu/indirect/private.h +7 -4
  27. data/vendor/scs/linsys/csparse.c +87 -0
  28. data/vendor/scs/linsys/csparse.h +34 -0
  29. data/vendor/scs/linsys/external/amd/SuiteSparse_config.c +6 -6
  30. data/vendor/scs/linsys/external/amd/SuiteSparse_config.h +6 -1
  31. data/vendor/scs/linsys/external/amd/amd_internal.h +1 -1
  32. data/vendor/scs/linsys/external/amd/amd_order.c +5 -5
  33. data/vendor/scs/linsys/external/qdldl/changes +2 -0
  34. data/vendor/scs/linsys/external/qdldl/qdldl.c +29 -46
  35. data/vendor/scs/linsys/external/qdldl/qdldl.h +33 -41
  36. data/vendor/scs/linsys/external/qdldl/qdldl_types.h +11 -3
  37. data/vendor/scs/linsys/gpu/gpu.c +58 -21
  38. data/vendor/scs/linsys/gpu/gpu.h +70 -35
  39. data/vendor/scs/linsys/gpu/indirect/private.c +394 -157
  40. data/vendor/scs/linsys/gpu/indirect/private.h +27 -12
  41. data/vendor/scs/linsys/scs_matrix.c +478 -0
  42. data/vendor/scs/linsys/scs_matrix.h +70 -0
  43. data/vendor/scs/scs.mk +14 -10
  44. data/vendor/scs/src/aa.c +394 -110
  45. data/vendor/scs/src/cones.c +497 -359
  46. data/vendor/scs/src/ctrlc.c +15 -5
  47. data/vendor/scs/src/linalg.c +107 -26
  48. data/vendor/scs/src/normalize.c +30 -72
  49. data/vendor/scs/src/rw.c +202 -27
  50. data/vendor/scs/src/scs.c +769 -571
  51. data/vendor/scs/src/scs_version.c +11 -3
  52. data/vendor/scs/src/util.c +37 -106
  53. data/vendor/scs/test/minunit.h +22 -8
  54. data/vendor/scs/test/problem_utils.h +180 -25
  55. data/vendor/scs/test/problems/degenerate.h +130 -0
  56. data/vendor/scs/test/problems/hs21_tiny_qp.h +124 -0
  57. data/vendor/scs/test/problems/hs21_tiny_qp_rw.h +116 -0
  58. data/vendor/scs/test/problems/infeasible_tiny_qp.h +100 -0
  59. data/vendor/scs/test/problems/qafiro_tiny_qp.h +199 -0
  60. data/vendor/scs/test/problems/random_prob +0 -0
  61. data/vendor/scs/test/problems/random_prob.h +45 -0
  62. data/vendor/scs/test/problems/rob_gauss_cov_est.h +188 -31
  63. data/vendor/scs/test/problems/small_lp.h +14 -13
  64. data/vendor/scs/test/problems/small_qp.h +352 -0
  65. data/vendor/scs/test/problems/test_validation.h +43 -0
  66. data/vendor/scs/test/problems/unbounded_tiny_qp.h +82 -0
  67. data/vendor/scs/test/random_socp_prob.c +54 -53
  68. data/vendor/scs/test/rng.h +109 -0
  69. data/vendor/scs/test/run_from_file.c +20 -11
  70. data/vendor/scs/test/run_tests.c +35 -2
  71. metadata +29 -98
  72. data/vendor/scs/linsys/amatrix.c +0 -305
  73. data/vendor/scs/linsys/amatrix.h +0 -36
  74. data/vendor/scs/linsys/amatrix.o +0 -0
  75. data/vendor/scs/linsys/cpu/direct/private.o +0 -0
  76. data/vendor/scs/linsys/cpu/indirect/private.o +0 -0
  77. data/vendor/scs/linsys/external/amd/SuiteSparse_config.o +0 -0
  78. data/vendor/scs/linsys/external/amd/amd_1.o +0 -0
  79. data/vendor/scs/linsys/external/amd/amd_2.o +0 -0
  80. data/vendor/scs/linsys/external/amd/amd_aat.o +0 -0
  81. data/vendor/scs/linsys/external/amd/amd_control.o +0 -0
  82. data/vendor/scs/linsys/external/amd/amd_defaults.o +0 -0
  83. data/vendor/scs/linsys/external/amd/amd_dump.o +0 -0
  84. data/vendor/scs/linsys/external/amd/amd_global.o +0 -0
  85. data/vendor/scs/linsys/external/amd/amd_info.o +0 -0
  86. data/vendor/scs/linsys/external/amd/amd_order.o +0 -0
  87. data/vendor/scs/linsys/external/amd/amd_post_tree.o +0 -0
  88. data/vendor/scs/linsys/external/amd/amd_postorder.o +0 -0
  89. data/vendor/scs/linsys/external/amd/amd_preprocess.o +0 -0
  90. data/vendor/scs/linsys/external/amd/amd_valid.o +0 -0
  91. data/vendor/scs/linsys/external/qdldl/qdldl.o +0 -0
  92. data/vendor/scs/src/aa.o +0 -0
  93. data/vendor/scs/src/cones.o +0 -0
  94. data/vendor/scs/src/ctrlc.o +0 -0
  95. data/vendor/scs/src/linalg.o +0 -0
  96. data/vendor/scs/src/normalize.o +0 -0
  97. data/vendor/scs/src/rw.o +0 -0
  98. data/vendor/scs/src/scs.o +0 -0
  99. data/vendor/scs/src/scs_version.o +0 -0
  100. data/vendor/scs/src/util.o +0 -0
  101. data/vendor/scs/test/data/small_random_socp +0 -0
  102. data/vendor/scs/test/problems/small_random_socp.h +0 -33
  103. data/vendor/scs/test/run_tests +0 -2
@@ -5,29 +5,44 @@
5
5
  extern "C" {
6
6
  #endif
7
7
 
8
- #include "gpu.h"
8
+ #include "csparse.h"
9
9
  #include "glbopts.h"
10
+ #include "gpu.h"
10
11
  #include "linalg.h"
11
12
  #include "scs.h"
12
13
 
13
-
14
14
  struct SCS_LIN_SYS_WORK {
15
+ scs_int n, m; /* linear system dimensions */
15
16
  /* reporting */
16
17
  scs_int tot_cg_its;
17
- scs_float total_solve_time;
18
+ scs_float *M; /* preconditioner on cpu */
18
19
  /* ALL BELOW HOSTED ON THE GPU */
19
- scs_float *p; /* cg iterate, n */
20
- scs_float *r; /* cg residual, n */
21
- scs_float *Gp; /* G * p, n */
22
- scs_float *bg; /* b, n */
23
- scs_float *tmp_m; /* m, used in mat_vec */
24
- scs_float *z; /* preconditioned */
25
- scs_float *M; /* preconditioner */
26
- ScsGpuMatrix *Ag; /* A matrix on GPU */
27
- ScsGpuMatrix *Agt; /* A trans matrix on GPU */
20
+ scs_float *p; /* cg iterate, n */
21
+ scs_float *r; /* cg residual, n */
22
+ scs_float *Gp; /* G * p, n */
23
+ scs_float *bg; /* b, n */
24
+ scs_float *tmp_m; /* m, used in mat_vec */
25
+ scs_float *z; /* preconditioned */
26
+ scs_float *M_gpu; /* preconditioner */
27
+ const ScsMatrix *A; /* does *not* own this memory */
28
+ const ScsMatrix *P; /* does *not* own this memory */
29
+ ScsGpuMatrix *Ag; /* A matrix on GPU */
30
+ ScsGpuMatrix *Agt; /* A trans matrix on GPU */
31
+ ScsGpuMatrix *Pg; /* P matrix on GPU */
28
32
  /* CUDA */
29
33
  cublasHandle_t cublas_handle;
30
34
  cusparseHandle_t cusparse_handle;
35
+ /* CUSPARSE */
36
+ size_t buffer_size;
37
+ void *buffer;
38
+ cusparseDnVecDescr_t dn_vec_m; /* Dense vector of length m */
39
+ cusparseDnVecDescr_t dn_vec_n; /* Dense vector of length n */
40
+ cusparseDnVecDescr_t dn_vec_n_p; /* Dense vector of length n */
41
+
42
+ /* rho terms */
43
+ scs_float *r_x_gpu;
44
+ scs_float *inv_r_y; /* inverse R_y */
45
+ scs_float *inv_r_y_gpu; /* inverse R_y on GPU */
31
46
  };
32
47
 
33
48
  #ifdef __cplusplus
@@ -0,0 +1,478 @@
1
+ /* contains routines common to direct and indirect sparse solvers */
2
+ #include "scs_matrix.h"
3
+ #include "linalg.h"
4
+ #include "linsys.h"
5
+ #include "util.h"
6
+
7
+ #define MIN_NORMALIZATION_FACTOR (1e-4)
8
+ #define MAX_NORMALIZATION_FACTOR (1e4)
9
+ #define NUM_RUIZ_PASSES (25) /* additional passes don't help much */
10
+ #define NUM_L2_PASSES (1) /* do one or zero, not more since not stable */
11
+
12
+ scs_int SCS(copy_matrix)(ScsMatrix **dstp, const ScsMatrix *src) {
13
+ scs_int Anz = src->p[src->n];
14
+ ScsMatrix *A = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
15
+ if (!A) {
16
+ return 0;
17
+ }
18
+ A->n = src->n;
19
+ A->m = src->m;
20
+ /* A values, size: NNZ A */
21
+ A->x = (scs_float *)scs_calloc(Anz, sizeof(scs_float));
22
+ /* A row index, size: NNZ A */
23
+ A->i = (scs_int *)scs_calloc(Anz, sizeof(scs_int));
24
+ /* A column pointer, size: n+1 */
25
+ A->p = (scs_int *)scs_calloc(src->n + 1, sizeof(scs_int));
26
+ if (!A->x || !A->i || !A->p) {
27
+ return 0;
28
+ }
29
+ memcpy(A->x, src->x, sizeof(scs_float) * Anz);
30
+ memcpy(A->i, src->i, sizeof(scs_int) * Anz);
31
+ memcpy(A->p, src->p, sizeof(scs_int) * (src->n + 1));
32
+ *dstp = A;
33
+ return 1;
34
+ }
35
+
36
+ scs_int SCS(validate_lin_sys)(const ScsMatrix *A, const ScsMatrix *P) {
37
+ scs_int i, j, r_max, Anz;
38
+ if (!A->x || !A->i || !A->p) {
39
+ scs_printf("data incompletely specified\n");
40
+ return -1;
41
+ }
42
+ /* detects some errors in A col ptrs: */
43
+ Anz = A->p[A->n];
44
+ if (Anz > 0) {
45
+ for (i = 0; i < A->n; ++i) {
46
+ if (A->p[i] == A->p[i + 1]) {
47
+ scs_printf("WARN: A->p (column pointers) not strictly increasing, "
48
+ "column %li empty\n",
49
+ (long)i);
50
+ } else if (A->p[i] > A->p[i + 1]) {
51
+ scs_printf("ERROR: A->p (column pointers) decreasing\n");
52
+ return -1;
53
+ }
54
+ }
55
+ }
56
+ if (((scs_float)Anz / A->m > A->n) || (Anz < 0)) {
57
+ scs_printf("Anz (nonzeros in A) = %li, outside of valid range\n",
58
+ (long)Anz);
59
+ return -1;
60
+ }
61
+ r_max = 0;
62
+ for (i = 0; i < Anz; ++i) {
63
+ if (A->i[i] > r_max) {
64
+ r_max = A->i[i];
65
+ }
66
+ }
67
+ if (r_max > A->m - 1) {
68
+ scs_printf("number of rows in A inconsistent with input dimension\n");
69
+ return -1;
70
+ }
71
+ if (P) {
72
+ if (P->n != A->n) {
73
+ scs_printf("P dimension = %li, inconsistent with n = %li\n", (long)P->n,
74
+ (long)A->n);
75
+ return -1;
76
+ }
77
+ if (P->m != P->n) {
78
+ scs_printf("P is not square\n");
79
+ return -1;
80
+ }
81
+ for (j = 0; j < P->n; j++) { /* cols */
82
+ for (i = P->p[j]; i < P->p[j + 1]; i++) {
83
+ if (P->i[i] > j) { /* if row > */
84
+ scs_printf("P is not upper triangular\n");
85
+ return -1;
86
+ }
87
+ }
88
+ }
89
+ }
90
+ return 0;
91
+ }
92
+
93
+ void SCS(free_scs_matrix)(ScsMatrix *A) {
94
+ if (A) {
95
+ scs_free(A->x);
96
+ scs_free(A->i);
97
+ scs_free(A->p);
98
+ scs_free(A);
99
+ }
100
+ }
101
+
102
+ static inline scs_float apply_limit(scs_float x) {
103
+ /* need to bound to 1 for cols/rows of all zeros, otherwise blows up */
104
+ x = x < MIN_NORMALIZATION_FACTOR ? 1.0 : x;
105
+ x = x > MAX_NORMALIZATION_FACTOR ? MAX_NORMALIZATION_FACTOR : x;
106
+ return x;
107
+ }
108
+
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) {
112
+ scs_int i, j, kk;
113
+ scs_float wrk;
114
+
115
+ /**************************** D ****************************/
116
+
117
+ /* initialize D */
118
+ for (i = 0; i < A->m; ++i) {
119
+ /* Dt[i] = 0.; */
120
+ Dt[i] = ABS(b[i]);
121
+ }
122
+
123
+ /* calculate row norms */
124
+ for (i = 0; i < A->n; ++i) {
125
+ for (j = A->p[i]; j < A->p[i + 1]; ++j) {
126
+ Dt[A->i[j]] = MAX(Dt[A->i[j]], ABS(A->x[j]));
127
+ }
128
+ }
129
+
130
+ /* accumulate D across each cone */
131
+ SCS(enforce_cone_boundaries)(cone, Dt, &SCS(norm_inf));
132
+
133
+ /* invert temporary vec to form D */
134
+ for (i = 0; i < A->m; ++i) {
135
+ Dt[i] = SAFEDIV_POS(1.0, SQRTF(apply_limit(Dt[i])));
136
+ }
137
+
138
+ /**************************** E ****************************/
139
+
140
+ /* initialize E */
141
+ for (i = 0; i < A->n; ++i) {
142
+ /* Et[i] = 0.; */
143
+ Et[i] = ABS(c[i]);
144
+ }
145
+
146
+ /* TODO: test not using P to determine scaling */
147
+ if (P) {
148
+ /* compute norm of cols of P (symmetric upper triangular) */
149
+ /* E = norm of cols of P */
150
+ /* Compute maximum across columns */
151
+ /* P(i, j) contributes to col j and col i (row i) due to symmetry */
152
+ for (j = 0; j < P->n; j++) { /* cols */
153
+ for (kk = P->p[j]; kk < P->p[j + 1]; kk++) {
154
+ i = P->i[kk]; /* row */
155
+ wrk = ABS(P->x[kk]);
156
+ Et[j] = MAX(wrk, Et[j]);
157
+ if (i != j) {
158
+ Et[i] = MAX(wrk, Et[i]);
159
+ }
160
+ }
161
+ }
162
+ }
163
+
164
+ /* calculate col norms, E */
165
+ for (i = 0; i < A->n; ++i) {
166
+ Et[i] = MAX(Et[i], SCS(norm_inf)(&(A->x[A->p[i]]), A->p[i + 1] - A->p[i]));
167
+ Et[i] = SAFEDIV_POS(1.0, SQRTF(apply_limit(Et[i])));
168
+ }
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
+ }
174
+
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) {
178
+ scs_int i, j, kk;
179
+ scs_float wrk, norm_c, norm_b;
180
+
181
+ /**************************** D ****************************/
182
+
183
+ /* initialize D */
184
+ for (i = 0; i < A->m; ++i) {
185
+ /* Dt[i] = 0.; */
186
+ Dt[i] = b[i] * b[i];
187
+ }
188
+
189
+ /* calculate row norms */
190
+ for (i = 0; i < A->n; ++i) {
191
+ for (j = A->p[i]; j < A->p[i + 1]; ++j) {
192
+ Dt[A->i[j]] += A->x[j] * A->x[j];
193
+ }
194
+ }
195
+ for (i = 0; i < A->m; ++i) {
196
+ Dt[i] = SQRTF(Dt[i]); /* l2 norm of rows */
197
+ }
198
+
199
+ /* accumulate D across each cone */
200
+ SCS(enforce_cone_boundaries)(cone, Dt, &SCS(mean));
201
+
202
+ for (i = 0; i < A->m; ++i) {
203
+ Dt[i] = SAFEDIV_POS(1.0, SQRTF(apply_limit(Dt[i])));
204
+ }
205
+
206
+ /**************************** E ****************************/
207
+
208
+ /* initialize E */
209
+ for (i = 0; i < A->n; ++i) {
210
+ /* Et[i] = 0.; */
211
+ Et[i] = c[i] * c[i];
212
+ }
213
+
214
+ /* TODO: test not using P to determine scaling */
215
+ if (P) {
216
+ /* compute norm of cols of P (symmetric upper triangular) */
217
+ /* E = norm of cols of P */
218
+ /* Compute maximum across columns */
219
+ /* P(i, j) contributes to col j and col i (row i) due to symmetry */
220
+ for (j = 0; j < P->n; j++) { /* cols */
221
+ for (kk = P->p[j]; kk < P->p[j + 1]; kk++) {
222
+ i = P->i[kk]; /* row */
223
+ wrk = P->x[kk] * P->x[kk];
224
+ Et[j] += wrk;
225
+ if (i != j) {
226
+ Et[i] += wrk;
227
+ }
228
+ }
229
+ }
230
+ }
231
+
232
+ /* calculate col norms, E */
233
+ for (i = 0; i < A->n; ++i) {
234
+ Et[i] += SCS(norm_sq)(&(A->x[A->p[i]]), A->p[i + 1] - A->p[i]);
235
+ Et[i] = SAFEDIV_POS(1.0, SQRTF(apply_limit(SQRTF(Et[i]))));
236
+ }
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
+ }
244
+
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) {
248
+ scs_int i, j;
249
+ /* scale the rows of A with D */
250
+ for (i = 0; i < A->n; ++i) {
251
+ for (j = A->p[i]; j < A->p[i + 1]; ++j) {
252
+ A->x[j] *= Dt[A->i[j]];
253
+ }
254
+ }
255
+
256
+ /* scale the cols of A with E */
257
+ for (i = 0; i < A->n; ++i) {
258
+ SCS(scale_array)(&(A->x[A->p[i]]), Et[i], A->p[i + 1] - A->p[i]);
259
+ }
260
+
261
+ if (P) {
262
+ /* scale the rows of P with E */
263
+ for (i = 0; i < P->n; ++i) {
264
+ for (j = P->p[i]; j < P->p[i + 1]; ++j) {
265
+ P->x[j] *= Et[P->i[j]];
266
+ }
267
+ }
268
+ /* scale the cols of P with E */
269
+ for (i = 0; i < P->n; ++i) {
270
+ SCS(scale_array)(&(P->x[P->p[i]]), Et[i], P->p[i + 1] - P->p[i]);
271
+ }
272
+ }
273
+
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
+ /* Accumulate scaling */
284
+ for (i = 0; i < A->m; ++i) {
285
+ scal->D[i] *= Dt[i];
286
+ }
287
+ for (i = 0; i < A->n; ++i) {
288
+ scal->E[i] *= Et[i];
289
+ }
290
+
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 */
295
+ /*
296
+ if (P) {
297
+ SCS(scale_array)(P->x, primal_scale, P->p[P->n]);
298
+ SCS(scale_array)(P->x, 1.0 / dual_scale, P->p[P->n]);
299
+ }
300
+ */
301
+
302
+ /* Accumulate scaling */
303
+ scal->primal_scale *= s;
304
+ scal->dual_scale *= s;
305
+ }
306
+
307
+ /* Will rescale as P -> EPE, A -> DAE, c -> sEc, b -> sDb, in-place.
308
+ * Essentially trying to rescale this matrix:
309
+ *
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]
313
+ *
314
+ * which results in:
315
+ *
316
+ * [ EPE EA'D sEc ]
317
+ * [ DAE 0 sDb ]
318
+ * [ sc'E sb'D 0 ]
319
+ *
320
+ * In other words D rescales the rows of A, b
321
+ * E rescales the cols of A and rows/cols of P, c'
322
+ *
323
+ * will repeatedly set: D^-1 ~ norm of rows of [ A b ]
324
+ *
325
+ * E^-1 ~ norm of cols of [ P ]
326
+ * [ A ]
327
+ * [ c']
328
+ *
329
+ * `s` is incorporated into dual_scale and primal_scale
330
+ *
331
+ * The main complication is that D has to respect cone boundaries.
332
+ *
333
+ */
334
+ ScsScaling *SCS(normalize_a_p)(ScsMatrix *P, ScsMatrix *A, scs_float *b,
335
+ scs_float *c, ScsConeWork *cone) {
336
+ scs_int i;
337
+ scs_float s;
338
+ ScsScaling *scal = (ScsScaling *)scs_calloc(1, sizeof(ScsScaling));
339
+ scs_float *Dt = (scs_float *)scs_calloc(A->m, sizeof(scs_float));
340
+ scs_float *Et = (scs_float *)scs_calloc(A->n, sizeof(scs_float));
341
+ scal->D = (scs_float *)scs_calloc(A->m, sizeof(scs_float));
342
+ scal->E = (scs_float *)scs_calloc(A->n, sizeof(scs_float));
343
+
344
+ #if VERBOSITY > 5
345
+ SCS(timer) normalize_timer;
346
+ SCS(tic)(&normalize_timer);
347
+ scs_printf("normalizing A and P\n");
348
+ #endif
349
+
350
+ /* init D, E */
351
+ scal->m = A->m;
352
+ for (i = 0; i < A->m; ++i) {
353
+ scal->D[i] = 1.;
354
+ }
355
+ scal->n = A->n;
356
+ for (i = 0; i < A->n; ++i) {
357
+ scal->E[i] = 1.;
358
+ }
359
+ scal->primal_scale = 1.;
360
+ scal->dual_scale = 1.;
361
+ 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);
364
+ }
365
+ 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);
368
+ }
369
+ scs_free(Dt);
370
+ scs_free(Et);
371
+
372
+ #if VERBOSITY > 5
373
+ scs_printf("finished normalizing A and P, time: %1.2es\n",
374
+ SCS(tocq)(&normalize_timer) / 1e3);
375
+ scs_printf("inf norm A %1.2e\n", SCS(norm_inf)(A->x, A->p[A->n]));
376
+ if (P) {
377
+ scs_printf("inf norm P %1.2e\n", SCS(norm_inf)(P->x, P->p[P->n]));
378
+ }
379
+ scs_printf("primal_scale %g\n", scal->primal_scale);
380
+ 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
+ scs_printf("norm D %g\n", SCS(norm_inf)(scal->D, A->m));
384
+ scs_printf("norm E %g\n", SCS(norm_inf)(scal->E, A->n));
385
+ #endif
386
+ return scal;
387
+ }
388
+
389
+ void SCS(un_normalize_a_p)(ScsMatrix *A, ScsMatrix *P, const ScsScaling *scal) {
390
+ scs_int i, j;
391
+ scs_float *D = scal->D;
392
+ scs_float *E = scal->E;
393
+ for (i = 0; i < A->n; ++i) {
394
+ SCS(scale_array)
395
+ (&(A->x[A->p[i]]), 1. / E[i], A->p[i + 1] - A->p[i]);
396
+ }
397
+ for (i = 0; i < A->n; ++i) {
398
+ for (j = A->p[i]; j < A->p[i + 1]; ++j) {
399
+ A->x[j] /= D[A->i[j]];
400
+ }
401
+ }
402
+ if (P) {
403
+ for (i = 0; i < P->n; ++i) {
404
+ SCS(scale_array)
405
+ (&(P->x[P->p[i]]), 1. / E[i], P->p[i + 1] - P->p[i]);
406
+ }
407
+ for (i = 0; i < P->n; ++i) {
408
+ for (j = P->p[i]; j < P->p[i + 1]; ++j) {
409
+ P->x[j] /= E[P->i[j]];
410
+ }
411
+ }
412
+ }
413
+ }
414
+
415
+ void SCS(accum_by_atrans)(const ScsMatrix *A, const scs_float *x,
416
+ scs_float *y) {
417
+ /* y += A'*x
418
+ A in column compressed format
419
+ parallelizes over columns (rows of A')
420
+ */
421
+ scs_int p, j;
422
+ scs_int c1, c2;
423
+ scs_float yj;
424
+ scs_int n = A->n;
425
+ scs_int *Ap = A->p;
426
+ scs_int *Ai = A->i;
427
+ scs_float *Ax = A->x;
428
+ #ifdef _OPENMP
429
+ #pragma omp parallel for private(p, c1, c2, yj)
430
+ #endif
431
+ for (j = 0; j < n; j++) {
432
+ yj = y[j];
433
+ c1 = Ap[j];
434
+ c2 = Ap[j + 1];
435
+ for (p = c1; p < c2; p++) {
436
+ yj += Ax[p] * x[Ai[p]];
437
+ }
438
+ y[j] = yj;
439
+ }
440
+ }
441
+
442
+ void SCS(accum_by_a)(const ScsMatrix *A, const scs_float *x, scs_float *y) {
443
+ /*y += A*x
444
+ A in column compressed format
445
+ */
446
+ scs_int p, j, i;
447
+ scs_int n = A->n;
448
+ scs_int *Ap = A->p;
449
+ scs_int *Ai = A->i;
450
+ scs_float *Ax = A->x;
451
+ for (j = 0; j < n; j++) { /* col */
452
+ for (p = Ap[j]; p < Ap[j + 1]; p++) {
453
+ i = Ai[p]; /* row */
454
+ y[i] += Ax[p] * x[j];
455
+ }
456
+ }
457
+ }
458
+
459
+ /* Since P is upper triangular need to be clever here */
460
+ void SCS(accum_by_p)(const ScsMatrix *P, const scs_float *x, scs_float *y) {
461
+ /* returns y += P x */
462
+ scs_int p, j, i;
463
+ scs_int n = P->n;
464
+ scs_int *Pp = P->p;
465
+ scs_int *Pi = P->i;
466
+ scs_float *Px = P->x;
467
+ /* y += P_upper x but skip diagonal entries*/
468
+ for (j = 0; j < n; j++) { /* col */
469
+ for (p = Pp[j]; p < Pp[j + 1]; p++) {
470
+ i = Pi[p]; /* row */
471
+ if (i != j) { /* skip the diagonal */
472
+ y[i] += Px[p] * x[j];
473
+ }
474
+ }
475
+ }
476
+ /* y += P_lower x */
477
+ SCS(accum_by_atrans)(P, x, y);
478
+ }
@@ -0,0 +1,70 @@
1
+ #ifndef SCS_MATRIX_H_GUARD
2
+ #define SCS_MATRIX_H_GUARD
3
+
4
+ #ifdef __cplusplus
5
+ extern "C" {
6
+ #endif
7
+
8
+ #include "glbopts.h"
9
+ #include "scs.h"
10
+ #include "scs_work.h"
11
+
12
+ /* Normalization routines, used if d->NORMALIZE is true */
13
+ /* normalizes A matrix, sets scal->E and scal->D diagonal scaling matrices,
14
+ * A -> D*A*E. D and E must be all positive entries, D must satisfy cone
15
+ * boundaries */
16
+ ScsScaling *SCS(normalize_a_p)(ScsMatrix *P, ScsMatrix *A, scs_float *b,
17
+ scs_float *c, ScsConeWork *cone);
18
+
19
+ /* unnormalizes A matrix, unnormalizes by w->D and w->E */
20
+ void SCS(un_normalize_a_p)(ScsMatrix *A, ScsMatrix *P, const ScsScaling *scal);
21
+
22
+ /* to free the memory allocated in a ScsMatrix (called on A and P at finish) */
23
+ void SCS(free_scs_matrix)(ScsMatrix *A);
24
+
25
+ /* copies A (instead of in-place normalization), returns 0 for failure,
26
+ * allocates memory for dstp */
27
+ scs_int SCS(copy_matrix)(ScsMatrix **dstp, const ScsMatrix *src);
28
+
29
+ scs_float SCS(cumsum)(scs_int *p, scs_int *c, scs_int n);
30
+
31
+ /**
32
+ * Validate the linear system inputs, returns < 0 if not valid inputs.
33
+ *
34
+ * @param A A data matrix
35
+ * @param P P data matrix
36
+ * @return status < 0 indicates failure
37
+ */
38
+ scs_int SCS(validate_lin_sys)(const ScsMatrix *A, const ScsMatrix *P);
39
+
40
+ /**
41
+ * Forms y += A^T * x
42
+ *
43
+ * @param A A data matrix
44
+ * @param x Input
45
+ * @param y Output
46
+ */
47
+ void SCS(accum_by_atrans)(const ScsMatrix *A, const scs_float *x, scs_float *y);
48
+
49
+ /**
50
+ * Forms y += A * x
51
+ *
52
+ * @param A Data matrix
53
+ * @param x Input
54
+ * @param y Output
55
+ */
56
+ void SCS(accum_by_a)(const ScsMatrix *A, const scs_float *x, scs_float *y);
57
+
58
+ /**
59
+ * Forms y += P * x
60
+ *
61
+ * @param P P data matrix
62
+ * @param x Input
63
+ * @param y Output
64
+ */
65
+ void SCS(accum_by_p)(const ScsMatrix *P, const scs_float *x, scs_float *y);
66
+
67
+ #ifdef __cplusplus
68
+ }
69
+ #endif
70
+ #endif
data/vendor/scs/scs.mk CHANGED
@@ -99,10 +99,6 @@ SFLOAT = 0
99
99
  ifneq ($(SFLOAT), 0)
100
100
  OPT_FLAGS += -DSFLOAT=$(SFLOAT) # use floats rather than doubles
101
101
  endif
102
- NOVALIDATE = 0
103
- ifneq ($(NOVALIDATE), 0)
104
- OPT_FLAGS += -DNOVALIDATE=$(NOVALIDATE)$ # remove data validation step
105
- endif
106
102
  NOTIMER = 0
107
103
  ifneq ($(NOTIMER), 0)
108
104
  OPT_FLAGS += -DNOTIMER=$(NOTIMER) # no timing, times reported as nan
@@ -115,12 +111,20 @@ GPU_TRANSPOSE_MAT = 1
115
111
  ifneq ($(GPU_TRANSPOSE_MAT), 0)
116
112
  OPT_FLAGS += -DGPU_TRANSPOSE_MAT=$(GPU_TRANSPOSE_MAT) # tranpose A mat in GPU memory
117
113
  endif
118
-
119
- ### VERBOSITY LEVELS: 0,1,2
120
- EXTRA_VERBOSE = 0
121
- ifneq ($(EXTRA_VERBOSE), 0)
122
- OPT_FLAGS += -DEXTRA_VERBOSE=$(EXTRA_VERBOSE) # extra verbosity level
114
+ NOVALIDATE = 0
115
+ ifneq ($(NOVALIDATE), 0)
116
+ OPT_FLAGS += -DNOVALIDATE=$(NOVALIDATE) # perform problem validation or skip
117
+ endif
118
+ ### VERBOSITY LEVELS: 0,1,2,...
119
+ VERBOSITY = 0
120
+ ifneq ($(VERBOSITY), 0)
121
+ OPT_FLAGS += -DVERBOSITY=$(VERBOSITY) # verbosity level
123
122
  endif
123
+ COVERAGE = 0
124
+ ifneq ($(COVERAGE), 0)
125
+ override CFLAGS += --coverage # generate test coverage data
126
+ endif
127
+
124
128
 
125
129
  ############ OPENMP: ############
126
130
  # set USE_OPENMP = 1 to allow openmp (multi-threaded matrix multiplies):
@@ -141,7 +145,7 @@ endif
141
145
  USE_LAPACK = 1
142
146
  ifneq ($(USE_LAPACK), 0)
143
147
  # edit these for your setup:
144
- BLASLDFLAGS = -lblas -llapack #-lgfortran
148
+ BLASLDFLAGS = -llapack -lblas # -lgfortran
145
149
  LDFLAGS += $(BLASLDFLAGS)
146
150
  OPT_FLAGS += -DUSE_LAPACK
147
151