scs 0.2.3 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +11 -6
- data/lib/scs/ffi.rb +30 -13
- data/lib/scs/solver.rb +32 -9
- data/lib/scs/version.rb +1 -1
- data/vendor/scs/CITATION.cff +39 -0
- data/vendor/scs/CMakeLists.txt +7 -8
- data/vendor/scs/Makefile +24 -15
- data/vendor/scs/README.md +5 -263
- data/vendor/scs/include/aa.h +67 -23
- data/vendor/scs/include/cones.h +17 -17
- data/vendor/scs/include/glbopts.h +98 -32
- data/vendor/scs/include/linalg.h +2 -4
- data/vendor/scs/include/linsys.h +58 -44
- data/vendor/scs/include/normalize.h +3 -3
- data/vendor/scs/include/rw.h +8 -2
- data/vendor/scs/include/scs.h +293 -133
- data/vendor/scs/include/util.h +3 -15
- data/vendor/scs/linsys/cpu/direct/private.c +220 -224
- data/vendor/scs/linsys/cpu/direct/private.h +13 -7
- data/vendor/scs/linsys/cpu/direct/private.o +0 -0
- data/vendor/scs/linsys/cpu/indirect/private.c +177 -110
- data/vendor/scs/linsys/cpu/indirect/private.h +8 -4
- data/vendor/scs/linsys/cpu/indirect/private.o +0 -0
- data/vendor/scs/linsys/csparse.c +87 -0
- data/vendor/scs/linsys/csparse.h +34 -0
- data/vendor/scs/linsys/csparse.o +0 -0
- data/vendor/scs/linsys/external/amd/SuiteSparse_config.c +1 -1
- data/vendor/scs/linsys/external/amd/SuiteSparse_config.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_1.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_2.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_aat.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_control.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_defaults.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_dump.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_global.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_info.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_internal.h +1 -1
- data/vendor/scs/linsys/external/amd/amd_order.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_post_tree.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_postorder.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_preprocess.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_valid.o +0 -0
- data/vendor/scs/linsys/external/qdldl/changes +2 -0
- data/vendor/scs/linsys/external/qdldl/qdldl.c +29 -46
- data/vendor/scs/linsys/external/qdldl/qdldl.h +33 -41
- data/vendor/scs/linsys/external/qdldl/qdldl.o +0 -0
- data/vendor/scs/linsys/external/qdldl/qdldl_types.h +11 -3
- data/vendor/scs/linsys/gpu/gpu.c +31 -33
- data/vendor/scs/linsys/gpu/gpu.h +48 -31
- data/vendor/scs/linsys/gpu/indirect/private.c +338 -232
- data/vendor/scs/linsys/gpu/indirect/private.h +23 -14
- data/vendor/scs/linsys/scs_matrix.c +498 -0
- data/vendor/scs/linsys/scs_matrix.h +70 -0
- data/vendor/scs/linsys/scs_matrix.o +0 -0
- data/vendor/scs/scs.mk +13 -9
- data/vendor/scs/src/aa.c +384 -109
- data/vendor/scs/src/aa.o +0 -0
- data/vendor/scs/src/cones.c +440 -353
- data/vendor/scs/src/cones.o +0 -0
- data/vendor/scs/src/ctrlc.c +15 -5
- data/vendor/scs/src/ctrlc.o +0 -0
- data/vendor/scs/src/linalg.c +84 -28
- data/vendor/scs/src/linalg.o +0 -0
- data/vendor/scs/src/normalize.c +22 -64
- data/vendor/scs/src/normalize.o +0 -0
- data/vendor/scs/src/rw.c +160 -21
- data/vendor/scs/src/rw.o +0 -0
- data/vendor/scs/src/scs.c +767 -563
- data/vendor/scs/src/scs.o +0 -0
- data/vendor/scs/src/scs_indir.o +0 -0
- data/vendor/scs/src/scs_version.c +9 -3
- data/vendor/scs/src/scs_version.o +0 -0
- data/vendor/scs/src/util.c +37 -106
- data/vendor/scs/src/util.o +0 -0
- data/vendor/scs/test/minunit.h +17 -8
- data/vendor/scs/test/problem_utils.h +176 -14
- data/vendor/scs/test/problems/degenerate.h +130 -0
- data/vendor/scs/test/problems/hs21_tiny_qp.h +124 -0
- data/vendor/scs/test/problems/hs21_tiny_qp_rw.h +116 -0
- data/vendor/scs/test/problems/infeasible_tiny_qp.h +100 -0
- data/vendor/scs/test/problems/qafiro_tiny_qp.h +199 -0
- data/vendor/scs/test/problems/random_prob +0 -0
- data/vendor/scs/test/problems/random_prob.h +45 -0
- data/vendor/scs/test/problems/rob_gauss_cov_est.h +188 -31
- data/vendor/scs/test/problems/small_lp.h +13 -14
- data/vendor/scs/test/problems/test_fails.h +43 -0
- data/vendor/scs/test/problems/unbounded_tiny_qp.h +82 -0
- data/vendor/scs/test/random_socp_prob.c +54 -53
- data/vendor/scs/test/rng.h +109 -0
- data/vendor/scs/test/run_from_file.c +19 -10
- data/vendor/scs/test/run_tests.c +27 -3
- metadata +20 -8
- data/vendor/scs/linsys/amatrix.c +0 -305
- data/vendor/scs/linsys/amatrix.h +0 -36
- data/vendor/scs/linsys/amatrix.o +0 -0
- data/vendor/scs/test/data/small_random_socp +0 -0
- data/vendor/scs/test/problems/small_random_socp.h +0 -33
- 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) {
|
4
|
-
|
5
|
-
|
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
|
data/vendor/scs/src/util.c
CHANGED
@@ -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
|
-
|
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) {
|
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
|
-
|
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(
|
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
|
183
|
-
void SCS(set_default_settings)(
|
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
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
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
|
}
|
data/vendor/scs/src/util.o
CHANGED
Binary file
|
data/vendor/scs/test/minunit.h
CHANGED
@@ -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
|
5
|
-
do {
|
6
|
-
if (
|
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
|
9
|
-
do {
|
10
|
-
|
11
|
-
|
12
|
-
|
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)
|
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,
|
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 ((
|
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
|
+
}
|