scs 0.3.2 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +10 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +35 -6
  5. data/lib/scs/matrix.rb +72 -0
  6. data/lib/scs/solver.rb +19 -26
  7. data/lib/scs/version.rb +1 -1
  8. data/lib/scs.rb +1 -0
  9. data/vendor/scs/CITATION.cff +2 -2
  10. data/vendor/scs/CMakeLists.txt +285 -169
  11. data/vendor/scs/Makefile +43 -18
  12. data/vendor/scs/README.md +3 -1
  13. data/vendor/scs/include/cones.h +5 -3
  14. data/vendor/scs/include/glbopts.h +35 -17
  15. data/vendor/scs/include/linsys.h +8 -8
  16. data/vendor/scs/include/normalize.h +1 -0
  17. data/vendor/scs/include/rw.h +3 -3
  18. data/vendor/scs/include/scs.h +51 -24
  19. data/vendor/scs/include/scs_types.h +3 -1
  20. data/vendor/scs/include/scs_work.h +13 -15
  21. data/vendor/scs/include/util.h +4 -2
  22. data/vendor/scs/linsys/cpu/direct/private.c +32 -153
  23. data/vendor/scs/linsys/cpu/direct/private.h +6 -6
  24. data/vendor/scs/linsys/cpu/indirect/private.c +9 -22
  25. data/vendor/scs/linsys/cpu/indirect/private.h +4 -2
  26. data/vendor/scs/linsys/csparse.c +140 -12
  27. data/vendor/scs/linsys/csparse.h +10 -17
  28. data/vendor/scs/linsys/external/amd/LICENSE.txt +0 -897
  29. data/vendor/scs/linsys/external/amd/SuiteSparse_config.c +4 -2
  30. data/vendor/scs/linsys/external/amd/SuiteSparse_config.h +0 -5
  31. data/vendor/scs/linsys/gpu/gpu.c +4 -4
  32. data/vendor/scs/linsys/gpu/gpu.h +1 -1
  33. data/vendor/scs/linsys/gpu/indirect/private.c +15 -26
  34. data/vendor/scs/linsys/mkl/direct/private.c +182 -0
  35. data/vendor/scs/linsys/mkl/direct/private.h +38 -0
  36. data/vendor/scs/linsys/scs_matrix.c +49 -72
  37. data/vendor/scs/linsys/scs_matrix.h +4 -3
  38. data/vendor/scs/scs.mk +39 -30
  39. data/vendor/scs/src/aa.c +0 -4
  40. data/vendor/scs/src/cones.c +78 -184
  41. data/vendor/scs/src/exp_cone.c +399 -0
  42. data/vendor/scs/src/normalize.c +51 -0
  43. data/vendor/scs/src/rw.c +139 -76
  44. data/vendor/scs/src/scs.c +275 -202
  45. data/vendor/scs/src/util.c +36 -13
  46. data/vendor/scs/test/minunit.h +2 -1
  47. data/vendor/scs/test/problem_utils.h +5 -4
  48. data/vendor/scs/test/problems/degenerate.h +1 -0
  49. data/vendor/scs/test/problems/hs21_tiny_qp.h +2 -1
  50. data/vendor/scs/test/problems/hs21_tiny_qp_rw.h +13 -4
  51. data/vendor/scs/test/problems/infeasible_tiny_qp.h +1 -0
  52. data/vendor/scs/test/problems/max_ent +0 -0
  53. data/vendor/scs/test/problems/max_ent.h +8 -0
  54. data/vendor/scs/test/problems/qafiro_tiny_qp.h +2 -1
  55. data/vendor/scs/test/problems/random_prob.h +2 -39
  56. data/vendor/scs/test/problems/rob_gauss_cov_est.h +15 -3
  57. data/vendor/scs/test/problems/small_lp.h +4 -1
  58. data/vendor/scs/test/problems/small_qp.h +42 -7
  59. data/vendor/scs/test/problems/test_exp_cone.h +84 -0
  60. data/vendor/scs/test/problems/test_prob_from_data_file.h +57 -0
  61. data/vendor/scs/test/problems/test_validation.h +4 -1
  62. data/vendor/scs/test/problems/unbounded_tiny_qp.h +3 -3
  63. data/vendor/scs/test/random_socp_prob.c +3 -1
  64. data/vendor/scs/test/run_from_file.c +22 -4
  65. data/vendor/scs/test/run_tests.c +22 -9
  66. metadata +12 -4
