scs 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/LICENSE.txt +1 -1
  4. data/README.md +1 -1
  5. data/lib/scs/version.rb +1 -1
  6. data/vendor/scs/CITATION.cff +2 -2
  7. data/vendor/scs/CMakeLists.txt +284 -168
  8. data/vendor/scs/Makefile +43 -18
  9. data/vendor/scs/README.md +1 -1
  10. data/vendor/scs/include/glbopts.h +32 -13
  11. data/vendor/scs/include/linsys.h +8 -8
  12. data/vendor/scs/include/scs.h +6 -2
  13. data/vendor/scs/include/scs_types.h +3 -1
  14. data/vendor/scs/include/scs_work.h +9 -8
  15. data/vendor/scs/include/util.h +1 -1
  16. data/vendor/scs/linsys/cpu/direct/private.c +32 -153
  17. data/vendor/scs/linsys/cpu/direct/private.h +6 -6
  18. data/vendor/scs/linsys/cpu/indirect/private.c +9 -22
  19. data/vendor/scs/linsys/cpu/indirect/private.h +4 -2
  20. data/vendor/scs/linsys/csparse.c +140 -12
  21. data/vendor/scs/linsys/csparse.h +10 -17
  22. data/vendor/scs/linsys/gpu/gpu.c +4 -4
  23. data/vendor/scs/linsys/gpu/gpu.h +1 -1
  24. data/vendor/scs/linsys/gpu/indirect/private.c +15 -26
  25. data/vendor/scs/linsys/mkl/direct/private.c +182 -0
  26. data/vendor/scs/linsys/mkl/direct/private.h +38 -0
  27. data/vendor/scs/linsys/scs_matrix.c +11 -5
  28. data/vendor/scs/scs.mk +39 -26
  29. data/vendor/scs/src/cones.c +15 -159
  30. data/vendor/scs/src/exp_cone.c +399 -0
  31. data/vendor/scs/src/normalize.c +4 -2
  32. data/vendor/scs/src/rw.c +93 -38
  33. data/vendor/scs/src/scs.c +83 -52
  34. data/vendor/scs/src/util.c +12 -3
  35. data/vendor/scs/test/minunit.h +2 -1
  36. data/vendor/scs/test/problem_utils.h +2 -1
  37. data/vendor/scs/test/problems/hs21_tiny_qp.h +1 -1
  38. data/vendor/scs/test/problems/hs21_tiny_qp_rw.h +8 -3
  39. data/vendor/scs/test/problems/max_ent +0 -0
  40. data/vendor/scs/test/problems/max_ent.h +8 -0
  41. data/vendor/scs/test/problems/random_prob.h +2 -43
  42. data/vendor/scs/test/problems/rob_gauss_cov_est.h +7 -2
  43. data/vendor/scs/test/problems/test_exp_cone.h +84 -0
  44. data/vendor/scs/test/problems/test_prob_from_data_file.h +57 -0
  45. data/vendor/scs/test/run_from_file.c +7 -1
  46. data/vendor/scs/test/run_tests.c +22 -9
  47. metadata +10 -3
data/vendor/scs/Makefile CHANGED
@@ -1,7 +1,7 @@
1
1
  # MAKEFILE for scs
2
2
  include scs.mk
3
3
 
4
- SCS_OBJECTS = src/util.o src/cones.o src/aa.o src/rw.o src/linalg.o src/ctrlc.o src/scs_version.o src/normalize.o
4
+ SCS_OBJECTS = src/util.o src/cones.o src/exp_cone.o src/aa.o src/rw.o src/linalg.o src/ctrlc.o src/scs_version.o src/normalize.o
5
5
  SCS_O = src/scs.o
6
6
  SCS_INDIR_O = src/scs_indir.o
7
7
 
@@ -19,7 +19,7 @@ TARGETS = $(OUT)/demo_socp_indirect $(OUT)/demo_socp_direct $(OUT)/run_from_file
19
19
  default: $(TARGETS) $(OUT)/libscsdir.a $(OUT)/libscsindir.a $(OUT)/libscsdir.$(SHARED) $(OUT)/libscsindir.$(SHARED)
20
20
  @echo "****************************************************************************************"
21
21
  @echo "Successfully compiled scs, copyright Brendan O'Donoghue 2012."
22
- @echo "To test, type '$(OUT)/demo_socp_direct' to solve a random SOCP."
22
+ @echo "To test, run 'make test' and then '$(OUT)/run_tests_direct'."
23
23
  @echo "**********************************************************************************"
24
24
  ifneq ($(USE_LAPACK), 0)
25
25
  @echo "Compiled with blas and lapack, can solve LPs, SOCPs, SDPs, ECPs, and PCPs"
@@ -41,6 +41,7 @@ $(SCS_INDIR_O): src/scs.c $(INC_FILES)
41
41
 
42
42
  src/util.o : src/util.c $(INC_FILES)
43
43
  src/cones.o : src/cones.c $(INC_FILES)
44
+ src/exp_cone.o : src/exp_cone.c $(INC_FILES)
44
45
  src/aa.o : src/aa.c $(INC_FILES)
45
46
  src/rw.o : src/rw.c $(INC_FILES)
46
47
  src/linalg.o: src/linalg.c $(INC_FILES)
@@ -49,6 +50,7 @@ src/scs_version.o: src/scs_version.c $(INC_FILES)
49
50
 
