scs 0.2.2 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -0
  3. data/LICENSE.txt +18 -18
  4. data/README.md +19 -14
  5. data/lib/scs/ffi.rb +31 -20
  6. data/lib/scs/solver.rb +32 -9
  7. data/lib/scs/version.rb +1 -1
  8. data/vendor/scs/CITATION.cff +39 -0
  9. data/vendor/scs/CMakeLists.txt +320 -0
  10. data/vendor/scs/Makefile +32 -23
  11. data/vendor/scs/README.md +9 -218
  12. data/vendor/scs/include/aa.h +67 -23
  13. data/vendor/scs/include/cones.h +22 -19
  14. data/vendor/scs/include/glbopts.h +107 -79
  15. data/vendor/scs/include/linalg.h +3 -4
  16. data/vendor/scs/include/linsys.h +58 -44
  17. data/vendor/scs/include/normalize.h +6 -5
  18. data/vendor/scs/include/rw.h +8 -2
  19. data/vendor/scs/include/scs.h +257 -141
  20. data/vendor/scs/include/scs_types.h +34 -0
  21. data/vendor/scs/include/scs_work.h +83 -0
  22. data/vendor/scs/include/util.h +3 -15
  23. data/vendor/scs/linsys/cpu/direct/private.c +241 -232
  24. data/vendor/scs/linsys/cpu/direct/private.h +13 -7
  25. data/vendor/scs/linsys/cpu/indirect/private.c +194 -118
  26. data/vendor/scs/linsys/cpu/indirect/private.h +7 -4
  27. data/vendor/scs/linsys/csparse.c +87 -0
  28. data/vendor/scs/linsys/csparse.h +34 -0
  29. data/vendor/scs/linsys/external/amd/SuiteSparse_config.c +6 -6
  30. data/vendor/scs/linsys/external/amd/SuiteSparse_config.h +6 -1
  31. data/vendor/scs/linsys/external/amd/amd_internal.h +1 -1
  32. data/vendor/scs/linsys/external/amd/amd_order.c +5 -5
  33. data/vendor/scs/linsys/external/qdldl/changes +2 -0
  34. data/vendor/scs/linsys/external/qdldl/qdldl.c +29 -46
  35. data/vendor/scs/linsys/external/qdldl/qdldl.h +33 -41
  36. data/vendor/scs/linsys/external/qdldl/qdldl_types.h +11 -3
  37. data/vendor/scs/linsys/gpu/gpu.c +58 -21
  38. data/vendor/scs/linsys/gpu/gpu.h +70 -35
  39. data/vendor/scs/linsys/gpu/indirect/private.c +394 -157
  40. data/vendor/scs/linsys/gpu/indirect/private.h +27 -12
  41. data/vendor/scs/linsys/scs_matrix.c +478 -0
  42. data/vendor/scs/linsys/scs_matrix.h +70 -0
  43. data/vendor/scs/scs.mk +14 -10
  44. data/vendor/scs/src/aa.c +394 -110
  45. data/vendor/scs/src/cones.c +497 -359
  46. data/vendor/scs/src/ctrlc.c +15 -5
  47. data/vendor/scs/src/linalg.c +107 -26
  48. data/vendor/scs/src/normalize.c +30 -72
  49. data/vendor/scs/src/rw.c +202 -27
  50. data/vendor/scs/src/scs.c +769 -571
  51. data/vendor/scs/src/scs_version.c +11 -3
  52. data/vendor/scs/src/util.c +37 -106
  53. data/vendor/scs/test/minunit.h +22 -8
  54. data/vendor/scs/test/problem_utils.h +180 -25
  55. data/vendor/scs/test/problems/degenerate.h +130 -0
  56. data/vendor/scs/test/problems/hs21_tiny_qp.h +124 -0
  57. data/vendor/scs/test/problems/hs21_tiny_qp_rw.h +116 -0
  58. data/vendor/scs/test/problems/infeasible_tiny_qp.h +100 -0
  59. data/vendor/scs/test/problems/qafiro_tiny_qp.h +199 -0
  60. data/vendor/scs/test/problems/random_prob +0 -0
  61. data/vendor/scs/test/problems/random_prob.h +45 -0
  62. data/vendor/scs/test/problems/rob_gauss_cov_est.h +188 -31
  63. data/vendor/scs/test/problems/small_lp.h +14 -13
  64. data/vendor/scs/test/problems/small_qp.h +352 -0
  65. data/vendor/scs/test/problems/test_validation.h +43 -0
  66. data/vendor/scs/test/problems/unbounded_tiny_qp.h +82 -0
  67. data/vendor/scs/test/random_socp_prob.c +54 -53
  68. data/vendor/scs/test/rng.h +109 -0
  69. data/vendor/scs/test/run_from_file.c +20 -11
  70. data/vendor/scs/test/run_tests.c +35 -2
  71. metadata +29 -98
  72. data/vendor/scs/linsys/amatrix.c +0 -305
  73. data/vendor/scs/linsys/amatrix.h +0 -36
  74. data/vendor/scs/linsys/amatrix.o +0 -0
  75. data/vendor/scs/linsys/cpu/direct/private.o +0 -0
  76. data/vendor/scs/linsys/cpu/indirect/private.o +0 -0
  77. data/vendor/scs/linsys/external/amd/SuiteSparse_config.o +0 -0
  78. data/vendor/scs/linsys/external/amd/amd_1.o +0 -0
  79. data/vendor/scs/linsys/external/amd/amd_2.o +0 -0
  80. data/vendor/scs/linsys/external/amd/amd_aat.o +0 -0
  81. data/vendor/scs/linsys/external/amd/amd_control.o +0 -0
  82. data/vendor/scs/linsys/external/amd/amd_defaults.o +0 -0
  83. data/vendor/scs/linsys/external/amd/amd_dump.o +0 -0
  84. data/vendor/scs/linsys/external/amd/amd_global.o +0 -0
  85. data/vendor/scs/linsys/external/amd/amd_info.o +0 -0
  86. data/vendor/scs/linsys/external/amd/amd_order.o +0 -0
  87. data/vendor/scs/linsys/external/amd/amd_post_tree.o +0 -0
  88. data/vendor/scs/linsys/external/amd/amd_postorder.o +0 -0
  89. data/vendor/scs/linsys/external/amd/amd_preprocess.o +0 -0
  90. data/vendor/scs/linsys/external/amd/amd_valid.o +0 -0
  91. data/vendor/scs/linsys/external/qdldl/qdldl.o +0 -0
  92. data/vendor/scs/src/aa.o +0 -0
  93. data/vendor/scs/src/cones.o +0 -0
  94. data/vendor/scs/src/ctrlc.o +0 -0
  95. data/vendor/scs/src/linalg.o +0 -0
  96. data/vendor/scs/src/normalize.o +0 -0
  97. data/vendor/scs/src/rw.o +0 -0
  98. data/vendor/scs/src/scs.o +0 -0
  99. data/vendor/scs/src/scs_version.o +0 -0
  100. data/vendor/scs/src/util.o +0 -0
  101. data/vendor/scs/test/data/small_random_socp +0 -0
  102. data/vendor/scs/test/problems/small_random_socp.h +0 -33
  103. data/vendor/scs/test/run_tests +0 -2