@@ -5,7 +5,7 @@
5
5
  #include "scs_matrix.h"
6
6
 
7
7
  /* return milli-seconds */
8
- #if (defined NOTIMER)
8
+ #if (defined NO_TIMER)
9
9
 
10
10
  void SCS(tic)(SCS(timer) * t) {
11
11
  }
@@ -71,7 +71,41 @@ scs_float SCS(tocq)(SCS(timer) * t) {
71
71
 
72
72
  #endif
73
73
 
74
- void SCS(free_data)(ScsData *d, ScsCone *k, ScsSettings *stgs) {
74
+ void SCS(deep_copy_data)(ScsData *dest, const ScsData *src) {
75
+ dest->n = src->n;
76
+ dest->m = src->m;
77
+ SCS(copy_matrix)(&(dest->A), src->A);
78
+ SCS(copy_matrix)(&(dest->P), src->P);
79
+ dest->b = (scs_float *)scs_calloc(dest->m, sizeof(scs_float));
80
+ memcpy(dest->b, src->b, dest->m * sizeof(scs_float));
81
+ dest->c = (scs_float *)scs_calloc(dest->n, sizeof(scs_float));
82
+ memcpy(dest->c, src->c, dest->n * sizeof(scs_float));
83
+ }
84
+
85
+ void SCS(deep_copy_stgs)(ScsSettings *dest, const ScsSettings *src) {
86
+ memcpy(dest, src, sizeof(ScsSettings));
87
+ /* MATLAB does something weird with strdup, so use strcpy instead */
88
+ char *tmp;
89
+ if (src->write_data_filename) {
90
+ /* sizeof(char) = 1 */
91
+ tmp = (char *)scs_malloc(strlen(src->write_data_filename) + 1);
92
+ strcpy(tmp, src->write_data_filename);
93
+ dest->write_data_filename = tmp;
94
+ } else {
95
+ dest->write_data_filename = SCS_NULL;
96
+ }
97
+ /* MATLAB does something weird with strdup, so use strcpy instead */
98
+ if (src->log_csv_filename) {
99
+ /* sizeof(char) = 1 */
100
+ tmp = (char *)scs_malloc(strlen(src->log_csv_filename) + 1);
101
+ strcpy(tmp, src->log_csv_filename);
102
+ dest->log_csv_filename = tmp;
103
+ } else {
104
+ dest->log_csv_filename = SCS_NULL;
105
+ }
106
+ }
107
+
108
+ void SCS(free_data)(ScsData *d) {
75
109
  if (d) {
76
110
  scs_free(d->b);
77
111
  scs_free(d->c);
@@ -83,17 +117,6 @@ void SCS(free_data)(ScsData *d, ScsCone *k, ScsSettings *stgs) {
83
117
  }
84
118
  scs_free(d);
85
119
  }
86
- if (k) {
87
- scs_free(k->bu);
88
- scs_free(k->bl);
89
- scs_free(k->q);
90
- scs_free(k->s);
91
- scs_free(k->p);
92
- scs_free(k);
93
- }
94
- if (stgs) {
95
- scs_free(stgs);
96
- }
97
120
  }
98
121
 
99
122
  void SCS(free_sol)(ScsSolution *sol) {
@@ -8,11 +8,13 @@
8
8
  return message; \
9
9
  } \
10
10
  } while (0)
11
+
11
12
  #define mu_assert(message, test) \
12
13
  do { \
13
14
  if (!(test)) \
14
15
  return message; \
15
16
  } while (0)
17
+
16
18
  #define mu_run_test(test) _mu_run_test(#test, test)
17
19
 
18
20
  #define _mu_run_test(name, test) \
@@ -21,7 +23,6 @@
21
23
  scs_printf("Running test: %s\n", name); \
22
24
  const char *message = test(); \
23
25
  tests_run++; \
24
- scs_printf("*********************************************************\n"); \
25
26
  if (message) \
26
27
  return message; \
27
28
  } while (0)