50
51
  $(DIRSRC)/private.o: $(DIRSRC)/private.c $(DIRSRC)/private.h
51
52
  $(INDIRSRC)/indirect/private.o: $(INDIRSRC)/private.c $(INDIRSRC)/private.h
53
+ $(MKLSRC)/private.o: $(MKLSRC)/private.c $(MKLSRC)/private.h
52
54
  $(LINSYS)/scs_matrix.o: $(LINSYS)/scs_matrix.c $(LINSYS)/scs_matrix.h
53
55
  $(LINSYS)/csparse.o: $(LINSYS)/csparse.c $(LINSYS)/csparse.h
54
56
 
@@ -62,45 +64,68 @@ $(OUT)/libscsindir.a: $(SCS_INDIR_O) $(SCS_OBJECTS) $(INDIRSRC)/private.o $(LINS
62
64
  $(ARCHIVE) $@ $^
63
65
  - $(RANLIB) $@
64
66
 
67
+ $(OUT)/libscsmkl.a: $(SCS_O) $(SCS_OBJECTS) $(MKLSRC)/private.o $(LINSYS)/scs_matrix.o $(LINSYS)/csparse.o
68
+ mkdir -p $(OUT)
69
+ $(ARCHIVE) $@ $^
70
+ - $(RANLIB) $@
71
+
65
72
  $(OUT)/libscsdir.$(SHARED): $(SCS_O) $(SCS_OBJECTS) $(DIRSRC)/private.o $(AMD_OBJS) $(LDL_OBJS) $(LINSYS)/scs_matrix.o $(LINSYS)/csparse.o
66
73
  mkdir -p $(OUT)
67
- $(CC) $(CFLAGS) -shared -Wl,$(SONAME),$(@:$(OUT)/%=%) -o $@ $^ $(LDFLAGS)
74
+ $(CC) $(CFLAGS) -shared -Wl,$(SONAME),$(@:$(OUT)/%=%) -o $@ $^ $(LDFLAGS) $(BLASLDFLAGS)
68
75
 
69
76
  $(OUT)/libscsindir.$(SHARED): $(SCS_INDIR_O) $(SCS_OBJECTS) $(INDIRSRC)/private.o $(LINSYS)/scs_matrix.o $(LINSYS)/csparse.o
70
77
  mkdir -p $(OUT)
71
- $(CC) $(CFLAGS) -shared -Wl,$(SONAME),$(@:$(OUT)/%=%) -o $@ $^ $(LDFLAGS)
78
+ $(CC) $(CFLAGS) -shared -Wl,$(SONAME),$(@:$(OUT)/%=%) -o $@ $^ $(LDFLAGS) $(BLASLDFLAGS)
79
+
80
+ $(OUT)/libscsmkl.$(SHARED): $(SCS_O) $(SCS_OBJECTS) $(MKLSRC)/private.o $(LINSYS)/scs_matrix.o $(LINSYS)/csparse.o
81
+ mkdir -p $(OUT)
82
+ $(CC) $(CFLAGS) -shared -Wl,$(SONAME),$(@:$(OUT)/%=%) -o $@ $^ $(LDFLAGS) $(MKLFLAGS)
72
83
 
73
84
  $(OUT)/demo_socp_direct: test/random_socp_prob.c $(OUT)/libscsdir.a
74
- $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
85
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(BLASLDFLAGS)
75
86
 
76
87
  $(OUT)/demo_socp_indirect: test/random_socp_prob.c $(OUT)/libscsindir.a
77
- $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
88
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(BLASLDFLAGS)
89
+
90
+ $(OUT)/demo_socp_mkl: test/random_socp_prob.c $(OUT)/libscsmkl.a
91
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(MKLFLAGS)
78
92
 
79
93
  $(OUT)/run_from_file_direct: test/run_from_file.c $(OUT)/libscsdir.a
80
- $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
94
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(BLASLDFLAGS)
81
95
 
82
96
  $(OUT)/run_from_file_indirect: test/run_from_file.c $(OUT)/libscsindir.a
83
- $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
97
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(BLASLDFLAGS)
84
98
 
85
99
  $(OUT)/run_from_file_gpu_indirect: test/run_from_file.c $(OUT)/libscsgpuindir.a
86
- $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(CULDFLAGS)
100
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(BLASLDFLAGS) $(CULDFLAGS)
87
101
 
88
102
  # basic testing
89
103
  .PHONY: test
90
104
  test: $(OUT)/run_tests_indirect $(OUT)/run_tests_direct
91
105
  $(OUT)/run_tests_indirect: test/run_tests.c $(OUT)/libscsindir.a
92
- $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -Itest
106
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(BLASLDFLAGS) -Itest
93
107
  $(OUT)/run_tests_direct: test/run_tests.c $(OUT)/libscsdir.a
94
- $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -Itest
108
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(BLASLDFLAGS) -Itest
109
+ $(OUT)/run_tests_mkl: test/run_tests.c $(OUT)/libscsmkl.a
110
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(MKLFLAGS) -Itest
111
+
95
112
 
96
113
  .PHONY: test_gpu
97
114
  test_gpu: $(OUT)/run_tests_gpu_indirect # $(OUT)/run_tests_gpu_direct
98
115
 
116
+ .PHONY: mkl
117
+ mkl: mklroot $(OUT)/libscsmkl.a $(OUT)/libscsmkl.$(SHARED) $(OUT)/run_tests_mkl $(OUT)/demo_socp_mkl
118
+ mklroot:
119
+ ifndef MKLROOT
120
+ $(error MKLROOT is undefined, set MKLROOT to the MKL install location)
121
+ endif
122
+
123
+
99
124
  $(OUT)/run_tests_gpu_indirect: test/run_tests.c $(OUT)/libscsgpuindir.a
100
- $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(CULDFLAGS) -Itest
125
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(BLASLDFLAGS) $(CULDFLAGS) -Itest
101
126
 
102
127
  # $(OUT)/run_tests_gpu_direct: test/run_tests.c $(OUT)/libscsgpudir.a
103
- # $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(CULDFLAGS) -Itest
128
+ # $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(BLASLDFLAGS) $(CULDFLAGS) -Itest
104
129
 
105
130
  # REQUIRES GPU AND CUDA INSTALLED
106
131
  gpu: gpu_indirect # gpu_direct
@@ -119,7 +144,7 @@ $(GPUINDIR)/private.o: $(GPUINDIR)/private.c
119
144
 
120
145
  # $(OUT)/libscsgpudir.$(SHARED): $(SCS_O) $(SCS_OBJECTS) $(GPUDIR)/private.o $(AMD_OBJS) $(LINSYS)/scs_matrix.o $(LINSYS)/gpu/gpu.o
121
146
  # mkdir -p $(OUT)
122
- # $(CC) $(CFLAGS) -shared -Wl,$(SONAME),$(@:$(OUT)/%=%) -o $@ $^ $(LDFLAGS) $(CULDFLAGS)
147
+ # $(CC) $(CFLAGS) -shared -Wl,$(SONAME),$(@:$(OUT)/%=%) -o $@ $^ $(LDFLAGS) $(BLASLDFLAGS) $(CULDFLAGS)
123
148
 
124
149
  # $(OUT)/libscsgpudir.a: $(SCS_INDIR_O) $(SCS_OBJECTS) $(GPUDIR)/private.o $(AMD_OBJS) $(LINSYS)/scs_matrix.o $(LINSYS)/gpu/gpu.o
125
150
  # mkdir -p $(OUT)
@@ -128,7 +153,7 @@ $(GPUINDIR)/private.o: $(GPUINDIR)/private.c
128
153
 
129
154
  $(OUT)/libscsgpuindir.$(SHARED): $(SCS_O) $(SCS_OBJECTS) $(GPUINDIR)/private.o $(LINSYS)/scs_matrix.o $(LINSYS)/csparse.o $(LINSYS)/gpu/gpu.o
130
155
  mkdir -p $(OUT)
131
- $(CC) $(CFLAGS) -shared -Wl,$(SONAME),$(@:$(OUT)/%=%) -o $@ $^ $(LDFLAGS) $(CULDFLAGS)
156
+ $(CC) $(CFLAGS) -shared -Wl,$(SONAME),$(@:$(OUT)/%=%) -o $@ $^ $(LDFLAGS) $(BLASLDFLAGS) $(CULDFLAGS)
132
157
 
133
158
  $(OUT)/libscsgpuindir.a: $(SCS_INDIR_O) $(SCS_OBJECTS) $(GPUINDIR)/private.o $(LINSYS)/scs_matrix.o $(LINSYS)/csparse.o $(LINSYS)/gpu/gpu.o
134
159
  mkdir -p $(OUT)
@@ -136,14 +161,14 @@ $(OUT)/libscsgpuindir.a: $(SCS_INDIR_O) $(SCS_OBJECTS) $(GPUINDIR)/private.o $(L
136
161
  - $(RANLIB) $@
137
162
 
138
163
  # $(OUT)/demo_socp_gpu_direct: test/random_socp_prob.c $(OUT)/libscsgpudir.a
139
- # $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(CULDFLAGS)
164
+ # $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(BLASLDFLAGS) $(CULDFLAGS)
140
165
 
141
166
  $(OUT)/demo_socp_gpu_indirect: test/random_socp_prob.c $(OUT)/libscsgpuindir.a
142
- $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(CULDFLAGS)
167
+ $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(BLASLDFLAGS) $(CULDFLAGS)
143
168
 
144
169
  .PHONY: clean purge
145
170
  clean:
146
- @rm -rf $(TARGETS) $(SCS_O) $(SCS_INDIR_O) $(SCS_OBJECTS) $(AMD_OBJS) $(LDL_OBJS) $(LINSYS)/*.o $(DIRSRC)/*.o $(INDIRSRC)/*.o $(GPUDIR)/*.o $(GPUINDIR)/*.o $(LINSYS)/gpu/*.o
171
+ @rm -rf $(TARGETS) $(SCS_O) $(SCS_INDIR_O) $(SCS_OBJECTS) $(AMD_OBJS) $(LDL_OBJS) $(LINSYS)/*.o $(DIRSRC)/*.o $(INDIRSRC)/*.o $(MKLSRC)/*.o $(GPUDIR)/*.o $(GPUINDIR)/*.o $(LINSYS)/gpu/*.o
147
172
  @rm -rf $(OUT)/*.dSYM
148
173
  @rm -rf matlab/*.mex*
149
174
  @rm -rf .idea
data/vendor/scs/README.md CHANGED
@@ -8,7 +8,7 @@
8
8
 
9
9
 
10
10
  SCS (`splitting conic solver`) is a numerical optimization package for solving
11
- large-scale convex cone problems. The current version is `3.2.0`.
11
+ large-scale convex cone problems. The current version is `3.2.3`.
12
12
 
13
13
  The full documentation is available [here](https://www.cvxgrp.org/scs/).
14
14
 
@@ -12,16 +12,17 @@ extern "C" {
12
12
  #define SCS(x) _scs_##x
13
13
  #endif
14
14
 
15
- /* SCS VERSION NUMBER ---------------------------------------------- */
15
+ /* SCS VERSION NUMBER ---------------------------------------------- */
16
16
  /* string literals automatically null-terminated */
17
- #define SCS_VERSION ("3.2.0")
17
+ #define SCS_VERSION ("3.2.3")
18
18
 
19
19
  /* verbosity level */
20
20
  #ifndef VERBOSITY
21
21
  #define VERBOSITY (0)
22
22
  #endif
23
23
 
24
- /* DEFAULT SOLVER PARAMETERS AND SETTINGS -------------------------- */
24
+ /* DEFAULT SOLVER PARAMETERS AND SETTINGS -------------------------- */
25
+ /* If you update any of these you must update the documentation manually */
25
26
  #define MAX_ITERS (100000)
26
27
  #define EPS_REL (1E-4)
27
28
  #define EPS_ABS (1E-4)
@@ -39,14 +40,13 @@ extern "C" {
39
40
  #define LOG_CSV_FILENAME (0)
40
41
  #define TIME_LIMIT_SECS (0.)
41
42
 
42
- /* redefine printfs and memory allocators as needed */
43
+ /* redefine printfs as needed */
44
+ #if NO_PRINTING > 0 /* Disable all printing */
45
+ #define scs_printf(...) /* No-op */
46
+ #else
43
47
  #ifdef MATLAB_MEX_FILE
44
48
  #include "mex.h"
45
49
  #define scs_printf mexPrintf
46
- #define scs_free mxFree
47
- #define scs_malloc mxMalloc
48
- #define scs_calloc mxCalloc
49
- #define scs_realloc mxRealloc
50
50
  #elif defined PYTHON
51
51
  #include <Python.h>
52
52
  /* see:
@@ -58,6 +58,27 @@ extern "C" {
58
58
  PySys_WriteStdout(__VA_ARGS__); \
59
59
  PyGILState_Release(gilstate); \
60
60
  }
61
+ #elif defined R_LANG
62
+ #include <R_ext/Print.h> /* Rprintf etc */
63
+ #include <stdio.h>
64
+ #include <stdlib.h>
65
+ #define scs_printf Rprintf
66
+ #else
67
+ #include <stdio.h>
68
+ #include <stdlib.h>
69
+ #define scs_printf printf
70
+ #endif
71
+ #endif
72
+
73
+ /* redefine memory allocators as needed */
74
+ #ifdef MATLAB_MEX_FILE
75
+ #include "mex.h"
76
+ #define scs_free mxFree
77
+ #define scs_malloc mxMalloc
78
+ #define scs_calloc mxCalloc
79
+ #define scs_realloc mxRealloc
80
+ #elif defined PYTHON
81
+ #include <Python.h>
61
82
  #if PY_MAJOR_VERSION >= 3
62
83
  #define scs_free PyMem_RawFree
63
84
  #define scs_malloc PyMem_RawMalloc
@@ -74,10 +95,8 @@ static inline void *scs_calloc(size_t count, size_t size) {
74
95
  }
75
96
  #endif
76
97
  #elif defined R_LANG
77
- #include <R_ext/Print.h> /* Rprintf etc */
78
98
  #include <stdio.h>
79
99
  #include <stdlib.h>
80
- #define scs_printf Rprintf
81
100
  #define scs_free free
82
101
  #define scs_malloc malloc
83
102
  #define scs_calloc calloc
@@ -85,7 +104,6 @@ static inline void *scs_calloc(size_t count, size_t size) {
85
104
  #else
86
105
  #include <stdio.h>
87
106
  #include <stdlib.h>
88
- #define scs_printf printf
89
107
  #define scs_free free
90
108
  #define scs_malloc malloc
91
109
  #define scs_calloc calloc
@@ -144,8 +162,9 @@ static inline void *scs_calloc(size_t count, size_t size) {
144
162
  /* how many iterations between heuristic residual rescaling */
145
163
  #define RESCALING_MIN_ITERS (100)
146
164
 
147
- #define EPS_TOL (1E-18)
148
- #define SAFEDIV_POS(X, Y) ((Y) < EPS_TOL ? ((X) / EPS_TOL) : (X) / (Y))
165
+ #define _DIV_EPS_TOL (1E-18)
166
+ #define SAFEDIV_POS(X, Y) \
167
+ ((Y) < _DIV_EPS_TOL ? ((X) / _DIV_EPS_TOL) : (X) / (Y))
149
168
 
150
169
  #if VERBOSITY > 0
151
170
  #define PRINT_INTERVAL (1)
@@ -23,15 +23,15 @@ extern "C" {
23
23
  * @return Linear system solver workspace.
24
24
  *
25
25
  */
26
- ScsLinSysWork *SCS(init_lin_sys_work)(const ScsMatrix *A, const ScsMatrix *P,
27
- const scs_float *diag_r);
26
+ ScsLinSysWork *scs_init_lin_sys_work(const ScsMatrix *A, const ScsMatrix *P,
27
+ const scs_float *diag_r);
28
28
 
29
29
  /**
30
30
  * Frees `ScsLinSysWork` structure and associated allocated memory.
31
31
  *
32
32
  * @param w Linear system private workspace.
33
33
  */
34
- void SCS(free_lin_sys_work)(ScsLinSysWork *w);
34
+ void scs_free_lin_sys_work(ScsLinSysWork *w);
35
35
 
36
36
  /**
37
37
  * Solves the linear system as required by SCS at each iteration:
@@ -48,11 +48,11 @@ void SCS(free_lin_sys_work)(ScsLinSysWork *w);
48
48
  * @param b Right hand side, contains solution at the end.
49
49
  * @param s Contains warm-start (may be NULL).
50
50
  * @param tol Tolerance required for the system solve.
51
- * @return status < 0 indicates failure.
51
+ * @return status != 0 indicates failure.
52
52
  *
53
53
  */
54
- scs_int SCS(solve_lin_sys)(ScsLinSysWork *w, scs_float *b, const scs_float *s,
55
- scs_float tol);
54
+ scs_int scs_solve_lin_sys(ScsLinSysWork *w, scs_float *b, const scs_float *s,
55
+ scs_float tol);
56
56
  /**
57
57
  * Update the linsys workspace when `R` is changed. For example, a
58
58
  * direct method for solving the linear system might need to update the
@@ -62,14 +62,14 @@ scs_int SCS(solve_lin_sys)(ScsLinSysWork *w, scs_float *b, const scs_float *s,
62
62
  * @param new_diag_r Updated `diag_r`, diagonal entries of R.
63
63
  *
64
64
  */
65
- void SCS(update_lin_sys_diag_r)(ScsLinSysWork *w, const scs_float *new_diag_r);
65
+ void scs_update_lin_sys_diag_r(ScsLinSysWork *w, const scs_float *new_diag_r);
66
66
 
67
67
  /**
68
68
  * Name of the linear solver.
69
69
  *
70
70
  * @return name of method.
71
71
  */
72
- const char *SCS(get_lin_sys_method)(void);
72
+ const char *scs_get_lin_sys_method(void);
73
73
 
74
74
  #ifdef __cplusplus
75
75
  }
@@ -1,5 +1,9 @@
1
- /* This file contains the outward facing SCS API. */
2
- /* It includes all the input/output data structs and the API functions. */
1
+ /*
2
+ * Public header containing the outward facing SCS API. It includes all the
3
+ * input/output data structs and the API functions. Make sure this file and
4
+ * `scs_types.h` are somewhere appropriate and then use `#include "scs.h"` to
5
+ * access the SCS public API.
6
+ */
3
7
 
4
8
  #ifndef SCS_H_GUARD
5
9
  #define SCS_H_GUARD
@@ -1,5 +1,7 @@
1
1
  /*
2
- * Definitions of primitive types used in SCS.
2
+ * Pulic header including definitions of primitive types used in SCS.
3
+ * Make sure this file and `scs.h` are somewhere appropriate and then use
4
+ * `#include "scs.h"` to access the SCS public API.
3
5
  */
4
6
 
5
7
  #ifndef SCS_TYPES_H_GUARD
@@ -54,14 +54,15 @@ struct SCS_WORK {
54
54
  scs_float *g; /* g = (I + M)^{-1} h */
55
55
  scs_float *lin_sys_warm_start; /* linear system warm-start (indirect only) */
56
56
  scs_float *diag_r; /* vector of R matrix diagonals (affects cone proj) */
57
- scs_float *b_orig, *c_orig; /* original unnormalized b and c vectors */
58
- AaWork *accel; /* struct for acceleration workspace */
59
- ScsData *d; /* Problem data deep copy NORMALIZED */
60
- ScsCone *k; /* Problem cone deep copy */
61
- ScsSettings *stgs; /* contains solver settings specified by user */
62
- ScsLinSysWork *p; /* struct populated by linear system solver */
63
- ScsScaling *scal; /* contains the re-scaling data */
64
- ScsConeWork *cone_work; /* workspace for the cone projection step */
57
+ scs_float *b_orig, *c_orig; /* original unnormalized b and c vectors */
58
+ scs_float nm_b_orig, nm_c_orig; /* unnormalized NORM(b), NORM(c) */
59
+ AaWork *accel; /* struct for acceleration workspace */
60
+ ScsData *d; /* Problem data deep copy NORMALIZED */
61
+ ScsCone *k; /* Problem cone deep copy */
62
+ ScsSettings *stgs; /* contains solver settings specified by user */
63
+ ScsLinSysWork *p; /* struct populated by linear system solver */
64
+ ScsScaling *scal; /* contains the re-scaling data */
65
+ ScsConeWork *cone_work; /* workspace for the cone projection step */
65
66
  /* normalized and unnormalized residuals */
66
67
  ScsResiduals *r_orig, *r_normalized;
67
68
  /* track x,y,s as alg progresses, tau *not* divided out */
@@ -11,7 +11,7 @@ extern "C" {
11
11
  #include <stdlib.h>
12
12
 
13
13
  /* timing code courtesy of A. Domahidi */
14
- #if (defined NOTIMER)
14
+ #if (defined NO_TIMER)
15
15
  typedef void *SCS(timer);
16
16
  #elif (defined _WIN32 || defined _WIN64 || defined _WINDLL)
17
17
  /* Use Windows QueryPerformanceCounter for timing */
@@ -1,20 +1,10 @@
1
1
  #include "private.h"
2
- #include "linsys.h"
3
2
 
4
- const char *SCS(get_lin_sys_method)() {
5
- return "sparse-direct";
3
+ const char *scs_get_lin_sys_method() {
4
+ return "sparse-direct-amd-qdldl";
6
5
  }
7
6
 
8
- /*
9
- char *SCS(get_lin_sys_summary)(ScsLinSysWork *p, const ScsInfo *info) {
10
- char *str = (char *)scs_malloc(sizeof(char) * 128);
11
- scs_int n = p->L->n;
12
- sprintf(str, "lin-sys: nnz(L): %li\n", (long)(p->L->p[n] + n));
13
- return str;
14
- }
15
- */
16
-
17
- void SCS(free_lin_sys_work)(ScsLinSysWork *p) {
7
+ void scs_free_lin_sys_work(ScsLinSysWork *p) {
18
8
  if (p) {
19
9
  SCS(cs_spfree)(p->L);
20
10
  SCS(cs_spfree)(p->kkt);
@@ -33,155 +23,43 @@ void SCS(free_lin_sys_work)(ScsLinSysWork *p) {
33
23
  }
34
24
  }
35
25
 
36
- static csc *form_kkt(const ScsMatrix *A, const ScsMatrix *P, scs_float *diag_p,
37
- const scs_float *diag_r, scs_int *diag_r_idxs) {
38
- /* ONLY UPPER TRIANGULAR PART IS STUFFED
39
- * forms column compressed kkt matrix
40
- * assumes column compressed form A matrix
41
- *
42
- * forms upper triangular part of [(I + P) A'; A -I]
43
- * P : n x n, A: m x n.
44
- */
45
- scs_int h, i, j, count;
46
- csc *Kcsc, *K;
47
- scs_int n = A->n;
48
- scs_int m = A->m;
49
- scs_int Anz = A->p[n];
50
- scs_int Knzmax;
51
- scs_int *idx_mapping;
52
- if (P) {
53
- /* Upper bound P + I upper triangular component as Pnz + n */
54
- Knzmax = n + m + Anz + P->p[n];
55
- } else {
56
- Knzmax = n + m + Anz;
57
- }
58
- K = SCS(cs_spalloc)(m + n, m + n, Knzmax, 1, 1);
59
-
60
- #if VERBOSITY > 0
61
- scs_printf("forming kkt\n");
62
- #endif
63
- /* Here we generate a triplet matrix and then compress to CSC */
64
- if (!K) {
65
- return SCS_NULL;
66
- }
67
-
68
- count = 0; /* element counter */
69
- if (P) {
70
- /* R_x + P in top left */
71
- for (j = 0; j < n; j++) { /* cols */
72
- diag_p[j] = 0.;
73
- /* empty column, add diagonal */
74
- if (P->p[j] == P->p[j + 1]) {
75
- K->i[count] = j;
76
- K->p[count] = j;
77
- K->x[count] = diag_r[j];
78
- diag_r_idxs[j] = count; /* store the indices where diag_r occurs */
79
- count++;
80
- }
81
- for (h = P->p[j]; h < P->p[j + 1]; h++) {
82
- i = P->i[h]; /* row */
83
- if (i > j) { /* only upper triangular needed */
84
- break;
85
- }
86
- K->i[count] = i;
87
- K->p[count] = j;
88
- K->x[count] = P->x[h];
89
- if (i == j) {
90
- /* P has diagonal element */
91
- diag_p[j] = P->x[h];
92
- K->x[count] += diag_r[j];
93
- diag_r_idxs[j] = count; /* store the indices where diag_r occurs */
94
- }
95
- count++;
96
- /* reached the end without adding diagonal, do it now */
97
- if ((i < j) && (h + 1 == P->p[j + 1] || P->i[h + 1] > j)) {
98
- K->i[count] = j;
99
- K->p[count] = j;
100
- K->x[count] = diag_r[j];
101
- diag_r_idxs[j] = count; /* store the indices where diag_r occurs */
102
- count++;
103
- }
104
- }
105
- }
106
- } else {
107
- /* R_x in top left */
108
- for (j = 0; j < n; j++) {
109
- diag_p[j] = 0.;
110
- K->i[count] = j;
111
- K->p[count] = j;
112
- K->x[count] = diag_r[j];
113
- diag_r_idxs[j] = count; /* store the indices where diag_r occurs */
114
- count++;
115
- }
116
- }
117
-
118
- /* A^T at top right */
119
- for (j = 0; j < n; j++) {
120
- for (h = A->p[j]; h < A->p[j + 1]; h++) {
121
- K->p[count] = A->i[h] + n;
122
- K->i[count] = j;
123
- K->x[count] = A->x[h];
124
- count++;
125
- }
126
- }
127
-
128
- /* -R_y at bottom right */
129
- for (j = 0; j < m; j++) {
130
- K->i[count] = j + n;
131
- K->p[count] = j + n;
132
- K->x[count] = -diag_r[j + n];
133
- diag_r_idxs[j + n] = count; /* store the indices where diag_r occurs */
134
- count++;
135
- }
136
-
137
- K->nz = count;
138
- idx_mapping = (scs_int *)scs_calloc(K->nz, sizeof(scs_int));
139
- Kcsc = SCS(cs_compress)(K, idx_mapping);
140
- for (i = 0; i < m + n; i++) {
141
- diag_r_idxs[i] = idx_mapping[diag_r_idxs[i]];
142
- }
143
- SCS(cs_spfree)(K);
144
- scs_free(idx_mapping);
145
- return Kcsc;
146
- }
147
-
148
- static scs_int _ldl_init(csc *A, scs_int *P, scs_float **info) {
26
+ static scs_int _ldl_init(ScsMatrix *A, scs_int *P, scs_float **info) {
149
27
  *info = (scs_float *)scs_calloc(AMD_INFO, sizeof(scs_float));
150
28
  return amd_order(A->n, A->p, A->i, P, (scs_float *)SCS_NULL, *info);
151
29
  }
152
30
 
153
31
  /* call only once */
154
32
  static scs_int ldl_prepare(ScsLinSysWork *p) {
155
- csc *kkt = p->kkt, *L = p->L;
156
- scs_int n = kkt->n;
33
+ ScsMatrix *kkt = p->kkt, *L = p->L;
34
+ scs_int nzmax, n = kkt->n;
157
35
  p->etree = (scs_int *)scs_calloc(n, sizeof(scs_int));
158
36
  p->Lnz = (scs_int *)scs_calloc(n, sizeof(scs_int));
159
37
  p->iwork = (scs_int *)scs_calloc(3 * n, sizeof(scs_int));
160
38
  L->p = (scs_int *)scs_calloc((1 + n), sizeof(scs_int));
161
- L->nzmax = QDLDL_etree(n, kkt->p, kkt->i, p->iwork, p->Lnz, p->etree);
162
- if (L->nzmax < 0) {
39
+ nzmax = QDLDL_etree(n, kkt->p, kkt->i, p->iwork, p->Lnz, p->etree);
40
+ if (nzmax < 0) {
163
41
  scs_printf("Error in elimination tree calculation.\n");
164
- if (L->nzmax == -1) {
42
+ if (nzmax == -1) {
165
43
  scs_printf("Matrix is not perfectly upper triangular.\n");
166
- } else if (L->nzmax == -2) {
44
+ } else if (nzmax == -2) {
167
45
  scs_printf("Integer overflow in L nonzero count.\n");
168
46
  }
169
- return L->nzmax;
47
+ return nzmax;
170
48
  }
171
49
 
172
- L->x = (scs_float *)scs_calloc(L->nzmax, sizeof(scs_float));
173
- L->i = (scs_int *)scs_calloc(L->nzmax, sizeof(scs_int));
50
+ L->x = (scs_float *)scs_calloc(nzmax, sizeof(scs_float));
51
+ L->i = (scs_int *)scs_calloc(nzmax, sizeof(scs_int));
174
52
  p->Dinv = (scs_float *)scs_calloc(n, sizeof(scs_float));
175
53
  p->D = (scs_float *)scs_calloc(n, sizeof(scs_float));
176
54
  p->bwork = (scs_int *)scs_calloc(n, sizeof(scs_int));
177
55
  p->fwork = (scs_float *)scs_calloc(n, sizeof(scs_float));
178
- return L->nzmax;
56
+ return nzmax;
179
57
  }
180
58
 
181
59
  /* can call many times */
182
60
  static scs_int ldl_factor(ScsLinSysWork *p, scs_int num_vars) {
183
61
  scs_int factor_status;
184
- csc *kkt = p->kkt, *L = p->L;
62
+ ScsMatrix *kkt = p->kkt, *L = p->L;
185
63
  #if VERBOSITY > 0
186
64
  scs_printf("numeric factorization\n");
187
65
  #endif
@@ -217,7 +95,7 @@ static void _ldl_permt(scs_int n, scs_float *x, scs_float *b, scs_int *P) {
217
95
  x[P[j]] = b[j];
218
96
  }
219
97
 
220
- static void _ldl_solve(scs_float *b, csc *L, scs_float *Dinv, scs_int *P,
98
+ static void _ldl_solve(scs_float *b, ScsMatrix *L, scs_float *Dinv, scs_int *P,
221
99
  scs_float *bp) {
222
100
  /* solves PLDL'P' x = b for x */
223
101
  scs_int n = L->n;
@@ -240,11 +118,11 @@ static scs_int *cs_pinv(scs_int const *p, scs_int n) {
240
118
  return pinv; /* return result */
241
119
  }
242
120
 
243
- static csc *cs_symperm(const csc *A, const scs_int *pinv, scs_int *idx_mapping,
244
- scs_int values) {
121
+ static ScsMatrix *cs_symperm(const ScsMatrix *A, const scs_int *pinv,
122
+ scs_int *idx_mapping, scs_int values) {
245
123
  scs_int i, j, p, q, i2, j2, n, *Ap, *Ai, *Cp, *Ci, *w;
246
124
  scs_float *Cx, *Ax;
247
- csc *C;
125
+ ScsMatrix *C;
248
126
  n = A->n;
249
127
  Ap = A->p;
250
128
  Ai = A->i;
@@ -290,14 +168,16 @@ static csc *cs_symperm(const csc *A, const scs_int *pinv, scs_int *idx_mapping,
290
168
  1); /* success; free workspace, return C */
291
169
  }
292
170
 
293
- static csc *permute_kkt(const ScsMatrix *A, const ScsMatrix *P,
294
- ScsLinSysWork *p, const scs_float *diag_r) {
171
+ static ScsMatrix *permute_kkt(const ScsMatrix *A, const ScsMatrix *P,
172
+ ScsLinSysWork *p, const scs_float *diag_r) {
295
173
  scs_float *info;
296
- scs_int *Pinv, amd_status, *idx_mapping, i;
297
- csc *kkt_perm, *kkt = form_kkt(A, P, p->diag_p, diag_r, p->diag_r_idxs);
174
+ scs_int *Pinv, amd_status, *idx_mapping, i, kkt_nnz;
175
+ ScsMatrix *kkt_perm;
176
+ ScsMatrix *kkt = SCS(form_kkt)(A, P, p->diag_p, diag_r, p->diag_r_idxs, 1);
298
177
  if (!kkt) {
299
178
  return SCS_NULL;
300
179
  }
180
+ kkt_nnz = kkt->p[kkt->n];
301
181
  amd_status = _ldl_init(kkt, p->perm, &info);
302
182
  if (amd_status < 0) {
303
183
  scs_printf("AMD permutatation error.\n");
@@ -308,7 +188,7 @@ static csc *permute_kkt(const ScsMatrix *A, const ScsMatrix *P,
308
188
  amd_info(info);
309
189
  #endif
310
190
  Pinv = cs_pinv(p->perm, A->n + A->m);
311
- idx_mapping = (scs_int *)scs_calloc(kkt->nzmax, sizeof(scs_int));
191
+ idx_mapping = (scs_int *)scs_calloc(kkt_nnz, sizeof(scs_int));
312
192
  kkt_perm = cs_symperm(kkt, Pinv, idx_mapping, 1);
313
193
  for (i = 0; i < A->n + A->m; i++) {
314
194
  p->diag_r_idxs[i] = idx_mapping[p->diag_r_idxs[i]];
@@ -320,7 +200,7 @@ static csc *permute_kkt(const ScsMatrix *A, const ScsMatrix *P,
320
200
  return kkt_perm;
321
201
  }
322
202
 
323
- void SCS(update_lin_sys_diag_r)(ScsLinSysWork *p, const scs_float *diag_r) {
203
+ void scs_update_lin_sys_diag_r(ScsLinSysWork *p, const scs_float *diag_r) {
324
204
  scs_int i, ldl_status;
325
205
  for (i = 0; i < p->n; ++i) {
326
206
  /* top left is R_x + P, bottom right is -R_y */
@@ -339,21 +219,20 @@ void SCS(update_lin_sys_diag_r)(ScsLinSysWork *p, const scs_float *diag_r) {
339
219
  }
340
220
  }
341
221
 
342
- ScsLinSysWork *SCS(init_lin_sys_work)(const ScsMatrix *A, const ScsMatrix *P,
343
- const scs_float *diag_r) {
222
+ ScsLinSysWork *scs_init_lin_sys_work(const ScsMatrix *A, const ScsMatrix *P,
223
+ const scs_float *diag_r) {
344
224
  ScsLinSysWork *p = (ScsLinSysWork *)scs_calloc(1, sizeof(ScsLinSysWork));
345
225
  scs_int n_plus_m = A->n + A->m, ldl_status, ldl_prepare_status;
346
226
  p->m = A->m;
347
227
  p->n = A->n;
348
228
  p->diag_p = (scs_float *)scs_calloc(A->n, sizeof(scs_float));
349
229
  p->perm = (scs_int *)scs_calloc(sizeof(scs_int), n_plus_m);
350
- p->L = (csc *)scs_calloc(1, sizeof(csc));
230
+ p->L = (ScsMatrix *)scs_calloc(1, sizeof(ScsMatrix));
351
231
  p->bp = (scs_float *)scs_calloc(n_plus_m, sizeof(scs_float));
352
232
  p->diag_r_idxs = (scs_int *)scs_calloc(n_plus_m, sizeof(scs_int));
353
233
  p->factorizations = 0;
354
234
  p->L->m = n_plus_m;
355
235
  p->L->n = n_plus_m;
356
- p->L->nz = -1;
357
236
  p->kkt = permute_kkt(A, P, p, diag_r);
358
237
  ldl_prepare_status = ldl_prepare(p);
359
238
  ldl_status = ldl_factor(p, A->n);
@@ -366,8 +245,8 @@ ScsLinSysWork *SCS(init_lin_sys_work)(const ScsMatrix *A, const ScsMatrix *P,
366
245
  return p;
367
246
  }
368
247
 
369
- scs_int SCS(solve_lin_sys)(ScsLinSysWork *p, scs_float *b, const scs_float *s,
370
- scs_float tol) {
248
+ scs_int scs_solve_lin_sys(ScsLinSysWork *p, scs_float *b, const scs_float *s,
249
+ scs_float tol) {
371
250
  /* returns solution to linear system */
372
251
  /* Ax = b with solution stored in b */
373
252
  _ldl_solve(b, p->L, p->Dinv, p->perm, p->bp);