scs 0.3.2 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/LICENSE.txt +1 -1
- data/README.md +35 -6
- data/lib/scs/matrix.rb +72 -0
- data/lib/scs/solver.rb +19 -26
- data/lib/scs/version.rb +1 -1
- data/lib/scs.rb +1 -0
- data/vendor/scs/CITATION.cff +2 -2
- data/vendor/scs/CMakeLists.txt +285 -169
- data/vendor/scs/Makefile +43 -18
- data/vendor/scs/README.md +3 -1
- data/vendor/scs/include/cones.h +5 -3
- data/vendor/scs/include/glbopts.h +35 -17
- data/vendor/scs/include/linsys.h +8 -8
- data/vendor/scs/include/normalize.h +1 -0
- data/vendor/scs/include/rw.h +3 -3
- data/vendor/scs/include/scs.h +51 -24
- data/vendor/scs/include/scs_types.h +3 -1
- data/vendor/scs/include/scs_work.h +13 -15
- data/vendor/scs/include/util.h +4 -2
- data/vendor/scs/linsys/cpu/direct/private.c +32 -153
- data/vendor/scs/linsys/cpu/direct/private.h +6 -6
- data/vendor/scs/linsys/cpu/indirect/private.c +9 -22
- data/vendor/scs/linsys/cpu/indirect/private.h +4 -2
- data/vendor/scs/linsys/csparse.c +140 -12
- data/vendor/scs/linsys/csparse.h +10 -17
- data/vendor/scs/linsys/external/amd/LICENSE.txt +0 -897
- data/vendor/scs/linsys/external/amd/SuiteSparse_config.c +4 -2
- data/vendor/scs/linsys/external/amd/SuiteSparse_config.h +0 -5
- data/vendor/scs/linsys/gpu/gpu.c +4 -4
- data/vendor/scs/linsys/gpu/gpu.h +1 -1
- data/vendor/scs/linsys/gpu/indirect/private.c +15 -26
- data/vendor/scs/linsys/mkl/direct/private.c +182 -0
- data/vendor/scs/linsys/mkl/direct/private.h +38 -0
- data/vendor/scs/linsys/scs_matrix.c +49 -72
- data/vendor/scs/linsys/scs_matrix.h +4 -3
- data/vendor/scs/scs.mk +39 -30
- data/vendor/scs/src/aa.c +0 -4
- data/vendor/scs/src/cones.c +78 -184
- data/vendor/scs/src/exp_cone.c +399 -0
- data/vendor/scs/src/normalize.c +51 -0
- data/vendor/scs/src/rw.c +139 -76
- data/vendor/scs/src/scs.c +275 -202
- data/vendor/scs/src/util.c +36 -13
- data/vendor/scs/test/minunit.h +2 -1
- data/vendor/scs/test/problem_utils.h +5 -4
- data/vendor/scs/test/problems/degenerate.h +1 -0
- data/vendor/scs/test/problems/hs21_tiny_qp.h +2 -1
- data/vendor/scs/test/problems/hs21_tiny_qp_rw.h +13 -4
- data/vendor/scs/test/problems/infeasible_tiny_qp.h +1 -0
- data/vendor/scs/test/problems/max_ent +0 -0
- data/vendor/scs/test/problems/max_ent.h +8 -0
- data/vendor/scs/test/problems/qafiro_tiny_qp.h +2 -1
- data/vendor/scs/test/problems/random_prob.h +2 -39
- data/vendor/scs/test/problems/rob_gauss_cov_est.h +15 -3
- data/vendor/scs/test/problems/small_lp.h +4 -1
- data/vendor/scs/test/problems/small_qp.h +42 -7
- data/vendor/scs/test/problems/test_exp_cone.h +84 -0
- data/vendor/scs/test/problems/test_prob_from_data_file.h +57 -0
- data/vendor/scs/test/problems/test_validation.h +4 -1
- data/vendor/scs/test/problems/unbounded_tiny_qp.h +3 -3
- data/vendor/scs/test/random_socp_prob.c +3 -1
- data/vendor/scs/test/run_from_file.c +22 -4
- data/vendor/scs/test/run_tests.c +22 -9
- metadata +12 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9005db60b3ebc21bfe74e18fbd90db752801cce6232c5dcbbf9746ed6a3772b9
|
4
|
+
data.tar.gz: 8d1eade7f1501cbf46e820a2e7b20133f008e14d2bcc098629643a9b750b55b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 98ecf4f8beb7215e0ca44a57e3345b257054948c311e8e749f31d698e27c7f6c66ccbaaa71bbb091a92d4a23809b9b98a5d65767ee8d58e78cc7a8f08a32e042
|
7
|
+
data.tar.gz: 4701d88bad2ae68509fba757a922019400a78f8d8c2bdf0e33f35f7e409c49b0e8306d0cc3281a542508e3a73176042bf16a6039aee5101430ff378689791686
|
data/CHANGELOG.md
CHANGED
data/LICENSE.txt
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
3
|
Copyright (c) 2012 Brendan O'Donoghue (bodonoghue85@gmail.com)
|
4
|
-
Copyright (c) 2019-
|
4
|
+
Copyright (c) 2019-2023 Andrew Kane
|
5
5
|
|
6
6
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
7
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[SCS](https://github.com/cvxgrp/scs) - the splitting conic solver - for Ruby
|
4
4
|
|
5
|
-
|
5
|
+
Check out [Opt](https://github.com/ankane/opt) for a high-level interface
|
6
6
|
|
7
7
|
[](https://github.com/ankane/scs-ruby/actions)
|
8
8
|
|
@@ -18,11 +18,16 @@ If installation fails, you may need to install [dependencies](#dependencies).
|
|
18
18
|
|
19
19
|
## Getting Started
|
20
20
|
|
21
|
-
Prep the problem
|
21
|
+
Prep the problem, like [this one](https://www.cvxgrp.org/scs/examples/python/basic_qp.html)
|
22
22
|
|
23
23
|
```ruby
|
24
|
-
data = {
|
25
|
-
|
24
|
+
data = {
|
25
|
+
p: SCS::Matrix.from_dense([[3, -1], [-1, 2]]),
|
26
|
+
a: SCS::Matrix.from_dense([[-1, 1], [1, 0], [0, 1]]),
|
27
|
+
b: [-1, 0.3, -0.5],
|
28
|
+
c: [-1, -1]
|
29
|
+
}
|
30
|
+
cone = {z: 1, l: 2}
|
26
31
|
```
|
27
32
|
|
28
33
|
And solve it
|
@@ -32,12 +37,36 @@ solver = SCS::Solver.new
|
|
32
37
|
solver.solve(data, cone)
|
33
38
|
```
|
34
39
|
|
40
|
+
## Data
|
41
|
+
|
42
|
+
Matrices can be a sparse matrix
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
a = SCS::Matrix.new(3, 2)
|
46
|
+
a[0, 0] = 1
|
47
|
+
a[1, 0] = 2
|
48
|
+
# or
|
49
|
+
SCS::Matrix.from_dense([[1, 0], [2, 0], [0, 0]])
|
50
|
+
```
|
51
|
+
|
52
|
+
Arrays can be Ruby arrays
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
[1, 2, 3]
|
56
|
+
```
|
57
|
+
|
58
|
+
Or Numo arrays
|
59
|
+
|
60
|
+
```ruby
|
61
|
+
Numo::NArray.cast([1, 2, 3])
|
62
|
+
```
|
63
|
+
|
35
64
|
## Settings
|
36
65
|
|
37
66
|
Default values shown
|
38
67
|
|
39
68
|
```ruby
|
40
|
-
solver.solve(data, cone,
|
69
|
+
solver.solve(data, cone,
|
41
70
|
normalize: true, # heuristic data rescaling
|
42
71
|
scale: 0.1, # if normalized, rescales by this factor
|
43
72
|
adaptive_scale: true, # heuristically adapt dual scale through the solve
|
@@ -54,7 +83,7 @@ solver.solve(data, cone, {
|
|
54
83
|
acceleration_interval: 10, # iterations to run Anderson acceleration
|
55
84
|
write_data_filename: nil, # filename to write data if set
|
56
85
|
log_csv_filename: nil # write csv logs of various quantities
|
57
|
-
|
86
|
+
)
|
58
87
|
```
|
59
88
|
|
60
89
|
## Direct vs Indirect
|
data/lib/scs/matrix.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
module SCS
|
2
|
+
class Matrix
|
3
|
+
attr_reader :m, :n
|
4
|
+
|
5
|
+
def initialize(m, n)
|
6
|
+
@m = m
|
7
|
+
@n = n
|
8
|
+
@data = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def []=(row_index, column_index, value)
|
12
|
+
raise IndexError, "row index out of bounds" if row_index < 0 || row_index >= @m
|
13
|
+
raise IndexError, "column index out of bounds" if column_index < 0 || column_index >= @n
|
14
|
+
# dictionary of keys, optimized for converting to CSC
|
15
|
+
# TODO try COO for performance
|
16
|
+
if value == 0
|
17
|
+
(@data[column_index] ||= {}).delete(row_index)
|
18
|
+
else
|
19
|
+
(@data[column_index] ||= {})[row_index] = value
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_csc
|
24
|
+
cx = []
|
25
|
+
ci = []
|
26
|
+
cp = []
|
27
|
+
|
28
|
+
# CSC format
|
29
|
+
# https://www.gormanalysis.com/blog/sparse-matrix-storage-formats/
|
30
|
+
cp << 0
|
31
|
+
n.times do |j|
|
32
|
+
(@data[j] || {}).sort_by { |k, v| k }.each do |k, v|
|
33
|
+
cx << v
|
34
|
+
ci << k
|
35
|
+
end
|
36
|
+
# cumulative column values
|
37
|
+
cp << cx.size
|
38
|
+
end
|
39
|
+
|
40
|
+
{
|
41
|
+
start: cp,
|
42
|
+
index: ci,
|
43
|
+
value: cx
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
# private, for tests
|
48
|
+
def nnz
|
49
|
+
@data.sum { |_, v| v.count }
|
50
|
+
end
|
51
|
+
|
52
|
+
def initialize_copy(other)
|
53
|
+
super
|
54
|
+
@data = @data.transform_values(&:dup)
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.from_dense(data)
|
58
|
+
data = data.to_a
|
59
|
+
m = data.size
|
60
|
+
n = m > 0 ? data.first.size : 0
|
61
|
+
|
62
|
+
mtx = Matrix.new(m, n)
|
63
|
+
data.each_with_index do |row, i|
|
64
|
+
raise ArgumentError, "row has different number of columns" if row.size != n
|
65
|
+
row.each_with_index do |v, j|
|
66
|
+
mtx[i, j] = v if v != 0
|
67
|
+
end
|
68
|
+
end
|
69
|
+
mtx
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/lib/scs/solver.rb
CHANGED
@@ -73,42 +73,35 @@ module SCS
|
|
73
73
|
char_ptr[0, idx].map(&:chr).join
|
74
74
|
end
|
75
75
|
|
76
|
-
# TODO add support sparse matrices
|
77
76
|
def csc_matrix(mtx, upper: false)
|
78
|
-
mtx = mtx.
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
# CSC format
|
87
|
-
# https://www.gormanalysis.com/blog/sparse-matrix-storage-formats/
|
88
|
-
cp << 0
|
89
|
-
n.times do |j|
|
90
|
-
mtx.each_with_index do |row, i|
|
91
|
-
if row[j] != 0 && (!upper || i <= j)
|
92
|
-
cx << row[j]
|
93
|
-
ci << i
|
77
|
+
mtx = Matrix.from_dense(mtx) unless mtx.is_a?(Matrix)
|
78
|
+
|
79
|
+
if upper
|
80
|
+
# TODO improve performance
|
81
|
+
mtx = mtx.dup
|
82
|
+
mtx.m.times do |i|
|
83
|
+
mtx.n.times do |j|
|
84
|
+
mtx[i, j] = 0 if i > j
|
94
85
|
end
|
95
86
|
end
|
96
|
-
# cumulative column values
|
97
|
-
cp << cx.size
|
98
87
|
end
|
99
88
|
|
89
|
+
csc = mtx.to_csc
|
90
|
+
|
100
91
|
# construct matrix
|
101
92
|
matrix = ffi::Matrix.malloc
|
102
|
-
matrix.x = float_array(
|
103
|
-
matrix.i = int_array(
|
104
|
-
matrix.p = int_array(
|
105
|
-
matrix.m = m
|
106
|
-
matrix.n = n
|
93
|
+
matrix.x = float_array(csc[:value])
|
94
|
+
matrix.i = int_array(csc[:index])
|
95
|
+
matrix.p = int_array(csc[:start])
|
96
|
+
matrix.m = mtx.m
|
97
|
+
matrix.n = mtx.n
|
107
98
|
matrix
|
108
99
|
end
|
109
100
|
|
110
101
|
def shape(a)
|
111
|
-
if
|
102
|
+
if a.is_a?(Matrix)
|
103
|
+
[a.m, a.n]
|
104
|
+
elsif defined?(::Matrix) && a.is_a?(::Matrix)
|
112
105
|
[a.row_count, a.column_count]
|
113
106
|
elsif defined?(Numo::NArray) && a.is_a?(Numo::NArray)
|
114
107
|
a.shape
|
@@ -126,7 +119,7 @@ module SCS
|
|
126
119
|
|
127
120
|
if data[:p]
|
128
121
|
raise ArgumentError, "Bad p shape" if shape(data[:p]) != [n, n]
|
129
|
-
cdata.p = csc_matrix(data[:p])
|
122
|
+
cdata.p = csc_matrix(data[:p], upper: true)
|
130
123
|
end
|
131
124
|
|
132
125
|
raise ArgumentError, "Bad b size" if data[:b].to_a.size != m
|
data/lib/scs/version.rb
CHANGED
data/lib/scs.rb
CHANGED
data/vendor/scs/CITATION.cff
CHANGED