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.
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