scs 0.2.3 → 0.3.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 +4 -0
- data/README.md +11 -6
- data/lib/scs/ffi.rb +30 -13
- data/lib/scs/solver.rb +32 -9
- data/lib/scs/version.rb +1 -1
- data/vendor/scs/CITATION.cff +39 -0
- data/vendor/scs/CMakeLists.txt +7 -8
- data/vendor/scs/Makefile +24 -15
- data/vendor/scs/README.md +5 -263
- data/vendor/scs/include/aa.h +67 -23
- data/vendor/scs/include/cones.h +17 -17
- data/vendor/scs/include/glbopts.h +98 -32
- data/vendor/scs/include/linalg.h +2 -4
- data/vendor/scs/include/linsys.h +58 -44
- data/vendor/scs/include/normalize.h +3 -3
- data/vendor/scs/include/rw.h +8 -2
- data/vendor/scs/include/scs.h +293 -133
- data/vendor/scs/include/util.h +3 -15
- data/vendor/scs/linsys/cpu/direct/private.c +220 -224
- data/vendor/scs/linsys/cpu/direct/private.h +13 -7
- data/vendor/scs/linsys/cpu/direct/private.o +0 -0
- data/vendor/scs/linsys/cpu/indirect/private.c +177 -110
- data/vendor/scs/linsys/cpu/indirect/private.h +8 -4
- data/vendor/scs/linsys/cpu/indirect/private.o +0 -0
- data/vendor/scs/linsys/csparse.c +87 -0
- data/vendor/scs/linsys/csparse.h +34 -0
- data/vendor/scs/linsys/csparse.o +0 -0
- data/vendor/scs/linsys/external/amd/SuiteSparse_config.c +1 -1
- data/vendor/scs/linsys/external/amd/SuiteSparse_config.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_1.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_2.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_aat.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_control.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_defaults.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_dump.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_global.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_info.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_internal.h +1 -1
- data/vendor/scs/linsys/external/amd/amd_order.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_post_tree.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_postorder.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_preprocess.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_valid.o +0 -0
- data/vendor/scs/linsys/external/qdldl/changes +2 -0
- data/vendor/scs/linsys/external/qdldl/qdldl.c +29 -46
- data/vendor/scs/linsys/external/qdldl/qdldl.h +33 -41
- data/vendor/scs/linsys/external/qdldl/qdldl.o +0 -0
- data/vendor/scs/linsys/external/qdldl/qdldl_types.h +11 -3
- data/vendor/scs/linsys/gpu/gpu.c +31 -33
- data/vendor/scs/linsys/gpu/gpu.h +48 -31
- data/vendor/scs/linsys/gpu/indirect/private.c +338 -232
- data/vendor/scs/linsys/gpu/indirect/private.h +23 -14
- data/vendor/scs/linsys/scs_matrix.c +498 -0
- data/vendor/scs/linsys/scs_matrix.h +70 -0
- data/vendor/scs/linsys/scs_matrix.o +0 -0
- data/vendor/scs/scs.mk +13 -9
- data/vendor/scs/src/aa.c +384 -109
- data/vendor/scs/src/aa.o +0 -0
- data/vendor/scs/src/cones.c +440 -353
- data/vendor/scs/src/cones.o +0 -0
- data/vendor/scs/src/ctrlc.c +15 -5
- data/vendor/scs/src/ctrlc.o +0 -0
- data/vendor/scs/src/linalg.c +84 -28
- data/vendor/scs/src/linalg.o +0 -0
- data/vendor/scs/src/normalize.c +22 -64
- data/vendor/scs/src/normalize.o +0 -0
- data/vendor/scs/src/rw.c +160 -21
- data/vendor/scs/src/rw.o +0 -0
- data/vendor/scs/src/scs.c +767 -563
- data/vendor/scs/src/scs.o +0 -0
- data/vendor/scs/src/scs_indir.o +0 -0
- data/vendor/scs/src/scs_version.c +9 -3
- data/vendor/scs/src/scs_version.o +0 -0
- data/vendor/scs/src/util.c +37 -106
- data/vendor/scs/src/util.o +0 -0
- data/vendor/scs/test/minunit.h +17 -8
- data/vendor/scs/test/problem_utils.h +176 -14
- data/vendor/scs/test/problems/degenerate.h +130 -0
- data/vendor/scs/test/problems/hs21_tiny_qp.h +124 -0
- data/vendor/scs/test/problems/hs21_tiny_qp_rw.h +116 -0
- data/vendor/scs/test/problems/infeasible_tiny_qp.h +100 -0
- data/vendor/scs/test/problems/qafiro_tiny_qp.h +199 -0
- data/vendor/scs/test/problems/random_prob +0 -0
- data/vendor/scs/test/problems/random_prob.h +45 -0
- data/vendor/scs/test/problems/rob_gauss_cov_est.h +188 -31
- data/vendor/scs/test/problems/small_lp.h +13 -14
- data/vendor/scs/test/problems/test_fails.h +43 -0
- data/vendor/scs/test/problems/unbounded_tiny_qp.h +82 -0
- data/vendor/scs/test/random_socp_prob.c +54 -53
- data/vendor/scs/test/rng.h +109 -0
- data/vendor/scs/test/run_from_file.c +19 -10
- data/vendor/scs/test/run_tests.c +27 -3
- metadata +20 -8
- data/vendor/scs/linsys/amatrix.c +0 -305
- data/vendor/scs/linsys/amatrix.h +0 -36
- data/vendor/scs/linsys/amatrix.o +0 -0
- data/vendor/scs/test/data/small_random_socp +0 -0
- data/vendor/scs/test/problems/small_random_socp.h +0 -33
- data/vendor/scs/test/run_tests +0 -2
@@ -1,43 +1,52 @@
|
|
1
1
|
#include "private.h"
|
2
|
+
#include "linsys.h"
|
3
|
+
#include "util.h"
|
4
|
+
#include <limits.h>
|
2
5
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
char *SCS(get_lin_sys_method)(const ScsMatrix *A, const ScsSettings *stgs) {
|
7
|
-
char *str = (char *)scs_malloc(sizeof(char) * 128);
|
8
|
-
sprintf(str, "sparse-indirect, nnz in A = %li, CG tol ~ 1/iter^(%2.2f)",
|
9
|
-
(long)A->p[A->n], stgs->cg_rate);
|
10
|
-
return str;
|
6
|
+
const char *SCS(get_lin_sys_method)() {
|
7
|
+
return "sparse-indirect";
|
11
8
|
}
|
12
9
|
|
10
|
+
/*
|
13
11
|
char *SCS(get_lin_sys_summary)(ScsLinSysWork *p, const ScsInfo *info) {
|
14
12
|
char *str = (char *)scs_malloc(sizeof(char) * 128);
|
15
|
-
sprintf(str,
|
16
|
-
|
17
|
-
(scs_float)p->tot_cg_its / (info->iter + 1),
|
18
|
-
p->total_solve_time / (info->iter + 1) / 1e3);
|
13
|
+
sprintf(str, "lin-sys: avg cg its: %2.2f\n",
|
14
|
+
(scs_float)p->tot_cg_its / (info->iter + 1));
|
19
15
|
p->tot_cg_its = 0;
|
20
|
-
p->total_solve_time = 0;
|
21
16
|
return str;
|
22
17
|
}
|
18
|
+
*/
|
23
19
|
|
24
|
-
/* M = inv ( diag (
|
25
|
-
static void
|
26
|
-
|
27
|
-
scs_int i;
|
20
|
+
/* set M = inv ( diag ( rho_x * I + P + A' R_y^{-1} A ) ) */
|
21
|
+
static void set_preconditioner(ScsLinSysWork *p) {
|
22
|
+
scs_int i, k;
|
28
23
|
scs_float *M = p->M;
|
24
|
+
const ScsMatrix *A = p->A;
|
25
|
+
const ScsMatrix *P = p->P;
|
29
26
|
|
30
|
-
#if
|
27
|
+
#if VERBOSITY > 0
|
31
28
|
scs_printf("getting pre-conditioner\n");
|
32
29
|
#endif
|
33
30
|
|
34
|
-
for (i = 0; i < A->n; ++i) {
|
35
|
-
M[i] =
|
36
|
-
|
37
|
-
|
31
|
+
for (i = 0; i < A->n; ++i) { /* cols */
|
32
|
+
M[i] = p->rho_x;
|
33
|
+
/* diag(A' R_y^{-1} A) */
|
34
|
+
for (k = A->p[i]; k < A->p[i + 1]; ++k) {
|
35
|
+
/* A->i[k] is row of entry k with value A->x[k] */
|
36
|
+
M[i] += A->x[k] * A->x[k] / p->rho_y_vec[A->i[k]];
|
37
|
+
}
|
38
|
+
if (P) {
|
39
|
+
for (k = P->p[i]; k < P->p[i + 1]; k++) {
|
40
|
+
/* diagonal element only */
|
41
|
+
if (P->i[k] == i) { /* row == col */
|
42
|
+
M[i] += P->x[k];
|
43
|
+
break;
|
44
|
+
}
|
45
|
+
}
|
46
|
+
}
|
47
|
+
M[i] = 1. / M[i];
|
38
48
|
}
|
39
|
-
|
40
|
-
#if EXTRA_VERBOSE > 0
|
49
|
+
#if VERBOSITY > 0
|
41
50
|
scs_printf("finished getting pre-conditioner\n");
|
42
51
|
#endif
|
43
52
|
}
|
@@ -54,15 +63,16 @@ static void transpose(const ScsMatrix *A, ScsLinSysWork *p) {
|
|
54
63
|
scs_float *Ax = A->x;
|
55
64
|
|
56
65
|
scs_int i, j, q, *z, c1, c2;
|
57
|
-
#if
|
66
|
+
#if VERBOSITY > 0
|
58
67
|
SCS(timer) transpose_timer;
|
59
68
|
scs_printf("transposing A\n");
|
60
69
|
SCS(tic)(&transpose_timer);
|
61
70
|
#endif
|
62
71
|
|
63
72
|
z = (scs_int *)scs_calloc(m, sizeof(scs_int));
|
64
|
-
for (i = 0; i < Ap[n]; i++)
|
65
|
-
|
73
|
+
for (i = 0; i < Ap[n]; i++)
|
74
|
+
z[Ai[i]]++; /* row counts */
|
75
|
+
SCS(cumsum)(Cp, z, m); /* row pointers */
|
66
76
|
|
67
77
|
for (j = 0; j < n; j++) {
|
68
78
|
c1 = Ap[j];
|
@@ -76,7 +86,7 @@ static void transpose(const ScsMatrix *A, ScsLinSysWork *p) {
|
|
76
86
|
}
|
77
87
|
scs_free(z);
|
78
88
|
|
79
|
-
#if
|
89
|
+
#if VERBOSITY > 0
|
80
90
|
scs_printf("finished transposing A, time: %1.2es\n",
|
81
91
|
SCS(tocq)(&transpose_timer) / 1e3);
|
82
92
|
#endif
|
@@ -100,40 +110,59 @@ void SCS(free_lin_sys_work)(ScsLinSysWork *p) {
|
|
100
110
|
}
|
101
111
|
}
|
102
112
|
|
103
|
-
/*
|
104
|
-
static void
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
memset(y, 0, A->n * sizeof(scs_float));
|
110
|
-
SCS(accum_by_atrans)(A, p, tmp, y);
|
111
|
-
SCS(add_scaled_array)(y, x, A->n, s->rho_x);
|
113
|
+
/* vec -> R_y^{-1} vec */
|
114
|
+
static void scale_by_diag_r(scs_float *vec, ScsLinSysWork *p) {
|
115
|
+
scs_int i;
|
116
|
+
for (i = 0; i < p->m; ++i) {
|
117
|
+
vec[i] /= p->rho_y_vec[i];
|
118
|
+
}
|
112
119
|
}
|
113
120
|
|
114
|
-
|
115
|
-
|
116
|
-
SCS(
|
121
|
+
/* we use a different accum_by_a here for speed */
|
122
|
+
static void accum_by_a(ScsLinSysWork *p, const scs_float *x, scs_float *y) {
|
123
|
+
SCS(accum_by_atrans)(p->At, x, y);
|
117
124
|
}
|
118
125
|
|
119
|
-
|
120
|
-
|
121
|
-
|
126
|
+
/* y = (rho_x * I + P + A' R_y^{-1} A) x */
|
127
|
+
static void mat_vec(const ScsMatrix *A, const ScsMatrix *P, ScsLinSysWork *p,
|
128
|
+
const scs_float *x, scs_float *y) {
|
129
|
+
scs_float *z = p->tmp;
|
130
|
+
memset(z, 0, A->m * sizeof(scs_float)); /* z = 0 */
|
131
|
+
memset(y, 0, A->n * sizeof(scs_float)); /* y = 0 */
|
132
|
+
if (P) {
|
133
|
+
SCS(accum_by_p)(P, x, y); /* y = Px */
|
134
|
+
}
|
135
|
+
accum_by_a(p, x, z); /* z = Ax */
|
136
|
+
scale_by_diag_r(z, p); /* z = R_y^{-1} A x */
|
137
|
+
SCS(accum_by_atrans)(A, z, y); /* y += A'z, y = Px + A' R_y^{-1} Ax */
|
138
|
+
/* y = rho_x * x + Px + A' R_y^{-1} A x */
|
139
|
+
SCS(add_scaled_array)(y, x, A->n, p->rho_x);
|
122
140
|
}
|
123
141
|
|
124
|
-
static void apply_pre_conditioner(scs_float *
|
125
|
-
|
142
|
+
static void apply_pre_conditioner(scs_float *z, scs_float *r, scs_int n,
|
143
|
+
ScsLinSysWork *pr) {
|
126
144
|
scs_int i;
|
127
|
-
*
|
145
|
+
scs_float *M = pr->M;
|
128
146
|
for (i = 0; i < n; ++i) {
|
129
147
|
z[i] = r[i] * M[i];
|
130
|
-
*ipzr += z[i] * r[i];
|
131
148
|
}
|
132
149
|
}
|
133
150
|
|
134
|
-
|
135
|
-
|
151
|
+
/* no need to update anything in this case */
|
152
|
+
void SCS(update_lin_sys_rho_y_vec)(ScsLinSysWork *p, scs_float *rho_y_vec) {
|
153
|
+
p->rho_y_vec = rho_y_vec; /* this isn't needed but do it to be safe */
|
154
|
+
set_preconditioner(p);
|
155
|
+
}
|
156
|
+
|
157
|
+
ScsLinSysWork *SCS(init_lin_sys_work)(const ScsMatrix *A, const ScsMatrix *P,
|
158
|
+
scs_float *rho_y_vec, scs_float rho_x) {
|
136
159
|
ScsLinSysWork *p = (ScsLinSysWork *)scs_calloc(1, sizeof(ScsLinSysWork));
|
160
|
+
p->A = A;
|
161
|
+
p->P = P;
|
162
|
+
p->m = A->m;
|
163
|
+
p->n = A->n;
|
164
|
+
p->rho_x = rho_x;
|
165
|
+
|
137
166
|
p->p = (scs_float *)scs_malloc((A->n) * sizeof(scs_float));
|
138
167
|
p->r = (scs_float *)scs_malloc((A->n) * sizeof(scs_float));
|
139
168
|
p->Gp = (scs_float *)scs_malloc((A->n) * sizeof(scs_float));
|
@@ -149,11 +178,11 @@ ScsLinSysWork *SCS(init_lin_sys_work)(const ScsMatrix *A,
|
|
149
178
|
transpose(A, p);
|
150
179
|
|
151
180
|
/* preconditioner memory */
|
152
|
-
p->
|
153
|
-
p->
|
154
|
-
|
181
|
+
p->rho_y_vec = rho_y_vec;
|
182
|
+
p->z = (scs_float *)scs_calloc(A->n, sizeof(scs_float));
|
183
|
+
p->M = (scs_float *)scs_calloc(A->n, sizeof(scs_float));
|
184
|
+
set_preconditioner(p);
|
155
185
|
|
156
|
-
p->total_solve_time = 0;
|
157
186
|
p->tot_cg_its = 0;
|
158
187
|
if (!p->p || !p->r || !p->Gp || !p->tmp || !p->At || !p->At->i || !p->At->p ||
|
159
188
|
!p->At->x) {
|
@@ -163,94 +192,132 @@ ScsLinSysWork *SCS(init_lin_sys_work)(const ScsMatrix *A,
|
|
163
192
|
return p;
|
164
193
|
}
|
165
194
|
|
166
|
-
/* solves (I+A'A)x = b, s warm start, solution stored in
|
167
|
-
|
168
|
-
|
195
|
+
/* solves (rho_x * I + P + A' R_y^{-1} A)x = b, s warm start, solution stored in
|
196
|
+
* b */
|
197
|
+
static scs_int pcg(ScsLinSysWork *pr, const scs_float *s, scs_float *b,
|
169
198
|
scs_int max_its, scs_float tol) {
|
170
|
-
scs_int i, n =
|
171
|
-
scs_float
|
199
|
+
scs_int i, n = pr->n;
|
200
|
+
scs_float ztr, ztr_prev, alpha;
|
172
201
|
scs_float *p = pr->p; /* cg direction */
|
173
202
|
scs_float *Gp = pr->Gp; /* updated CG direction */
|
174
203
|
scs_float *r = pr->r; /* cg residual */
|
175
204
|
scs_float *z = pr->z; /* for preconditioning */
|
176
|
-
scs_float *M = pr->M; /* inverse diagonal preconditioner */
|
177
205
|
|
178
|
-
|
206
|
+
const ScsMatrix *A = pr->A;
|
207
|
+
const ScsMatrix *P = pr->P;
|
208
|
+
|
209
|
+
if (!s) {
|
210
|
+
/* take s = 0 */
|
211
|
+
/* r = b */
|
179
212
|
memcpy(r, b, n * sizeof(scs_float));
|
213
|
+
/* b = 0 */
|
180
214
|
memset(b, 0, n * sizeof(scs_float));
|
181
215
|
} else {
|
182
|
-
|
183
|
-
|
184
|
-
|
216
|
+
/* r = Mat * s */
|
217
|
+
mat_vec(A, P, pr, s, r);
|
218
|
+
/* r = Mat * s - b */
|
219
|
+
SCS(add_scaled_array)(r, b, n, -1.);
|
220
|
+
/* r = b - Mat * s */
|
221
|
+
SCS(scale_array)(r, -1., n);
|
222
|
+
/* b = s */
|
185
223
|
memcpy(b, s, n * sizeof(scs_float));
|
186
224
|
}
|
187
225
|
|
188
226
|
/* check to see if we need to run CG at all */
|
189
|
-
if (
|
227
|
+
if (CG_NORM(r, n) < MAX(tol, 1e-12)) {
|
190
228
|
return 0;
|
191
229
|
}
|
192
230
|
|
193
|
-
|
231
|
+
/* z = M r (M is inverse preconditioner) */
|
232
|
+
apply_pre_conditioner(z, r, n, pr);
|
233
|
+
/* ztr = z'r */
|
234
|
+
ztr = SCS(dot)(z, r, n);
|
235
|
+
/* p = z */
|
194
236
|
memcpy(p, z, n * sizeof(scs_float));
|
195
237
|
|
196
238
|
for (i = 0; i < max_its; ++i) {
|
197
|
-
|
198
|
-
|
239
|
+
/* Gp = Mat * p */
|
240
|
+
mat_vec(A, P, pr, p, Gp);
|
241
|
+
/* alpha = z'r / p'G p */
|
242
|
+
alpha = ztr / SCS(dot)(p, Gp, n);
|
243
|
+
/* b += alpha * p */
|
199
244
|
SCS(add_scaled_array)(b, p, n, alpha);
|
245
|
+
/* r -= alpha * G p */
|
200
246
|
SCS(add_scaled_array)(r, Gp, n, -alpha);
|
201
247
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
(long)i + 1);
|
248
|
+
#if VERBOSITY > 3
|
249
|
+
scs_printf("tol: %.4e, resid: %.4e, iters: %li\n", tol, CG_NORM(r, n),
|
250
|
+
(long)i + 1);
|
206
251
|
#endif
|
252
|
+
if (CG_NORM(r, n) < tol) {
|
207
253
|
return i + 1;
|
208
254
|
}
|
209
|
-
|
210
|
-
apply_pre_conditioner(
|
211
|
-
|
212
|
-
|
213
|
-
SCS(
|
255
|
+
/* z = M r (M is inverse preconditioner) */
|
256
|
+
apply_pre_conditioner(z, r, n, pr);
|
257
|
+
ztr_prev = ztr;
|
258
|
+
/* ztr = z'r */
|
259
|
+
ztr = SCS(dot)(z, r, n);
|
260
|
+
/* p = beta * p, where beta = ztr / ztr_prev */
|
261
|
+
SCS(scale_array)(p, ztr / ztr_prev, n);
|
262
|
+
/* p = z + beta * p */
|
263
|
+
SCS(add_scaled_array)(p, z, n, 1.);
|
214
264
|
}
|
215
265
|
return i;
|
216
266
|
}
|
217
267
|
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
268
|
+
/* solves Mx = b, for x but stores result in b */
|
269
|
+
/* s contains warm-start (if available) */
|
270
|
+
/*
|
271
|
+
* [x] = [rho_x I + P A' ]^{-1} [rx]
|
272
|
+
* [y] [ A -R_y ] [ry]
|
273
|
+
*
|
274
|
+
* R_y = diag(rho_y_vec)
|
275
|
+
*
|
276
|
+
* becomes:
|
277
|
+
*
|
278
|
+
* x = (rho_x I + P + A' R_y^{-1} A)^{-1} (rx + A' R_y^{-1} ry)
|
279
|
+
* y = R_y^{-1} (Ax - ry)
|
280
|
+
*
|
281
|
+
*/
|
282
|
+
scs_int SCS(solve_lin_sys)(ScsLinSysWork *p, scs_float *b, const scs_float *s,
|
283
|
+
scs_float tol) {
|
284
|
+
scs_int cg_its, max_iters;
|
285
|
+
|
286
|
+
if (tol <= 0.) {
|
287
|
+
scs_printf("Warning: tol = %4f <= 0, likely compiled without setting "
|
288
|
+
"INDIRECT flag.\n",
|
289
|
+
tol);
|
290
|
+
}
|
291
|
+
|
292
|
+
if (CG_NORM(b, p->n + p->m) <= 1e-12) {
|
293
|
+
memset(b, 0, (p->n + p->m) * sizeof(scs_float));
|
294
|
+
return 0;
|
239
295
|
}
|
240
296
|
|
241
|
-
p->
|
242
|
-
|
243
|
-
|
297
|
+
/* use p->tmp here, and in mat_vec, can do both since they don't overlap */
|
298
|
+
/* b = [rx; ry] */
|
299
|
+
/* tmp = ry */
|
300
|
+
memcpy(p->tmp, &(b[p->n]), p->m * sizeof(scs_float));
|
301
|
+
/* tmp = R_y^{-1} * ry */
|
302
|
+
scale_by_diag_r(p->tmp, p);
|
303
|
+
/* b[:n] = rx + A' R_y^{-1} ry */
|
304
|
+
SCS(accum_by_atrans)(p->A, p->tmp, b);
|
305
|
+
/* set max_iters to 10 * n (though in theory n is enough for any tol) */
|
306
|
+
max_iters = 10 * p->n;
|
307
|
+
/* solves (rho_x I + P + A' R_y^{-1} A)x = b, s warm start, solution stored in
|
308
|
+
* b */
|
309
|
+
cg_its = pcg(p, s, b, max_iters, tol); /* b[:n] = x */
|
310
|
+
|
311
|
+
/* b[n:] = -ry */
|
312
|
+
SCS(scale_array)(&(b[p->n]), -1., p->m);
|
313
|
+
/* b[n:] = Ax - ry */
|
314
|
+
accum_by_a(p, b, &(b[p->n]));
|
315
|
+
/* b[n:] = R_y^{-1} (Ax - ry) = y */
|
316
|
+
scale_by_diag_r(&(b[p->n]), p);
|
317
|
+
p->tot_cg_its += cg_its;
|
318
|
+
#if VERBOSITY > 1
|
319
|
+
scs_printf("tol %.3e\n", tol);
|
320
|
+
scs_printf("cg_its %i\n", (int)cg_its);
|
244
321
|
#endif
|
245
322
|
return 0;
|
246
323
|
}
|
247
|
-
|
248
|
-
void SCS(normalize_a)(ScsMatrix *A, const ScsSettings *stgs, const ScsCone *k,
|
249
|
-
ScsScaling *scal) {
|
250
|
-
SCS(_normalize_a)(A, stgs, k, scal);
|
251
|
-
}
|
252
|
-
|
253
|
-
void SCS(un_normalize_a)(ScsMatrix *A, const ScsSettings *stgs,
|
254
|
-
const ScsScaling *scal) {
|
255
|
-
SCS(_un_normalize_a)(A, stgs, scal);
|
256
|
-
}
|
@@ -5,24 +5,28 @@
|
|
5
5
|
extern "C" {
|
6
6
|
#endif
|
7
7
|
|
8
|
-
#include <math.h>
|
9
|
-
#include "amatrix.h"
|
10
8
|
#include "glbopts.h"
|
11
9
|
#include "linalg.h"
|
12
10
|
#include "scs.h"
|
11
|
+
#include "scs_matrix.h"
|
12
|
+
#include <math.h>
|
13
13
|
|
14
14
|
struct SCS_LIN_SYS_WORK {
|
15
|
+
scs_int n, m; /* linear system dimensions */
|
15
16
|
scs_float *p; /* cg iterate */
|
16
17
|
scs_float *r; /* cg residual */
|
17
18
|
scs_float *Gp;
|
18
19
|
scs_float *tmp;
|
19
|
-
ScsMatrix *
|
20
|
+
const ScsMatrix *A; /* does *not* own this memory */
|
21
|
+
const ScsMatrix *P; /* does *not* own this memory */
|
22
|
+
ScsMatrix *At; /* does own this memory */
|
20
23
|
/* preconditioning */
|
21
24
|
scs_float *z;
|
22
25
|
scs_float *M;
|
23
26
|
/* reporting */
|
24
27
|
scs_int tot_cg_its;
|
25
|
-
scs_float
|
28
|
+
scs_float *rho_y_vec;
|
29
|
+
scs_float rho_x;
|
26
30
|
};
|
27
31
|
|
28
32
|
#ifdef __cplusplus
|
Binary file
|
@@ -0,0 +1,87 @@
|
|
1
|
+
/* Routines modified from CSparse, T. Davis et al */
|
2
|
+
|
3
|
+
#include "csparse.h"
|
4
|
+
|
5
|
+
csc *SCS(cs_spalloc)(scs_int m, scs_int n, scs_int nzmax, scs_int values,
|
6
|
+
scs_int triplet) {
|
7
|
+
csc *A = (csc *)scs_calloc(1, sizeof(csc)); /* allocate the csc struct */
|
8
|
+
if (!A) {
|
9
|
+
return SCS_NULL;
|
10
|
+
} /* out of memory */
|
11
|
+
A->m = m; /* define dimensions and nzmax */
|
12
|
+
A->n = n;
|
13
|
+
A->nzmax = nzmax = MAX(nzmax, 1);
|
14
|
+
A->nz = triplet ? 0 : -1; /* allocate triplet or comp.col */
|
15
|
+
A->p = (scs_int *)scs_malloc((triplet ? nzmax : n + 1) * sizeof(scs_int));
|
16
|
+
A->i = (scs_int *)scs_malloc(nzmax * sizeof(scs_int));
|
17
|
+
A->x = values ? (scs_float *)scs_malloc(nzmax * sizeof(scs_float)) : SCS_NULL;
|
18
|
+
return (!A->p || !A->i || (values && !A->x)) ? SCS(cs_spfree)(A) : A;
|
19
|
+
}
|
20
|
+
|
21
|
+
csc *SCS(cs_done)(csc *C, void *w, void *x, scs_int ok) {
|
22
|
+
scs_free(w); /* free workspace */
|
23
|
+
scs_free(x);
|
24
|
+
return ok ? C : SCS(cs_spfree)(C); /* return result if OK, else free it */
|
25
|
+
}
|
26
|
+
|
27
|
+
/* C = compressed-column form of a triplet matrix T */
|
28
|
+
csc *SCS(cs_compress)(const csc *T, scs_int *idx_mapping) {
|
29
|
+
scs_int m, n, nz, p, k, *Cp, *Ci, *w, *Ti, *Tj;
|
30
|
+
scs_float *Cx, *Tx;
|
31
|
+
csc *C;
|
32
|
+
m = T->m;
|
33
|
+
n = T->n;
|
34
|
+
Ti = T->i;
|
35
|
+
Tj = T->p;
|
36
|
+
Tx = T->x;
|
37
|
+
nz = T->nz;
|
38
|
+
C = SCS(cs_spalloc)(m, n, nz, Tx != SCS_NULL, 0); /* allocate result */
|
39
|
+
w = (scs_int *)scs_calloc(n, sizeof(scs_int)); /* get workspace */
|
40
|
+
if (!C || !w) {
|
41
|
+
return SCS(cs_done)(C, w, SCS_NULL, 0);
|
42
|
+
} /* out of memory */
|
43
|
+
Cp = C->p;
|
44
|
+
Ci = C->i;
|
45
|
+
Cx = C->x;
|
46
|
+
for (k = 0; k < nz; k++) {
|
47
|
+
w[Tj[k]]++; /* column counts */
|
48
|
+
}
|
49
|
+
SCS(cumsum)(Cp, w, n); /* column pointers */
|
50
|
+
for (k = 0; k < nz; k++) {
|
51
|
+
Ci[p = w[Tj[k]]++] = Ti[k]; /* A(i,j) is the pth entry in C */
|
52
|
+
if (idx_mapping) {
|
53
|
+
idx_mapping[k] = p;
|
54
|
+
} /* old to new indices */
|
55
|
+
if (Cx) {
|
56
|
+
Cx[p] = Tx[k];
|
57
|
+
}
|
58
|
+
}
|
59
|
+
return SCS(cs_done)(C, w, SCS_NULL, 1); /* success; free w and return C */
|
60
|
+
}
|
61
|
+
|
62
|
+
scs_float SCS(cumsum)(scs_int *p, scs_int *c, scs_int n) {
|
63
|
+
scs_int i, nz = 0;
|
64
|
+
scs_float nz2 = 0;
|
65
|
+
if (!p || !c) {
|
66
|
+
return (-1);
|
67
|
+
} /* check inputs */
|
68
|
+
for (i = 0; i < n; i++) {
|
69
|
+
p[i] = nz;
|
70
|
+
nz += c[i];
|
71
|
+
nz2 += c[i]; /* also in scs_float to avoid scs_int overflow */
|
72
|
+
c[i] = p[i]; /* also copy p[0..n-1] back into c[0..n-1]*/
|
73
|
+
}
|
74
|
+
p[n] = nz;
|
75
|
+
return nz2; /* return sum (c [0..n-1]) */
|
76
|
+
}
|
77
|
+
|
78
|
+
csc *SCS(cs_spfree)(csc *A) {
|
79
|
+
if (!A) {
|
80
|
+
return SCS_NULL;
|
81
|
+
} /* do nothing if A already SCS_NULL */
|
82
|
+
scs_free(A->p);
|
83
|
+
scs_free(A->i);
|
84
|
+
scs_free(A->x);
|
85
|
+
scs_free(A);
|
86
|
+
return (csc *)SCS_NULL; /* free the csc struct and return SCS_NULL */
|
87
|
+
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
/* Routines modified from CSparse, T. Davis et al */
|
2
|
+
|
3
|
+
#ifndef CS_H_GUARD
|
4
|
+
#define CS_H_GUARD
|
5
|
+
|
6
|
+
#ifdef __cplusplus
|
7
|
+
extern "C" {
|
8
|
+
#endif
|
9
|
+
|
10
|
+
#include "glbopts.h"
|
11
|
+
#include "scs.h"
|
12
|
+
|
13
|
+
/* matrix in compressed-column or triplet form */
|
14
|
+
typedef struct SPARSE_MATRIX {
|
15
|
+
scs_int nzmax; /* maximum number of entries */
|
16
|
+
scs_int m; /* number of rows */
|
17
|
+
scs_int n; /* number of columns */
|
18
|
+
scs_int *p; /* column pointers (size n+1) or col indices (size nzmax) */
|
19
|
+
scs_int *i; /* row indices, size nzmax */
|
20
|
+
scs_float *x; /* numerical values, size nzmax */
|
21
|
+
scs_int nz; /* # of entries in triplet matrix, -1 for compressed-col */
|
22
|
+
} csc;
|
23
|
+
|
24
|
+
csc *SCS(cs_spalloc)(scs_int m, scs_int n, scs_int nzmax, scs_int values,
|
25
|
+
scs_int triplet);
|
26
|
+
csc *SCS(cs_done)(csc *C, void *w, void *x, scs_int ok);
|
27
|
+
csc *SCS(cs_compress)(const csc *T, scs_int *idx_mapping);
|
28
|
+
scs_float SCS(cumsum)(scs_int *p, scs_int *c, scs_int n);
|
29
|
+
csc *SCS(cs_spfree)(csc *A);
|
30
|
+
|
31
|
+
#ifdef __cplusplus
|
32
|
+
}
|
33
|
+
#endif
|
34
|
+
#endif
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|