lib/scs/solver.rb in scs-0.3.2 vs lib/scs/solver.rb in scs-0.4.0
- old
+ new
@@ -71,46 +71,39 @@
def read_string(char_ptr)
idx = char_ptr.index { |v| v == 0 }
char_ptr[0, idx].map(&:chr).join
end
- # TODO add support sparse matrices
def csc_matrix(mtx, upper: false)
- mtx = mtx.to_a
+ mtx = Matrix.from_dense(mtx) unless mtx.is_a?(Matrix)
- m, n = shape(mtx)
-
- cx = []
- ci = []
- cp = []
-
- # CSC format
- # https://www.gormanalysis.com/blog/sparse-matrix-storage-formats/
- cp << 0
- n.times do |j|
- mtx.each_with_index do |row, i|
- if row[j] != 0 && (!upper || i <= j)
- cx << row[j]
- ci << i
+ if upper
+ # TODO improve performance
+ mtx = mtx.dup
+ mtx.m.times do |i|
+ mtx.n.times do |j|
+ mtx[i, j] = 0 if i > j
end
end
- # cumulative column values
- cp << cx.size
end
+ csc = mtx.to_csc
+
# construct matrix
matrix = ffi::Matrix.malloc
- matrix.x = float_array(cx)
- matrix.i = int_array(ci)
- matrix.p = int_array(cp)
- matrix.m = m
- matrix.n = n
+ matrix.x = float_array(csc[:value])
+ matrix.i = int_array(csc[:index])
+ matrix.p = int_array(csc[:start])
+ matrix.m = mtx.m
+ matrix.n = mtx.n
matrix
end
def shape(a)
- if defined?(Matrix) && a.is_a?(Matrix)
+ if a.is_a?(Matrix)
+ [a.m, a.n]
+ elsif defined?(::Matrix) && a.is_a?(::Matrix)
[a.row_count, a.column_count]
elsif defined?(Numo::NArray) && a.is_a?(Numo::NArray)
a.shape
else
[a.size, a.first.size]
@@ -124,10 +117,10 @@
cdata.n = n
cdata.a = csc_matrix(data[:a])
if data[:p]
raise ArgumentError, "Bad p shape" if shape(data[:p]) != [n, n]
- cdata.p = csc_matrix(data[:p])
+ cdata.p = csc_matrix(data[:p], upper: true)
end
raise ArgumentError, "Bad b size" if data[:b].to_a.size != m
cdata.b = float_array(data[:b])