lib/osqp/solver.rb in osqp-0.1.3 vs lib/osqp/solver.rb in osqp-0.2.0
- old
+ new
@@ -2,21 +2,31 @@
class Solver
def setup(p, q, a, l, u, **settings)
# settings
set = create_settings(settings)
+ # ensure bounds within OSQP infinity
+ l = l.map { |v| v < -FFI::OSQP_INFTY ? -FFI::OSQP_INFTY : v }
+ u = u.map { |v| v > FFI::OSQP_INFTY ? FFI::OSQP_INFTY : v }
+
# data
- refs = []
+ # do not assign directly to struct to keep refs
m, n = shape(a)
+ p = csc_matrix(p, upper: true)
+ q = float_array(q)
+ a = csc_matrix(a)
+ l = float_array(l)
+ u = float_array(u)
+
data = FFI::Data.malloc
data.n = n
data.m = m
- data.p = csc_matrix(p, refs, upper: true)
- data.q = float_array(q, refs)
- data.a = csc_matrix(a, refs)
- data.l = float_array(l, refs)
- data.u = float_array(u, refs)
+ data.p = p
+ data.q = q
+ data.a = a
+ data.l = l
+ data.u = u
# work
work = FFI::Workspace.malloc
check_result FFI.osqp_setup(work.to_ptr.ref, data, set)
@work = work
@@ -102,22 +112,18 @@
raise Error, message
end
end
- def float_array(arr, refs = nil)
+ def float_array(arr)
# OSQP float = double
- ptr = Fiddle::Pointer[arr.to_a.pack("d*")]
- refs << ptr if refs
- ptr
+ Fiddle::Pointer[arr.to_a.pack("d*")]
end
- def int_array(arr, refs = nil)
+ def int_array(arr)
# OSQP int = long long
- ptr = Fiddle::Pointer[arr.to_a.pack("q*")]
- refs << ptr if refs
- ptr
+ Fiddle::Pointer[arr.to_a.pack("q*")]
end
def read_float_array(ptr, size)
# OSQP float = double
ptr[0, size * Fiddle::SIZEOF_DOUBLE].unpack("d*")
@@ -127,11 +133,11 @@
idx = char_ptr.index { |v| v == 0 }
char_ptr[0, idx].map(&:chr).join
end
# TODO add support sparse matrices
- def csc_matrix(mtx, refs, upper: false)
+ def csc_matrix(mtx, upper: false)
mtx = mtx.to_a
m, n = shape(mtx)
cx = []
@@ -151,14 +157,17 @@
# cumulative column values
cp << cx.size
end
nnz = cx.size
- cx = float_array(cx, refs)
- ci = int_array(ci, refs)
- cp = int_array(cp, refs)
+ cx = float_array(cx)
+ ci = int_array(ci)
+ cp = int_array(cp)
- FFI.csc_matrix(m, n, nnz, cx, ci, cp)
+ ptr = FFI.csc_matrix(m, n, nnz, cx, ci, cp)
+ # save refs
+ ptr.instance_variable_set(:@osqp_refs, [cx, ci, cp])
+ ptr
end
def dimensions
data = FFI::Data.new(@work.data)
[data.m, data.n]