pnmatrix 1.2.4
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/ext/nmatrix/binary_format.txt +53 -0
- data/ext/nmatrix/data/complex.h +388 -0
- data/ext/nmatrix/data/data.cpp +274 -0
- data/ext/nmatrix/data/data.h +651 -0
- data/ext/nmatrix/data/meta.h +64 -0
- data/ext/nmatrix/data/ruby_object.h +386 -0
- data/ext/nmatrix/extconf.rb +70 -0
- data/ext/nmatrix/math/asum.h +99 -0
- data/ext/nmatrix/math/cblas_enums.h +36 -0
- data/ext/nmatrix/math/cblas_templates_core.h +507 -0
- data/ext/nmatrix/math/gemm.h +241 -0
- data/ext/nmatrix/math/gemv.h +178 -0
- data/ext/nmatrix/math/getrf.h +255 -0
- data/ext/nmatrix/math/getrs.h +121 -0
- data/ext/nmatrix/math/imax.h +82 -0
- data/ext/nmatrix/math/laswp.h +165 -0
- data/ext/nmatrix/math/long_dtype.h +62 -0
- data/ext/nmatrix/math/magnitude.h +54 -0
- data/ext/nmatrix/math/math.h +751 -0
- data/ext/nmatrix/math/nrm2.h +165 -0
- data/ext/nmatrix/math/rot.h +117 -0
- data/ext/nmatrix/math/rotg.h +106 -0
- data/ext/nmatrix/math/scal.h +71 -0
- data/ext/nmatrix/math/trsm.h +336 -0
- data/ext/nmatrix/math/util.h +162 -0
- data/ext/nmatrix/math.cpp +1368 -0
- data/ext/nmatrix/nm_memory.h +60 -0
- data/ext/nmatrix/nmatrix.cpp +285 -0
- data/ext/nmatrix/nmatrix.h +476 -0
- data/ext/nmatrix/ruby_constants.cpp +151 -0
- data/ext/nmatrix/ruby_constants.h +106 -0
- data/ext/nmatrix/ruby_nmatrix.c +3130 -0
- data/ext/nmatrix/storage/common.cpp +77 -0
- data/ext/nmatrix/storage/common.h +183 -0
- data/ext/nmatrix/storage/dense/dense.cpp +1096 -0
- data/ext/nmatrix/storage/dense/dense.h +129 -0
- data/ext/nmatrix/storage/list/list.cpp +1628 -0
- data/ext/nmatrix/storage/list/list.h +138 -0
- data/ext/nmatrix/storage/storage.cpp +730 -0
- data/ext/nmatrix/storage/storage.h +99 -0
- data/ext/nmatrix/storage/yale/class.h +1139 -0
- data/ext/nmatrix/storage/yale/iterators/base.h +143 -0
- data/ext/nmatrix/storage/yale/iterators/iterator.h +131 -0
- data/ext/nmatrix/storage/yale/iterators/row.h +450 -0
- data/ext/nmatrix/storage/yale/iterators/row_stored.h +140 -0
- data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +169 -0
- data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +124 -0
- data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
- data/ext/nmatrix/storage/yale/yale.cpp +2074 -0
- data/ext/nmatrix/storage/yale/yale.h +203 -0
- data/ext/nmatrix/types.h +55 -0
- data/ext/nmatrix/util/io.cpp +279 -0
- data/ext/nmatrix/util/io.h +115 -0
- data/ext/nmatrix/util/sl_list.cpp +627 -0
- data/ext/nmatrix/util/sl_list.h +144 -0
- data/ext/nmatrix/util/util.h +78 -0
- data/lib/nmatrix/blas.rb +378 -0
- data/lib/nmatrix/cruby/math.rb +744 -0
- data/lib/nmatrix/enumerate.rb +253 -0
- data/lib/nmatrix/homogeneous.rb +241 -0
- data/lib/nmatrix/io/fortran_format.rb +138 -0
- data/lib/nmatrix/io/harwell_boeing.rb +221 -0
- data/lib/nmatrix/io/market.rb +263 -0
- data/lib/nmatrix/io/point_cloud.rb +189 -0
- data/lib/nmatrix/jruby/decomposition.rb +24 -0
- data/lib/nmatrix/jruby/enumerable.rb +13 -0
- data/lib/nmatrix/jruby/error.rb +4 -0
- data/lib/nmatrix/jruby/math.rb +501 -0
- data/lib/nmatrix/jruby/nmatrix_java.rb +840 -0
- data/lib/nmatrix/jruby/operators.rb +283 -0
- data/lib/nmatrix/jruby/slice.rb +264 -0
- data/lib/nmatrix/lapack_core.rb +181 -0
- data/lib/nmatrix/lapack_plugin.rb +44 -0
- data/lib/nmatrix/math.rb +953 -0
- data/lib/nmatrix/mkmf.rb +100 -0
- data/lib/nmatrix/monkeys.rb +137 -0
- data/lib/nmatrix/nmatrix.rb +1172 -0
- data/lib/nmatrix/rspec.rb +75 -0
- data/lib/nmatrix/shortcuts.rb +1163 -0
- data/lib/nmatrix/version.rb +39 -0
- data/lib/nmatrix/yale_functions.rb +118 -0
- data/lib/nmatrix.rb +28 -0
- data/spec/00_nmatrix_spec.rb +892 -0
- data/spec/01_enum_spec.rb +196 -0
- data/spec/02_slice_spec.rb +407 -0
- data/spec/03_nmatrix_monkeys_spec.rb +80 -0
- data/spec/2x2_dense_double.mat +0 -0
- data/spec/4x4_sparse.mat +0 -0
- data/spec/4x5_dense.mat +0 -0
- data/spec/blas_spec.rb +215 -0
- data/spec/elementwise_spec.rb +311 -0
- data/spec/homogeneous_spec.rb +100 -0
- data/spec/io/fortran_format_spec.rb +88 -0
- data/spec/io/harwell_boeing_spec.rb +98 -0
- data/spec/io/test.rua +9 -0
- data/spec/io_spec.rb +159 -0
- data/spec/lapack_core_spec.rb +482 -0
- data/spec/leakcheck.rb +16 -0
- data/spec/math_spec.rb +1363 -0
- data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
- data/spec/nmatrix_yale_spec.rb +286 -0
- data/spec/rspec_monkeys.rb +56 -0
- data/spec/rspec_spec.rb +35 -0
- data/spec/shortcuts_spec.rb +474 -0
- data/spec/slice_set_spec.rb +162 -0
- data/spec/spec_helper.rb +172 -0
- data/spec/stat_spec.rb +214 -0
- data/spec/test.pcd +20 -0
- data/spec/utm5940.mtx +83844 -0
- metadata +295 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# = NMatrix
|
|
2
|
+
#
|
|
3
|
+
# A linear algebra library for scientific computation in Ruby.
|
|
4
|
+
# NMatrix is part of SciRuby.
|
|
5
|
+
#
|
|
6
|
+
# NMatrix was originally inspired by and derived from NArray, by
|
|
7
|
+
# Masahiro Tanaka: http://narray.rubyforge.org
|
|
8
|
+
#
|
|
9
|
+
# == Copyright Information
|
|
10
|
+
#
|
|
11
|
+
# SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
|
|
12
|
+
# NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
|
|
13
|
+
#
|
|
14
|
+
# Please see LICENSE.txt for additional copyright notices.
|
|
15
|
+
#
|
|
16
|
+
# == Contributing
|
|
17
|
+
#
|
|
18
|
+
# By contributing source code to SciRuby, you agree to be bound by
|
|
19
|
+
# our Contributor Agreement:
|
|
20
|
+
#
|
|
21
|
+
# * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
|
|
22
|
+
#
|
|
23
|
+
# == 01_enum_spec.rb
|
|
24
|
+
#
|
|
25
|
+
# Enumerator tests for NMatrix. These should load early, as they
|
|
26
|
+
# test functionality essential to matrix printing.
|
|
27
|
+
#
|
|
28
|
+
require 'spec_helper'
|
|
29
|
+
|
|
30
|
+
describe "NMatrix enumeration for" do
|
|
31
|
+
[:dense, :yale, :list].each do |stype|
|
|
32
|
+
context stype do
|
|
33
|
+
let(:n) { create_rectangular_matrix(stype) }
|
|
34
|
+
let(:m) { n[1..4,1..3] }
|
|
35
|
+
|
|
36
|
+
if stype == :yale
|
|
37
|
+
it "should iterate properly along each row of a slice" do
|
|
38
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
39
|
+
vv = []
|
|
40
|
+
ii = []
|
|
41
|
+
jj = []
|
|
42
|
+
m.extend NMatrix::YaleFunctions
|
|
43
|
+
m.each_row do |row|
|
|
44
|
+
row.each_with_indices do |v,i,j|
|
|
45
|
+
vv << v
|
|
46
|
+
ii << i
|
|
47
|
+
jj << j
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
expect(vv).to eq([7,8,9, 12,13,0, 0,0,0, 0,17,18])
|
|
52
|
+
expect(ii).to eq([0]*12)
|
|
53
|
+
expect(jj).to eq([0,1,2]*4)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "should iterate along diagonal portion of A array" do
|
|
57
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
58
|
+
vv = []
|
|
59
|
+
ii = []
|
|
60
|
+
jj = []
|
|
61
|
+
n.send :__yale_stored_diagonal_each_with_indices__ do |v,i,j|
|
|
62
|
+
vv << v
|
|
63
|
+
ii << i
|
|
64
|
+
jj << j
|
|
65
|
+
end
|
|
66
|
+
expect(vv).to eq([1,7,13,0,19])
|
|
67
|
+
expect(ii).to eq([0,1,2,3,4])
|
|
68
|
+
expect(jj).to eq(ii)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "should iterate along non-diagonal portion of A array" do
|
|
72
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
73
|
+
vv = []
|
|
74
|
+
ii = []
|
|
75
|
+
jj = []
|
|
76
|
+
n.send :__yale_stored_nondiagonal_each_with_indices__ do |v,i,j|
|
|
77
|
+
vv << v
|
|
78
|
+
ii << i
|
|
79
|
+
jj << j
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
expect(vv).to eq([2,3,4,5, 6,8,9,10, 11,12,14,15, 16,17,18,20])
|
|
83
|
+
expect(ii).to eq([[0]*4, [1]*4, [2]*4, [4]*4].flatten)
|
|
84
|
+
expect(jj).to eq([1,2,3,4, 0,2,3,5, 0,1,4,5, 0,2,3,5])
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it "should iterate along a sliced diagonal portion of an A array" do
|
|
88
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
89
|
+
m = n[0..3,1..3]
|
|
90
|
+
vv = []
|
|
91
|
+
ii = []
|
|
92
|
+
jj = []
|
|
93
|
+
m.send :__yale_stored_diagonal_each_with_indices__ do |v,i,j|
|
|
94
|
+
vv << v
|
|
95
|
+
ii << i
|
|
96
|
+
jj << j
|
|
97
|
+
end
|
|
98
|
+
expect(vv).to eq([7,13,0])
|
|
99
|
+
expect(ii).to eq([1,2,3])
|
|
100
|
+
expect(jj).to eq([0,1,2])
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "should iterate along a sliced non-diagonal portion of a sliced A array" do
|
|
104
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
105
|
+
vv = []
|
|
106
|
+
ii = []
|
|
107
|
+
jj = []
|
|
108
|
+
n.extend NMatrix::YaleFunctions
|
|
109
|
+
m.extend NMatrix::YaleFunctions
|
|
110
|
+
m.send :__yale_stored_nondiagonal_each_with_indices__ do |v,i,j|
|
|
111
|
+
vv << v
|
|
112
|
+
ii << i
|
|
113
|
+
jj << j
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
expect(ii).to eq([0,0, 1, 3,3 ])
|
|
117
|
+
expect(jj).to eq([1,2, 0, 1,2 ])
|
|
118
|
+
expect(vv).to eq([8,9, 12, 17,18])
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it "should visit each stored element of the matrix in order by indices" do
|
|
122
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
123
|
+
vv = []
|
|
124
|
+
ii = []
|
|
125
|
+
jj = []
|
|
126
|
+
n.each_ordered_stored_with_indices do |v,i,j|
|
|
127
|
+
vv << v
|
|
128
|
+
ii << i
|
|
129
|
+
jj << j
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
expect(vv).to eq([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 16, 17, 18, 19, 20])
|
|
133
|
+
expect(ii).to eq([[0]*5, [1]*5, [2]*5, [3]*1, [4]*5].flatten)
|
|
134
|
+
expect(jj).to eq([0,1,2,3,4, 0,1,2,3,5, 0,1,2,4,5, 3, 0,2,3,4,5])
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
it "should visit each stored element of the slice in order by indices" do
|
|
138
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
139
|
+
vv = []
|
|
140
|
+
ii = []
|
|
141
|
+
jj = []
|
|
142
|
+
m.each_ordered_stored_with_indices do |v,i,j|
|
|
143
|
+
vv << v
|
|
144
|
+
ii << i
|
|
145
|
+
jj << j
|
|
146
|
+
end
|
|
147
|
+
expect(ii).to eq([0,0,0, 1,1, 2, 3,3 ])
|
|
148
|
+
expect(jj).to eq([0,1,2, 0,1, 2, 1,2 ])
|
|
149
|
+
expect(vv).to eq([7,8,9, 12,13, 0, 17,18 ])
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
it "should visit each cell in the matrix as if dense, making indices available" do
|
|
154
|
+
vv = []
|
|
155
|
+
ii = []
|
|
156
|
+
jj = []
|
|
157
|
+
n.each_with_indices do |v,i,j|
|
|
158
|
+
vv << v
|
|
159
|
+
ii << i
|
|
160
|
+
jj << j
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
expect(vv).to eq([1,2,3,4,5,0,6,7,8,9,0,10,11,12,13,0,14,15,0,0,0,0,0,0,16,0,17,18,19,20])
|
|
164
|
+
expect(ii).to eq([[0]*6, [1]*6, [2]*6, [3]*6, [4]*6].flatten)
|
|
165
|
+
expect(jj).to eq([0,1,2,3,4,5]*5)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
it "should visit each cell in the slice as if dense, making indices available" do
|
|
169
|
+
vv = []
|
|
170
|
+
ii = []
|
|
171
|
+
jj = []
|
|
172
|
+
m.each_with_indices do |v,i,j|
|
|
173
|
+
vv << v
|
|
174
|
+
ii << i
|
|
175
|
+
jj << j
|
|
176
|
+
end
|
|
177
|
+
expect(jj).to eq([0,1,2]*4)
|
|
178
|
+
expect(ii).to eq([[0]*3, [1]*3, [2]*3, [3]*3].flatten)
|
|
179
|
+
expect(vv).to eq([7,8,9,12,13,0,0,0,0,0,17,18])
|
|
180
|
+
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
if stype == :list or stype == :dense then
|
|
184
|
+
it "should correctly map to a matrix with a single element" do
|
|
185
|
+
nm = N.new([1], [2.0], stype: stype)
|
|
186
|
+
expect(nm.map { |e| e**2 }).to eq N.new([1], [4.0], stype: stype)
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
it "should correctly map to a matrix with multiple elements" do
|
|
190
|
+
nm = N.new([2], [2.0, 2.0], stype: stype)
|
|
191
|
+
expect(nm.map { |e| e**2 }).to eq N.new([2], [4.0, 4.0], stype: stype)
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|
|
196
|
+
end
|
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
# = NMatrix
|
|
2
|
+
#
|
|
3
|
+
# A linear algebra library for scientific computation in Ruby.
|
|
4
|
+
# NMatrix is part of SciRuby.
|
|
5
|
+
#
|
|
6
|
+
# NMatrix was originally inspired by and derived from NArray, by
|
|
7
|
+
# Masahiro Tanaka: http://narray.rubyforge.org
|
|
8
|
+
#
|
|
9
|
+
# == Copyright Information
|
|
10
|
+
#
|
|
11
|
+
# SciRuby is Copyright (c) 2010 - 2014, Ruby Science Foundation
|
|
12
|
+
# NMatrix is Copyright (c) 2012 - 2014, John Woods and the Ruby Science Foundation
|
|
13
|
+
#
|
|
14
|
+
# Please see LICENSE.txt for additional copyright notices.
|
|
15
|
+
#
|
|
16
|
+
# == Contributing
|
|
17
|
+
#
|
|
18
|
+
# By contributing source code to SciRuby, you agree to be bound by
|
|
19
|
+
# our Contributor Agreement:
|
|
20
|
+
#
|
|
21
|
+
# * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
|
|
22
|
+
#
|
|
23
|
+
# == 02_slice_spec.rb
|
|
24
|
+
#
|
|
25
|
+
# Test of slice operations. High priority tests since reference
|
|
26
|
+
# slicing is needed for pretty_print.
|
|
27
|
+
#
|
|
28
|
+
require 'spec_helper'
|
|
29
|
+
|
|
30
|
+
describe "Slice operation" do
|
|
31
|
+
include RSpec::Longrun::DSL
|
|
32
|
+
|
|
33
|
+
[:dense, :list, :yale].each do |stype|
|
|
34
|
+
context "for #{stype}" do
|
|
35
|
+
#GC.start # don't have to do this, but it helps to make sure we've cleaned up our pointers properly.
|
|
36
|
+
let(:stype_matrix) { create_matrix(stype) }
|
|
37
|
+
|
|
38
|
+
it "should correctly return a row of a reference-slice" do
|
|
39
|
+
n = create_rectangular_matrix(stype)
|
|
40
|
+
stype_matrix = n[1..4,1..3]
|
|
41
|
+
expect(stype_matrix.row(1, :copy)).to eq(stype_matrix.row(1, :reference))
|
|
42
|
+
expect(stype_matrix.row(1, :copy).to_flat_array).to eq([12,13,0])
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
if stype == :yale
|
|
46
|
+
it "should binary search for the left boundary of a partial row of stored indices correctly" do
|
|
47
|
+
#FIXME
|
|
48
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
49
|
+
n = NMatrix.new(10, stype: :yale, dtype: :int32)
|
|
50
|
+
n[3,0] = 1
|
|
51
|
+
#n[3,2] = 2
|
|
52
|
+
n[3,3] = 3
|
|
53
|
+
n[3,4] = 4
|
|
54
|
+
n[3,6] = 5
|
|
55
|
+
n[3,8] = 6
|
|
56
|
+
n[3,9] = 7
|
|
57
|
+
vs = []
|
|
58
|
+
is = []
|
|
59
|
+
js = []
|
|
60
|
+
|
|
61
|
+
n[3,1..9].each_stored_with_indices do |v,i,j|
|
|
62
|
+
vs << v
|
|
63
|
+
is << i
|
|
64
|
+
js << j
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
expect(vs).to eq([3,4,5,6,7])
|
|
68
|
+
expect(js).to eq([2,3,5,7,8])
|
|
69
|
+
expect(is).to eq([0,0,0,0,0])
|
|
70
|
+
end
|
|
71
|
+
elsif stype == :list
|
|
72
|
+
it "should iterate across a partial row of stored indices" do
|
|
73
|
+
vs = []
|
|
74
|
+
is = []
|
|
75
|
+
js = []
|
|
76
|
+
|
|
77
|
+
STDERR.puts("now") if stype == :yale
|
|
78
|
+
stype_matrix[2,1..2].each_stored_with_indices do |v,i,j|
|
|
79
|
+
vs << v
|
|
80
|
+
is << i
|
|
81
|
+
js << j
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
expect(vs).to eq([7,8])
|
|
85
|
+
expect(is).to eq([0,0])
|
|
86
|
+
expect(js).to eq([0,1])
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
unless stype == :dense
|
|
91
|
+
it "should iterate across a row of stored indices" do
|
|
92
|
+
#FIXME
|
|
93
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
94
|
+
vs = []
|
|
95
|
+
is = []
|
|
96
|
+
js = []
|
|
97
|
+
stype_matrix[2,0..2].each_stored_with_indices do |v,i,j|
|
|
98
|
+
vs << v
|
|
99
|
+
is << i
|
|
100
|
+
js << j
|
|
101
|
+
end
|
|
102
|
+
expect(vs).to eq(stype == :yale ? [8,6,7] : [6,7,8])
|
|
103
|
+
expect(is).to eq([0,0,0])
|
|
104
|
+
expect(js).to eq(stype == :yale ? [2,0,1] : [0,1,2])
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "should iterate across a submatrix of stored indices" do
|
|
108
|
+
#FIXME
|
|
109
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
110
|
+
vs = []
|
|
111
|
+
is = []
|
|
112
|
+
js = []
|
|
113
|
+
stype_matrix[0..1,1..2].each_stored_with_indices do |v,i,j|
|
|
114
|
+
vs << v
|
|
115
|
+
is << i
|
|
116
|
+
js << j
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
expect(vs).to eq(stype == :yale ? [4,1,2,5] : [1,2,4,5])
|
|
120
|
+
expect(is).to eq(stype == :yale ? [1,0,0,1] : [0,0,1,1])
|
|
121
|
+
expect(js).to eq(stype == :yale ? [0,0,1,1] : [0,1,0,1])
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
it "should return correct supershape" do
|
|
126
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
127
|
+
x = NMatrix.random([10,12])
|
|
128
|
+
y = x[0...8,5...12]
|
|
129
|
+
expect(y.shape).to eq([8,7])
|
|
130
|
+
expect(y.supershape).to eq([10,12])
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
it "should have #is_ref? method" do
|
|
134
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
135
|
+
a = stype_matrix[0..1, 0..1]
|
|
136
|
+
b = stype_matrix.slice(0..1, 0..1)
|
|
137
|
+
expect(stype_matrix.is_ref?).to be false
|
|
138
|
+
expect(a.is_ref?).to be true
|
|
139
|
+
expect(b.is_ref?).to be false
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
it "reference should compare with non-reference" do
|
|
143
|
+
expect(stype_matrix.slice(1..2,0..1)).to eq(stype_matrix[1..2, 0..1])
|
|
144
|
+
expect(stype_matrix[1..2,0..1]).to eq(stype_matrix.slice(1..2, 0..1))
|
|
145
|
+
expect(stype_matrix[1..2,0..1]).to eq(stype_matrix[1..2, 0..1])
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
context "with copying" do
|
|
149
|
+
it 'should return an NMatrix' do
|
|
150
|
+
n = stype_matrix.slice(0..1,0..1)
|
|
151
|
+
expect(nm_eql(n, NMatrix.new([2,2], [0,1,3,4], dtype: :int32))).to be true
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
it 'should return a copy of 2x2 matrix to self elements' do
|
|
155
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
156
|
+
n = stype_matrix.slice(1..2,0..1)
|
|
157
|
+
expect(n.shape).to eql([2,2])
|
|
158
|
+
|
|
159
|
+
expect(n[1,1]).to eq(stype_matrix[2,1])
|
|
160
|
+
n[1,1] = -9
|
|
161
|
+
expect(stype_matrix[2,1]).to eql(7)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
it 'should return a 1x2 matrix without refs to self elements' do
|
|
165
|
+
#FIXME
|
|
166
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
167
|
+
n = stype_matrix.slice(0,1..2)
|
|
168
|
+
expect(n.shape).to eql([1,2])
|
|
169
|
+
|
|
170
|
+
expect(n[0]).to eq(stype_matrix[0,1])
|
|
171
|
+
expect(n[1]).to eq(stype_matrix[0,2])
|
|
172
|
+
n[0] = -9
|
|
173
|
+
expect(stype_matrix[0,1]).to eql(1)
|
|
174
|
+
expect(stype_matrix[0,2]).to eql(2)
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
it 'should return a 2x1 matrix without refs to self elements' do
|
|
178
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
179
|
+
stype_matrix.extend NMatrix::YaleFunctions
|
|
180
|
+
|
|
181
|
+
n = stype_matrix.slice(0..1,1)
|
|
182
|
+
expect(n.shape).to eql([2,1])
|
|
183
|
+
|
|
184
|
+
expect(n[0]).to eq(stype_matrix[0,1])
|
|
185
|
+
expect(n[1]).to eq(stype_matrix[1,1])
|
|
186
|
+
n[0] = -9
|
|
187
|
+
expect(stype_matrix[0,1]).to eql(1)
|
|
188
|
+
expect(stype_matrix[1,1]).to eql(4)
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
it 'should be correct slice for range 0..2 and 0...3' do
|
|
192
|
+
expect(stype_matrix.slice(0..2,0..2)).to eq(stype_matrix.slice(0...3,0...3))
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
[:dense, :list, :yale].each do |cast_type|
|
|
196
|
+
it "should cast copied slice from #{stype.upcase} to #{cast_type.upcase}" do
|
|
197
|
+
expect(nm_eql(stype_matrix.slice(1..2, 1..2).cast(cast_type, :int32), stype_matrix.slice(1..2,1..2))).to be true
|
|
198
|
+
expect(nm_eql(stype_matrix.slice(0..1, 1..2).cast(cast_type, :int32), stype_matrix.slice(0..1,1..2))).to be true
|
|
199
|
+
expect(nm_eql(stype_matrix.slice(1..2, 0..1).cast(cast_type, :int32), stype_matrix.slice(1..2,0..1))).to be true
|
|
200
|
+
expect(nm_eql(stype_matrix.slice(0..1, 0..1).cast(cast_type, :int32), stype_matrix.slice(0..1,0..1))).to be true
|
|
201
|
+
|
|
202
|
+
# Non square
|
|
203
|
+
expect(nm_eql(stype_matrix.slice(0..2, 1..2).cast(cast_type, :int32), stype_matrix.slice(0..2,1..2))).to be true
|
|
204
|
+
#require 'pry'
|
|
205
|
+
#binding.pry if cast_type == :yale
|
|
206
|
+
expect(nm_eql(stype_matrix.slice(1..2, 0..2).cast(cast_type, :int32), stype_matrix.slice(1..2,0..2))).to be true
|
|
207
|
+
|
|
208
|
+
# Full
|
|
209
|
+
expect(nm_eql(stype_matrix.slice(0..2, 0..2).cast(cast_type, :int32), stype_matrix)).to be true
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# Yale:
|
|
215
|
+
#context "by copy" do
|
|
216
|
+
#it "should correctly preserve zeros" do
|
|
217
|
+
# stype_matrix = NMatrix.new(:yale, 3, :int64)
|
|
218
|
+
# column_slice = stype_matrix.column(2, :copy)
|
|
219
|
+
# column_slice[0].should == 0
|
|
220
|
+
# column_slice[1].should == 0
|
|
221
|
+
# column_slice[2].should == 0
|
|
222
|
+
#end
|
|
223
|
+
#end
|
|
224
|
+
|
|
225
|
+
context "by reference" do
|
|
226
|
+
it 'should return an NMatrix' do
|
|
227
|
+
n = stype_matrix[0..1,0..1]
|
|
228
|
+
expect(nm_eql(n, NMatrix.new([2,2], [0,1,3,4], dtype: :int32))).to be true
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
it 'should return a 2x2 matrix with refs to self elements' do
|
|
232
|
+
#FIXME
|
|
233
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby? # and :cast_type != :dense
|
|
234
|
+
n = stype_matrix[1..2,0..1]
|
|
235
|
+
expect(n.shape).to eql([2,2])
|
|
236
|
+
|
|
237
|
+
expect(n[0,0]).to eq(stype_matrix[1,0])
|
|
238
|
+
n[0,0] = -9
|
|
239
|
+
expect(stype_matrix[1,0]).to eql(-9)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it 'should return a 1x2 vector with refs to self elements' do
|
|
243
|
+
#FIXME
|
|
244
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby? # and :cast_type != :dense
|
|
245
|
+
n = stype_matrix[0,1..2]
|
|
246
|
+
expect(n.shape).to eql([1,2])
|
|
247
|
+
|
|
248
|
+
expect(n[0]).to eq(stype_matrix[0,1])
|
|
249
|
+
n[0] = -9
|
|
250
|
+
expect(stype_matrix[0,1]).to eql(-9)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
it 'should return a 2x1 vector with refs to self elements' do
|
|
254
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
255
|
+
n = stype_matrix[0..1,1]
|
|
256
|
+
expect(n.shape).to eql([2,1])
|
|
257
|
+
|
|
258
|
+
expect(n[0]).to eq(stype_matrix[0,1])
|
|
259
|
+
n[0] = -9
|
|
260
|
+
expect(stype_matrix[0,1]).to eql(-9)
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
it 'should slice again' do
|
|
264
|
+
n = stype_matrix[1..2, 1..2]
|
|
265
|
+
expect(nm_eql(n[1,0..1], NVector.new(2, [7,8], dtype: :int32).transpose)).to be true
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
it 'should be correct slice for range 0..2 and 0...3' do
|
|
269
|
+
expect(stype_matrix[0..2,0..2]).to eq(stype_matrix[0...3,0...3])
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
it 'should correctly handle :* slice notation' do
|
|
273
|
+
expect(stype_matrix[:*,0]).to eq stype_matrix[0...stype_matrix.shape[0], 0]
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
if stype == :dense
|
|
277
|
+
[:byte,:int8,:int16,:int32,:int64,:float32,:float64].each do |left_dtype|
|
|
278
|
+
[:byte,:int8,:int16,:int32,:int64,:float32,:float64].each do |right_dtype|
|
|
279
|
+
|
|
280
|
+
# Won't work if they're both 1-byte, due to overflow.
|
|
281
|
+
next if [:byte,:int8].include?(left_dtype) && [:byte,:int8].include?(right_dtype)
|
|
282
|
+
|
|
283
|
+
# For now, don't bother testing int-int mult.
|
|
284
|
+
#next if [:int8,:int16,:int32,:int64].include?(left_dtype) && [:int8,:int16,:int32,:int64].include?(right_dtype)
|
|
285
|
+
it "handles #{left_dtype.to_s} dot #{right_dtype.to_s} matrix multiplication" do
|
|
286
|
+
#STDERR.puts "dtype=#{dtype.to_s}"
|
|
287
|
+
#STDERR.puts "2"
|
|
288
|
+
|
|
289
|
+
nary = if left_dtype.to_s =~ /complex/
|
|
290
|
+
COMPLEX_MATRIX43A_ARRAY
|
|
291
|
+
else
|
|
292
|
+
MATRIX43A_ARRAY
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
mary = if right_dtype.to_s =~ /complex/
|
|
296
|
+
COMPLEX_MATRIX32A_ARRAY
|
|
297
|
+
else
|
|
298
|
+
MATRIX32A_ARRAY
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
n = NMatrix.new([4,3], nary, dtype: left_dtype)[1..3,1..2]
|
|
302
|
+
m = NMatrix.new([3,2], mary, dtype: right_dtype)[1..2,0..1]
|
|
303
|
+
|
|
304
|
+
r = n.dot m
|
|
305
|
+
expect(r.shape).to eql([3,2])
|
|
306
|
+
|
|
307
|
+
expect(r[0,0]).to eq(219.0)
|
|
308
|
+
expect(r[0,1]).to eq(185.0)
|
|
309
|
+
expect(r[1,0]).to eq(244.0)
|
|
310
|
+
expect(r[1,1]).to eq(205.0)
|
|
311
|
+
expect(r[2,0]).to eq(42.0)
|
|
312
|
+
expect(r[2,1]).to eq(35.0)
|
|
313
|
+
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
context "operations" do
|
|
319
|
+
|
|
320
|
+
it "correctly transposes slices" do
|
|
321
|
+
expect(stype_matrix[0...3,0].transpose).to eq NMatrix[[0, 3, 6]]
|
|
322
|
+
expect(stype_matrix[0...3,1].transpose).to eq NMatrix[[1, 4, 7]]
|
|
323
|
+
expect(stype_matrix[0...3,2].transpose).to eq NMatrix[[2, 5, 8]]
|
|
324
|
+
expect(stype_matrix[0,0...3].transpose).to eq NMatrix[[0], [1], [2]]
|
|
325
|
+
expect(stype_matrix[1,0...3].transpose).to eq NMatrix[[3], [4], [5]]
|
|
326
|
+
expect(stype_matrix[2,0...3].transpose).to eq NMatrix[[6], [7], [8]]
|
|
327
|
+
expect(stype_matrix[1..2,1..2].transpose).to eq NMatrix[[4, 7], [5, 8]]
|
|
328
|
+
end
|
|
329
|
+
|
|
330
|
+
it "adds slices" do
|
|
331
|
+
expect(NMatrix[[0,0,0]] + stype_matrix[1,0..2]).to eq NMatrix[[3, 4, 5]]
|
|
332
|
+
end
|
|
333
|
+
|
|
334
|
+
it "scalar adds to slices" do
|
|
335
|
+
expect(stype_matrix[1,0..2]+1).to eq NMatrix[[4, 5, 6]]
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
it "compares slices to scalars" do
|
|
339
|
+
#FIXME
|
|
340
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
341
|
+
(stype_matrix[1, 0..2] > 2).each { |e| expect(e != 0).to be true }
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
it "iterates only over elements in the slice" do
|
|
345
|
+
els = []
|
|
346
|
+
stype_matrix[1, 0..2].each { |e| els << e }
|
|
347
|
+
expect(els.size).to eq 3
|
|
348
|
+
expect(els[0]).to eq 3
|
|
349
|
+
expect(els[1]).to eq 4
|
|
350
|
+
expect(els[2]).to eq 5
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
it "iterates with index only over elements in the slice" do
|
|
354
|
+
els = []
|
|
355
|
+
stype_matrix[1, 0..2].each_stored_with_indices { |a| els << a }
|
|
356
|
+
expect(els.size).to eq 3
|
|
357
|
+
expect(els[0]).to eq [3, 0, 0]
|
|
358
|
+
expect(els[1]).to eq [4, 0, 1]
|
|
359
|
+
expect(els[2]).to eq [5, 0, 2]
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
example 'should be cleaned up by garbage collector without errors' do
|
|
367
|
+
step "reference slice" do
|
|
368
|
+
1.times do
|
|
369
|
+
n = stype_matrix[1..2,0..1]
|
|
370
|
+
end
|
|
371
|
+
GC.start
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
step "reference slice of casted-copy" do
|
|
375
|
+
expect(stype_matrix).to eq(NMatrix.new([3,3], (0..9).to_a, dtype: :int32).cast(stype, :int32))
|
|
376
|
+
n = nil
|
|
377
|
+
1.times do
|
|
378
|
+
m = NMatrix.new([2,2], [1,2,3,4]).cast(stype, :int32)
|
|
379
|
+
n = m[0..1,0..1]
|
|
380
|
+
end
|
|
381
|
+
GC.start
|
|
382
|
+
expect(n).to eq(NMatrix.new([2,2], [1,2,3,4]).cast(stype, :int32))
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
[:dense, :list, :yale].each do |cast_type|
|
|
387
|
+
it "should cast a square reference-slice from #{stype.upcase} to #{cast_type.upcase}" do
|
|
388
|
+
expect(nm_eql(stype_matrix[1..2, 1..2].cast(cast_type), stype_matrix[1..2,1..2])).to be true
|
|
389
|
+
expect(nm_eql(stype_matrix[0..1, 1..2].cast(cast_type), stype_matrix[0..1,1..2])).to be true
|
|
390
|
+
expect(nm_eql(stype_matrix[1..2, 0..1].cast(cast_type), stype_matrix[1..2,0..1])).to be true
|
|
391
|
+
expect(nm_eql(stype_matrix[0..1, 0..1].cast(cast_type), stype_matrix[0..1,0..1])).to be true
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
it "should cast a rectangular reference-slice from #{stype.upcase} to #{cast_type.upcase}" do
|
|
395
|
+
# Non square
|
|
396
|
+
expect(nm_eql(stype_matrix[0..2, 1..2].cast(cast_type), stype_matrix[0..2,1..2])).to be true # FIXME: memory problem.
|
|
397
|
+
expect(nm_eql(stype_matrix[1..2, 0..2].cast(cast_type), stype_matrix[1..2,0..2])).to be true # this one is fine
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
it "should cast a square full-matrix reference-slice from #{stype.upcase} to #{cast_type.upcase}" do
|
|
401
|
+
expect(nm_eql(stype_matrix[0..2, 0..2].cast(cast_type), stype_matrix)).to be true
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
end
|
|
407
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe NMatrix do
|
|
4
|
+
describe "#to_a" do
|
|
5
|
+
it "creates an Array with the same dimensions" do
|
|
6
|
+
n = NMatrix.seq([3,2])
|
|
7
|
+
expect(n.to_a).to eq([[0, 1], [2, 3], [4, 5]])
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it "creates an Array with the proper element type" do
|
|
11
|
+
n = NMatrix.seq([3,2], dtype: :float64)
|
|
12
|
+
expect(n.to_a).to eq([[0.0, 1.0], [2.0, 3.0], [4.0, 5.0]])
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "properly interprets list matrices" do
|
|
16
|
+
n = NMatrix.seq([3,2], stype: :list)
|
|
17
|
+
expect(n.to_a).to eq([[0, 1], [2, 3], [4, 5]])
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "properly interprets yale matrices" do
|
|
21
|
+
n = NMatrix.seq([3,2], stype: :yale)
|
|
22
|
+
expect(n.to_a).to eq([[0, 1], [2, 3], [4, 5]])
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe Array do
|
|
28
|
+
describe "#to_nm" do
|
|
29
|
+
# [0, 1, 2, 3, 4, 5]
|
|
30
|
+
let(:a) {(0..5).to_a}
|
|
31
|
+
|
|
32
|
+
it "uses a given shape and type" do
|
|
33
|
+
expect(a.to_nm([3,2]).dtype).to eq :int64
|
|
34
|
+
expect(a.to_nm([3,2])).to eq(NMatrix.seq([3,2]))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "guesses dtype based on first element" do
|
|
38
|
+
a[0] = 0.0
|
|
39
|
+
expect(a.to_nm([3,2]).dtype).to eq :float64
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
it "defaults to dtype :object if necessary" do
|
|
43
|
+
#FIXME
|
|
44
|
+
pending("not yet implemented for object dtype for NMatrix-JRuby") if jruby?
|
|
45
|
+
a = %w(this is an array of strings)
|
|
46
|
+
expect(a.to_nm([3,2]).dtype).to eq :object
|
|
47
|
+
expect(a.to_nm([3,2])).to eq(NMatrix.new([3,2], a, dtype: :object))
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "attempts to intuit the shape of the Array" do
|
|
51
|
+
a = [[0, 1], [2, 3], [4, 5]]
|
|
52
|
+
expect(a.to_nm).to eq(NMatrix.new([3,2], a.flatten))
|
|
53
|
+
expect(a.to_nm.dtype).to eq :int64
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "creates an object Array for inconsistent dimensions" do
|
|
57
|
+
a = [[0, 1, 2], [3], [4, 5]]
|
|
58
|
+
expect(a.to_nm).to eq(NMatrix.new([3], a, dtype: :object))
|
|
59
|
+
expect(a.to_nm.dtype).to eq :object
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "intuits shape of Array into multiple dimensions" do
|
|
63
|
+
a = [[[0], [1]], [[2], [3]], [[4], [5]]]
|
|
64
|
+
expect(a.to_nm).to eq(NMatrix.new([3,2,1], a.flatten))
|
|
65
|
+
expect(a).to eq(a.to_nm.to_a)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
it "is reflective with NMatrix#to_a" do
|
|
69
|
+
a = [[0, 1, 2], [3], [4, 5]]
|
|
70
|
+
expect(a).to eq(a.to_nm.to_a)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
it "does not permanently alter the Array" do
|
|
74
|
+
a = [[0, 1], [2, 3], [4, 5]]
|
|
75
|
+
expect(a.to_nm).to eq(NMatrix.new([3,2], a.flatten))
|
|
76
|
+
expect(a).to eq([[0, 1], [2, 3], [4, 5]])
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
Binary file
|
data/spec/4x4_sparse.mat
ADDED
|
Binary file
|
data/spec/4x5_dense.mat
ADDED
|
Binary file
|