nmatrix 0.0.3 → 0.0.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.
- data/.gitignore +3 -0
- data/CONTRIBUTING.md +66 -0
- data/Gemfile +1 -1
- data/History.txt +68 -10
- data/LICENSE.txt +2 -2
- data/Manifest.txt +2 -0
- data/README.rdoc +90 -69
- data/Rakefile +18 -9
- data/ext/nmatrix/data/complex.h +7 -7
- data/ext/nmatrix/data/data.cpp +2 -7
- data/ext/nmatrix/data/data.h +7 -4
- data/ext/nmatrix/data/rational.h +2 -2
- data/ext/nmatrix/data/ruby_object.h +3 -10
- data/ext/nmatrix/extconf.rb +79 -54
- data/ext/nmatrix/new_extconf.rb +11 -12
- data/ext/nmatrix/nmatrix.cpp +94 -125
- data/ext/nmatrix/nmatrix.h +38 -17
- data/ext/nmatrix/ruby_constants.cpp +2 -15
- data/ext/nmatrix/ruby_constants.h +2 -14
- data/ext/nmatrix/storage/common.cpp +2 -2
- data/ext/nmatrix/storage/common.h +2 -2
- data/ext/nmatrix/storage/dense.cpp +206 -31
- data/ext/nmatrix/storage/dense.h +5 -2
- data/ext/nmatrix/storage/list.cpp +52 -4
- data/ext/nmatrix/storage/list.h +3 -2
- data/ext/nmatrix/storage/storage.cpp +6 -6
- data/ext/nmatrix/storage/storage.h +2 -2
- data/ext/nmatrix/storage/yale.cpp +202 -49
- data/ext/nmatrix/storage/yale.h +5 -4
- data/ext/nmatrix/ttable_helper.rb +108 -108
- data/ext/nmatrix/types.h +2 -15
- data/ext/nmatrix/util/io.cpp +2 -2
- data/ext/nmatrix/util/io.h +2 -2
- data/ext/nmatrix/util/lapack.h +2 -2
- data/ext/nmatrix/util/math.cpp +14 -14
- data/ext/nmatrix/util/math.h +2 -2
- data/ext/nmatrix/util/sl_list.cpp +2 -2
- data/ext/nmatrix/util/sl_list.h +2 -2
- data/ext/nmatrix/util/util.h +2 -2
- data/lib/nmatrix.rb +13 -35
- data/lib/nmatrix/blas.rb +182 -56
- data/lib/nmatrix/io/market.rb +38 -14
- data/lib/nmatrix/io/mat5_reader.rb +393 -278
- data/lib/nmatrix/io/mat_reader.rb +121 -107
- data/lib/nmatrix/lapack.rb +59 -14
- data/lib/nmatrix/monkeys.rb +32 -30
- data/lib/nmatrix/nmatrix.rb +204 -100
- data/lib/nmatrix/nvector.rb +166 -57
- data/lib/nmatrix/shortcuts.rb +364 -231
- data/lib/nmatrix/version.rb +8 -4
- data/nmatrix.gemspec +5 -3
- data/scripts/mac-brew-gcc.sh +1 -1
- data/spec/blas_spec.rb +80 -2
- data/spec/math_spec.rb +78 -32
- data/spec/nmatrix_list_spec.rb +55 -55
- data/spec/nmatrix_spec.rb +60 -117
- data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
- data/spec/nmatrix_yale_spec.rb +214 -198
- data/spec/nvector_spec.rb +58 -2
- data/spec/shortcuts_spec.rb +156 -32
- data/spec/slice_spec.rb +229 -178
- data/spec/spec_helper.rb +2 -2
- metadata +71 -21
data/spec/shortcuts_spec.rb
CHANGED
@@ -29,39 +29,49 @@
|
|
29
29
|
require File.join(File.dirname(__FILE__), "spec_helper.rb")
|
30
30
|
|
31
31
|
describe NMatrix do
|
32
|
-
|
32
|
+
|
33
33
|
it "zeros() creates a matrix of zeros" do
|
34
34
|
m = NMatrix.zeros(3)
|
35
35
|
n = NMatrix.new([3, 3], 0)
|
36
|
-
|
36
|
+
|
37
37
|
m.should.eql? n
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
it "ones() creates a matrix of ones" do
|
41
41
|
m = NMatrix.ones(3)
|
42
42
|
n = NMatrix.new([3, 3], 1)
|
43
|
-
|
44
|
-
m.should.eql? n
|
43
|
+
|
44
|
+
m.should.eql? n
|
45
45
|
end
|
46
|
-
|
46
|
+
|
47
47
|
it "eye() creates an identity matrix" do
|
48
48
|
m = NMatrix.eye(3)
|
49
49
|
identity3 = NMatrix.new([3, 3], [1, 0, 0, 0, 1, 0, 0, 0, 1])
|
50
|
-
|
50
|
+
|
51
51
|
m.should.eql? identity3
|
52
52
|
end
|
53
|
-
|
53
|
+
|
54
54
|
it "random() creates a matrix of random numbers" do
|
55
55
|
m = NMatrix.random(2)
|
56
|
-
|
56
|
+
|
57
|
+
m.stype.should == :dense
|
58
|
+
m.dtype.should == :float64
|
59
|
+
end
|
60
|
+
|
61
|
+
it "random() only accepts an integer or an array as dimension" do
|
62
|
+
m = NMatrix.random([2, 2])
|
63
|
+
|
57
64
|
m.stype.should == :dense
|
58
65
|
m.dtype.should == :float64
|
66
|
+
|
67
|
+
expect { NMatrix.random(2.0) }.to raise_error
|
68
|
+
expect { NMatrix.random("not an array or integer") }.to raise_error
|
59
69
|
end
|
60
|
-
|
70
|
+
|
61
71
|
it "seq() creates a matrix of integers, sequentially" do
|
62
72
|
m = NMatrix.seq(2) # 2x2 matrix.
|
63
73
|
value = 0
|
64
|
-
|
74
|
+
|
65
75
|
2.times do |i|
|
66
76
|
2.times do |j|
|
67
77
|
m[i, j].should == value
|
@@ -69,86 +79,200 @@ describe NMatrix do
|
|
69
79
|
end
|
70
80
|
end
|
71
81
|
end
|
72
|
-
|
82
|
+
|
73
83
|
it "seq() only accepts an integer or a 2-element array as dimension" do
|
84
|
+
m = NMatrix.seq([2, 2])
|
85
|
+
value = 0
|
86
|
+
|
87
|
+
2.times do |i|
|
88
|
+
2.times do |j|
|
89
|
+
m[i, j].should == value
|
90
|
+
value += 1
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
74
94
|
expect { NMatrix.seq([1, 2, 3]) }.to raise_error
|
75
95
|
expect { NMatrix.seq("not an array or integer") }.to raise_error
|
76
96
|
end
|
77
|
-
|
97
|
+
|
98
|
+
it "indgen() creates a matrix of integers as well as seq()" do
|
99
|
+
m = NMatrix.indgen(2) # 2x2 matrix.
|
100
|
+
value = 0
|
101
|
+
|
102
|
+
2.times do |i|
|
103
|
+
2.times do |j|
|
104
|
+
m[i, j].should == value
|
105
|
+
value += 1
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
it "findgen creates a matrix of floats, sequentially" do
|
111
|
+
m = NMatrix.findgen(2) # 2x2 matrix.
|
112
|
+
value = 0
|
113
|
+
|
114
|
+
2.times do |i|
|
115
|
+
2.times do |j|
|
116
|
+
(m[i, j]/10).should be_within(Float::EPSILON).of(value.to_f/10)
|
117
|
+
value += 1
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
it "bindgen() creates a matrix of bytes" do
|
123
|
+
m = NMatrix.bindgen(2) # 2x2 matrix.
|
124
|
+
value = 0
|
125
|
+
|
126
|
+
2.times do |i|
|
127
|
+
2.times do |j|
|
128
|
+
m[i, j].should == value
|
129
|
+
value += 1
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
it "cindgen() creates a matrix of complexes" do
|
135
|
+
m = NMatrix.cindgen(2) # 2x2 matrix.
|
136
|
+
value = 0
|
137
|
+
|
138
|
+
2.times do |i|
|
139
|
+
2.times do |j|
|
140
|
+
m[i, j].real.should be_within(Float::EPSILON).of(value)
|
141
|
+
m[i, j].imag.should be_within(Float::EPSILON).of(0.0)
|
142
|
+
value += 1
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
78
147
|
it "column() returns a NMatrix" do
|
79
148
|
m = NMatrix.random(3)
|
80
|
-
|
149
|
+
|
81
150
|
m.column(2).is_a?(NMatrix).should be_true
|
82
151
|
end
|
83
|
-
|
152
|
+
|
84
153
|
it "column() accepts a second parameter (only :copy or :reference)" do
|
85
154
|
m = NMatrix.random(3)
|
86
|
-
|
155
|
+
|
87
156
|
expect { m.column(1, :copy) }.to_not raise_error
|
88
157
|
expect { m.column(1, :reference) }.to_not raise_error
|
89
|
-
|
158
|
+
|
90
159
|
expect { m.column(1, :derp) }.to raise_error
|
91
160
|
end
|
161
|
+
|
162
|
+
it "row() returns a NMatrix" do
|
163
|
+
m = NMatrix.random(3)
|
164
|
+
|
165
|
+
m.row(2).is_a?(NMatrix).should be_true
|
166
|
+
end
|
167
|
+
|
168
|
+
it "row() accepts a second parameter (only :copy or :reference)" do
|
169
|
+
m = NMatrix.random(3)
|
170
|
+
|
171
|
+
expect { m.row(1, :copy) }.to_not raise_error
|
172
|
+
expect { m.row(1, :reference) }.to_not raise_error
|
173
|
+
|
174
|
+
expect { m.row(1, :derp) }.to raise_error
|
175
|
+
end
|
92
176
|
end
|
93
177
|
|
94
178
|
describe "NVector" do
|
95
|
-
|
179
|
+
|
96
180
|
it "zeros() creates a vector of zeros" do
|
97
181
|
v = NVector.zeros(4)
|
98
|
-
|
182
|
+
|
99
183
|
4.times do |i|
|
100
184
|
v[i].should == 0
|
101
185
|
end
|
102
186
|
end
|
103
|
-
|
187
|
+
|
104
188
|
it "ones() creates a vector of ones" do
|
105
189
|
v = NVector.ones(3)
|
106
|
-
|
190
|
+
|
107
191
|
3.times do |i|
|
108
192
|
v[i].should == 1
|
109
193
|
end
|
110
194
|
end
|
111
|
-
|
195
|
+
|
112
196
|
it "random() creates a vector of random numbers" do
|
113
|
-
v = NVector.
|
197
|
+
v = NVector.random(4)
|
114
198
|
v.dtype.should == :float64
|
115
199
|
v.stype.should == :dense
|
116
200
|
end
|
117
|
-
|
201
|
+
|
118
202
|
it "seq() creates a vector of integers, sequentially" do
|
119
203
|
v = NVector.seq(7)
|
120
204
|
i = 0
|
121
|
-
|
205
|
+
|
122
206
|
v.each do |elem|
|
123
207
|
elem.should == i
|
124
208
|
i += 1
|
125
209
|
end
|
126
210
|
end
|
127
|
-
|
211
|
+
|
128
212
|
it "seq() only accepts integers as dimension" do
|
129
213
|
expect { NVector.seq(3) }.to_not raise_error
|
130
214
|
|
131
215
|
expect { NVector.seq([1, 3]) }.to raise_error
|
132
216
|
expect { NVector.seq(:wtf) }.to raise_error
|
133
217
|
end
|
134
|
-
|
218
|
+
|
219
|
+
it "indgen() creates a vector of integers as well as seq()" do
|
220
|
+
v = NVector.indgen(7)
|
221
|
+
i = 0
|
222
|
+
|
223
|
+
v.each do |elem|
|
224
|
+
elem.should == i
|
225
|
+
i += 1
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
it "findgen creates a vector of floats, sequentially" do
|
230
|
+
v = NVector.findgen(2)
|
231
|
+
|
232
|
+
2.times do |i|
|
233
|
+
(v[i]/10).should be_within(Float::EPSILON).of(i.to_f/10)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
it "bindgen() creates a vector of bytes, sequentially" do
|
238
|
+
v = NVector.bindgen(7)
|
239
|
+
i = 0
|
240
|
+
|
241
|
+
v.each do |elem|
|
242
|
+
elem.should == i
|
243
|
+
i += 1
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
it "cindgen() creates a vector of complexes, sequentially" do
|
248
|
+
v = NVector.cindgen(2)
|
249
|
+
value = 0
|
250
|
+
|
251
|
+
2.times do |i|
|
252
|
+
v[i].real.should be_within(Float::EPSILON).of(value)
|
253
|
+
v[i].imag.should be_within(Float::EPSILON).of(0.0)
|
254
|
+
value += 1
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
|
135
259
|
it "linspace() creates a vector with n values equally spaced between a and b" do
|
136
260
|
v = NVector.linspace(0, 2, 5)
|
137
261
|
i = 0
|
138
|
-
|
262
|
+
|
139
263
|
v.each do |elem|
|
140
264
|
elem.should == i * 0.5
|
141
265
|
i += 1
|
142
266
|
end
|
143
|
-
end
|
267
|
+
end
|
144
268
|
end
|
145
269
|
|
146
270
|
describe "Inline constructor" do
|
147
|
-
|
271
|
+
|
148
272
|
it "creates a NMatrix with the given values" do
|
149
273
|
m = NMatrix.new([2, 2], [1, 4, 6, 7])
|
150
274
|
n = N[[1, 4], [6, 7]]
|
151
|
-
|
152
|
-
m.should.eql? n
|
275
|
+
|
276
|
+
m.should.eql? n
|
153
277
|
end
|
154
278
|
end
|
data/spec/slice_spec.rb
CHANGED
@@ -20,226 +20,277 @@
|
|
20
20
|
#
|
21
21
|
# * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
|
22
22
|
#
|
23
|
-
# ==
|
23
|
+
# == slice_spec.rb
|
24
24
|
#
|
25
|
-
# Test of slice operations.
|
25
|
+
# Test of slice operations.
|
26
26
|
#
|
27
27
|
require File.dirname(__FILE__) + "/spec_helper.rb"
|
28
28
|
|
29
29
|
describe "Slice operation" do
|
30
30
|
[:dense, :list, :yale].each do |stype|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
context "for #{stype}" do
|
32
|
+
before :each do
|
33
|
+
@m = create_matrix(stype)
|
34
|
+
end
|
35
35
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
unless stype == :yale
|
37
|
+
it "should have #is_ref? method" do
|
38
|
+
a = @m[0..1, 0..1]
|
39
|
+
b = @m.slice(0..1, 0..1)
|
40
40
|
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
@m.is_ref?.should be_false
|
43
|
+
a.is_ref?.should be_true
|
44
|
+
b.is_ref?.should be_false
|
45
|
+
end
|
46
46
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
47
|
+
it "reference should compare with non-reference" do
|
48
|
+
@m.slice(1..2,0..1).should == @m[1..2, 0..1]
|
49
|
+
@m[1..2,0..1].should == @m.slice(1..2, 0..1)
|
50
|
+
@m[1..2,0..1].should == @m[1..2, 0..1]
|
51
|
+
end
|
52
|
+
end # unless stype == :yale
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
54
|
+
context "with copying" do
|
55
|
+
it 'should return an NMatrix' do
|
56
|
+
n = @m.slice(0..1,0..1)
|
57
|
+
nm_eql(n, NMatrix.new([2,2], [0,1,3,4], :int32)).should be_true
|
58
|
+
end
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
it 'should return a copy of 2x2 matrix to self elements' do
|
61
|
+
n = @m.slice(1..2,0..1)
|
62
|
+
n.shape.should eql([2,2])
|
63
63
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
64
|
+
n[1,1].should == @m[2,1]
|
65
|
+
n[1,1] = -9
|
66
|
+
@m[2,1].should eql(7)
|
67
|
+
end
|
68
68
|
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
it 'should return a 1x2 matrix with refs to self elements' do
|
70
|
+
n = @m.slice(0,1..2)
|
71
|
+
n.shape.should eql([1,2])
|
72
72
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
73
|
+
n[0,0].should == @m[0,1]
|
74
|
+
n[0,0] = -9
|
75
|
+
@m[0,1].should eql(1)
|
76
|
+
end
|
77
77
|
|
78
|
-
|
79
|
-
|
80
|
-
|
78
|
+
it 'should return a 2x1 matrix with refs to self elements' do
|
79
|
+
n = @m.slice(0..1,1)
|
80
|
+
n.shape.should eql([2,1])
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
82
|
+
n[0,0].should == @m[0,1]
|
83
|
+
n[0,0] = -9
|
84
|
+
@m[0,1].should eql(1)
|
85
|
+
end
|
86
86
|
|
87
|
-
|
88
|
-
|
89
|
-
end
|
90
|
-
|
91
|
-
[:dense, :list, :yale].each do |cast_type|
|
92
|
-
it "should cast from #{stype.upcase} to #{cast_type.upcase}" do
|
93
|
-
nm_eql(@m.slice(1..2, 1..2).cast(cast_type, :int32), @m.slice(1..2,1..2)).should be_true
|
94
|
-
nm_eql(@m.slice(0..1, 1..2).cast(cast_type, :int32), @m.slice(0..1,1..2)).should be_true
|
95
|
-
nm_eql(@m.slice(1..2, 0..1).cast(cast_type, :int32), @m.slice(1..2,0..1)).should be_true
|
96
|
-
nm_eql(@m.slice(0..1, 0..1).cast(cast_type, :int32), @m.slice(0..1,0..1)).should be_true
|
97
|
-
|
98
|
-
# Non square
|
99
|
-
nm_eql(@m.slice(0..2, 1..2).cast(cast_type, :int32), @m.slice(0..2,1..2)).should be_true
|
100
|
-
nm_eql(@m.slice(1..2, 0..2).cast(cast_type, :int32), @m.slice(1..2,0..2)).should be_true
|
101
|
-
|
102
|
-
# Full
|
103
|
-
nm_eql(@m.slice(0..2, 0..2).cast(cast_type, :int32), @m).should be_true
|
87
|
+
it 'should be correct slice for range 0..2 and 0...3' do
|
88
|
+
@m.slice(0..2,0..2).should == @m.slice(0...3,0...3)
|
104
89
|
end
|
105
|
-
end
|
106
|
-
end
|
107
90
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
else
|
115
|
-
context "by reference" do
|
116
|
-
it 'should return an NMatrix' do
|
117
|
-
n = @m[0..1,0..1]
|
118
|
-
nm_eql(n, NMatrix.new([2,2], [0,1,3,4], :int32)).should be_true
|
119
|
-
end
|
91
|
+
[:dense, :list, :yale].each do |cast_type|
|
92
|
+
it "should cast from #{stype.upcase} to #{cast_type.upcase}" do
|
93
|
+
nm_eql(@m.slice(1..2, 1..2).cast(cast_type, :int32), @m.slice(1..2,1..2)).should be_true
|
94
|
+
nm_eql(@m.slice(0..1, 1..2).cast(cast_type, :int32), @m.slice(0..1,1..2)).should be_true
|
95
|
+
nm_eql(@m.slice(1..2, 0..1).cast(cast_type, :int32), @m.slice(1..2,0..1)).should be_true
|
96
|
+
nm_eql(@m.slice(0..1, 0..1).cast(cast_type, :int32), @m.slice(0..1,0..1)).should be_true
|
120
97
|
|
121
|
-
|
122
|
-
|
123
|
-
|
98
|
+
# Non square
|
99
|
+
nm_eql(@m.slice(0..2, 1..2).cast(cast_type, :int32), @m.slice(0..2,1..2)).should be_true
|
100
|
+
nm_eql(@m.slice(1..2, 0..2).cast(cast_type, :int32), @m.slice(1..2,0..2)).should be_true
|
124
101
|
|
125
|
-
|
126
|
-
|
127
|
-
|
102
|
+
# Full
|
103
|
+
nm_eql(@m.slice(0..2, 0..2).cast(cast_type, :int32), @m).should be_true
|
104
|
+
end
|
105
|
+
end
|
128
106
|
end
|
129
107
|
|
130
|
-
it 'should return a 1x2 matrix with refs to self elements' do
|
131
|
-
n = @m[0,1..2]
|
132
|
-
n.shape.should eql([1,2])
|
133
108
|
|
134
|
-
n[0,0].should == @m[0,1]
|
135
|
-
n[0,0] = -9
|
136
|
-
@m[0,1].should eql(-9)
|
137
|
-
end
|
138
109
|
|
139
|
-
|
140
|
-
|
141
|
-
|
110
|
+
if stype == :yale
|
111
|
+
context "by reference" do
|
112
|
+
it "should raise an error" do
|
113
|
+
expect{ @m[1..2,1..2] }.to raise_error(NotImplementedError)
|
114
|
+
end
|
115
|
+
end
|
142
116
|
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
117
|
+
context "by copy" do
|
118
|
+
it "should correctly preserve zeros" do
|
119
|
+
@m = NMatrix.new(:yale, 3, :int64)
|
120
|
+
column_slice = @m.column(2, :copy)
|
121
|
+
column_slice[0,0].should == 0
|
122
|
+
column_slice[1,0].should == 0
|
123
|
+
column_slice[2,0].should == 0
|
124
|
+
end
|
125
|
+
end
|
126
|
+
else
|
127
|
+
context "by reference" do
|
128
|
+
it 'should return an NMatrix' do
|
129
|
+
n = @m[0..1,0..1]
|
130
|
+
nm_eql(n, NMatrix.new([2,2], [0,1,3,4], :int32)).should be_true
|
131
|
+
end
|
147
132
|
|
148
|
-
|
133
|
+
it 'should return a 2x2 matrix with refs to self elements' do
|
134
|
+
n = @m[1..2,0..1]
|
135
|
+
n.shape.should eql([2,2])
|
149
136
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
137
|
+
n[0,0].should == @m[1,0]
|
138
|
+
n[0,0] = -9
|
139
|
+
@m[1,0].should eql(-9)
|
140
|
+
end
|
154
141
|
|
155
|
-
|
156
|
-
|
157
|
-
|
142
|
+
it 'should return a 1x2 matrix with refs to self elements' do
|
143
|
+
n = @m[0,1..2]
|
144
|
+
n.shape.should eql([1,2])
|
145
|
+
|
146
|
+
n[0,0].should == @m[0,1]
|
147
|
+
n[0,0] = -9
|
148
|
+
@m[0,1].should eql(-9)
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'should return a 2x1 matrix with refs to self elements' do
|
152
|
+
n = @m[0..1,1]
|
153
|
+
n.shape.should eql([2,1])
|
154
|
+
|
155
|
+
n[0,0].should == @m[0,1]
|
156
|
+
n[0,0] = -9
|
157
|
+
@m[0,1].should eql(-9)
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'should set value from NMatrix'
|
161
|
+
|
162
|
+
it 'should slice again' do
|
163
|
+
n = @m[1..2, 1..2]
|
164
|
+
nm_eql(n[1,0..1], NMatrix.new([1,2], [7,8])).should be_true
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'should be correct slice for range 0..2 and 0...3' do
|
168
|
+
@m[0..2,0..2].should == @m[0...3,0...3]
|
169
|
+
end
|
170
|
+
|
171
|
+
if stype == :dense
|
172
|
+
[:byte,:int8,:int16,:int32,:int64,:float32,:float64,:rational64,:rational128].each do |left_dtype|
|
173
|
+
[:byte,:int8,:int16,:int32,:int64,:float32,:float64,:rational64,:rational128].each do |right_dtype|
|
174
|
+
|
175
|
+
# Won't work if they're both 1-byte, due to overflow.
|
176
|
+
next if [:byte,:int8].include?(left_dtype) && [:byte,:int8].include?(right_dtype)
|
177
|
+
|
178
|
+
# For now, don't bother testing int-int mult.
|
179
|
+
#next if [:int8,:int16,:int32,:int64].include?(left_dtype) && [:int8,:int16,:int32,:int64].include?(right_dtype)
|
180
|
+
it "handles #{left_dtype.to_s} dot #{right_dtype.to_s} matrix multiplication" do
|
181
|
+
#STDERR.puts "dtype=#{dtype.to_s}"
|
182
|
+
#STDERR.puts "2"
|
183
|
+
|
184
|
+
nary = if left_dtype.to_s =~ /complex/
|
185
|
+
COMPLEX_MATRIX43A_ARRAY
|
186
|
+
elsif left_dtype.to_s =~ /rational/
|
187
|
+
RATIONAL_MATRIX43A_ARRAY
|
188
|
+
else
|
189
|
+
MATRIX43A_ARRAY
|
190
|
+
end
|
191
|
+
|
192
|
+
mary = if right_dtype.to_s =~ /complex/
|
193
|
+
COMPLEX_MATRIX32A_ARRAY
|
194
|
+
elsif right_dtype.to_s =~ /rational/
|
195
|
+
RATIONAL_MATRIX32A_ARRAY
|
196
|
+
else
|
197
|
+
MATRIX32A_ARRAY
|
198
|
+
end
|
199
|
+
|
200
|
+
n = NMatrix.new([4,3], nary, left_dtype)[1..3,1..2]
|
201
|
+
m = NMatrix.new([3,2], mary, right_dtype)[1..2,0..1]
|
202
|
+
|
203
|
+
r = n.dot m
|
204
|
+
r.shape.should eql([3,2])
|
205
|
+
|
206
|
+
r[0,0].should == 219.0
|
207
|
+
r[0,1].should == 185.0
|
208
|
+
r[1,0].should == 244.0
|
209
|
+
r[1,1].should == 205.0
|
210
|
+
r[2,0].should == 42.0
|
211
|
+
r[2,1].should == 35.0
|
212
|
+
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
158
216
|
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
r[0,0].should == 219.0
|
195
|
-
r[0,1].should == 185.0
|
196
|
-
r[1,0].should == 244.0
|
197
|
-
r[1,1].should == 205.0
|
198
|
-
r[2,0].should == 42.0
|
199
|
-
r[2,1].should == 35.0
|
217
|
+
context "operations" do
|
218
|
+
|
219
|
+
it "correctly transposes slices" do
|
220
|
+
@m[0...3,0].transpose.should eq N[[0, 3, 6]]
|
221
|
+
end
|
222
|
+
|
223
|
+
it "adds slices" do
|
224
|
+
(N[[0,0,0]] + @m[1,0..2]).should eq N[[3, 4, 5]]
|
225
|
+
end
|
226
|
+
|
227
|
+
it "scalar adds to slices" do
|
228
|
+
(@m[1,0..2]+1).should eq N[[4, 5, 6]]
|
229
|
+
end
|
230
|
+
|
231
|
+
it "compares slices to scalars" do
|
232
|
+
(@m[1, 0..2] > 2).each { |e| (e != 0).should be_true }
|
233
|
+
end
|
234
|
+
|
235
|
+
it "iterates only over elements in the slice" do
|
236
|
+
els = []
|
237
|
+
@m[1, 0..2].each { |e| els << e }
|
238
|
+
els.size.should eq 3
|
239
|
+
els[0].should eq 3
|
240
|
+
els[1].should eq 4
|
241
|
+
els[2].should eq 5
|
242
|
+
end
|
243
|
+
|
244
|
+
it "iterates with index only over elements in the slice" do
|
245
|
+
els = []
|
246
|
+
@m[1, 0..2].each_stored_with_indices { |a| els << a }
|
247
|
+
els.size.should eq 3
|
248
|
+
els[0].should eq [3, 0, 0]
|
249
|
+
els[1].should eq [4, 0, 1]
|
250
|
+
els[2].should eq [5, 0, 2]
|
251
|
+
end
|
200
252
|
|
201
253
|
end
|
254
|
+
|
202
255
|
end
|
203
|
-
end
|
204
|
-
end
|
205
256
|
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
257
|
+
it 'should be cleaned up by garbage collector without errors' do
|
258
|
+
1.times do
|
259
|
+
n = @m[1..2,0..1]
|
260
|
+
end
|
261
|
+
GC.start
|
262
|
+
@m.should == NMatrix.new(:dense, [3,3], (0..9).to_a, :int32).cast(stype, :int32)
|
263
|
+
n = nil
|
264
|
+
1.times do
|
265
|
+
m = NMatrix.new(:dense, [2,2], [1,2,3,4]).cast(stype, :int32)
|
266
|
+
n = m[0..1,0..1]
|
267
|
+
end
|
268
|
+
GC.start
|
269
|
+
n.should == NMatrix.new(:dense, [2,2], [1,2,3,4]).cast(stype, :int32)
|
270
|
+
end
|
220
271
|
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
272
|
+
[:dense, :list, :yale].each do |cast_type|
|
273
|
+
it "should cast from #{stype.upcase} to #{cast_type.upcase}" do
|
274
|
+
nm_eql(@m[1..2, 1..2].cast(cast_type, :int32), @m[1..2,1..2]).should be_true
|
275
|
+
nm_eql(@m[0..1, 1..2].cast(cast_type, :int32), @m[0..1,1..2]).should be_true
|
276
|
+
nm_eql(@m[1..2, 0..1].cast(cast_type, :int32), @m[1..2,0..1]).should be_true
|
277
|
+
nm_eql(@m[0..1, 0..1].cast(cast_type, :int32), @m[0..1,0..1]).should be_true
|
227
278
|
|
228
|
-
|
229
|
-
|
230
|
-
|
279
|
+
# Non square
|
280
|
+
nm_eql(@m[0..2, 1..2].cast(cast_type, :int32), @m[0..2,1..2]).should be_true
|
281
|
+
nm_eql(@m[1..2, 0..2].cast(cast_type, :int32), @m[1..2,0..2]).should be_true
|
231
282
|
|
232
|
-
|
233
|
-
|
283
|
+
# Full
|
284
|
+
nm_eql(@m[0..2, 0..2].cast(cast_type, :int32), @m).should be_true
|
285
|
+
end
|
286
|
+
end
|
234
287
|
end
|
235
288
|
end
|
236
|
-
end
|
237
|
-
end
|
238
289
|
end # unless stype == :yale
|
239
290
|
end
|
240
291
|
|
241
292
|
# Stupid but independent comparison
|
242
|
-
def nm_eql(n, m)
|
293
|
+
def nm_eql(n, m) #:nodoc:
|
243
294
|
if n.shape != m.shape
|
244
295
|
false
|
245
296
|
else
|
@@ -247,11 +298,11 @@ describe "Slice operation" do
|
|
247
298
|
n.shape[1].times do |j|
|
248
299
|
if n[i,j] != m[i,j]
|
249
300
|
puts "n[#{i},#{j}] != m[#{i},#{j}] (#{n[i,j]} != #{m[i,j]})"
|
250
|
-
return false
|
301
|
+
return false
|
251
302
|
end
|
252
303
|
end
|
253
304
|
end
|
254
305
|
true
|
255
|
-
end
|
306
|
+
end
|
256
307
|
end
|
257
308
|
end
|