osqp 0.2.1 → 0.2.2
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 +4 -0
- data/README.md +2 -0
- data/lib/osqp/matrix.rb +17 -9
- data/lib/osqp/solver.rb +33 -8
- data/lib/osqp/version.rb +1 -1
- data/lib/osqp.rb +0 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f94b0363a8ee43efba253d1138642c54832aed26cd2bc7d8e4bfb064453754fd
|
4
|
+
data.tar.gz: 673f1fa4d56747e26e0ab36cdd642c21d2c0d93c6233bb37502cfff805421d54
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4af98ca5b0b140d3f20e82b64220583f3a0b720a45da74ea25ff4ca6b1921188d14ef12c8f4fb87e171c55f3e166ac8572c6856e94aae484687b8193e90ee6c2
|
7
|
+
data.tar.gz: df8999d0333e4467223931e89e5ad1b88567dca38f502a387e1077f21a652fdf86ab6c5171c56d030122eeba85f4265eba9d1737481a7f79a77cc8e6a1fe410e
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
The [OSQP](https://osqp.org/) (Operator Splitting Quadratic Program) solver for Ruby
|
4
4
|
|
5
|
+
Check out [Opt](https://github.com/ankane/opt) for a high-level interface
|
6
|
+
|
5
7
|
[](https://github.com/ankane/osqp-ruby/actions)
|
6
8
|
|
7
9
|
## Installation
|
data/lib/osqp/matrix.rb
CHANGED
@@ -11,6 +11,8 @@ module OSQP
|
|
11
11
|
def []=(row_index, column_index, value)
|
12
12
|
raise IndexError, "row index out of bounds" if row_index < 0 || row_index >= @m
|
13
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
|
14
16
|
if value == 0
|
15
17
|
(@data[column_index] ||= {}).delete(row_index)
|
16
18
|
else
|
@@ -18,7 +20,7 @@ module OSQP
|
|
18
20
|
end
|
19
21
|
end
|
20
22
|
|
21
|
-
def
|
23
|
+
def to_csc
|
22
24
|
cx = []
|
23
25
|
ci = []
|
24
26
|
cp = []
|
@@ -35,15 +37,21 @@ module OSQP
|
|
35
37
|
cp << cx.size
|
36
38
|
end
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
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
|
42
51
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
ptr
|
52
|
+
def initialize_copy(other)
|
53
|
+
super
|
54
|
+
@data = @data.transform_values(&:dup)
|
47
55
|
end
|
48
56
|
|
49
57
|
def self.from_dense(data)
|
data/lib/osqp/solver.rb
CHANGED
@@ -11,17 +11,17 @@ module OSQP
|
|
11
11
|
# data
|
12
12
|
# do not assign directly to struct to keep refs
|
13
13
|
p = csc_matrix(p, upper: true)
|
14
|
-
q =
|
14
|
+
q = float_array(q)
|
15
15
|
a = csc_matrix(a)
|
16
|
-
l =
|
17
|
-
u =
|
16
|
+
l = float_array(l)
|
17
|
+
u = float_array(u)
|
18
18
|
|
19
19
|
data = FFI::Data.malloc
|
20
20
|
data.n = a.n
|
21
21
|
data.m = a.m
|
22
|
-
data.p = p
|
22
|
+
data.p = matrix_ptr(p)
|
23
23
|
data.q = q
|
24
|
-
data.a = a
|
24
|
+
data.a = matrix_ptr(a)
|
25
25
|
data.l = l
|
26
26
|
data.u = u
|
27
27
|
|
@@ -73,11 +73,11 @@ module OSQP
|
|
73
73
|
raise Error, "Expected y to be size #{m}, got #{y.size}" if y && y.size != m
|
74
74
|
|
75
75
|
if x && y
|
76
|
-
check_result FFI.osqp_warm_start(@work,
|
76
|
+
check_result FFI.osqp_warm_start(@work, float_array(x), float_array(y))
|
77
77
|
elsif x
|
78
|
-
check_result FFI.osqp_warm_start_x(@work,
|
78
|
+
check_result FFI.osqp_warm_start_x(@work, float_array(x))
|
79
79
|
elsif y
|
80
|
-
check_result FFI.osqp_warm_start_y(@work,
|
80
|
+
check_result FFI.osqp_warm_start_y(@work, float_array(y))
|
81
81
|
else
|
82
82
|
raise Error, "Must set x or y"
|
83
83
|
end
|
@@ -113,6 +113,16 @@ module OSQP
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
+
def float_array(arr)
|
117
|
+
# OSQP float = double
|
118
|
+
Fiddle::Pointer[arr.to_a.pack("d*")]
|
119
|
+
end
|
120
|
+
|
121
|
+
def int_array(arr)
|
122
|
+
# OSQP int = long long
|
123
|
+
Fiddle::Pointer[arr.to_a.pack("q*")]
|
124
|
+
end
|
125
|
+
|
116
126
|
def read_float_array(ptr, size)
|
117
127
|
# OSQP float = double
|
118
128
|
ptr[0, size * Fiddle::SIZEOF_DOUBLE].unpack("d*")
|
@@ -127,6 +137,8 @@ module OSQP
|
|
127
137
|
mtx = Matrix.from_dense(mtx) unless mtx.is_a?(Matrix)
|
128
138
|
|
129
139
|
if upper
|
140
|
+
# TODO improve performance
|
141
|
+
mtx = mtx.dup
|
130
142
|
mtx.m.times do |i|
|
131
143
|
mtx.n.times do |j|
|
132
144
|
mtx[i, j] = 0 if i > j
|
@@ -137,6 +149,19 @@ module OSQP
|
|
137
149
|
mtx
|
138
150
|
end
|
139
151
|
|
152
|
+
def matrix_ptr(mtx)
|
153
|
+
csc = mtx.to_csc
|
154
|
+
nnz = csc[:value].size
|
155
|
+
cx = float_array(csc[:value])
|
156
|
+
ci = int_array(csc[:index])
|
157
|
+
cp = int_array(csc[:start])
|
158
|
+
|
159
|
+
ptr = FFI.csc_matrix(mtx.m, mtx.n, nnz, cx, ci, cp)
|
160
|
+
# save refs
|
161
|
+
ptr.instance_variable_set(:@osqp_refs, [cx, ci, cp])
|
162
|
+
ptr
|
163
|
+
end
|
164
|
+
|
140
165
|
def dimensions
|
141
166
|
data = FFI::Data.new(@work.data)
|
142
167
|
[data.m, data.n]
|
data/lib/osqp/version.rb
CHANGED
data/lib/osqp.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: osqp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email: andrew@ankane.org
|
@@ -70,7 +70,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
70
|
- !ruby/object:Gem::Version
|
71
71
|
version: '0'
|
72
72
|
requirements: []
|
73
|
-
rubygems_version: 3.
|
73
|
+
rubygems_version: 3.4.1
|
74
74
|
signing_key:
|
75
75
|
specification_version: 4
|
76
76
|
summary: OSQP (Operator Splitting Quadratic Program) solver for Ruby
|