@@ -1,5 +1,13 @@
1
+ #ifdef __cplusplus
2
+ extern "C" {
3
+ #endif
4
+
1
5
  #include "glbopts.h"
2
6
 
3
- const char *SCS(version)(void) { return SCS_VERSION; }
4
- size_t SCS(sizeof_int)(void) { return sizeof(scs_int); }
5
- size_t SCS(sizeof_float)(void) { return sizeof(scs_float); }
7
+ const char *scs_version(void) {
8
+ return SCS_VERSION;
9
+ }
10
+
11
+ #ifdef __cplusplus
12
+ }
13
+ #endif
@@ -2,12 +2,16 @@
2
2
 
3
3
  #include "glbopts.h"
4
4
  #include "linsys.h"
5
+ #include "scs_matrix.h"
5
6
 
6
7
  /* return milli-seconds */
7
8
  #if (defined NOTIMER)
8
9
 
9
- void SCS(tic)(SCS(timer) * t) {}
10
- scs_float SCS(tocq)(SCS(timer) * t) { return NAN; }
10
+ void SCS(tic)(SCS(timer) * t) {
11
+ }
12
+ scs_float SCS(tocq)(SCS(timer) * t) {
13
+ return NAN;
14
+ }
11
15
 
12
16
  #elif (defined _WIN32 || _WIN64 || defined _WINDLL)
13
17
 
