scs 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }