scs 0.2.3 → 0.3.0

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 (100) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/README.md +11 -6
  4. data/lib/scs/ffi.rb +30 -13
  5. data/lib/scs/solver.rb +32 -9
  6. data/lib/scs/version.rb +1 -1
  7. data/vendor/scs/CITATION.cff +39 -0
  8. data/vendor/scs/CMakeLists.txt +7 -8
  9. data/vendor/scs/Makefile +24 -15
  10. data/vendor/scs/README.md +5 -263
  11. data/vendor/scs/include/aa.h +67 -23
  12. data/vendor/scs/include/cones.h +17 -17
  13. data/vendor/scs/include/glbopts.h +98 -32
  14. data/vendor/scs/include/linalg.h +2 -4
  15. data/vendor/scs/include/linsys.h +58 -44
  16. data/vendor/scs/include/normalize.h +3 -3
  17. data/vendor/scs/include/rw.h +8 -2
  18. data/vendor/scs/include/scs.h +293 -133
  19. data/vendor/scs/include/util.h +3 -15
  20. data/vendor/scs/linsys/cpu/direct/private.c +220 -224
  21. data/vendor/scs/linsys/cpu/direct/private.h +13 -7
  22. data/vendor/scs/linsys/cpu/direct/private.o +0 -0
  23. data/vendor/scs/linsys/cpu/indirect/private.c +177 -110
  24. data/vendor/scs/linsys/cpu/indirect/private.h +8 -4
  25. data/vendor/scs/linsys/cpu/indirect/private.o +0 -0
  26. data/vendor/scs/linsys/csparse.c +87 -0
  27. data/vendor/scs/linsys/csparse.h +34 -0
  28. data/vendor/scs/linsys/csparse.o +0 -0
  29. data/vendor/scs/linsys/external/amd/SuiteSparse_config.c +1 -1
  30. data/vendor/scs/linsys/external/amd/SuiteSparse_config.o +0 -0
  31. data/vendor/scs/linsys/external/amd/amd_1.o +0 -0
  32. data/vendor/scs/linsys/external/amd/amd_2.o +0 -0
  33. data/vendor/scs/linsys/external/amd/amd_aat.o +0 -0
  34. data/vendor/scs/linsys/external/amd/amd_control.o +0 -0
  35. data/vendor/scs/linsys/external/amd/amd_defaults.o +0 -0
  36. data/vendor/scs/linsys/external/amd/amd_dump.o +0 -0
  37. data/vendor/scs/linsys/external/amd/amd_global.o +0 -0
  38. data/vendor/scs/linsys/external/amd/amd_info.o +0 -0
  39. data/vendor/scs/linsys/external/amd/amd_internal.h +1 -1
  40. data/vendor/scs/linsys/external/amd/amd_order.o +0 -0
  41. data/vendor/scs/linsys/external/amd/amd_post_tree.o +0 -0
  42. data/vendor/scs/linsys/external/amd/amd_postorder.o +0 -0
  43. data/vendor/scs/linsys/external/amd/amd_preprocess.o +0 -0
  44. data/vendor/scs/linsys/external/amd/amd_valid.o +0 -0
  45. data/vendor/scs/linsys/external/qdldl/changes +2 -0
  46. data/vendor/scs/linsys/external/qdldl/qdldl.c +29 -46
  47. data/vendor/scs/linsys/external/qdldl/qdldl.h +33 -41
  48. data/vendor/scs/linsys/external/qdldl/qdldl.o +0 -0
  49. data/vendor/scs/linsys/external/qdldl/qdldl_types.h +11 -3
  50. data/vendor/scs/linsys/gpu/gpu.c +31 -33
  51. data/vendor/scs/linsys/gpu/gpu.h +48 -31
  52. data/vendor/scs/linsys/gpu/indirect/private.c +338 -232
  53. data/vendor/scs/linsys/gpu/indirect/private.h +23 -14
  54. data/vendor/scs/linsys/scs_matrix.c +498 -0
  55. data/vendor/scs/linsys/scs_matrix.h +70 -0
  56. data/vendor/scs/linsys/scs_matrix.o +0 -0
  57. data/vendor/scs/scs.mk +13 -9
  58. data/vendor/scs/src/aa.c +384 -109
  59. data/vendor/scs/src/aa.o +0 -0
  60. data/vendor/scs/src/cones.c +440 -353
  61. data/vendor/scs/src/cones.o +0 -0
  62. data/vendor/scs/src/ctrlc.c +15 -5
  63. data/vendor/scs/src/ctrlc.o +0 -0
  64. data/vendor/scs/src/linalg.c +84 -28
  65. data/vendor/scs/src/linalg.o +0 -0
  66. data/vendor/scs/src/normalize.c +22 -64
  67. data/vendor/scs/src/normalize.o +0 -0
  68. data/vendor/scs/src/rw.c +160 -21
  69. data/vendor/scs/src/rw.o +0 -0
  70. data/vendor/scs/src/scs.c +767 -563
  71. data/vendor/scs/src/scs.o +0 -0
  72. data/vendor/scs/src/scs_indir.o +0 -0
  73. data/vendor/scs/src/scs_version.c +9 -3
  74. data/vendor/scs/src/scs_version.o +0 -0
  75. data/vendor/scs/src/util.c +37 -106
  76. data/vendor/scs/src/util.o +0 -0
  77. data/vendor/scs/test/minunit.h +17 -8
  78. data/vendor/scs/test/problem_utils.h +176 -14
  79. data/vendor/scs/test/problems/degenerate.h +130 -0
  80. data/vendor/scs/test/problems/hs21_tiny_qp.h +124 -0
  81. data/vendor/scs/test/problems/hs21_tiny_qp_rw.h +116 -0
  82. data/vendor/scs/test/problems/infeasible_tiny_qp.h +100 -0
  83. data/vendor/scs/test/problems/qafiro_tiny_qp.h +199 -0
  84. data/vendor/scs/test/problems/random_prob +0 -0
  85. data/vendor/scs/test/problems/random_prob.h +45 -0
  86. data/vendor/scs/test/problems/rob_gauss_cov_est.h +188 -31
  87. data/vendor/scs/test/problems/small_lp.h +13 -14
  88. data/vendor/scs/test/problems/test_fails.h +43 -0
  89. data/vendor/scs/test/problems/unbounded_tiny_qp.h +82 -0
  90. data/vendor/scs/test/random_socp_prob.c +54 -53
  91. data/vendor/scs/test/rng.h +109 -0
  92. data/vendor/scs/test/run_from_file.c +19 -10
  93. data/vendor/scs/test/run_tests.c +27 -3
  94. metadata +20 -8
  95. data/vendor/scs/linsys/amatrix.c +0 -305
  96. data/vendor/scs/linsys/amatrix.h +0 -36
  97. data/vendor/scs/linsys/amatrix.o +0 -0
  98. data/vendor/scs/test/data/small_random_socp +0 -0
  99. data/vendor/scs/test/problems/small_random_socp.h +0 -33
  100. data/vendor/scs/test/run_tests +0 -2
