scs 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/README.md +8 -8
  4. data/lib/scs/ffi.rb +1 -7
  5. data/lib/scs/version.rb +1 -1
  6. data/vendor/scs/CITATION.cff +1 -1
  7. data/vendor/scs/CMakeLists.txt +55 -7
  8. data/vendor/scs/Makefile +9 -9
  9. data/vendor/scs/README.md +2 -1
  10. data/vendor/scs/include/aa.h +1 -1
  11. data/vendor/scs/include/cones.h +14 -11
  12. data/vendor/scs/include/glbopts.h +26 -64
  13. data/vendor/scs/include/linalg.h +2 -1
  14. data/vendor/scs/include/linsys.h +13 -13
  15. data/vendor/scs/include/normalize.h +6 -5
  16. data/vendor/scs/include/scs.h +43 -87
  17. data/vendor/scs/include/scs_types.h +34 -0
  18. data/vendor/scs/include/scs_work.h +83 -0
  19. data/vendor/scs/linsys/cpu/direct/private.c +86 -73
  20. data/vendor/scs/linsys/cpu/direct/private.h +2 -2
  21. data/vendor/scs/linsys/cpu/indirect/private.c +42 -33
  22. data/vendor/scs/linsys/cpu/indirect/private.h +1 -2
  23. data/vendor/scs/linsys/csparse.c +3 -3
  24. data/vendor/scs/linsys/external/amd/SuiteSparse_config.c +6 -6
  25. data/vendor/scs/linsys/external/amd/SuiteSparse_config.h +6 -1
  26. data/vendor/scs/linsys/external/amd/amd_order.c +5 -5
  27. data/vendor/scs/linsys/gpu/gpu.h +8 -11
  28. data/vendor/scs/linsys/gpu/indirect/private.c +72 -49
  29. data/vendor/scs/linsys/gpu/indirect/private.h +14 -13
  30. data/vendor/scs/linsys/scs_matrix.c +26 -46
  31. data/vendor/scs/linsys/scs_matrix.h +4 -4
  32. data/vendor/scs/scs.mk +1 -1
  33. data/vendor/scs/src/aa.c +13 -4
  34. data/vendor/scs/src/cones.c +143 -92
  35. data/vendor/scs/src/linalg.c +25 -0
  36. data/vendor/scs/src/normalize.c +26 -26
  37. data/vendor/scs/src/rw.c +48 -12
  38. data/vendor/scs/src/scs.c +104 -110
  39. data/vendor/scs/src/scs_version.c +8 -6
  40. data/vendor/scs/src/util.c +1 -1
  41. data/vendor/scs/test/minunit.h +6 -1
  42. data/vendor/scs/test/problem_utils.h +28 -35
  43. data/vendor/scs/test/problems/degenerate.h +1 -1
  44. data/vendor/scs/test/problems/hs21_tiny_qp.h +1 -1
  45. data/vendor/scs/test/problems/hs21_tiny_qp_rw.h +1 -1
  46. data/vendor/scs/test/problems/infeasible_tiny_qp.h +1 -1
  47. data/vendor/scs/test/problems/qafiro_tiny_qp.h +3 -3
  48. data/vendor/scs/test/problems/random_prob.h +1 -1
  49. data/vendor/scs/test/problems/rob_gauss_cov_est.h +1 -1
  50. data/vendor/scs/test/problems/small_lp.h +3 -1
  51. data/vendor/scs/test/problems/small_qp.h +352 -0
  52. data/vendor/scs/test/problems/{test_fails.h → test_validation.h} +3 -3
  53. data/vendor/scs/test/problems/unbounded_tiny_qp.h +1 -1
  54. data/vendor/scs/test/random_socp_prob.c +1 -1
  55. data/vendor/scs/test/run_from_file.c +1 -1
  56. data/vendor/scs/test/run_tests.c +23 -14
  57. metadata +8 -5
@@ -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
- #include <string.h>
11
+ /* Contains definitions of primitive types `scs_int` and `scs_float`. */
12
+ #include "scs_types.h"
9
13
 
10
- #include "aa.h"
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 SCS_ACCEL_WORK ScsAccelWork;
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 column compressed
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
- * main library API
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 *SCS(init)(const ScsData *d, const ScsCone *k, const ScsSettings *stgs);
225
+ ScsWork *scs_init(const ScsData *d, const ScsCone *k, const ScsSettings *stgs);
274
226
 