@@ -190,6 +190,7 @@ const char *verify_solution_correct(ScsData *d, ScsCone *k, ScsSettings *stgs,
190
190
 
191
191
  /************** OPTIMALITY ****************/
192
192
 
193
+ /* TODO: the MAX expansion computes these norms many times */
193
194
  grl = MAX(MAX(ABS(xt_p_x), ABS(ctx)), ABS(bty));
194
195
  prl = MAX(MAX(NORM(b, m), NORM(s, m)), NORM(ax, m));
195
196
  drl = MAX(MAX(NORM(c, n), NORM(px, n)), NORM(aty, n));
@@ -205,17 +206,17 @@ const char *verify_solution_correct(ScsData *d, ScsCone *k, ScsSettings *stgs,
205
206
  /**************** ASSERTS *****************/
206
207
  if (status == SCS_SOLVED) {
207
208
  mu_assert_less("Primal residual ERROR", ABS(res_pri - info->res_pri),
208
- 1e-11);
209
+ 1e-10);
209
210
  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)));
211
+ 1e-10);
212
+ mu_assert_less("Gap ERROR", ABS(gap - info->gap), 1e-7 * (1 + ABS(gap)));
212
213
  mu_assert_less("Primal obj ERROR", ABS(pobj - info->pobj),
213
214
  1e-9 * (1 + ABS(pobj)));
214
215
  mu_assert_less("Dual obj ERROR", ABS(dobj - info->dobj),
215
216
  1e-9 * (1 + ABS(dobj)));
216
217
  /* slightly looser tol */
217
218
  mu_assert_less("Complementary slackness ERROR", ABS(sty),
218
- 1e-8 * MAX(NORM(s, m), NORM(y, m)));
219
+ 5e-8 * MAX(NORM(s, m), NORM(y, m)));
219
220
  mu_assert_less("s cone dist ERROR", ABS(sdist), 1e-5);
220
221
  mu_assert_less("y cone dist ERROR", ABS(ydist), 1e-5);
221
222
 
@@ -1,6 +1,7 @@
1
1
  #include "glbopts.h"
2
2
  #include "linalg.h"
3
3
  #include "minunit.h"
4
+ #include "problem_utils.h"
4
5
  #include "scs.h"
5
6
  #include "scs_matrix.h"
6
7
  #include "util.h"
@@ -1,6 +1,7 @@
1
1
  #include "glbopts.h"
2
2
  #include "linalg.h"
3
3
  #include "minunit.h"
4
+ #include "problem_utils.h"
4
5
  #include "scs.h"
5
6
  #include "scs_matrix.h"
6
7
  #include "util.h"