data/vendor/scs/src/scs.o CHANGED
Binary file
Binary file
@@ -1,5 +1,11 @@
1
1
  #include "glbopts.h"
2
2
 
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); }
3
+ const char *SCS(version)(void) {
4
+ return SCS_VERSION;
5
+ }
6
+ size_t SCS(sizeof_int)(void) {
7
+ return sizeof(scs_int);
8
+ }
9
+ size_t SCS(sizeof_float)(void) {
10
+ return sizeof(scs_float);
11
+ }
Binary file
@@ -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
  }
Binary file
@@ -1,13 +1,22 @@
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) \
17
+ do { \
18
+ const char *message = test(); \
19
+ tests_run++; \
20
+ if (message) \
21
+ return message; \
13
22
  } while (0)
@@ -1,10 +1,13 @@
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
13
  #define PI (3.141592654)
@@ -19,16 +22,13 @@
19
22
  #define INTRW "%i"
20
23
  #endif
21
24
 
22
- void gen_random_prob_data(scs_int nnz, scs_int col_nnz, ScsData *d, ScsCone *k,
23
- ScsSolution *opt_sol);
24
-
25
25
  /* uniform random number in [-1,1] */
26
26
  static scs_float rand_scs_float(void) {
27
- return 2 * (((scs_float)rand()) / RAND_MAX) - 1;
27
+ return 2 * (((scs_float)ran_arr_next()) / RAND_MAX) - 1;
28
28
  }