275
227
  /**
276
- * Solve quadratic cone program initialized by SCS(init).
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 SCS(solve)(ScsWork *w, ScsSolution *sol, ScsInfo *info);
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 SCS(finish)(ScsWork *w);
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 SCS(set_default_settings)(ScsSettings *stgs);
265
+ void scs_set_default_settings(ScsSettings *stgs);
313
266
 
314
- const char *SCS(version)(void);
315
- size_t SCS(sizeof_int)(void);
316
- size_t SCS(sizeof_float)(void);
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->rho_y_vec_idxs);
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 *rho_y_vec, scs_int *rho_y_vec_idxs,
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, k, kk;
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
- kk = 0; /* element counter */
68
+ count = 0; /* element counter */
69
69
  if (P) {
70
- /* I + P in top left */
71
- for (j = 0; j < P->n; j++) { /* cols */
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[kk] = j;
75
- K->p[kk] = j;
76
- K->x[kk] = rho_x;
77
- kk++;
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 (k = P->p[j]; k < P->p[j + 1]; k++) {
80
- i = P->i[k]; /* row */
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[kk] = i;
85
- K->p[kk] = j;
86
- K->x[kk] = P->x[k];
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
- K->x[kk] += rho_x;
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
- kk++;
95
+ count++;
92
96
  /* reached the end without adding diagonal, do it now */
93
- if ((i < j) && (k + 1 == P->p[j + 1] || P->i[k + 1] > j)) {
94
- K->i[kk] = j;
95
- K->p[kk] = j;
96
- K->x[kk] = rho_x;
97
- kk++;
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
- /* rho_x * I in top left */
103
- for (k = 0; k < A->n; k++) {
104
- K->i[kk] = k;
105
- K->p[kk] = k;
106
- K->x[kk] = rho_x;
107
- kk++;
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 (k = A->p[j]; k < A->p[j + 1]; k++) {
114
- K->p[kk] = A->i[k] + n;
115
- K->i[kk] = j;
116
- K->x[kk] = A->x[k];
117
- kk++;
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
- /* -rho_y_vec * I at bottom right */
122
- for (k = 0; k < m; k++) {
123
- K->i[kk] = k + n;
124
- K->p[kk] = k + n;
125
- K->x[kk] = -rho_y_vec[k];
126
- rho_y_vec_idxs[k] = kk; /* store the indices where rho_y_vec occurs */
127
- kk++;
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
- K->nz = kk;
130
- idx_mapping = (scs_int *)scs_malloc(K->nz * sizeof(scs_int));
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 < A->m; i++) {
133
- rho_y_vec_idxs[i] = idx_mapping[rho_y_vec_idxs[i]];
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 *)scs_malloc(AMD_INFO * sizeof(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 *)scs_malloc(n * sizeof(scs_int));
150
- p->Lnz = (scs_int *)scs_malloc(n * sizeof(scs_int));
151
- p->iwork = (scs_int *)scs_malloc(3 * n * sizeof(scs_int));
152
- L->p = (scs_int *)scs_malloc((1 + n) * sizeof(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 *)scs_malloc(L->nzmax * sizeof(scs_float));
165
- L->i = (scs_int *)scs_malloc(L->nzmax * sizeof(scs_int));
166
- p->Dinv = (scs_float *)scs_malloc(n * sizeof(scs_float));
167
- p->D = (scs_float *)scs_malloc(n * sizeof(scs_float));
168
- p->bwork = (scs_int *)scs_malloc(n * sizeof(scs_int));
169
- p->fwork = (scs_float *)scs_malloc(n * sizeof(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 *)scs_malloc(n * sizeof(scs_int)); /* allocate result */
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 *rho_y_vec) {
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, rho_y_vec, p->rho_y_vec_idxs, p->rho_x);
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 *)scs_malloc(kkt->nzmax * sizeof(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->rho_y_vec_idxs[i] = idx_mapping[p->rho_y_vec_idxs[i]];
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(update_lin_sys_rho_y_vec)(ScsLinSysWork *p, scs_float *rho_y_vec) {
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->m; ++i) {
318
- p->kkt->x[p->rho_y_vec_idxs[i]] = -rho_y_vec[i];
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 *rho_y_vec, scs_float rho_x) {
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->rho_x = rho_x;
336
- p->perm = (scs_int *)scs_malloc(sizeof(scs_int) * n_plus_m);
337
- p->L = (csc *)scs_malloc(sizeof(csc));
338
- p->bp = (scs_float *)scs_malloc(n_plus_m * sizeof(scs_float));
339
- p->rho_y_vec_idxs = (scs_int *)scs_malloc(A->m * sizeof(scs_int));
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, rho_y_vec);
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 *rho_y_vec_idxs;
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 rho_x;
26
+ scs_float *diag_p;
27
27
  };
28
28
 
29
29
  #ifdef __cplusplus