scs 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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);