29
29
 
30
30
  void gen_random_prob_data(scs_int nnz, scs_int col_nnz, ScsData *d, ScsCone *k,
31
- ScsSolution *opt_sol) {
31
+ ScsSolution *opt_sol, scs_int seed) {
32
32
  scs_int n = d->n;
33
33
  scs_int m = d->m;
34
34
  ScsMatrix *A = d->A = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
@@ -39,6 +39,7 @@ void gen_random_prob_data(scs_int nnz, scs_int col_nnz, ScsData *d, ScsCone *k,
39
39
  scs_float *s = opt_sol->s = (scs_float *)scs_calloc(m, sizeof(scs_float));
40
40
  /* temporary variables */
41
41
  scs_float *z = (scs_float *)scs_calloc(m, sizeof(scs_float));
42
+ ScsConeWork *tmp_cone_work;
42
43
  scs_int i, j, r, rn, rm;
43
44
 
44
45
  A->i = (scs_int *)scs_calloc(nnz, sizeof(scs_int));
@@ -50,8 +51,9 @@ void gen_random_prob_data(scs_int nnz, scs_int col_nnz, ScsData *d, ScsCone *k,
50
51
  for (i = 0; i < m; i++) {
51
52
  y[i] = z[i] = rand_scs_float();
52
53
  }
53
-
54
- SCS(proj_dual_cone)(y, k, SCS_NULL, SCS_NULL, -1);
54
+ tmp_cone_work = SCS(init_cone)(k, SCS_NULL, m);
55
+ SCS(proj_dual_cone)(y, k, tmp_cone_work, 0);
56
+ SCS(finish_cone(tmp_cone_work));
55
57
 
56
58
  for (i = 0; i < m; i++) {
57
59
  b[i] = s[i] = y[i] - z[i];
@@ -65,18 +67,15 @@ void gen_random_prob_data(scs_int nnz, scs_int col_nnz, ScsData *d, ScsCone *k,
65
67
  c = -A'*y
66
68
  b = A*x + s
67
69
  */
70
+ ran_start(seed);
68
71
  A->p[0] = 0;
69
- scs_printf("Generating random matrix:\n");
70
72
  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
73
  r = 0;
75
74
  for (i = 0; i < m && r < col_nnz; ++i) {
76
75
  /* generate a unique sorted array via Knuths alg */
77
76
  rn = m - i;
78
77
  rm = col_nnz - r;
79
- if ((rand() % rn) < rm) {
78
+ if ((ran_arr_next() % rn) < rm) {
80
79
  A->x[r + j * col_nnz] = rand_scs_float();
81
80
  A->i[r + j * col_nnz] = i;
82
81
  b[i] += A->x[r + j * col_nnz] * x[j];
@@ -86,8 +85,171 @@ void gen_random_prob_data(scs_int nnz, scs_int col_nnz, ScsData *d, ScsCone *k,
86
85
  }
87
86
  A->p[j + 1] = (j + 1) * col_nnz;
88
87
  }
89
- scs_printf("done\n");
90
88
  scs_free(z);
91
89
  }
92
90
 
91
+ static scs_float get_dual_cone_dist(const scs_float *y, const ScsCone *k,
92
+ ScsConeWork *c, scs_int m) {
93
+ scs_float dist;
94
+ scs_float *t = (scs_float *)scs_calloc(m, sizeof(scs_float));
95
+ memcpy(t, y, m * sizeof(scs_float));
96
+ SCS(proj_dual_cone)(t, k, c, 0);
97
+ dist = SCS(norm_inf_diff)(t, y, m);
98
+ scs_free(t);
99
+ return dist;
100
+ }
101
+
102
+ /* via moreau */
103
+ static scs_float get_pri_cone_dist(const scs_float *s, const ScsCone *k,
104
+ ScsConeWork *c, scs_int m) {
105
+ scs_float dist;
106
+ scs_float *t = (scs_float *)scs_calloc(m, sizeof(scs_float));
107
+ memcpy(t, s, m * sizeof(scs_float));
108
+ SCS(scale_array)(t, -1.0, m);
109
+ SCS(proj_dual_cone)(t, k, c, 0);
110
+ dist = SCS(norm_inf)(t, m); /* ||s - Pi_c(s)|| = ||Pi_c*(-s)|| */
111
+ scs_free(t);
112
+ return dist;
113
+ }
114
+
115
+ const char *verify_solution_correct(ScsData *d, ScsCone *k, ScsSettings *stgs,
116
+ ScsInfo *info, ScsSolution *sol,
117
+ scs_int status) {
118
+ scs_int n = d->n, m = d->m;
119
+ scs_float *x = sol->x;
120
+ scs_float *y = sol->y;
121
+ scs_float *s = sol->s;
122
+
123
+ scs_float *c = d->c;
124
+ scs_float *b = d->b;
125
+
126
+ scs_float *primal = scs_calloc(m, sizeof(scs_float));
127
+ scs_float *ax = scs_calloc(m, sizeof(scs_float));
128
+ scs_float *dual = scs_calloc(n, sizeof(scs_float));
129
+ scs_float *px = scs_calloc(n, sizeof(scs_float));
130
+ scs_float *aty = scs_calloc(n, sizeof(scs_float));
131
+
132
+ scs_float res_pri, res_dual, res_infeas, res_unbdd_a, res_unbdd_p;
133
+ scs_float ctx, bty, xt_p_x, gap, pobj, dobj, sty;
134
+ scs_float grl, prl, drl;
135
+
136
+ scs_float sdist = NAN, ydist = NAN;
137
+
138
+ ScsConeWork *cone_work = SCS(init_cone)(k, SCS_NULL, m);
139
+
140
+ /**************** PRIMAL *********************/
141
+ memset(ax, 0, m * sizeof(scs_float));
142
+ /* Ax */
143
+ SCS(accum_by_a)(d->A, x, ax);
144
+
145
+ memcpy(primal, ax, m * sizeof(scs_float));
146
+ /* Ax + s */
147
+ SCS(add_scaled_array)(primal, s, m, 1.);
148
+
149
+ /* unbounded residual |Ax + s| */
150
+ res_unbdd_a = NORM(primal, m);
151
+
152
+ /* Ax + s - b */
153
+ SCS(add_scaled_array)(primal, b, m, -1.0);
154
+
155
+ res_pri = NORM(primal, m);
156
+
157
+ /**************** DUAL *********************/
158
+ memset(px, 0, n * sizeof(scs_float));
159
+ if (d->P) {
160
+ /* px = Px */
161
+ SCS(accum_by_p)(d->P, x, px);
162
+ xt_p_x = SCS(dot)(px, x, n);
163
+ res_unbdd_p = NORM(px, n);
164
+ } else {
165
+ xt_p_x = 0;
166
+ res_unbdd_p = 0;
167
+ }
168
+
169
+ memset(aty, 0, n * sizeof(scs_float));
170
+ /* aty = A'y */
171
+ SCS(accum_by_atrans)(d->A, y, aty);
172
+ res_infeas = NORM(aty, n);
173
+
174
+ memcpy(dual, aty, n * sizeof(scs_float));
175
+ /* Px + A'y */
176
+ SCS(add_scaled_array)(dual, px, n, 1.);
177
+ /* Px + A'y + c */
178
+ SCS(add_scaled_array)(dual, c, n, 1.0);
179
+
180
+ res_dual = NORM(dual, n);
181
+
182
+ /**************** CONES *****************/
183
+
184
+ if (status == SCS_SOLVED || status == SCS_UNBOUNDED) {
185
+ sdist = get_pri_cone_dist(sol->s, k, cone_work, m);
186
+ }
187
+ if (status == SCS_SOLVED || status == SCS_INFEASIBLE) {
188
+ ydist = get_dual_cone_dist(sol->y, k, cone_work, m);
189
+ }
190
+
191
+ /**************** OTHERS *****************/
192
+ sty = SCS(dot)(y, s, m);
193
+
194
+ bty = SCS(dot)(y, b, m);
195
+ ctx = SCS(dot)(x, c, n);
196
+
197
+ gap = ABS(xt_p_x + ctx + bty);
198
+ pobj = xt_p_x / 2. + ctx;
199
+ dobj = -xt_p_x / 2. - bty;
200
+
201
+ /************** OPTIMALITY ****************/
202
+
203
+ grl = MAX(MAX(ABS(xt_p_x), ABS(ctx)), ABS(bty));
204
+ prl = MAX(MAX(NORM(b, m), NORM(s, m)), NORM(ax, m));
205
+ drl = MAX(MAX(NORM(c, n), NORM(px, n)), NORM(aty, n));
206
+
207
+ /**************** CLEANUP *****************/
208
+ scs_free(primal);
209
+ scs_free(dual);
210
+ scs_free(px);
211
+ scs_free(ax);
212
+ scs_free(aty);
213
+ SCS(finish_cone)(cone_work);
214
+
215
+ /**************** ASSERTS *****************/
216
+ if (status == SCS_SOLVED) {
217
+ mu_assert_less("Primal residual ERROR", ABS(res_pri - info->res_pri),
218
+ 1e-12);
219
+ mu_assert_less("Dual residual ERROR", ABS(res_dual - info->res_dual),
220
+ 1e-12);
221
+ mu_assert_less("Gap ERROR", ABS(gap - info->gap), 1e-12);
222
+ mu_assert_less("Primal obj ERROR", ABS(pobj - info->pobj), 1e-12);
223
+ mu_assert_less("Dual obj ERROR", ABS(dobj - info->dobj), 1e-12);
224
+ /* slightly looser tol */
225
+ mu_assert_less("Complementary slackness ERROR", ABS(sty), 1e-6);
226
+ mu_assert_less("s cone dist ERROR", ABS(sdist), 1e-5);
227
+ mu_assert_less("y cone dist ERROR", ABS(ydist), 1e-5);
228
+
229
+ mu_assert_less("Primal feas ERROR", res_pri,
230
+ stgs->eps_abs + stgs->eps_rel * prl);
231
+ mu_assert_less("Dual feas ERROR", res_dual,
232
+ stgs->eps_abs + stgs->eps_rel * drl);
233
+ mu_assert_less("Gap ERROR", gap, stgs->eps_abs + stgs->eps_rel * grl);
234
+
235
+ } else if (status == SCS_INFEASIBLE) {
236
+ mu_assert_less("Infeas ERROR", ABS(res_infeas - info->res_infeas), 1e-8);
237
+ mu_assert_less("bty ERROR", ABS(bty + 1), 1e-12);
238
+ mu_assert_less("y cone dist ERROR", ABS(ydist), 1e-5);
239
+ mu_assert_less("Infeas invalid ERROR", res_infeas, stgs->eps_infeas);
240
+
241
+ } else if (status == SCS_UNBOUNDED) {
242
+ mu_assert_less("Unbdd_a ERROR", ABS(res_unbdd_a - info->res_unbdd_a), 1e-8);
243
+ mu_assert_less("Unbdd_p ERROR", ABS(res_unbdd_p - info->res_unbdd_p), 1e-8);
244
+ mu_assert_less("ctx ERROR", ABS(ctx + 1), 1e-12);
245
+ mu_assert_less("s cone dist ERROR", ABS(sdist), 1e-5);
246
+ mu_assert_less("Unbounded P invalid ERROR", res_unbdd_p, stgs->eps_infeas);
247
+ mu_assert_less("Unbounded A invalid ERROR", res_unbdd_a, stgs->eps_infeas);
248
+
249
+ } else {
250
+ return "INVALID STATUS";
251
+ }
252
+ return 0;
253
+ }
254
+
93
255
  #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
+ }