scs 0.3.1 → 0.3.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +8 -8
- data/lib/scs/ffi.rb +1 -7
- data/lib/scs/version.rb +1 -1
- data/vendor/scs/CITATION.cff +1 -1
- data/vendor/scs/CMakeLists.txt +55 -7
- data/vendor/scs/Makefile +9 -9
- data/vendor/scs/README.md +2 -1
- data/vendor/scs/include/aa.h +1 -1
- data/vendor/scs/include/cones.h +14 -11
- data/vendor/scs/include/glbopts.h +26 -64
- data/vendor/scs/include/linalg.h +2 -1
- data/vendor/scs/include/linsys.h +13 -13
- data/vendor/scs/include/normalize.h +6 -5
- data/vendor/scs/include/scs.h +43 -87
- data/vendor/scs/include/scs_types.h +34 -0
- data/vendor/scs/include/scs_work.h +83 -0
- data/vendor/scs/linsys/cpu/direct/private.c +86 -73
- data/vendor/scs/linsys/cpu/direct/private.h +2 -2
- data/vendor/scs/linsys/cpu/indirect/private.c +42 -33
- data/vendor/scs/linsys/cpu/indirect/private.h +1 -2
- data/vendor/scs/linsys/csparse.c +3 -3
- data/vendor/scs/linsys/external/amd/SuiteSparse_config.c +6 -6
- data/vendor/scs/linsys/external/amd/SuiteSparse_config.h +6 -1
- data/vendor/scs/linsys/external/amd/amd_order.c +5 -5
- data/vendor/scs/linsys/gpu/gpu.h +8 -11
- data/vendor/scs/linsys/gpu/indirect/private.c +72 -49
- data/vendor/scs/linsys/gpu/indirect/private.h +14 -13
- data/vendor/scs/linsys/scs_matrix.c +26 -46
- data/vendor/scs/linsys/scs_matrix.h +4 -4
- data/vendor/scs/scs.mk +1 -1
- data/vendor/scs/src/aa.c +13 -4
- data/vendor/scs/src/cones.c +143 -92
- data/vendor/scs/src/linalg.c +25 -0
- data/vendor/scs/src/normalize.c +26 -26
- data/vendor/scs/src/rw.c +48 -12
- data/vendor/scs/src/scs.c +104 -110
- data/vendor/scs/src/scs_version.c +8 -6
- data/vendor/scs/src/util.c +1 -1
- data/vendor/scs/test/minunit.h +6 -1
- data/vendor/scs/test/problem_utils.h +28 -35
- data/vendor/scs/test/problems/degenerate.h +1 -1
- data/vendor/scs/test/problems/hs21_tiny_qp.h +1 -1
- data/vendor/scs/test/problems/hs21_tiny_qp_rw.h +1 -1
- data/vendor/scs/test/problems/infeasible_tiny_qp.h +1 -1
- data/vendor/scs/test/problems/qafiro_tiny_qp.h +3 -3
- data/vendor/scs/test/problems/random_prob.h +1 -1
- data/vendor/scs/test/problems/rob_gauss_cov_est.h +1 -1
- data/vendor/scs/test/problems/small_lp.h +3 -1
- data/vendor/scs/test/problems/small_qp.h +352 -0
- data/vendor/scs/test/problems/{test_fails.h → test_validation.h} +3 -3
- data/vendor/scs/test/problems/unbounded_tiny_qp.h +1 -1
- data/vendor/scs/test/random_socp_prob.c +1 -1
- data/vendor/scs/test/run_from_file.c +1 -1
- data/vendor/scs/test/run_tests.c +23 -14
- metadata +8 -5
data/vendor/scs/include/scs.h
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
/* This file contains the outward facing SCS API. */
|
2
|
+
/* It includes all the input/output data structs and the API functions. */
|
3
|
+
|
1
4
|
#ifndef SCS_H_GUARD
|
2
5
|
#define SCS_H_GUARD
|
3
6
|
|
@@ -5,20 +8,34 @@
|
|
5
8
|
extern "C" {
|
6
9
|
#endif
|
7
10
|
|
8
|
-
|
11
|
+
/* Contains definitions of primitive types `scs_int` and `scs_float`. */
|
12
|
+
#include "scs_types.h"
|
9
13
|
|
10
|
-
|
11
|
-
#include "glbopts.h"
|
14
|
+
/* The following abstract structs are implemented later. */
|
12
15
|
|
13
16
|
/** Struct containing acceleration workspace. Implemented by acceleration. */
|
14
|
-
typedef struct
|
17
|
+
typedef struct ACCEL_WORK AaWork;
|
15
18
|
/** Struct containing cone projection workspace. Implemented by cones. */
|
16
19
|
typedef struct SCS_CONE_WORK ScsConeWork;
|
17
20
|
/** Struct containing linear system workspace. Implemented by linear solver. */
|
18
21
|
typedef struct SCS_LIN_SYS_WORK ScsLinSysWork;
|
22
|
+
/** Struct containing SCS workspace. Implemented in `scs_work.h`. */
|
23
|
+
typedef struct SCS_WORK ScsWork;
|
24
|
+
|
25
|
+
/* SCS returns one of the following integer exit flags: */
|
26
|
+
#define SCS_INFEASIBLE_INACCURATE (-7)
|
27
|
+
#define SCS_UNBOUNDED_INACCURATE (-6)
|
28
|
+
#define SCS_SIGINT (-5)
|
29
|
+
#define SCS_FAILED (-4)
|
30
|
+
#define SCS_INDETERMINATE (-3)
|
31
|
+
#define SCS_INFEASIBLE (-2) /* primal infeasible, dual unbounded */
|
32
|
+
#define SCS_UNBOUNDED (-1) /* primal unbounded, dual infeasible */
|
33
|
+
#define SCS_UNFINISHED (0) /* never returned, used as placeholder */
|
34
|
+
#define SCS_SOLVED (1)
|
35
|
+
#define SCS_SOLVED_INACCURATE (2)
|
19
36
|
|
20
|
-
/** This defines the data matrices which should be supplied in
|
21
|
-
* format with zero based indexing.
|
37
|
+
/** This defines the data matrices which should be supplied in compressed
|
38
|
+
* sparse column format with zero based indexing.
|
22
39
|
*/
|
23
40
|
typedef struct {
|
24
41
|
/** Matrix values, size: number of non-zeros. */
|
@@ -120,7 +137,10 @@ typedef struct {
|
|
120
137
|
|
121
138
|
/** Contains primal-dual solution arrays or a certificate of infeasibility.
|
122
139
|
* Check the exit flag to determine whether this contains a solution or a
|
123
|
-
* certificate.
|
140
|
+
* certificate. If when passed into SCS the members `x`, `y`, `s` are
|
141
|
+
* NULL then SCS will allocate memory for them which should be managed
|
142
|
+
* by the user to prevent memory leaks.
|
143
|
+
*/
|
124
144
|
typedef struct {
|
125
145
|
/** Primal variable. */
|
126
146
|
scs_float *x;
|
@@ -136,6 +156,8 @@ typedef struct {
|
|
136
156
|
scs_int iter;
|
137
157
|
/** Status string, e.g. 'solved'. */
|
138
158
|
char status[128];
|
159
|
+
/** Linear system solver used. */
|
160
|
+
char lin_sys_solver[128];
|
139
161
|
/** Status as scs_int, defined in glbopts.h. */
|
140
162
|
scs_int status_val;
|
141
163
|
/** Number of updates to scale. */
|
@@ -176,78 +198,8 @@ typedef struct {
|
|
176
198
|
scs_float accel_time;
|
177
199
|
} ScsInfo;
|
178
200
|
|
179
|
-
/* the following structs are not exposed to user */
|
180
|
-
|
181
|
-
/** Contains normalization variables. */
|
182
|
-
typedef struct {
|
183
|
-
scs_float *D, *E; /* for normalization */
|
184
|
-
scs_float primal_scale, dual_scale;
|
185
|
-
} ScsScaling;
|
186
|
-
|
187
|
-
/** Holds residual information. */
|
188
|
-
typedef struct {
|
189
|
-
scs_int last_iter;
|
190
|
-
scs_float xt_p_x; /* x' P x */
|
191
|
-
scs_float xt_p_x_tau; /* x'Px * tau^2 *not* divided out */
|
192
|
-
scs_float ctx;
|
193
|
-
scs_float ctx_tau; /* tau *not* divided out */
|
194
|
-
scs_float bty;
|
195
|
-
scs_float bty_tau; /* tau *not* divided out */
|
196
|
-
scs_float pobj; /* primal objective */
|
197
|
-
scs_float dobj; /* dual objective */
|
198
|
-
scs_float gap; /* pobj - dobj */
|
199
|
-
scs_float tau;
|
200
|
-
scs_float kap;
|
201
|
-
scs_float res_pri;
|
202
|
-
scs_float res_dual;
|
203
|
-
scs_float res_infeas;
|
204
|
-
scs_float res_unbdd_p;
|
205
|
-
scs_float res_unbdd_a;
|
206
|
-
/* tau NOT divided out */
|
207
|
-
scs_float *ax, *ax_s, *px, *aty, *ax_s_btau, *px_aty_ctau;
|
208
|
-
} ScsResiduals;
|
209
|
-
|
210
|
-
/** Workspace for SCS */
|
211
|
-
typedef struct {
|
212
|
-
/* x_prev = x from previous iteration */
|
213
|
-
scs_int time_limit_reached; /* set if the time-limit is reached */
|
214
|
-
scs_float *u, *u_t;
|
215
|
-
scs_float *v, *v_prev;
|
216
|
-
scs_float *rsk; /* rsk [ r; s; kappa ] */
|
217
|
-
scs_float *h; /* h = [c; b] */
|
218
|
-
scs_float *g; /* g = (I + M)^{-1} h */
|
219
|
-
scs_float *lin_sys_warm_start; /* linear system warm-start (indirect only) */
|
220
|
-
scs_float *rho_y_vec; /* vector of rho y parameters (affects cone project) */
|
221
|
-
AaWork *accel; /* struct for acceleration workspace */
|
222
|
-
scs_float *b_orig, *c_orig; /* original b and c vectors */
|
223
|
-
scs_float *b_normalized, *c_normalized; /* normalized b and c vectors */
|
224
|
-
scs_int m, n; /* A has m rows, n cols */
|
225
|
-
ScsMatrix *A; /* (possibly normalized) A matrix */
|
226
|
-
ScsMatrix *P; /* (possibly normalized) P matrix */
|
227
|
-
ScsLinSysWork *p; /* struct populated by linear system solver */
|
228
|
-
ScsScaling *scal; /* contains the re-scaling data */
|
229
|
-
ScsConeWork *cone_work; /* workspace for the cone projection step */
|
230
|
-
scs_int *cone_boundaries; /* array with boundaries of cones */
|
231
|
-
scs_int cone_boundaries_len; /* total length of cones */
|
232
|
-
/* normalized and unnormalized residuals */
|
233
|
-
ScsResiduals *r_orig, *r_normalized;
|
234
|
-
/* track x,y,s as alg progresses, tau *not* divided out */
|
235
|
-
ScsSolution *xys_orig, *xys_normalized;
|
236
|
-
/* updating scale params workspace */
|
237
|
-
scs_float sum_log_scale_factor;
|
238
|
-
scs_int last_scale_update_iter, n_log_scale_factor, scale_updates;
|
239
|
-
/* aa norm stat */
|
240
|
-
scs_float aa_norm;
|
241
|
-
scs_int rejected_accel_steps, accepted_accel_steps;
|
242
|
-
scs_float setup_time; /* time taken for setup phase (milliseconds) */
|
243
|
-
scs_float scale; /* current scale parameter */
|
244
|
-
const ScsData *d;
|
245
|
-
const ScsCone *k;
|
246
|
-
const ScsSettings *stgs; /* contains solver settings specified by user */
|
247
|
-
} ScsWork;
|
248
|
-
|
249
201
|
/*
|
250
|
-
*
|
202
|
+
* Main library API.
|
251
203
|
*/
|
252
204
|
|
253
205
|
/**
|
@@ -270,24 +222,24 @@ typedef struct {
|
|
270
222
|
* @param stgs SCS solver settings.
|
271
223
|
* @return Solver work struct.
|
272
224
|
*/
|
273
|
-
ScsWork *
|
225
|
+
ScsWork *scs_init(const ScsData *d, const ScsCone *k, const ScsSettings *stgs);
|
274
226
|
|
275
227
|
/**
|
276
|
-
* Solve quadratic cone program initialized by
|
228
|
+
* Solve quadratic cone program initialized by scs_init.
|
277
229
|
*
|
278
230
|
* @param w Workspace allocated by init.
|
279
231
|
* @param sol Solver solution struct, will contain solution at termination.
|
280
232
|
* @param info Solver info reporting.
|
281
233
|
* @return Flag containing problem status (see \a glbopts.h).
|
282
234
|
*/
|
283
|
-
scs_int
|
235
|
+
scs_int scs_solve(ScsWork *w, ScsSolution *sol, ScsInfo *info);
|
284
236
|
|
285
237
|
/**
|
286
238
|
* Clean up allocated SCS workspace.
|
287
239
|
*
|
288
240
|
* @param w Workspace allocated by init, will be deallocated.
|
289
241
|
*/
|
290
|
-
void
|
242
|
+
void scs_finish(ScsWork *w);
|
291
243
|
|
292
244
|
/**
|
293
245
|
* Solve quadratic cone program defined by data in d and cone k.
|
@@ -297,7 +249,8 @@ void SCS(finish)(ScsWork *w);
|
|
297
249
|
* @param d Problem data.
|
298
250
|
* @param k Cone data.
|
299
251
|
* @param stgs SCS solver settings.
|
300
|
-
* @param sol Solution will be stored here.
|
252
|
+
* @param sol Solution will be stored here. If members `x`, `y`, `s` are
|
253
|
+
* NULL then SCS will allocate memory for them.
|
301
254
|
* @param info Information about the solve will be stored here.
|
302
255
|
* @return Flag that determines solve type (see \a glbopts.h).
|
303
256
|
*/
|
@@ -309,11 +262,14 @@ scs_int scs(const ScsData *d, const ScsCone *k, const ScsSettings *stgs,
|
|
309
262
|
*
|
310
263
|
* @param stgs Settings struct that will be populated.
|
311
264
|
*/
|
312
|
-
void
|
265
|
+
void scs_set_default_settings(ScsSettings *stgs);
|
313
266
|
|
314
|
-
|
315
|
-
|
316
|
-
|
267
|
+
/**
|
268
|
+
* Helper function simply returns the current version of SCS as a string.
|
269
|
+
*
|
270
|
+
* @return SCS version as a string.
|
271
|
+
*/
|
272
|
+
const char *scs_version(void);
|
317
273
|
|
318
274
|
#ifdef __cplusplus
|
319
275
|
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
/*
|
2
|
+
* Definitions of primitive types used in SCS.
|
3
|
+
*/
|
4
|
+
|
5
|
+
#ifndef SCS_TYPES_H_GUARD
|
6
|
+
#define SCS_TYPES_H_GUARD
|
7
|
+
|
8
|
+
#ifdef __cplusplus
|
9
|
+
extern "C" {
|
10
|
+
#endif
|
11
|
+
|
12
|
+
#ifdef DLONG
|
13
|
+
/*#ifdef _WIN64
|
14
|
+
#include <stdint.h>
|
15
|
+
typedef int64_t scs_int;
|
16
|
+
#else
|
17
|
+
typedef long scs_int;
|
18
|
+
#endif
|
19
|
+
*/
|
20
|
+
typedef long long scs_int;
|
21
|
+
#else
|
22
|
+
typedef int scs_int;
|
23
|
+
#endif
|
24
|
+
|
25
|
+
#ifndef SFLOAT
|
26
|
+
typedef double scs_float;
|
27
|
+
#else
|
28
|
+
typedef float scs_float;
|
29
|
+
#endif
|
30
|
+
|
31
|
+
#ifdef __cplusplus
|
32
|
+
}
|
33
|
+
#endif
|
34
|
+
#endif
|
@@ -0,0 +1,83 @@
|
|
1
|
+
/*
|
2
|
+
* Define ScsWork and related internal-only structs (not part of external API).
|
3
|
+
*/
|
4
|
+
|
5
|
+
#ifndef SCS_WORK_H_GUARD
|
6
|
+
#define SCS_WORK_H_GUARD
|
7
|
+
|
8
|
+
#ifdef __cplusplus
|
9
|
+
extern "C" {
|
10
|
+
#endif
|
11
|
+
|
12
|
+
/** Contains normalization variables. */
|
13
|
+
typedef struct {
|
14
|
+
scs_float *D, *E; /* for normalization */
|
15
|
+
scs_int m; /* Length of D */
|
16
|
+
scs_int n; /* Length of E */
|
17
|
+
scs_float primal_scale, dual_scale;
|
18
|
+
} ScsScaling;
|
19
|
+
|
20
|
+
/** Holds residual information. */
|
21
|
+
typedef struct {
|
22
|
+
scs_int last_iter;
|
23
|
+
scs_float xt_p_x; /* x' P x */
|
24
|
+
scs_float xt_p_x_tau; /* x'Px * tau^2 *not* divided out */
|
25
|
+
scs_float ctx;
|
26
|
+
scs_float ctx_tau; /* tau *not* divided out */
|
27
|
+
scs_float bty;
|
28
|
+
scs_float bty_tau; /* tau *not* divided out */
|
29
|
+
scs_float pobj; /* primal objective */
|
30
|
+
scs_float dobj; /* dual objective */
|
31
|
+
scs_float gap; /* pobj - dobj */
|
32
|
+
scs_float tau;
|
33
|
+
scs_float kap;
|
34
|
+
scs_float res_pri;
|
35
|
+
scs_float res_dual;
|
36
|
+
scs_float res_infeas;
|
37
|
+
scs_float res_unbdd_p;
|
38
|
+
scs_float res_unbdd_a;
|
39
|
+
/* tau NOT divided out */
|
40
|
+
scs_float *ax, *ax_s, *px, *aty, *ax_s_btau, *px_aty_ctau;
|
41
|
+
} ScsResiduals;
|
42
|
+
|
43
|
+
/** Workspace for SCS */
|
44
|
+
struct SCS_WORK {
|
45
|
+
/* x_prev = x from previous iteration */
|
46
|
+
scs_int time_limit_reached; /* set if the time-limit is reached */
|
47
|
+
scs_float *u, *u_t;
|
48
|
+
scs_float *v, *v_prev;
|
49
|
+
scs_float *rsk; /* rsk [ r; s; kappa ] */
|
50
|
+
scs_float *h; /* h = [c; b] */
|
51
|
+
scs_float *g; /* g = (I + M)^{-1} h */
|
52
|
+
scs_float *lin_sys_warm_start; /* linear system warm-start (indirect only) */
|
53
|
+
scs_float *diag_r; /* vector of R matrix diagonals (affects cone proj) */
|
54
|
+
AaWork *accel; /* struct for acceleration workspace */
|
55
|
+
scs_float *b_orig, *c_orig; /* original b and c vectors */
|
56
|
+
scs_float *b_normalized, *c_normalized; /* normalized b and c vectors */
|
57
|
+
scs_int m, n; /* A has m rows, n cols */
|
58
|
+
ScsMatrix *A; /* (possibly normalized) A matrix */
|
59
|
+
ScsMatrix *P; /* (possibly normalized) P matrix */
|
60
|
+
ScsLinSysWork *p; /* struct populated by linear system solver */
|
61
|
+
ScsScaling *scal; /* contains the re-scaling data */
|
62
|
+
ScsConeWork *cone_work; /* workspace for the cone projection step */
|
63
|
+
/* normalized and unnormalized residuals */
|
64
|
+
ScsResiduals *r_orig, *r_normalized;
|
65
|
+
/* track x,y,s as alg progresses, tau *not* divided out */
|
66
|
+
ScsSolution *xys_orig, *xys_normalized;
|
67
|
+
/* updating scale params workspace */
|
68
|
+
scs_float sum_log_scale_factor;
|
69
|
+
scs_int last_scale_update_iter, n_log_scale_factor, scale_updates;
|
70
|
+
/* aa norm stat */
|
71
|
+
scs_float aa_norm;
|
72
|
+
scs_int rejected_accel_steps, accepted_accel_steps;
|
73
|
+
scs_float setup_time; /* time taken for setup phase (milliseconds) */
|
74
|
+
scs_float scale; /* current scale parameter */
|
75
|
+
const ScsData *d;
|
76
|
+
const ScsCone *k;
|
77
|
+
const ScsSettings *stgs; /* contains solver settings specified by user */
|
78
|
+
};
|
79
|
+
|
80
|
+
#ifdef __cplusplus
|
81
|
+
}
|
82
|
+
#endif
|
83
|
+
#endif
|
@@ -18,10 +18,11 @@ void SCS(free_lin_sys_work)(ScsLinSysWork *p) {
|
|
18
18
|
if (p) {
|
19
19
|
SCS(cs_spfree)(p->L);
|
20
20
|
SCS(cs_spfree)(p->kkt);
|
21
|
+
scs_free(p->diag_p);
|
21
22
|
scs_free(p->perm);
|
22
23
|
scs_free(p->Dinv);
|
23
24
|
scs_free(p->bp);
|
24
|
-
scs_free(p->
|
25
|
+
scs_free(p->diag_r_idxs);
|
25
26
|
scs_free(p->Lnz);
|
26
27
|
scs_free(p->iwork);
|
27
28
|
scs_free(p->etree);
|
@@ -32,9 +33,8 @@ void SCS(free_lin_sys_work)(ScsLinSysWork *p) {
|
|
32
33
|
}
|
33
34
|
}
|
34
35
|
|
35
|
-
static csc *form_kkt(const ScsMatrix *A, const ScsMatrix *P,
|
36
|
-
scs_float *
|
37
|
-
scs_float rho_x) {
|
36
|
+
static csc *form_kkt(const ScsMatrix *A, const ScsMatrix *P, scs_float *diag_p,
|
37
|
+
const scs_float *diag_r, scs_int *diag_r_idxs) {
|
38
38
|
/* ONLY UPPER TRIANGULAR PART IS STUFFED
|
39
39
|
* forms column compressed kkt matrix
|
40
40
|
* assumes column compressed form A matrix
|
@@ -42,7 +42,7 @@ static csc *form_kkt(const ScsMatrix *A, const ScsMatrix *P,
|
|
42
42
|
* forms upper triangular part of [(I + P) A'; A -I]
|
43
43
|
* P : n x n, A: m x n.
|
44
44
|
*/
|
45
|
-
scs_int i, j,
|
45
|
+
scs_int h, i, j, count;
|
46
46
|
csc *Kcsc, *K;
|
47
47
|
scs_int n = A->n;
|
48
48
|
scs_int m = A->m;
|
@@ -65,72 +65,80 @@ static csc *form_kkt(const ScsMatrix *A, const ScsMatrix *P,
|
|
65
65
|
return SCS_NULL;
|
66
66
|
}
|
67
67
|
|
68
|
-
|
68
|
+
count = 0; /* element counter */
|
69
69
|
if (P) {
|
70
|
-
/*
|
71
|
-
for (j = 0; j <
|
70
|
+
/* R_x + P in top left */
|
71
|
+
for (j = 0; j < n; j++) { /* cols */
|
72
|
+
diag_p[j] = 0.;
|
72
73
|
/* empty column, add diagonal */
|
73
74
|
if (P->p[j] == P->p[j + 1]) {
|
74
|
-
K->i[
|
75
|
-
K->p[
|
76
|
-
K->x[
|
77
|
-
|
75
|
+
K->i[count] = j;
|
76
|
+
K->p[count] = j;
|
77
|
+
K->x[count] = diag_r[j];
|
78
|
+
diag_r_idxs[j] = count; /* store the indices where diag_r occurs */
|
79
|
+
count++;
|
78
80
|
}
|
79
|
-
for (
|
80
|
-
i = P->i[
|
81
|
+
for (h = P->p[j]; h < P->p[j + 1]; h++) {
|
82
|
+
i = P->i[h]; /* row */
|
81
83
|
if (i > j) { /* only upper triangular needed */
|
82
84
|
break;
|
83
85
|
}
|
84
|
-
K->i[
|
85
|
-
K->p[
|
86
|
-
K->x[
|
86
|
+
K->i[count] = i;
|
87
|
+
K->p[count] = j;
|
88
|
+
K->x[count] = P->x[h];
|
87
89
|
if (i == j) {
|
88
90
|
/* P has diagonal element */
|
89
|
-
|
91
|
+
diag_p[j] = P->x[h];
|
92
|
+
K->x[count] += diag_r[j];
|
93
|
+
diag_r_idxs[j] = count; /* store the indices where diag_r occurs */
|
90
94
|
}
|
91
|
-
|
95
|
+
count++;
|
92
96
|
/* reached the end without adding diagonal, do it now */
|
93
|
-
if ((i < j) && (
|
94
|
-
K->i[
|
95
|
-
K->p[
|
96
|
-
K->x[
|
97
|
-
|
97
|
+
if ((i < j) && (h + 1 == P->p[j + 1] || P->i[h + 1] > j)) {
|
98
|
+
K->i[count] = j;
|
99
|
+
K->p[count] = j;
|
100
|
+
K->x[count] = diag_r[j];
|
101
|
+
diag_r_idxs[j] = count; /* store the indices where diag_r occurs */
|
102
|
+
count++;
|
98
103
|
}
|
99
104
|
}
|
100
105
|
}
|
101
106
|
} else {
|
102
|
-
/*
|
103
|
-
for (
|
104
|
-
|
105
|
-
K->
|
106
|
-
K->
|
107
|
-
|
107
|
+
/* R_x in top left */
|
108
|
+
for (j = 0; j < n; j++) {
|
109
|
+
diag_p[j] = 0.;
|
110
|
+
K->i[count] = j;
|
111
|
+
K->p[count] = j;
|
112
|
+
K->x[count] = diag_r[j];
|
113
|
+
diag_r_idxs[j] = count; /* store the indices where diag_r occurs */
|
114
|
+
count++;
|
108
115
|
}
|
109
116
|
}
|
110
117
|
|
111
118
|
/* A^T at top right */
|
112
119
|
for (j = 0; j < n; j++) {
|
113
|
-
for (
|
114
|
-
K->p[
|
115
|
-
K->i[
|
116
|
-
K->x[
|
117
|
-
|
120
|
+
for (h = A->p[j]; h < A->p[j + 1]; h++) {
|
121
|
+
K->p[count] = A->i[h] + n;
|
122
|
+
K->i[count] = j;
|
123
|
+
K->x[count] = A->x[h];
|
124
|
+
count++;
|
118
125
|
}
|
119
126
|
}
|
120
127
|
|
121
|
-
/* -
|
122
|
-
for (
|
123
|
-
K->i[
|
124
|
-
K->p[
|
125
|
-
K->x[
|
126
|
-
|
127
|
-
|
128
|
+
/* -R_y at bottom right */
|
129
|
+
for (j = 0; j < m; j++) {
|
130
|
+
K->i[count] = j + n;
|
131
|
+
K->p[count] = j + n;
|
132
|
+
K->x[count] = -diag_r[j + n];
|
133
|
+
diag_r_idxs[j + n] = count; /* store the indices where diag_r occurs */
|
134
|
+
count++;
|
128
135
|
}
|
129
|
-
|
130
|
-
|
136
|
+
|
137
|
+
K->nz = count;
|
138
|
+
idx_mapping = (scs_int *)scs_calloc(K->nz, sizeof(scs_int));
|
131
139
|
Kcsc = SCS(cs_compress)(K, idx_mapping);
|
132
|
-
for (i = 0; i <
|
133
|
-
|
140
|
+
for (i = 0; i < m + n; i++) {
|
141
|
+
diag_r_idxs[i] = idx_mapping[diag_r_idxs[i]];
|
134
142
|
}
|
135
143
|
SCS(cs_spfree)(K);
|
136
144
|
scs_free(idx_mapping);
|
@@ -138,7 +146,7 @@ static csc *form_kkt(const ScsMatrix *A, const ScsMatrix *P,
|
|
138
146
|
}
|
139
147
|
|
140
148
|
static scs_int _ldl_init(csc *A, scs_int *P, scs_float **info) {
|
141
|
-
*info = (scs_float *)
|
149
|
+
*info = (scs_float *)scs_calloc(AMD_INFO, sizeof(scs_float));
|
142
150
|
return amd_order(A->n, A->p, A->i, P, (scs_float *)SCS_NULL, *info);
|
143
151
|
}
|
144
152
|
|
@@ -146,10 +154,10 @@ static scs_int _ldl_init(csc *A, scs_int *P, scs_float **info) {
|
|
146
154
|
static scs_int ldl_prepare(ScsLinSysWork *p) {
|
147
155
|
csc *kkt = p->kkt, *L = p->L;
|
148
156
|
scs_int n = kkt->n;
|
149
|
-
p->etree = (scs_int *)
|
150
|
-
p->Lnz = (scs_int *)
|
151
|
-
p->iwork = (scs_int *)
|
152
|
-
L->p = (scs_int *)
|
157
|
+
p->etree = (scs_int *)scs_calloc(n, sizeof(scs_int));
|
158
|
+
p->Lnz = (scs_int *)scs_calloc(n, sizeof(scs_int));
|
159
|
+
p->iwork = (scs_int *)scs_calloc(3 * n, sizeof(scs_int));
|
160
|
+
L->p = (scs_int *)scs_calloc((1 + n), sizeof(scs_int));
|
153
161
|
L->nzmax = QDLDL_etree(n, kkt->p, kkt->i, p->iwork, p->Lnz, p->etree);
|
154
162
|
if (L->nzmax < 0) {
|
155
163
|
scs_printf("Error in elimination tree calculation.\n");
|
@@ -161,12 +169,12 @@ static scs_int ldl_prepare(ScsLinSysWork *p) {
|
|
161
169
|
return L->nzmax;
|
162
170
|
}
|
163
171
|
|
164
|
-
L->x = (scs_float *)
|
165
|
-
L->i = (scs_int *)
|
166
|
-
p->Dinv = (scs_float *)
|
167
|
-
p->D = (scs_float *)
|
168
|
-
p->bwork = (scs_int *)
|
169
|
-
p->fwork = (scs_float *)
|
172
|
+
L->x = (scs_float *)scs_calloc(L->nzmax, sizeof(scs_float));
|
173
|
+
L->i = (scs_int *)scs_calloc(L->nzmax, sizeof(scs_int));
|
174
|
+
p->Dinv = (scs_float *)scs_calloc(n, sizeof(scs_float));
|
175
|
+
p->D = (scs_float *)scs_calloc(n, sizeof(scs_float));
|
176
|
+
p->bwork = (scs_int *)scs_calloc(n, sizeof(scs_int));
|
177
|
+
p->fwork = (scs_float *)scs_calloc(n, sizeof(scs_float));
|
170
178
|
return L->nzmax;
|
171
179
|
}
|
172
180
|
|
@@ -223,7 +231,7 @@ static scs_int *cs_pinv(scs_int const *p, scs_int n) {
|
|
223
231
|
if (!p) {
|
224
232
|
return SCS_NULL;
|
225
233
|
} /* p = SCS_NULL denotes identity */
|
226
|
-
pinv = (scs_int *)
|
234
|
+
pinv = (scs_int *)scs_calloc(n, sizeof(scs_int)); /* allocate result */
|
227
235
|
if (!pinv) {
|
228
236
|
return SCS_NULL;
|
229
237
|
} /* out of memory */
|
@@ -283,10 +291,10 @@ static csc *cs_symperm(const csc *A, const scs_int *pinv, scs_int *idx_mapping,
|
|
283
291
|
}
|
284
292
|
|
285
293
|
static csc *permute_kkt(const ScsMatrix *A, const ScsMatrix *P,
|
286
|
-
ScsLinSysWork *p, scs_float *
|
294
|
+
ScsLinSysWork *p, const scs_float *diag_r) {
|
287
295
|
scs_float *info;
|
288
296
|
scs_int *Pinv, amd_status, *idx_mapping, i;
|
289
|
-
csc *kkt_perm, *kkt = form_kkt(A, P,
|
297
|
+
csc *kkt_perm, *kkt = form_kkt(A, P, p->diag_p, diag_r, p->diag_r_idxs);
|
290
298
|
if (!kkt) {
|
291
299
|
return SCS_NULL;
|
292
300
|
}
|
@@ -300,10 +308,10 @@ static csc *permute_kkt(const ScsMatrix *A, const ScsMatrix *P,
|
|
300
308
|
amd_info(info);
|
301
309
|
#endif
|
302
310
|
Pinv = cs_pinv(p->perm, A->n + A->m);
|
303
|
-
idx_mapping = (scs_int *)
|
311
|
+
idx_mapping = (scs_int *)scs_calloc(kkt->nzmax, sizeof(scs_int));
|
304
312
|
kkt_perm = cs_symperm(kkt, Pinv, idx_mapping, 1);
|
305
|
-
for (i = 0; i < A->m; i++) {
|
306
|
-
p->
|
313
|
+
for (i = 0; i < A->n + A->m; i++) {
|
314
|
+
p->diag_r_idxs[i] = idx_mapping[p->diag_r_idxs[i]];
|
307
315
|
}
|
308
316
|
SCS(cs_spfree)(kkt);
|
309
317
|
scs_free(Pinv);
|
@@ -312,10 +320,15 @@ static csc *permute_kkt(const ScsMatrix *A, const ScsMatrix *P,
|
|
312
320
|
return kkt_perm;
|
313
321
|
}
|
314
322
|
|
315
|
-
void SCS(
|
323
|
+
void SCS(update_lin_sys_diag_r)(ScsLinSysWork *p, const scs_float *diag_r) {
|
316
324
|
scs_int i, ldl_status;
|
317
|
-
for (i = 0; i < p->
|
318
|
-
|
325
|
+
for (i = 0; i < p->n; ++i) {
|
326
|
+
/* top left is R_x + P, bottom right is -R_y */
|
327
|
+
p->kkt->x[p->diag_r_idxs[i]] = p->diag_p[i] + diag_r[i];
|
328
|
+
}
|
329
|
+
for (i = p->n; i < p->n + p->m; ++i) {
|
330
|
+
/* top left is R_x + P, bottom right is -R_y */
|
331
|
+
p->kkt->x[p->diag_r_idxs[i]] = -diag_r[i];
|
319
332
|
}
|
320
333
|
ldl_status = ldl_factor(p, p->n);
|
321
334
|
if (ldl_status < 0) {
|
@@ -327,21 +340,21 @@ void SCS(update_lin_sys_rho_y_vec)(ScsLinSysWork *p, scs_float *rho_y_vec) {
|
|
327
340
|
}
|
328
341
|
|
329
342
|
ScsLinSysWork *SCS(init_lin_sys_work)(const ScsMatrix *A, const ScsMatrix *P,
|
330
|
-
scs_float *
|
343
|
+
const scs_float *diag_r) {
|
331
344
|
ScsLinSysWork *p = (ScsLinSysWork *)scs_calloc(1, sizeof(ScsLinSysWork));
|
332
345
|
scs_int n_plus_m = A->n + A->m, ldl_status, ldl_prepare_status;
|
333
346
|
p->m = A->m;
|
334
347
|
p->n = A->n;
|
335
|
-
p->
|
336
|
-
p->perm = (scs_int *)
|
337
|
-
p->L = (csc *)
|
338
|
-
p->bp = (scs_float *)
|
339
|
-
p->
|
348
|
+
p->diag_p = (scs_float *)scs_calloc(A->n, sizeof(scs_float));
|
349
|
+
p->perm = (scs_int *)scs_calloc(sizeof(scs_int), n_plus_m);
|
350
|
+
p->L = (csc *)scs_calloc(1, sizeof(csc));
|
351
|
+
p->bp = (scs_float *)scs_calloc(n_plus_m, sizeof(scs_float));
|
352
|
+
p->diag_r_idxs = (scs_int *)scs_calloc(n_plus_m, sizeof(scs_int));
|
340
353
|
p->factorizations = 0;
|
341
354
|
p->L->m = n_plus_m;
|
342
355
|
p->L->n = n_plus_m;
|
343
356
|
p->L->nz = -1;
|
344
|
-
p->kkt = permute_kkt(A, P, p,
|
357
|
+
p->kkt = permute_kkt(A, P, p, diag_r);
|
345
358
|
ldl_prepare_status = ldl_prepare(p);
|
346
359
|
ldl_status = ldl_factor(p, A->n);
|
347
360
|
if (ldl_prepare_status < 0 || ldl_status < 0) {
|
@@ -18,12 +18,12 @@ struct SCS_LIN_SYS_WORK {
|
|
18
18
|
scs_float *Dinv; /* inverse diagonal matrix of factorization */
|
19
19
|
scs_int *perm; /* permutation of KKT matrix for factorization */
|
20
20
|
scs_float *bp; /* workspace memory for solves */
|
21
|
-
scs_int *
|
21
|
+
scs_int *diag_r_idxs;
|
22
22
|
scs_int factorizations;
|
23
23
|
/* ldl factorization workspace */
|
24
24
|
scs_float *D, *fwork;
|
25
25
|
scs_int *etree, *iwork, *Lnz, *bwork;
|
26
|
-
scs_float
|
26
|
+
scs_float *diag_p;
|
27
27
|
};
|
28
28
|
|
29
29
|
#ifdef __cplusplus
|