@@ -46,7 +50,9 @@ scs_float SCS(tocq)(SCS(timer) * t) {
46
50
 
47
51
  #else
48
52
 
49
- void SCS(tic)(SCS(timer) * t) { clock_gettime(CLOCK_MONOTONIC, &t->tic); }
53
+ void SCS(tic)(SCS(timer) * t) {
54
+ clock_gettime(CLOCK_MONOTONIC, &t->tic);
55
+ }
50
56
 
51
57
  scs_float SCS(tocq)(SCS(timer) * t) {
52
58
  struct timespec temp;
@@ -65,109 +71,29 @@ scs_float SCS(tocq)(SCS(timer) * t) {
65
71
 
66
72
  #endif
67
73
 
68
- scs_float SCS(toc)(SCS(timer) * t) {
69
- scs_float time = SCS(tocq)(t);
70
- scs_printf("time: %8.4f milli-seconds.\n", time);
71
- return time;
72
- }
73
-
74
- scs_float SCS(str_toc)(char *str, SCS(timer) * t) {
75
- scs_float time = SCS(tocq)(t);
76
- scs_printf("%s - time: %8.4f milli-seconds.\n", str, time);
77
- return time;
78
- }
79
-
80
- void SCS(print_cone_data)(const ScsCone *k) {
81
- scs_int i;
82
- scs_printf("num zeros = %i\n", (int)k->f);
83
- scs_printf("num LP = %i\n", (int)k->l);
84
- scs_printf("num SOCs = %i\n", (int)k->qsize);
85
- scs_printf("soc array:\n");
86
- for (i = 0; i < k->qsize; i++) {
87
- scs_printf("%i\n", (int)k->q[i]);
88
- }
89
- scs_printf("num SDCs = %i\n", (int)k->ssize);
90
- scs_printf("sdc array:\n");
91
- for (i = 0; i < k->ssize; i++) {
92
- scs_printf("%i\n", (int)k->s[i]);
93
- }
94
- scs_printf("num ep = %i\n", (int)k->ep);
95
- scs_printf("num ed = %i\n", (int)k->ed);
96
- scs_printf("num PCs = %i\n", (int)k->psize);
97
- scs_printf("pow array:\n");
98
- for (i = 0; i < k->psize; i++) {
99
- scs_printf("%4f\n", (double)k->p[i]);
100
- }
101
- }
102
-
103
- void SCS(print_work)(const ScsWork *w) {
104
- scs_int i, l = w->n + w->m;
105
- scs_printf("\n u_t is \n");
106
- for (i = 0; i < l; i++) {
107
- scs_printf("%f\n", w->u_t[i]);
108
- }
109
- scs_printf("\n u is \n");
110
- for (i = 0; i < l; i++) {
111
- scs_printf("%f\n", w->u[i]);
112
- }
113
- scs_printf("\n v is \n");
114
- for (i = 0; i < l; i++) {
115
- scs_printf("%f\n", w->v[i]);
116
- }
117
- }
118
-
119
- void SCS(print_data)(const ScsData *d) {
120
- scs_printf("m = %i\n", (int)d->m);
121
- scs_printf("n = %i\n", (int)d->n);
122
-
123
- scs_printf("max_iters = %i\n", (int)d->stgs->max_iters);
124
- scs_printf("verbose = %i\n", (int)d->stgs->verbose);
125
- scs_printf("normalize = %i\n", (int)d->stgs->normalize);
126
- scs_printf("warm_start = %i\n", (int)d->stgs->warm_start);
127
- scs_printf("acceleration_lookback = %i\n",
128
- (int)d->stgs->acceleration_lookback);
129
- scs_printf("eps = %4f\n", d->stgs->eps);
130
- scs_printf("alpha = %4f\n", d->stgs->alpha);
131
- scs_printf("rho_x = %4f\n", d->stgs->rho_x);
132
- scs_printf("cg_rate = %4f\n", d->stgs->cg_rate);
133
- scs_printf("scale = %4f\n", d->stgs->scale);
134
- scs_printf("write_data_filename = %s\n",
135
- (char *)d->stgs->write_data_filename);
136
- }
137
-
138
- void SCS(print_array)(const scs_float *arr, scs_int n, const char *name) {
139
- scs_int i, j, k = 0;
140
- scs_int num_on_one_line = 10;
141
- scs_printf("\n");
142
- for (i = 0; i < n / num_on_one_line; ++i) {
143
- for (j = 0; j < num_on_one_line; ++j) {
144
- scs_printf("%s[%li] = %4f, ", name, (long)k, arr[k]);
145
- k++;
146
- }
147
- scs_printf("\n");
148
- }
149
- for (j = k; j < n; ++j) {
150
- scs_printf("%s[%li] = %4f, ", name, (long)j, arr[j]);
151
- }
152
- scs_printf("\n");
153
- }
154
-
155
- void SCS(free_data)(ScsData *d, ScsCone *k) {
74
+ void SCS(free_data)(ScsData *d, ScsCone *k, ScsSettings *stgs) {
156
75
  if (d) {
157
76
  scs_free(d->b);
158
77
  scs_free(d->c);
159
- scs_free(d->stgs);
160
78
  if (d->A) {
161
- SCS(free_a_matrix)(d->A);
79
+ SCS(free_scs_matrix)(d->A);
80
+ }
81
+ if (d->P) {
82
+ SCS(free_scs_matrix)(d->P);
162
83
  }
163
84
  scs_free(d);
164
85
  }
165
86
  if (k) {
87
+ scs_free(k->bu);
88
+ scs_free(k->bl);
166
89
  scs_free(k->q);
167
90
  scs_free(k->s);
168
91
  scs_free(k->p);
169
92
  scs_free(k);
170
93
  }
94
+ if (stgs) {
95
+ scs_free(stgs);
96
+ }
171
97
  }
172
98
 
173
99
  void SCS(free_sol)(ScsSolution *sol) {
@@ -179,18 +105,23 @@ void SCS(free_sol)(ScsSolution *sol) {
179
105
  }
180
106
  }
181
107
 
182
- /* assumes d->stgs already allocated memory */
183
- void SCS(set_default_settings)(ScsData *d) {
108
+ /* assumes stgs already allocated memory */
109
+ void scs_set_default_settings(ScsSettings *stgs) {
184
110
  /* These constants are defined in include/glbopts.h */
185
- d->stgs->max_iters = MAX_ITERS;
186
- d->stgs->eps = EPS;
187
- d->stgs->alpha = ALPHA;
188
- d->stgs->rho_x = RHO_X;
189
- d->stgs->scale = SCALE;
190
- d->stgs->cg_rate = CG_RATE;
191
- d->stgs->verbose = VERBOSE;
192
- d->stgs->normalize = NORMALIZE;
193
- d->stgs->warm_start = WARM_START;
194
- d->stgs->acceleration_lookback = ACCELERATION_LOOKBACK;
195
- d->stgs->write_data_filename = WRITE_DATA_FILENAME;
111
+ stgs->max_iters = MAX_ITERS;
112
+ stgs->eps_abs = EPS_ABS;
113
+ stgs->eps_rel = EPS_REL;
114
+ stgs->eps_infeas = EPS_INFEAS;
115
+ stgs->alpha = ALPHA;
116
+ stgs->rho_x = RHO_X;
117
+ stgs->scale = SCALE;
118
+ stgs->verbose = VERBOSE;
119
+ stgs->normalize = NORMALIZE;
120
+ stgs->warm_start = WARM_START;
121
+ stgs->acceleration_lookback = ACCELERATION_LOOKBACK;
122
+ stgs->acceleration_interval = ACCELERATION_INTERVAL;
123
+ stgs->adaptive_scale = ADAPTIVE_SCALE;
124
+ stgs->write_data_filename = WRITE_DATA_FILENAME;
125
+ stgs->log_csv_filename = LOG_CSV_FILENAME;
126
+ stgs->time_limit_secs = TIME_LIMIT_SECS;
196
127
  }
@@ -1,13 +1,27 @@
1
1
  /* Taken from http://www.jera.com/techinfo/jtns/jtn002.html */
2
2
 
3
3
  /* Simple Macros for testing */
4
- #define mu_assert(message, test) \
5
- do { \
6
- if (!(test)) return message; \
4
+ #define mu_assert_less(message, a, b) \
5
+ do { \
6
+ if (a > b) { \
7
+ scs_printf("%s: %1.3e > %1.3e\n", message, a, b); \
8
+ return message; \
9
+ } \
7
10
  } while (0)
8
- #define mu_run_test(test) \
9
- do { \
10
- const char *message = test(); \
11
- tests_run++; \
12
- if (message) return message; \
11
+ #define mu_assert(message, test) \
12
+ do { \
13
+ if (!(test)) \
14
+ return message; \
15
+ } while (0)
16
+ #define mu_run_test(test) _mu_run_test(#test, test)
17
+
18
+ #define _mu_run_test(name, test) \
19
+ do { \
20
+ scs_printf("*********************************************************\n"); \
21
+ scs_printf("Running test: %s\n", name); \
22
+ const char *message = test(); \
23
+ tests_run++; \
24
+ scs_printf("*********************************************************\n"); \
25
+ if (message) \
26
+ return message; \
13
27
  } while (0)
@@ -1,34 +1,24 @@
1
1
  #ifndef PUTILS_H_GUARD
2
2
  #define PUTILS_H_GUARD
3
3
 
4
- #include "amatrix.h"
5
4
  #include "cones.h"
6
5
  #include "linalg.h"
6
+ #include "linsys.h"
7
+ #include "minunit.h"
8
+ #include "rng.h"
7
9
  #include "scs.h"
10
+ #include "scs_matrix.h"
8
11
  #include "util.h"
9
12
 
10
- #define PI (3.141592654)
11
- #ifdef DLONG
12
- #ifdef _WIN64
13
- /* this is a Microsoft extension, but also works with min_g_w-w64 */
14
- #define INTRW "%I64d"
15
- #else
16
- #define INTRW "%ld"
17
- #endif
18
- #else
19
- #define INTRW "%i"
20
- #endif
21
-
22
- void gen_random_prob_data(scs_int nnz, scs_int col_nnz, ScsData *d, ScsCone *k,
23
- ScsSolution *opt_sol);
13
+ #define _MAX_RAND_VAL (1073741823) /* 2^30 - 1 */
24
14
 
25
15
  /* uniform random number in [-1,1] */
26
16
  static scs_float rand_scs_float(void) {
27
- return 2 * (((scs_float)rand()) / RAND_MAX) - 1;
17
+ return 2 * (((scs_float)ran_arr_next()) / _MAX_RAND_VAL) - 1; /* in [-1, 1] */
28
18
  }
29
19
 
30
20
  void gen_random_prob_data(scs_int nnz, scs_int col_nnz, ScsData *d, ScsCone *k,
31
- ScsSolution *opt_sol) {
21
+ ScsSolution *opt_sol, scs_int seed) {
32
22
  scs_int n = d->n;
33
23
  scs_int m = d->m;
34
24
  ScsMatrix *A = d->A = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
@@ -39,6 +29,7 @@ void gen_random_prob_data(scs_int nnz, scs_int col_nnz, ScsData *d, ScsCone *k,
39
29
  scs_float *s = opt_sol->s = (scs_float *)scs_calloc(m, sizeof(scs_float));
40
30
  /* temporary variables */
41
31
  scs_float *z = (scs_float *)scs_calloc(m, sizeof(scs_float));
32
+ ScsConeWork *tmp_cone_work;
42
33
  scs_int i, j, r, rn, rm;
43
34
 
44
35
  A->i = (scs_int *)scs_calloc(nnz, sizeof(scs_int));
@@ -50,8 +41,9 @@ void gen_random_prob_data(scs_int nnz, scs_int col_nnz, ScsData *d, ScsCone *k,
50
41
  for (i = 0; i < m; i++) {
51
42
  y[i] = z[i] = rand_scs_float();
52
43
  }
53
-
54
- SCS(proj_dual_cone)(y, k, SCS_NULL, SCS_NULL, -1);
44
+ tmp_cone_work = SCS(init_cone)(k, m);
45
+ SCS(proj_dual_cone)(y, tmp_cone_work, SCS_NULL, SCS_NULL);
46
+ SCS(finish_cone(tmp_cone_work));
55
47
 
56
48
  for (i = 0; i < m; i++) {
57
49
  b[i] = s[i] = y[i] - z[i];
@@ -65,18 +57,15 @@ void gen_random_prob_data(scs_int nnz, scs_int col_nnz, ScsData *d, ScsCone *k,
65
57
  c = -A'*y
66
58
  b = A*x + s
67
59
  */
60
+ ran_start(seed);
68
61
  A->p[0] = 0;
69
- scs_printf("Generating random matrix:\n");
70
62
  for (j = 0; j < n; j++) { /* column */
71
- if (j * 100 % n == 0 && (j * 100 / n) % 10 == 0) {
72
- scs_printf("%ld%%\n", (long)(j * 100 / n));
73
- }
74
63
  r = 0;
75
64
  for (i = 0; i < m && r < col_nnz; ++i) {
76
65
  /* generate a unique sorted array via Knuths alg */
77
66
  rn = m - i;
78
67
  rm = col_nnz - r;
79
- if ((rand() % rn) < rm) {
68
+ if ((ran_arr_next() % rn) < rm) {
80
69
  A->x[r + j * col_nnz] = rand_scs_float();
81
70
  A->i[r + j * col_nnz] = i;
82
71
  b[i] += A->x[r + j * col_nnz] * x[j];
@@ -86,8 +75,174 @@ void gen_random_prob_data(scs_int nnz, scs_int col_nnz, ScsData *d, ScsCone *k,
86
75
  }
87
76
  A->p[j + 1] = (j + 1) * col_nnz;
88
77
  }
89
- scs_printf("done\n");
90
78
  scs_free(z);
91
79
  }
92
80
 
81
+ static scs_float get_dual_cone_dist(const scs_float *y, ScsConeWork *c,
82
+ scs_int m) {
83
+ scs_float dist;
84
+ scs_float *t = (scs_float *)scs_calloc(m, sizeof(scs_float));
85
+ memcpy(t, y, m * sizeof(scs_float));
86
+ SCS(proj_dual_cone)(t, c, SCS_NULL, SCS_NULL);
87
+ dist = SCS(norm_inf_diff)(t, y, m);
88
+ scs_free(t);
89
+ return dist;
90
+ }
91
+
92
+ /* via moreau */
93
+ static scs_float get_pri_cone_dist(const scs_float *s, ScsConeWork *c,
94
+ scs_int m) {
95
+ scs_float dist;
96
+ scs_float *t = (scs_float *)scs_calloc(m, sizeof(scs_float));
97
+ memcpy(t, s, m * sizeof(scs_float));
98
+ SCS(scale_array)(t, -1.0, m);
99
+ SCS(proj_dual_cone)(t, c, SCS_NULL, SCS_NULL);
100
+ dist = SCS(norm_inf)(t, m); /* ||s - Pi_c(s)|| = ||Pi_c*(-s)|| */
101
+ scs_free(t);
102
+ return dist;
103
+ }
104
+
105
+ const char *verify_solution_correct(ScsData *d, ScsCone *k, ScsSettings *stgs,
106
+ ScsInfo *info, ScsSolution *sol,
107
+ scs_int status) {
108
+ scs_int n = d->n, m = d->m;
109
+ scs_float *x = sol->x;
110
+ scs_float *y = sol->y;
111
+ scs_float *s = sol->s;
112
+
113
+ scs_float *c = d->c;
114
+ scs_float *b = d->b;
115
+
116
+ scs_float *primal = (scs_float *)scs_calloc(m, sizeof(scs_float));
117
+ scs_float *ax = (scs_float *)scs_calloc(m, sizeof(scs_float));
118
+ scs_float *dual = (scs_float *)scs_calloc(n, sizeof(scs_float));
119
+ scs_float *px = (scs_float *)scs_calloc(n, sizeof(scs_float));
120
+ scs_float *aty = (scs_float *)scs_calloc(n, sizeof(scs_float));
121
+
122
+ scs_float res_pri, res_dual, res_infeas, res_unbdd_a, res_unbdd_p;
123
+ scs_float ctx, bty, xt_p_x, gap, pobj, dobj, sty;
124
+ scs_float grl, prl, drl;
125
+
126
+ scs_float sdist = NAN, ydist = NAN;
127
+
128
+ ScsConeWork *cone_work = SCS(init_cone)(k, m);
129
+
130
+ /**************** PRIMAL *********************/
131
+ memset(ax, 0, m * sizeof(scs_float));
132
+ /* Ax */
133
+ SCS(accum_by_a)(d->A, x, ax);
134
+
135
+ memcpy(primal, ax, m * sizeof(scs_float));
136
+ /* Ax + s */
137
+ SCS(add_scaled_array)(primal, s, m, 1.);
138
+
139
+ /* unbounded residual |Ax + s| */
140
+ res_unbdd_a = NORM(primal, m);
141
+
142
+ /* Ax + s - b */
143
+ SCS(add_scaled_array)(primal, b, m, -1.0);
144
+
145
+ res_pri = NORM(primal, m);
146
+
147
+ /**************** DUAL *********************/
148
+ memset(px, 0, n * sizeof(scs_float));
149
+ if (d->P) {
150
+ /* px = Px */
151
+ SCS(accum_by_p)(d->P, x, px);
152
+ xt_p_x = SCS(dot)(px, x, n);
153
+ res_unbdd_p = NORM(px, n);
154
+ } else {
155
+ xt_p_x = 0;
156
+ res_unbdd_p = 0;
157
+ }
158
+
159
+ memset(aty, 0, n * sizeof(scs_float));
160
+ /* aty = A'y */
161
+ SCS(accum_by_atrans)(d->A, y, aty);
162
+ res_infeas = NORM(aty, n);
163
+
164
+ memcpy(dual, aty, n * sizeof(scs_float));
165
+ /* Px + A'y */
166
+ SCS(add_scaled_array)(dual, px, n, 1.);
167
+ /* Px + A'y + c */
168
+ SCS(add_scaled_array)(dual, c, n, 1.0);
169
+
170
+ res_dual = NORM(dual, n);
171
+
172
+ /**************** CONES *****************/
173
+
174
+ if (status == SCS_SOLVED || status == SCS_UNBOUNDED) {
175
+ sdist = get_pri_cone_dist(sol->s, cone_work, m);
176
+ }
177
+ if (status == SCS_SOLVED || status == SCS_INFEASIBLE) {
178
+ ydist = get_dual_cone_dist(sol->y, cone_work, m);
179
+ }
180
+
181
+ /**************** OTHERS *****************/
182
+ sty = SCS(dot)(y, s, m);
183
+
184
+ bty = SCS(dot)(y, b, m);
185
+ ctx = SCS(dot)(x, c, n);
186
+
187
+ gap = ABS(xt_p_x + ctx + bty);
188
+ pobj = xt_p_x / 2. + ctx;
189
+ dobj = -xt_p_x / 2. - bty;
190
+
191
+ /************** OPTIMALITY ****************/
192
+
193
+ grl = MAX(MAX(ABS(xt_p_x), ABS(ctx)), ABS(bty));
194
+ prl = MAX(MAX(NORM(b, m), NORM(s, m)), NORM(ax, m));
195
+ drl = MAX(MAX(NORM(c, n), NORM(px, n)), NORM(aty, n));
196
+
197
+ /**************** CLEANUP *****************/
198
+ scs_free(primal);
199
+ scs_free(dual);
200
+ scs_free(px);
201
+ scs_free(ax);
202
+ scs_free(aty);
203
+ SCS(finish_cone)(cone_work);
204
+
205
+ /**************** ASSERTS *****************/
206
+ if (status == SCS_SOLVED) {
207
+ mu_assert_less("Primal residual ERROR", ABS(res_pri - info->res_pri),
208
+ 1e-11);
209
+ mu_assert_less("Dual residual ERROR", ABS(res_dual - info->res_dual),
210
+ 1e-11);
211
+ mu_assert_less("Gap ERROR", ABS(gap - info->gap), 1e-8 * (1 + ABS(gap)));
212
+ mu_assert_less("Primal obj ERROR", ABS(pobj - info->pobj),
213
+ 1e-9 * (1 + ABS(pobj)));
214
+ mu_assert_less("Dual obj ERROR", ABS(dobj - info->dobj),
215
+ 1e-9 * (1 + ABS(dobj)));
216
+ /* slightly looser tol */
217
+ mu_assert_less("Complementary slackness ERROR", ABS(sty),
218
+ 1e-8 * MAX(NORM(s, m), NORM(y, m)));
219
+ mu_assert_less("s cone dist ERROR", ABS(sdist), 1e-5);
220
+ mu_assert_less("y cone dist ERROR", ABS(ydist), 1e-5);
221
+
222
+ mu_assert_less("Primal feas ERROR", res_pri,
223
+ stgs->eps_abs + stgs->eps_rel * prl);
224
+ mu_assert_less("Dual feas ERROR", res_dual,
225
+ stgs->eps_abs + stgs->eps_rel * drl);
226
+ mu_assert_less("Gap feas ERROR", gap, stgs->eps_abs + stgs->eps_rel * grl);
227
+
228
+ } else if (status == SCS_INFEASIBLE) {
229
+ mu_assert_less("Infeas ERROR", ABS(res_infeas - info->res_infeas), 1e-8);
230
+ mu_assert_less("bty ERROR", ABS(bty + 1), 1e-12);
231
+ mu_assert_less("y cone dist ERROR", ABS(ydist), 1e-5);
232
+ mu_assert_less("Infeas invalid ERROR", res_infeas, stgs->eps_infeas);
233
+
234
+ } else if (status == SCS_UNBOUNDED) {
235
+ mu_assert_less("Unbdd_a ERROR", ABS(res_unbdd_a - info->res_unbdd_a), 1e-8);
236
+ mu_assert_less("Unbdd_p ERROR", ABS(res_unbdd_p - info->res_unbdd_p), 1e-8);
237
+ mu_assert_less("ctx ERROR", ABS(ctx + 1), 1e-12);
238
+ mu_assert_less("s cone dist ERROR", ABS(sdist), 1e-5);
239
+ mu_assert_less("Unbounded P invalid ERROR", res_unbdd_p, stgs->eps_infeas);
240
+ mu_assert_less("Unbounded A invalid ERROR", res_unbdd_a, stgs->eps_infeas);
241
+
242
+ } else {
243
+ return "INVALID STATUS";
244
+ }
245
+ return 0;
246
+ }
247
+
93
248
  #endif
@@ -0,0 +1,130 @@
1
+ #include "glbopts.h"
2
+ #include "linalg.h"
3
+ #include "minunit.h"
4
+ #include "scs.h"
5
+ #include "scs_matrix.h"
6
+ #include "util.h"
7
+
8
+ /* test degenerate cones */
9
+ static const char *degenerate(void) {
10
+ ScsCone *k = (ScsCone *)scs_calloc(1, sizeof(ScsCone));
11
+ ScsData *d = (ScsData *)scs_calloc(1, sizeof(ScsData));
12
+ ScsSettings *stgs = (ScsSettings *)scs_calloc(1, sizeof(ScsSettings));
13
+ ScsSolution *sol = (ScsSolution *)scs_calloc(1, sizeof(ScsSolution));
14
+ ScsInfo info = {0};
15
+ scs_int exitflag, success;
16
+ scs_float tpobj, tdobj, perr, derr;
17
+ const char *fail;
18
+
19
+ /* data */
20
+ scs_float Ax[] = {-10., -1., 1., -1.};
21
+ scs_int Ai[] = {1, 2, 1, 3};
22
+ scs_int Ap[] = {0, 2, 4};
23
+
24
+ scs_float Px[] = {0.02, 2.};
25
+ scs_int Pi[] = {0, 1};
26
+ scs_int Pp[] = {0, 1, 2};
27
+
28
+ scs_float b[] = {1., -1., 2., -0.5};
29
+ scs_float c[] = {1., 2.};
30
+
31
+ scs_int m = 4;
32
+ scs_int n = 2;
33
+
34
+ /* used later: */
35
+ scs_int sq[] = {1};
36
+
37
+ /* end data */
38
+
39
+ d->m = m;
40
+ d->n = n;
41
+ d->b = b;
42
+ d->c = c;
43
+
44
+ d->A = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
45
+ d->P = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
46
+
47
+ d->A->m = m;
48
+ d->A->n = n;
49
+
50
+ d->A->x = Ax;
51
+ d->A->i = Ai;
52
+ d->A->p = Ap;
53
+
54
+ d->P->m = n;
55
+ d->P->n = n;
56
+
57
+ d->P->x = Px;
58
+ d->P->i = Pi;
59
+ d->P->p = Pp;
60
+
61
+ scs_set_default_settings(stgs);
62
+ stgs->eps_abs = 1e-6;
63
+ stgs->eps_rel = 1e-6;
64
+ stgs->eps_infeas = 1e-9;
65
+
66
+ /* positive orthants */
67
+ k->l = 4;
68
+ exitflag = scs(d, k, stgs, sol, &info);
69
+ fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
70
+ if (fail) {
71
+ return fail;
72
+ }
73
+ mu_assert("bsize: SCS failed to produce outputflag SCS_SOLVED",
74
+ exitflag == SCS_SOLVED);
75
+
76
+ tpobj = info.pobj;
77
+ tdobj = info.dobj;
78
+
79
+ /* degenerate box cone */
80
+ k->bsize = 1;
81
+ k->l = 3;
82
+ exitflag = scs(d, k, stgs, sol, &info);
83
+ fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
84
+ if (fail) {
85
+ return fail;
86
+ }
87
+ perr = info.pobj - tpobj;
88
+ derr = info.dobj - tdobj;
89
+ success = ABS(perr) < 1e-8 && ABS(derr) < 1e-8 && exitflag == SCS_SOLVED;
90
+ mu_assert("degenerate box cone failure", success);
91
+
92
+ /* degenerate SOC cone */
93
+ k->bsize = 0;
94
+ k->q = sq;
95
+ k->qsize = 1;
96
+ k->l = 3;
97
+ exitflag = scs(d, k, stgs, sol, &info);
98
+ fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
99
+ if (fail) {
100
+ return fail;
101
+ }
102
+ perr = info.pobj - tpobj;
103
+ derr = info.dobj - tdobj;
104
+ success = ABS(perr) < 1e-8 && ABS(derr) < 1e-8 && exitflag == SCS_SOLVED;
105
+ mu_assert("degenerate SOC cone failure", success);
106
+
107
+ /* degenerate PSD cone */
108
+ k->q = 0;
109
+ k->qsize = 0;
110
+ k->s = sq;
111
+ k->ssize = 1;
112
+ k->l = 3;
113
+ exitflag = scs(d, k, stgs, sol, &info);
114
+ fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
115
+ if (fail) {
116
+ return fail;
117
+ }
118
+ perr = info.pobj - tpobj;
119
+ derr = info.dobj - tdobj;
120
+ success = ABS(perr) < 1e-8 && ABS(derr) < 1e-8 && exitflag == SCS_SOLVED;
121
+ mu_assert("degenerate PSD cone failure", success);
122
+
123
+ SCS(free_sol)(sol);
124
+ scs_free(d->A);
125
+ scs_free(d->P);
126
+ scs_free(k);
127
+ scs_free(stgs);
128
+ scs_free(d);
129
+ return fail;
130
+ }