scs 0.2.0
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.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +84 -0
- data/ext/scs/Rakefile +11 -0
- data/lib/scs/ffi.rb +117 -0
- data/lib/scs/solver.rb +178 -0
- data/lib/scs/version.rb +3 -0
- data/lib/scs.rb +17 -0
- data/vendor/scs/LICENSE.txt +21 -0
- data/vendor/scs/Makefile +164 -0
- data/vendor/scs/README.md +220 -0
- data/vendor/scs/include/aa.h +56 -0
- data/vendor/scs/include/cones.h +46 -0
- data/vendor/scs/include/ctrlc.h +33 -0
- data/vendor/scs/include/glbopts.h +177 -0
- data/vendor/scs/include/linalg.h +26 -0
- data/vendor/scs/include/linsys.h +64 -0
- data/vendor/scs/include/normalize.h +18 -0
- data/vendor/scs/include/rw.h +17 -0
- data/vendor/scs/include/scs.h +161 -0
- data/vendor/scs/include/scs_blas.h +51 -0
- data/vendor/scs/include/util.h +65 -0
- data/vendor/scs/linsys/amatrix.c +305 -0
- data/vendor/scs/linsys/amatrix.h +36 -0
- data/vendor/scs/linsys/amatrix.o +0 -0
- data/vendor/scs/linsys/cpu/direct/private.c +366 -0
- data/vendor/scs/linsys/cpu/direct/private.h +26 -0
- data/vendor/scs/linsys/cpu/direct/private.o +0 -0
- data/vendor/scs/linsys/cpu/indirect/private.c +256 -0
- data/vendor/scs/linsys/cpu/indirect/private.h +31 -0
- data/vendor/scs/linsys/cpu/indirect/private.o +0 -0
- data/vendor/scs/linsys/external/amd/LICENSE.txt +934 -0
- data/vendor/scs/linsys/external/amd/SuiteSparse_config.c +469 -0
- data/vendor/scs/linsys/external/amd/SuiteSparse_config.h +254 -0
- data/vendor/scs/linsys/external/amd/SuiteSparse_config.o +0 -0
- data/vendor/scs/linsys/external/amd/amd.h +400 -0
- data/vendor/scs/linsys/external/amd/amd_1.c +180 -0
- data/vendor/scs/linsys/external/amd/amd_1.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_2.c +1842 -0
- data/vendor/scs/linsys/external/amd/amd_2.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_aat.c +184 -0
- data/vendor/scs/linsys/external/amd/amd_aat.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_control.c +64 -0
- data/vendor/scs/linsys/external/amd/amd_control.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_defaults.c +37 -0
- data/vendor/scs/linsys/external/amd/amd_defaults.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_dump.c +179 -0
- data/vendor/scs/linsys/external/amd/amd_dump.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_global.c +16 -0
- data/vendor/scs/linsys/external/amd/amd_global.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_info.c +119 -0
- data/vendor/scs/linsys/external/amd/amd_info.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_internal.h +304 -0
- data/vendor/scs/linsys/external/amd/amd_order.c +199 -0
- data/vendor/scs/linsys/external/amd/amd_order.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_post_tree.c +120 -0
- data/vendor/scs/linsys/external/amd/amd_post_tree.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_postorder.c +206 -0
- data/vendor/scs/linsys/external/amd/amd_postorder.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_preprocess.c +118 -0
- data/vendor/scs/linsys/external/amd/amd_preprocess.o +0 -0
- data/vendor/scs/linsys/external/amd/amd_valid.c +92 -0
- data/vendor/scs/linsys/external/amd/amd_valid.o +0 -0
- data/vendor/scs/linsys/external/amd/changes +11 -0
- data/vendor/scs/linsys/external/qdldl/LICENSE +201 -0
- data/vendor/scs/linsys/external/qdldl/README.md +120 -0
- data/vendor/scs/linsys/external/qdldl/changes +4 -0
- data/vendor/scs/linsys/external/qdldl/qdldl.c +298 -0
- data/vendor/scs/linsys/external/qdldl/qdldl.h +177 -0
- data/vendor/scs/linsys/external/qdldl/qdldl.o +0 -0
- data/vendor/scs/linsys/external/qdldl/qdldl_types.h +21 -0
- data/vendor/scs/linsys/gpu/gpu.c +41 -0
- data/vendor/scs/linsys/gpu/gpu.h +85 -0
- data/vendor/scs/linsys/gpu/indirect/private.c +304 -0
- data/vendor/scs/linsys/gpu/indirect/private.h +36 -0
- data/vendor/scs/scs.mk +181 -0
- data/vendor/scs/src/aa.c +224 -0
- data/vendor/scs/src/aa.o +0 -0
- data/vendor/scs/src/cones.c +802 -0
- data/vendor/scs/src/cones.o +0 -0
- data/vendor/scs/src/ctrlc.c +77 -0
- data/vendor/scs/src/ctrlc.o +0 -0
- data/vendor/scs/src/linalg.c +84 -0
- data/vendor/scs/src/linalg.o +0 -0
- data/vendor/scs/src/normalize.c +93 -0
- data/vendor/scs/src/normalize.o +0 -0
- data/vendor/scs/src/rw.c +167 -0
- data/vendor/scs/src/rw.o +0 -0
- data/vendor/scs/src/scs.c +975 -0
- data/vendor/scs/src/scs.o +0 -0
- data/vendor/scs/src/scs_version.c +5 -0
- data/vendor/scs/src/scs_version.o +0 -0
- data/vendor/scs/src/util.c +196 -0
- data/vendor/scs/src/util.o +0 -0
- data/vendor/scs/test/data/small_random_socp +0 -0
- data/vendor/scs/test/minunit.h +13 -0
- data/vendor/scs/test/problem_utils.h +93 -0
- data/vendor/scs/test/problems/rob_gauss_cov_est.h +85 -0
- data/vendor/scs/test/problems/small_lp.h +50 -0
- data/vendor/scs/test/problems/small_random_socp.h +33 -0
- data/vendor/scs/test/random_socp_prob.c +171 -0
- data/vendor/scs/test/run_from_file.c +69 -0
- data/vendor/scs/test/run_tests +2 -0
- data/vendor/scs/test/run_tests.c +32 -0
- metadata +203 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: a3d577e9f481249087408220ac5a609c9eef5efcd8befd5b81368f3b84daca30
|
|
4
|
+
data.tar.gz: 1d1a05bcb8326b8a5f06a29715bae4a9788fdf9ee416410d33134da102efc1e9
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 50e6df0f1faef9c92d5659557b0dcaf4fc1342ea224a61fee1f45abf3c22031314ccc7c61ec7c4756722d29f02f30dddb3e5dc0bdba3e1618e3b6f600622f38b
|
|
7
|
+
data.tar.gz: 6a2e023b50207693e349dac6f159fe97d58dfc3fa3dc095c6a580da24c61a39b795b412c4120b3950ffa3f3ffec5e1b93319ca537e0b645e431ad02fb96943c7
|
data/CHANGELOG.md
ADDED
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) 2019 Andrew Kane
|
|
2
|
+
|
|
3
|
+
MIT License
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+
a copy of this software and associated documentation files (the
|
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+
the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be
|
|
14
|
+
included in all copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# SCS
|
|
2
|
+
|
|
3
|
+
[SCS](https://github.com/cvxgrp/scs) - the splitting conic solver - for Ruby
|
|
4
|
+
|
|
5
|
+
:fire: Supports many different [problem types](https://www.cvxpy.org/tutorial/advanced/index.html#choosing-a-solver)
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Add this line to your application’s Gemfile:
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
gem 'scs'
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Getting Started
|
|
16
|
+
|
|
17
|
+
Prep the problem
|
|
18
|
+
|
|
19
|
+
```ruby
|
|
20
|
+
data = {a: [[1], [-1]], b: [1, 0], c: [-1]}
|
|
21
|
+
cone = {q: [], l: 2}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
And solve it
|
|
25
|
+
|
|
26
|
+
```ruby
|
|
27
|
+
solver = SCS::Solver.new
|
|
28
|
+
result = solver.solve(data, cone)
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Settings
|
|
32
|
+
|
|
33
|
+
Default values shown
|
|
34
|
+
|
|
35
|
+
```ruby
|
|
36
|
+
solver.solve(data, cone, {
|
|
37
|
+
normalize: true, # heuristic data rescaling
|
|
38
|
+
scale: 1.0, # if normalized, rescales by this factor
|
|
39
|
+
rho_x: 1e-3, # x equality constraint scaling
|
|
40
|
+
max_iters: 5000, # maximum iterations to take
|
|
41
|
+
eps: 1e-5, # convergence tolerance
|
|
42
|
+
alpha: 1.5, # relaxation parameter
|
|
43
|
+
cg_rate: 2.0, # for indirect, tolerance goes down like (1/iter)^cg_rate
|
|
44
|
+
verbose: true, # write out progress
|
|
45
|
+
warm_start: false, # warm start
|
|
46
|
+
acceleration_lookback: 10, # memory for acceleration
|
|
47
|
+
write_data_filename: nil # filename to write data if set
|
|
48
|
+
})
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Direct vs Indirect
|
|
52
|
+
|
|
53
|
+
SCS comes with two solvers: a direct solver which uses a cached LDL factorization and an indirect solver based on conjugate gradients. For the indirect solver, use:
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
SCS::Solver.new(indirect: true)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Resources
|
|
60
|
+
|
|
61
|
+
- [Conic Optimization via Operator Splitting and Homogeneous Self-Dual Embedding](https://web.stanford.edu/~boyd/papers/scs.html)
|
|
62
|
+
|
|
63
|
+
## History
|
|
64
|
+
|
|
65
|
+
View the [changelog](https://github.com/ankane/scs/blob/master/CHANGELOG.md)
|
|
66
|
+
|
|
67
|
+
## Contributing
|
|
68
|
+
|
|
69
|
+
Everyone is encouraged to help improve this project. Here are a few ways you can help:
|
|
70
|
+
|
|
71
|
+
- [Report bugs](https://github.com/ankane/scs/issues)
|
|
72
|
+
- Fix bugs and [submit pull requests](https://github.com/ankane/scs/pulls)
|
|
73
|
+
- Write, clarify, or fix documentation
|
|
74
|
+
- Suggest or add new features
|
|
75
|
+
|
|
76
|
+
To get started with development and testing:
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
git clone https://github.com/ankane/scs.git
|
|
80
|
+
cd scs
|
|
81
|
+
bundle install
|
|
82
|
+
bundle exec rake compile
|
|
83
|
+
bundle exec rake test
|
|
84
|
+
```
|
data/ext/scs/Rakefile
ADDED
data/lib/scs/ffi.rb
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
module SCS
|
|
2
|
+
module FFI
|
|
3
|
+
module Direct
|
|
4
|
+
def self.lib_name
|
|
5
|
+
"libscsdir"
|
|
6
|
+
end
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
module Indirect
|
|
10
|
+
def self.lib_name
|
|
11
|
+
"libscsindir"
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
ext =
|
|
16
|
+
if Gem.win_platform?
|
|
17
|
+
"dll"
|
|
18
|
+
elsif RbConfig::CONFIG["host_os"] =~ /darwin/i
|
|
19
|
+
"dylib"
|
|
20
|
+
else
|
|
21
|
+
"so"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
[Direct, Indirect].each do |m|
|
|
25
|
+
m.module_eval do
|
|
26
|
+
extend Fiddle::Importer
|
|
27
|
+
|
|
28
|
+
dlload File.expand_path("../../vendor/scs/out/#{lib_name}.#{ext}", __dir__)
|
|
29
|
+
|
|
30
|
+
extern "size_t scs_sizeof_int(void)"
|
|
31
|
+
extern "size_t scs_sizeof_float(void)"
|
|
32
|
+
|
|
33
|
+
# TODO support other sizes
|
|
34
|
+
raise Error, "Unsupported int size" if scs_sizeof_int != 4
|
|
35
|
+
raise Error, "Unsupported float size" if scs_sizeof_float != 8
|
|
36
|
+
|
|
37
|
+
typealias "scs_float", "double"
|
|
38
|
+
typealias "scs_int", "int"
|
|
39
|
+
|
|
40
|
+
m::Data = struct [
|
|
41
|
+
"scs_int m",
|
|
42
|
+
"scs_int n",
|
|
43
|
+
"ScsMatrix *a",
|
|
44
|
+
"scs_float *b",
|
|
45
|
+
"scs_float *c",
|
|
46
|
+
"ScsSettings *stgs"
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
m::Cone = struct [
|
|
50
|
+
"scs_int f",
|
|
51
|
+
"scs_int l",
|
|
52
|
+
"scs_int *q",
|
|
53
|
+
"scs_int qsize",
|
|
54
|
+
"scs_int *s",
|
|
55
|
+
"scs_int ssize",
|
|
56
|
+
"scs_int ep",
|
|
57
|
+
"scs_int ed",
|
|
58
|
+
"scs_float *p",
|
|
59
|
+
"scs_int psize",
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
m::Solution = struct [
|
|
63
|
+
"scs_float *x",
|
|
64
|
+
"scs_float *y",
|
|
65
|
+
"scs_float *s"
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
m::Info = struct [
|
|
69
|
+
"scs_int iter",
|
|
70
|
+
"char status[32]",
|
|
71
|
+
"scs_int status_val",
|
|
72
|
+
"scs_float pobj",
|
|
73
|
+
"scs_float dobj",
|
|
74
|
+
"scs_float res_pri",
|
|
75
|
+
"scs_float res_dual",
|
|
76
|
+
"scs_float res_infeas",
|
|
77
|
+
"scs_float res_unbdd",
|
|
78
|
+
"scs_float rel_gap",
|
|
79
|
+
"scs_float setup_time",
|
|
80
|
+
"scs_float solve_time"
|
|
81
|
+
]
|
|
82
|
+
|
|
83
|
+
m::Settings = struct [
|
|
84
|
+
"scs_int normalize",
|
|
85
|
+
"scs_float scale",
|
|
86
|
+
"scs_float rho_x",
|
|
87
|
+
"scs_int max_iters",
|
|
88
|
+
"scs_float eps",
|
|
89
|
+
"scs_float alpha",
|
|
90
|
+
"scs_float cg_rate",
|
|
91
|
+
"scs_int verbose",
|
|
92
|
+
"scs_int warm_start",
|
|
93
|
+
"scs_int acceleration_lookback",
|
|
94
|
+
"const char* write_data_filename"
|
|
95
|
+
]
|
|
96
|
+
|
|
97
|
+
m::Matrix = struct [
|
|
98
|
+
"scs_float *x",
|
|
99
|
+
"scs_int *i",
|
|
100
|
+
"scs_int *p",
|
|
101
|
+
"scs_int m",
|
|
102
|
+
"scs_int n"
|
|
103
|
+
]
|
|
104
|
+
|
|
105
|
+
# scs.h
|
|
106
|
+
extern "ScsWork *scs_init(const ScsData *d, const ScsCone *k, ScsInfo *info)"
|
|
107
|
+
extern "scs_int scs_solve(ScsWork *w, const ScsData *d, const ScsCone *k, ScsSolution *sol, ScsInfo *info)"
|
|
108
|
+
extern "void scs_finish(ScsWork *w)"
|
|
109
|
+
extern "scs_int scs(const ScsData *d, const ScsCone *k, ScsSolution *sol, ScsInfo *info)"
|
|
110
|
+
extern "const char *scs_version(void)"
|
|
111
|
+
|
|
112
|
+
# utils.h
|
|
113
|
+
extern "void scs_set_default_settings(ScsData *d)"
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
data/lib/scs/solver.rb
ADDED
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
module SCS
|
|
2
|
+
class Solver
|
|
3
|
+
def initialize(indirect: false)
|
|
4
|
+
@ffi = indirect ? FFI::Indirect : FFI::Direct
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def solve(data, cone, **settings)
|
|
8
|
+
cdata = create_data(data)
|
|
9
|
+
set_settings(cdata, settings)
|
|
10
|
+
ccone = create_cone(cone)
|
|
11
|
+
|
|
12
|
+
solution = calloc(ffi::Solution.size) # alloc clear memory
|
|
13
|
+
info = ffi::Info.malloc
|
|
14
|
+
|
|
15
|
+
ffi.scs(cdata, ccone, solution, info)
|
|
16
|
+
|
|
17
|
+
solution = ffi::Solution.new(solution)
|
|
18
|
+
x = read_float_array(solution.x, cdata.n)
|
|
19
|
+
y = read_float_array(solution.y, cdata.m)
|
|
20
|
+
s = read_float_array(solution.s, cdata.m)
|
|
21
|
+
|
|
22
|
+
{
|
|
23
|
+
x: x,
|
|
24
|
+
y: y,
|
|
25
|
+
s: s,
|
|
26
|
+
iter: info.iter,
|
|
27
|
+
status: read_string(info.status),
|
|
28
|
+
status_val: info.status_val,
|
|
29
|
+
pobj: info.pobj,
|
|
30
|
+
dobj: info.dobj,
|
|
31
|
+
res_pri: info.res_pri,
|
|
32
|
+
res_dual: info.res_dual,
|
|
33
|
+
res_infeas: info.res_infeas,
|
|
34
|
+
res_unbdd: info.res_unbdd,
|
|
35
|
+
rel_gap: info.rel_gap,
|
|
36
|
+
setup_time: info.setup_time,
|
|
37
|
+
solve_time: info.solve_time
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def check_result(ret)
|
|
44
|
+
raise Error, "Error code #{ret}" if ret != 0
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def read_string(char_ptr)
|
|
48
|
+
idx = char_ptr.index { |v| v == 0 }
|
|
49
|
+
char_ptr[0, idx].map(&:chr).join
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def float_array(arr)
|
|
53
|
+
# SCS float = double
|
|
54
|
+
Fiddle::Pointer[arr.to_a.pack("d*")]
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def read_float_array(ptr, size)
|
|
58
|
+
# SCS float = double
|
|
59
|
+
ptr[0, size * Fiddle::SIZEOF_DOUBLE].unpack("d*")
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def int_array(arr)
|
|
63
|
+
# SCS int = int
|
|
64
|
+
Fiddle::Pointer[arr.to_a.pack("i!*")]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def read_string(char_ptr)
|
|
68
|
+
idx = char_ptr.index { |v| v == 0 }
|
|
69
|
+
char_ptr[0, idx].map(&:chr).join
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# TODO add support sparse matrices
|
|
73
|
+
def csc_matrix(mtx, upper: false)
|
|
74
|
+
mtx = mtx.to_a
|
|
75
|
+
|
|
76
|
+
m, n = shape(mtx)
|
|
77
|
+
|
|
78
|
+
cx = []
|
|
79
|
+
ci = []
|
|
80
|
+
cp = []
|
|
81
|
+
|
|
82
|
+
# CSC format
|
|
83
|
+
# https://www.gormanalysis.com/blog/sparse-matrix-storage-formats/
|
|
84
|
+
cp << 0
|
|
85
|
+
n.times do |j|
|
|
86
|
+
mtx.each_with_index do |row, i|
|
|
87
|
+
if row[j] != 0 && (!upper || i <= j)
|
|
88
|
+
cx << row[j]
|
|
89
|
+
ci << i
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
# cumulative column values
|
|
93
|
+
cp << cx.size
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# construct matrix
|
|
97
|
+
matrix = ffi::Matrix.malloc
|
|
98
|
+
matrix.x = float_array(cx)
|
|
99
|
+
matrix.i = int_array(ci)
|
|
100
|
+
matrix.p = int_array(cp)
|
|
101
|
+
matrix.m = m
|
|
102
|
+
matrix.n = n
|
|
103
|
+
matrix
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def shape(a)
|
|
107
|
+
if defined?(Matrix) && a.is_a?(Matrix)
|
|
108
|
+
[a.row_count, a.column_count]
|
|
109
|
+
elsif defined?(Numo::NArray) && a.is_a?(Numo::NArray)
|
|
110
|
+
a.shape
|
|
111
|
+
else
|
|
112
|
+
[a.size, a.first.size]
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def create_data(data)
|
|
117
|
+
m, n = shape(data[:a])
|
|
118
|
+
cdata = ffi::Data.malloc
|
|
119
|
+
cdata.m = m
|
|
120
|
+
cdata.n = n
|
|
121
|
+
cdata.a = csc_matrix(data[:a])
|
|
122
|
+
cdata.b = float_array(data[:b])
|
|
123
|
+
cdata.c = float_array(data[:c])
|
|
124
|
+
cdata
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def create_cone(cone)
|
|
128
|
+
ccone = ffi::Cone.malloc
|
|
129
|
+
ccone.f = cone[:f].to_i
|
|
130
|
+
ccone.l = cone[:l].to_i
|
|
131
|
+
ccone.q = int_array(cone[:q])
|
|
132
|
+
ccone.qsize = cone[:q].to_a.size
|
|
133
|
+
ccone.s = int_array(cone[:s])
|
|
134
|
+
ccone.ssize = cone[:s].to_a.size
|
|
135
|
+
ccone.ep = cone[:ep].to_i
|
|
136
|
+
ccone.ed = cone[:ed].to_i
|
|
137
|
+
ccone.p = float_array(cone[:p])
|
|
138
|
+
ccone.psize = cone[:p].to_a.size
|
|
139
|
+
ccone
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def set_settings(data, settings)
|
|
143
|
+
set = ffi::Settings.malloc
|
|
144
|
+
data.stgs = set
|
|
145
|
+
ffi.scs_set_default_settings(data)
|
|
146
|
+
|
|
147
|
+
# hack for setting members with []=
|
|
148
|
+
# safer than send("#{k}=", v)
|
|
149
|
+
entity = set.to_ptr
|
|
150
|
+
settings.each do |k, v|
|
|
151
|
+
entity[k.to_s] = settings_value(v)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
set
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# handle booleans
|
|
158
|
+
def settings_value(v)
|
|
159
|
+
case v
|
|
160
|
+
when true
|
|
161
|
+
1
|
|
162
|
+
when false
|
|
163
|
+
0
|
|
164
|
+
else
|
|
165
|
+
v
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# alloc clear memory
|
|
170
|
+
def calloc(size)
|
|
171
|
+
Fiddle::Pointer["\x00" * size]
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
def ffi
|
|
175
|
+
@ffi
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
end
|
data/lib/scs/version.rb
ADDED
data/lib/scs.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# stdlib
|
|
2
|
+
require "fiddle/import"
|
|
3
|
+
|
|
4
|
+
# modules
|
|
5
|
+
require "scs/solver"
|
|
6
|
+
require "scs/version"
|
|
7
|
+
|
|
8
|
+
module SCS
|
|
9
|
+
class Error < StandardError; end
|
|
10
|
+
|
|
11
|
+
def self.lib_version
|
|
12
|
+
FFI::Direct.scs_version.to_s
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# friendlier error message
|
|
16
|
+
autoload :FFI, "scs/ffi"
|
|
17
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
The MIT License (MIT)
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2012 Brendan O'Donoghue (bodonoghue85@gmail.com)
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/vendor/scs/Makefile
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# MAKEFILE for scs
|
|
2
|
+
include scs.mk
|
|
3
|
+
|
|
4
|
+
SCS_OBJECTS = src/scs.o 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
|
|
5
|
+
|
|
6
|
+
SRC_FILES = $(wildcard src/*.c)
|
|
7
|
+
INC_FILES = $(wildcard include/*.h)
|
|
8
|
+
|
|
9
|
+
AMD_SOURCE = $(wildcard $(EXTSRC)/amd/*.c)
|
|
10
|
+
LDL_SOURCE = $(EXTSRC)/qdldl/qdldl.c
|
|
11
|
+
AMD_OBJS = $(AMD_SOURCE:.c=.o)
|
|
12
|
+
LDL_OBJS = $(LDL_SOURCE:.c=.o)
|
|
13
|
+
TARGETS = $(OUT)/demo_socp_indirect $(OUT)/demo_socp_direct $(OUT)/run_from_file_indirect $(OUT)/run_from_file_direct
|
|
14
|
+
|
|
15
|
+
.PHONY: default
|
|
16
|
+
|
|
17
|
+
default: $(TARGETS) $(OUT)/libscsdir.a $(OUT)/libscsindir.a $(OUT)/libscsdir.$(SHARED) $(OUT)/libscsindir.$(SHARED)
|
|
18
|
+
@echo "****************************************************************************************"
|
|
19
|
+
@echo "Successfully compiled scs, copyright Brendan O'Donoghue 2012."
|
|
20
|
+
@echo "To test, type '$(OUT)/demo_socp_indirect' to solve a random SOCP."
|
|
21
|
+
@echo "**********************************************************************************"
|
|
22
|
+
ifneq ($(USE_LAPACK), 0)
|
|
23
|
+
@echo "Compiled with blas and lapack, can solve LPs, SOCPs, SDPs, ECPs, and PCPs"
|
|
24
|
+
else
|
|
25
|
+
@echo "NOT compiled with blas/lapack, cannot solve SDPs (can solve LPs, SOCPs, ECPs, and PCPs)."
|
|
26
|
+
@echo "To solve SDPs, install blas and lapack, then edit scs.mk to set USE_LAPACK=1"
|
|
27
|
+
@echo "and point to the library install locations, and recompile with 'make purge', 'make'."
|
|
28
|
+
endif
|
|
29
|
+
@echo "****************************************************************************************"
|
|
30
|
+
|
|
31
|
+
%.o : src/%.c
|
|
32
|
+
$(CC) $(CFLAGS) -c $< -o $@
|
|
33
|
+
|
|
34
|
+
src/scs.o : $(SRC_FILES) $(INC_FILES)
|
|
35
|
+
src/util.o : src/util.c include/util.h include/glbopts.h
|
|
36
|
+
src/cones.o : src/cones.c include/cones.h include/scs_blas.h
|
|
37
|
+
src/aa.o : src/aa.c include/aa.h include/scs_blas.h
|
|
38
|
+
src/rw.o : src/rw.c include/rw.h
|
|
39
|
+
src/cs.o : src/cs.c include/cs.h
|
|
40
|
+
src/linalg.o: src/linalg.c include/linalg.h
|
|
41
|
+
src/ctrl.o : src/ctrl.c include/ctrl.h
|
|
42
|
+
src/scs_version.o: src/scs_version.c include/glbopts.h
|
|
43
|
+
|
|
44
|
+
$(DIRSRC)/private.o: $(DIRSRC)/private.c $(DIRSRC)/private.h
|
|
45
|
+
$(INDIRSRC)/indirect/private.o: $(INDIRSRC)/private.c $(INDIRSRC)/private.h
|
|
46
|
+
$(LINSYS)/amatrix.o: $(LINSYS)/amatrix.c $(LINSYS)/amatrix.h
|
|
47
|
+
|
|
48
|
+
$(OUT)/libscsdir.a: $(SCS_OBJECTS) $(DIRSRC)/private.o $(AMD_OBJS) $(LDL_OBJS) $(LINSYS)/amatrix.o
|
|
49
|
+
mkdir -p $(OUT)
|
|
50
|
+
$(ARCHIVE) $@ $^
|
|
51
|
+
- $(RANLIB) $@
|
|
52
|
+
|
|
53
|
+
$(OUT)/libscsindir.a: $(SCS_OBJECTS) $(INDIRSRC)/private.o $(LINSYS)/amatrix.o
|
|
54
|
+
mkdir -p $(OUT)
|
|
55
|
+
$(ARCHIVE) $@ $^
|
|
56
|
+
- $(RANLIB) $@
|
|
57
|
+
|
|
58
|
+
$(OUT)/libscsdir.$(SHARED): $(SCS_OBJECTS) $(DIRSRC)/private.o $(AMD_OBJS) $(LDL_OBJS) $(LINSYS)/amatrix.o
|
|
59
|
+
mkdir -p $(OUT)
|
|
60
|
+
$(CC) $(CFLAGS) -shared -Wl,$(SONAME),$(@:$(OUT)/%=%) -o $@ $^ $(LDFLAGS)
|
|
61
|
+
|
|
62
|
+
$(OUT)/libscsindir.$(SHARED): $(SCS_OBJECTS) $(INDIRSRC)/private.o $(LINSYS)/amatrix.o
|
|
63
|
+
mkdir -p $(OUT)
|
|
64
|
+
$(CC) $(CFLAGS) -shared -Wl,$(SONAME),$(@:$(OUT)/%=%) -o $@ $^ $(LDFLAGS)
|
|
65
|
+
|
|
66
|
+
$(OUT)/demo_socp_direct: test/random_socp_prob.c $(OUT)/libscsdir.a
|
|
67
|
+
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
|
68
|
+
|
|
69
|
+
$(OUT)/demo_socp_indirect: test/random_socp_prob.c $(OUT)/libscsindir.a
|
|
70
|
+
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
|
71
|
+
|
|
72
|
+
$(OUT)/run_from_file_direct: test/run_from_file.c $(OUT)/libscsdir.a
|
|
73
|
+
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
|
74
|
+
|
|
75
|
+
$(OUT)/run_from_file_indirect: test/run_from_file.c $(OUT)/libscsindir.a
|
|
76
|
+
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
|
|
77
|
+
|
|
78
|
+
$(OUT)/run_from_file_gpu_indirect: test/run_from_file.c $(OUT)/libscsgpuindir.a
|
|
79
|
+
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(CULDFLAGS)
|
|
80
|
+
|
|
81
|
+
# basic testing
|
|
82
|
+
.PHONY: test
|
|
83
|
+
test: $(OUT)/run_tests_indirect $(OUT)/run_tests_direct
|
|
84
|
+
$(OUT)/run_tests_indirect: test/run_tests.c $(OUT)/libscsindir.a
|
|
85
|
+
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -Itest
|
|
86
|
+
$(OUT)/run_tests_direct: test/run_tests.c $(OUT)/libscsdir.a
|
|
87
|
+
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -Itest
|
|
88
|
+
|
|
89
|
+
.PHONY: test_gpu
|
|
90
|
+
test_gpu: $(OUT)/run_tests_gpu_indirect # $(OUT)/run_tests_gpu_direct
|
|
91
|
+
|
|
92
|
+
$(OUT)/run_tests_gpu_indirect: test/run_tests.c $(OUT)/libscsgpuindir.a
|
|
93
|
+
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(CULDFLAGS) -Itest
|
|
94
|
+
|
|
95
|
+
# $(OUT)/run_tests_gpu_direct: test/run_tests.c $(OUT)/libscsgpudir.a
|
|
96
|
+
# $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(CULDFLAGS) -Itest
|
|
97
|
+
|
|
98
|
+
# REQUIRES GPU AND CUDA INSTALLED
|
|
99
|
+
gpu: gpu_indirect # gpu_direct
|
|
100
|
+
|
|
101
|
+
# gpu_direct: $(OUT)/demo_socp_gpu_direct $(OUT)/libscsgpudir.$(SHARED) $(OUT)/libscsgpudir.a $(OUT)/run_from_file_gpu_direct
|
|
102
|
+
gpu_indirect: $(OUT)/demo_socp_gpu_indirect $(OUT)/libscsgpuindir.$(SHARED) $(OUT)/libscsgpuindir.a $(OUT)/run_from_file_gpu_indirect
|
|
103
|
+
|
|
104
|
+
$(LINSYS)/gpu/gpu.o: $(LINSYS)/gpu/gpu.c
|
|
105
|
+
$(CUCC) -c -o $@ $^ $(CUDAFLAGS)
|
|
106
|
+
|
|
107
|
+
# $(GPUDIR)/private.o: $(GPUDIR)/private.c
|
|
108
|
+
# $(CUCC) -c -o $(GPUDIR)/private.o $^ $(CUDAFLAGS)
|
|
109
|
+
|
|
110
|
+
$(GPUINDIR)/private.o: $(GPUINDIR)/private.c
|
|
111
|
+
$(CUCC) -c -o $(GPUINDIR)/private.o $^ $(CUDAFLAGS)
|
|
112
|
+
|
|
113
|
+
# $(OUT)/libscsgpudir.$(SHARED): $(SCS_OBJECTS) $(GPUDIR)/private.o $(AMD_OBJS) $(LINSYS)/amatrix.o $(LINSYS)/gpu/gpu.o
|
|
114
|
+
# mkdir -p $(OUT)
|
|
115
|
+
# $(CC) $(CFLAGS) -shared -Wl,$(SONAME),$(@:$(OUT)/%=%) -o $@ $^ $(LDFLAGS) $(CULDFLAGS)
|
|
116
|
+
|
|
117
|
+
# $(OUT)/libscsgpudir.a: $(SCS_OBJECTS) $(GPUDIR)/private.o $(AMD_OBJS) $(LINSYS)/amatrix.o $(LINSYS)/gpu/gpu.o
|
|
118
|
+
# mkdir -p $(OUT)
|
|
119
|
+
# $(ARCHIVE) $@ $^
|
|
120
|
+
# - $(RANLIB) $@
|
|
121
|
+
|
|
122
|
+
$(OUT)/libscsgpuindir.$(SHARED): $(SCS_OBJECTS) $(GPUINDIR)/private.o $(LINSYS)/amatrix.o $(LINSYS)/gpu/gpu.o
|
|
123
|
+
mkdir -p $(OUT)
|
|
124
|
+
$(CC) $(CFLAGS) -shared -Wl,$(SONAME),$(@:$(OUT)/%=%) -o $@ $^ $(LDFLAGS) $(CULDFLAGS)
|
|
125
|
+
|
|
126
|
+
$(OUT)/libscsgpuindir.a: $(SCS_OBJECTS) $(GPUINDIR)/private.o $(LINSYS)/amatrix.o $(LINSYS)/gpu/gpu.o
|
|
127
|
+
mkdir -p $(OUT)
|
|
128
|
+
$(ARCHIVE) $@ $^
|
|
129
|
+
- $(RANLIB) $@
|
|
130
|
+
|
|
131
|
+
# $(OUT)/demo_socp_gpu_direct: test/random_socp_prob.c $(OUT)/libscsgpudir.a
|
|
132
|
+
# $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(CULDFLAGS)
|
|
133
|
+
|
|
134
|
+
$(OUT)/demo_socp_gpu_indirect: test/random_socp_prob.c $(OUT)/libscsgpuindir.a
|
|
135
|
+
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) $(CULDFLAGS)
|
|
136
|
+
|
|
137
|
+
.PHONY: clean purge
|
|
138
|
+
clean:
|
|
139
|
+
@rm -rf $(TARGETS) $(SCS_OBJECTS) $(AMD_OBJS) $(LDL_OBJS) $(LINSYS)/*.o $(DIRSRC)/*.o $(INDIRSRC)/*.o $(GPUDIR)/*.o $(GPUINDIR)/*.o
|
|
140
|
+
@rm -rf $(OUT)/*.dSYM
|
|
141
|
+
@rm -rf matlab/*.mex*
|
|
142
|
+
@rm -rf .idea
|
|
143
|
+
@rm -rf python/*.pyc
|
|
144
|
+
@rm -rf python/build
|
|
145
|
+
purge: clean
|
|
146
|
+
@rm -rf $(OUT)
|
|
147
|
+
|
|
148
|
+
INSTALL_INC_FILES = $(INC_FILES)
|
|
149
|
+
|
|
150
|
+
INSTALL_TARGETS = $(OUT)/libscsdir.a $(OUT)/libscsindir.a $(OUT)/libscsdir.$(SHARED) $(OUT)/libscsindir.$(SHARED)
|
|
151
|
+
INSTALL_GPU_TARGETS = $(OUT)/libscsgpuindir.a $(OUT)/libscsgpuindir.$(SHARED) # $(OUT)/libscsgpudir.a $(OUT)/libscsgpudir.$(SHARED)
|
|
152
|
+
|
|
153
|
+
INSTALL_INC_DIR = $(DESTDIR)$(PREFIX)/include/scs/
|
|
154
|
+
INSTALL_LIB_DIR = $(DESTDIR)$(PREFIX)/lib/
|
|
155
|
+
|
|
156
|
+
.PHONY: install install_gpu
|
|
157
|
+
install: $(INSTALL_INC_FILES) $(INSTALL_TARGETS)
|
|
158
|
+
$(INSTALL) -d $(INSTALL_INC_DIR) $(INSTALL_LIB_DIR)
|
|
159
|
+
$(INSTALL) -m 644 $(INSTALL_INC_FILES) $(INSTALL_INC_DIR)
|
|
160
|
+
$(INSTALL) -m 644 $(INSTALL_TARGETS) $(INSTALL_LIB_DIR)
|
|
161
|
+
install_gpu: $(INSTALL_INC_FILES) $(INSTALL_GPU_TARGETS)
|
|
162
|
+
$(INSTALL) -d $(INSTALL_INC_DIR) $(INSTALL_LIB_DIR)
|
|
163
|
+
$(INSTALL) -m 644 $(INSTALL_INC_FILES) $(INSTALL_INC_DIR)
|
|
164
|
+
$(INSTALL) -m 644 $(INSTALL_GPU_TARGETS) $(INSTALL_LIB_DIR)
|