@@ -67,7 +68,7 @@ static const char *hs21_tiny_qp(void) {
67
68
  scs_set_default_settings(stgs);
68
69
  stgs->eps_abs = 1e-6;
69
70
  stgs->eps_rel = 1e-6;
70
- stgs->eps_infeas = 1e-9;
71
+ stgs->eps_infeas = 0.; /* disable due to gpu test finding cert */
71
72
 
72
73
  exitflag = scs(d, k, stgs, sol, &info);
73
74
 
@@ -1,6 +1,7 @@
1
1
  #include "glbopts.h"
2
2
  #include "linalg.h"
3
3
  #include "minunit.h"
4
+ #include "problem_utils.h"
4
5
  #include "rw.h"
5
6
  #include "scs.h"
6
7
  #include "scs_matrix.h"
@@ -15,7 +16,7 @@ static const char *hs21_tiny_qp_rw(void) {
15
16
  ScsInfo info = {0};
16
17
  scs_int exitflag;
17
18
  scs_float perr, derr;
18
- scs_int success;
19
+ scs_int success, read_status;
19
20
  const char *fail;
20
21
 
21
22
  /* data */
@@ -69,7 +70,7 @@ static const char *hs21_tiny_qp_rw(void) {
69
70
  scs_set_default_settings(stgs);
70
71
  stgs->eps_abs = 1e-6;
71
72
  stgs->eps_rel = 1e-6;
72
- stgs->eps_infeas = 1e-9;
73
+ stgs->eps_infeas = 0.; /* disable due to gpu test finding cert */
73
74
 
74
75
  stgs->write_data_filename = "hs21_tiny_qp";
75
76
  stgs->max_iters = 1;
@@ -83,7 +84,12 @@ static const char *hs21_tiny_qp_rw(void) {
83
84
  scs_free(stgs);
84
85
  scs_free(d);
85
86
 
86
- SCS(read_data)("hs21_tiny_qp", &d, &k, &stgs);
87
+ read_status = SCS(read_data)("hs21_tiny_qp", &d, &k, &stgs);
88
+
89
+ if (read_status < 0) {
90
+ return "Data read failure, exit.\n";
91
+ }
92
+
87
93
  stgs->max_iters = 1000;
88
94
  /* solve with read data */
89
95
  exitflag = scs(d, k, stgs, sol, &info);
@@ -110,7 +116,10 @@ static const char *hs21_tiny_qp_rw(void) {
110
116
  mu_assert("hs21_tiny_qp: SCS failed to produce outputflag SCS_SOLVED",
111
117
  success);
112
118
 
119
+ SCS(free_data)(d);
120
+ SCS(free_cone)(k);
113
121
  SCS(free_sol)(sol);
114
- SCS(free_data)(d, k, stgs);
122
+ scs_free(stgs);
123
+
115
124
  return fail;
116
125
  }
@@ -1,6 +1,7 @@
1
1
  #include "glbopts.h"
2
2
  #include "linalg.h"
3
3
  #include "minunit.h"
4
+ #include "problem_utils.h"
4
5
  #include "scs.h"
5
6
  #include "scs_matrix.h"
6
7
  #include "util.h"
Binary file
@@ -0,0 +1,8 @@
1
+ #include "glbopts.h"
2
+ #include "problems/test_prob_from_data_file.h"
3
+ #include "scs.h"
4
+
5
+ static const char *max_ent(void) {
6
+ scs_float OPT = -6.067087663361563; /* from ecos */
7
+ return _test_prob_from_data("test/problems/max_ent", OPT);
8
+ }
@@ -1,6 +1,7 @@
1
1
  #include "glbopts.h"
2
2
  #include "linalg.h"
3
3
  #include "minunit.h"
4
+ #include "problem_utils.h"
4
5
  #include "scs.h"
5
6
  #include "scs_matrix.h"
6
7
  #include "util.h"
@@ -141,7 +142,7 @@ static const char *qafiro_tiny_qp(void) {
141
142
  stgs->warm_start = 1;
142
143
  exitflag = scs(d, k, stgs, sol, &info);
143
144
  /* 25 iters should be enough if warm-started */
144
- mu_assert("qafiro_tiny_qp: warm-start failure", info.iter <= 50);
145
+ mu_assert("qafiro_tiny_qp: warm-start failure", info.iter <= 100);
145
146
  success = ABS(perr) < 1e-4 && ABS(derr) < 1e-4 && exitflag == SCS_SOLVED;
146
147
 
147
148
  mu_assert("qafiro_tiny_qp: SCS failed to produce outputflag SCS_SOLVED",
@@ -1,45 +1,8 @@
1
1
  #include "glbopts.h"
2
- #include "minunit.h"
3
- #include "problem_utils.h"
2
+ #include "problems/test_prob_from_data_file.h"
4
3
  #include "scs.h"
5
- #include "util.h"
6
4
 
7
5
  static const char *random_prob(void) {
8
- scs_int read_status;
9
- ScsData *d;
10
- ScsCone *k;
11
- ScsSettings *stgs;
12
- ScsSolution *sol;
13
- ScsInfo info = {0};
14
- scs_int exitflag;
15
- scs_float perr, derr;
16
- scs_int success;
17
- const char *fail;
18
-
19
6
  scs_float OPT = 5.751458006385587;
20
-
21
- read_status = SCS(read_data)("test/problems/random_prob", &d, &k, &stgs);
22
-
23
- if (read_status < 0) {
24
- return "Data read failure, exit.\n";
25
- }
26
-
27
- stgs->eps_abs = 1e-6;
28
- stgs->eps_rel = 1e-6;
29
-
30
- sol = (ScsSolution *)scs_calloc(1, sizeof(ScsSolution));
31
- exitflag = scs(d, k, stgs, sol, &info);
32
-
33
- perr = SCS(dot)(d->c, sol->x, d->n) - OPT;
34
- derr = -SCS(dot)(d->b, sol->y, d->m) - OPT;
35
- scs_printf("primal obj error %4e\n", perr);
36
- scs_printf("dual obj error %4e\n", derr);
37
-
38
- success = ABS(perr) < 1e-4 && ABS(derr) < 1e-4 && exitflag == SCS_SOLVED;
39
-
40
- mu_assert("random_prob: SCS failed to produce SCS_SOLVED", success);
41
- fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
42
- SCS(free_data)(d, k, stgs);
43
- SCS(free_sol)(sol);
44
- return fail;
7
+ return _test_prob_from_data("test/problems/random_prob", OPT);
45
8
  }
@@ -1,6 +1,8 @@
1
1
  #include "glbopts.h"
2
2
  #include "linalg.h"
3
3
  #include "minunit.h"
4
+ #include "problem_utils.h"
5
+ #include "rw.h"
4
6
  #include "scs.h"
5
7
  #include "scs_matrix.h"
6
8
  #include "util.h"
@@ -13,7 +15,7 @@ static const char *rob_gauss_cov_est(void) {
13
15
  ScsInfo info = {0};
14
16
  scs_int exitflag;
15
17
  scs_float perr, derr;
16
- scs_int success;
18
+ scs_int success, read_status;
17
19
  const char *fail;
18
20
 
19
21
  /* data */
@@ -173,6 +175,8 @@ static const char *rob_gauss_cov_est(void) {
173
175
  mu_assert("rob_gauss_cov_est: SCS failed to produce outputflag SCS_SOLVED",
174
176
  success);
175
177
  fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
178
+ if (fail)
179
+ return fail;
176
180
 
177
181
  /* test warm-starting */
178
182
  stgs->warm_start = 1;
@@ -196,7 +200,12 @@ static const char *rob_gauss_cov_est(void) {
196
200
  scs_free(stgs);
197
201
  scs_free(d);
198
202
 
199
- SCS(read_data)("rob_gauss_cov_est", &d, &k, &stgs);
203
+ read_status = SCS(read_data)("rob_gauss_cov_est", &d, &k, &stgs);
204
+
205
+ if (read_status < 0) {
206
+ return "Data read failure, exit.\n";
207
+ }
208
+
200
209
  stgs->max_iters = 1000;
201
210
  /* solve with read data */
202
211
  exitflag = scs(d, k, stgs, sol, &info);
@@ -236,7 +245,10 @@ static const char *rob_gauss_cov_est(void) {
236
245
  mu_assert("rob_gauss_cov_est_rw: SCS failed to produce outputflag SCS_SOLVED",
237
246
  success);
238
247
 
248
+ SCS(free_data)(d);
249
+ SCS(free_cone)(k);
239
250
  SCS(free_sol)(sol);
240
- SCS(free_data)(d, k, stgs);
251
+ scs_free(stgs);
252
+
241
253
  return fail;
242
254
  }
@@ -44,8 +44,11 @@ static const char *small_lp(void) {
44
44
 
45
45
  mu_assert("small_lp: SCS failed to produce outputflag SCS_SOLVED", success);
46
46
  fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
47
- SCS(free_data)(d, k, stgs);
47
+ SCS(free_data)(d);
48
+ SCS(free_cone)(k);
48
49
  SCS(free_sol)(sol);
49
50
  SCS(free_sol)(opt_sol);
51
+ scs_free(stgs);
52
+
50
53
  return fail;
51
54
  }
@@ -251,7 +251,7 @@ scs_float u[] = {
251
251
  96.00000, 96.00000, 96.00000, 96.00000, 96.00000, 96.00000,
252
252
  96.00000, 96.00000, 96.00000, 96.00000, 96.00000, 96.00000,
253
253
  96.00000, 96.00000, 96.00000, 96.00000};
254
- scs_float q[] = {0.00000, 0.00000, -35.02643, 0.00000, 0.00000,
254
+ scs_float c[] = {0.00000, 0.00000, -35.02643, 0.00000, 0.00000,
255
255
  -3.56718, 0.00000, -17.41907, 0.00000, 0.00000,
256
256
  -17.64691, 0.00000, 0.00000, 0.00000, 0.00000,
257
257
  0.00000, 0.00000, 0.00000, 0.00000, 0.00000,
@@ -298,7 +298,7 @@ static const char *small_qp(void) {
298
298
  d->n = n;
299
299
  d->b = (scs_float *)scs_calloc(m + 1, sizeof(scs_float));
300
300
  d->b[0] = 1; /* t var in box cone */
301
- d->c = q;
301
+ d->c = c;
302
302
 
303
303
  d->A = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
304
304
  d->A->m = m + 1; /* t var in box cone */
@@ -332,11 +332,48 @@ static const char *small_qp(void) {
332
332
  stgs->eps_rel = 1e-6;
333
333
  stgs->eps_infeas = 1e-10;
334
334
 
335
- exitflag = scs(d, k, stgs, sol, &info);
335
+ ScsWork *w = scs_init(d, k, stgs);
336
+ exitflag = scs_solve(w, sol, &info, 0);
336
337
  success = exitflag == SCS_SOLVED;
337
338
 
338
339
  mu_assert("small_qp: SCS failed to produce outputflag SCS_SOLVED", success);
339
340
  fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
341
+ if (fail)
342
+ return fail;
343
+
344
+ /* test updating c */
345
+ d->c[0] = 1.0; /* set to new value */
346
+ scs_update(w, SCS_NULL, d->c);
347
+ exitflag = scs_solve(w, sol, &info, 1);
348
+ success = exitflag == SCS_SOLVED;
349
+
350
+ mu_assert("small_qp: SCS failed to produce outputflag SCS_SOLVED", success);
351
+ fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
352
+ if (fail)
353
+ return fail;
354
+
355
+ /* test updating b */
356
+ d->b[0] = 4.0; /* set to new value */
357
+ scs_update(w, d->b, SCS_NULL);
358
+ exitflag = scs_solve(w, sol, &info, 1);
359
+ success = exitflag == SCS_SOLVED;
360
+
361
+ mu_assert("small_qp: SCS failed to produce outputflag SCS_SOLVED", success);
362
+ fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
363
+ if (fail)
364
+ return fail;
365
+
366
+ /* revert back to original data */
367
+ d->c[0] = 0.0; /* revert to original value */
368
+ d->b[0] = 1.0; /* revert to original value */
369
+ scs_update(w, d->b, d->c);
370
+ exitflag = scs_solve(w, sol, &info, 1);
371
+ success = exitflag == SCS_SOLVED;
372
+
373
+ mu_assert("small_qp: SCS failed to produce outputflag SCS_SOLVED", success);
374
+ fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
375
+
376
+ scs_finish(w);
340
377
 
341
378
  scs_free(d->A);
342
379
  scs_free(d->P);
@@ -344,9 +381,7 @@ static const char *small_qp(void) {
344
381
  scs_free(k);
345
382
  scs_free(d);
346
383
  scs_free(stgs);
347
- scs_free(sol->x);
348
- scs_free(sol->y);
349
- scs_free(sol->s);
350
- scs_free(sol);
384
+ SCS(free_sol)(sol);
385
+
351
386
  return fail;
352
387
  }
@@ -0,0 +1,84 @@
1
+ #include "glbopts.h"
2
+ #include "linalg.h"
3
+ #include "minunit.h"
4
+ #include "scs.h"
5
+
6
+ /* Forward declare exponential cone projection routine.
7
+ * Implemented in exp_cone.c.
8
+ */
9
+ scs_float SCS(proj_pd_exp_cone)(scs_float *v0, scs_int primal);
10
+
11
+ static scs_int _run_exp_cone_test(scs_float *v0, scs_float *vp_true,
12
+ scs_float *vd_true) {
13
+ scs_int success = 1;
14
+ scs_float vp[3], vd[3];
15
+ const scs_float TOL = 1e-6;
16
+
17
+ memcpy(vp, v0, 3 * sizeof(scs_float));
18
+ memcpy(vd, v0, 3 * sizeof(scs_float));
19
+
20
+ /* inefficient, but just for testing */
21
+ SCS(proj_pd_exp_cone)(vp, 1);
22
+ SCS(proj_pd_exp_cone)(vd, 0);
23
+
24
+ scs_printf("*******************************\n");
25
+ scs_printf("v0: (%f, %f, %f)\n", v0[0], v0[1], v0[2]);
26
+ scs_printf("vp: (%f, %f, %f)\n", vp[0], vp[1], vp[2]);
27
+ scs_printf("vp_true: (%f, %f, %f)\n", vp_true[0], vp_true[1], vp_true[2]);
28
+ scs_printf("vd: (%f, %f, %f)\n", vd[0], vd[1], vd[2]);
29
+ scs_printf("vd_true: (%f, %f, %f)\n", vd_true[0], vd_true[1], vd_true[2]);
30
+
31
+ success &= (SCS(norm_diff)(vp, vp_true, 3) <= TOL);
32
+ success &= (SCS(norm_diff)(vd, vd_true, 3) <= TOL);
33
+ /* Moreau decomposition holds only for polar */
34
+ /*
35
+ success &= (SCS(dot)(vp, vd, 3) <= TOL);
36
+ success &= (ABS(v0[0] - vp[0] + vd[0]) <= TOL);
37
+ success &= (ABS(v0[1] - vp[1] + vd[1]) <= TOL);
38
+ success &= (ABS(v0[2] - vp[2] + vd[2]) <= TOL);
39
+ */
40
+
41
+ if (!success) {
42
+ scs_printf("Failed.\n");
43
+ }
44
+
45
+ return success;
46
+ }
47
+
48
+ static const char *test_exp_cone(void) {
49
+ scs_int success = 1;
50
+ scs_int i;
51
+ /* test points */
52
+ scs_float v0[6][3] = {
53
+ {1, 2, 3},
54
+ {0.14814832, 1.04294573, 0.67905585},
55
+ {-0.78301134, 1.82790084, -1.05417044},
56
+ {1.3282585, -0.43277314, 1.7468072},
57
+ {0.67905585, 0.14814832, 1.04294573},
58
+ {0.50210027, 0.12314491, -1.77568921},
59
+ };
60
+ /* primal projections */
61
+ scs_float vp[6][3] = {
62
+ {0.8899428, 1.94041881, 3.06957226},
63
+ {-0.02001571, 0.8709169, 0.85112944},
64
+ {-1.17415616, 0.9567094, 0.280399},
65
+ {0.53160512, 0.2804836, 1.86652094},
66
+ {0.38322814, 0.27086569, 1.11482228},
67
+ {0., 0., 0.},
68
+ };
69
+ /* dual projections */
70
+ scs_float vd[6][3] = {
71
+ {-0., 2., 3.},
72
+ {-0., 1.04294573, 0.67905585},
73
+ {-0.68541419, 1.85424082, 0.01685653},
74
+ {-0.02277033, -0.12164823, 1.75085347},
75
+ {-0., 0.14814832, 1.04294573},
76
+ {-0., 0.12314491, -0.},
77
+ };
78
+
79
+ for (i = 0; i < 6; ++i) {
80
+ success &= _run_exp_cone_test(v0[i], vp[i], vd[i]);
81
+ }
82
+ mu_assert("test_exp_cone: Failure", success);
83
+ return 0;
84
+ }
@@ -0,0 +1,57 @@
1
+ #ifndef _SCS_FILE_TEST_CHASSIS
2
+ #define _SCS_FILE_TEST_CHASSIS
3
+
4
+ #include "glbopts.h"
5
+ #include "minunit.h"
6
+ #include "problem_utils.h"
7
+ #include "rw.h"
8
+ #include "scs.h"
9
+ #include "util.h"
10
+
11
+ static const char *_test_prob_from_data(const char *file, scs_float OPT) {
12
+ scs_int read_status;
13
+ ScsData *d;
14
+ ScsCone *k;
15
+ ScsSettings *stgs;
16
+ ScsSolution *sol;
17
+ ScsInfo info = {0};
18
+ scs_int exitflag;
19
+ scs_float perr, derr;
20
+ scs_int success;
21
+ const char *fail;
22
+
23
+ read_status = SCS(read_data)(file, &d, &k, &stgs);
24
+
25
+ if (read_status < 0) {
26
+ return "Data read failure, exit.\n";
27
+ }
28
+
29
+ stgs->eps_abs = 1e-6;
30
+ stgs->eps_rel = 1e-6;
31
+
32
+ sol = (ScsSolution *)scs_calloc(1, sizeof(ScsSolution));
33
+ exitflag = scs(d, k, stgs, sol, &info);
34
+
35
+ perr = SCS(dot)(d->c, sol->x, d->n) - OPT;
36
+ derr = -SCS(dot)(d->b, sol->y, d->m) - OPT;
37
+ scs_printf("primal obj error %4e\n", perr);
38
+ scs_printf("dual obj error %4e\n", derr);
39
+
40
+ success = ABS(perr) < 1e-4 && ABS(derr) < 1e-4 && exitflag == SCS_SOLVED;
41
+ if (!success) {
42
+ scs_printf("%s: FAILED\n", file);
43
+ }
44
+ mu_assert(file, success);
45
+ fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
46
+ SCS(free_data)(d);
47
+ SCS(free_cone)(k);
48
+ SCS(free_sol)(sol);
49
+ scs_free(stgs);
50
+
51
+ if (fail) {
52
+ scs_printf("%s: FAILED\n", file);
53
+ }
54
+ return fail;
55
+ }
56
+
57
+ #endif
@@ -36,8 +36,11 @@ static const char *test_validation(void) {
36
36
 
37
37
  mu_assert("test_fails: SCS failed to produce outputflag SCS_FAILED",
38
38
  exitflag == SCS_FAILED);
39
- SCS(free_data)(d, k, stgs);
39
+ SCS(free_data)(d);
40
+ SCS(free_cone)(k);
40
41
  SCS(free_sol)(sol);
41
42
  SCS(free_sol)(opt_sol);
43
+ scs_free(stgs);
44
+
42
45
  return 0;
43
46
  }
@@ -1,6 +1,7 @@
1
1
  #include "glbopts.h"
2
2
  #include "linalg.h"
3
3
  #include "minunit.h"
4
+ #include "problem_utils.h"
4
5
  #include "scs.h"
5
6
  #include "scs_matrix.h"
6
7
  #include "util.h"
@@ -73,10 +74,9 @@ static const char *unbounded_tiny_qp(void) {
73
74
  fail = verify_solution_correct(d, k, stgs, &info, sol, exitflag);
74
75
 
75
76
  SCS(free_sol)(sol);
76
- scs_free(d->A);
77
- scs_free(d->P);
78
- scs_free(k);
77
+ SCS(free_cone)(k);
79
78
  scs_free(stgs);
79
+ scs_free(d->A);
80
80
  scs_free(d);
81
81
  return fail;
82
82
  }
@@ -164,9 +164,11 @@ int main(int argc, char **argv) {
164
164
  scs_printf("scs dua obj = %4f\n", -SCS(dot)(d->b, sol->y, d->m));
165
165
  }
166
166
 
167
- SCS(free_data)(d, k, stgs);
167
+ SCS(free_data)(d);
168
+ SCS(free_cone)(k);
168
169
  SCS(free_sol)(sol);
169
170
  SCS(free_sol)(opt_sol);
171
+ scs_free(stgs);
170
172
 
171
173
  return 0;
172
174
  }
@@ -60,19 +60,37 @@ int main(int argc, char **argv) {
60
60
  }
61
61
  for (i = 2; i < argc; i += 2) {
62
62
  if (argc < i + 2) {
63
- scs_printf("Incorrect number of arguments supplied\n.");
64
- SCS(free_data)(d, k, stgs);
63
+ scs_printf("Incorrect number of arguments supplied.\n");
64
+
65
+ SCS(free_data)(d);
66
+ SCS(free_cone)(k);
67
+ scs_free(stgs);
68
+
65
69
  return -1;
66
70
  }
67
71
  if (override_setting(stgs, argv[i], argv[i + 1]) < 0) {
68
72
  scs_printf("Unrecognized setting %s\n", argv[i]);
69
- SCS(free_data)(d, k, stgs);
73
+
74
+ SCS(free_data)(d);
75
+ SCS(free_cone)(k);
76
+ scs_free(stgs);
77
+
70
78
  return -1;
71
79
  }
72
80
  }
81
+ if (!stgs->verbose) {
82
+ scs_printf(
83
+ "File data set `verbose` to 0, SCS will not output information. Add "
84
+ "`verbose 1` to call to override.\n");
85
+ }
86
+ scs_printf("Solving problem.\n");
73
87
  sol = (ScsSolution *)scs_calloc(1, sizeof(ScsSolution));
74
88
  scs(d, k, stgs, sol, &info);
75
- SCS(free_data)(d, k, stgs);
89
+
90
+ SCS(free_data)(d);
91
+ SCS(free_cone)(k);
76
92
  SCS(free_sol)(sol);
93
+ scs_free(stgs);
94
+
77
95
  return 0;
78
96
  }