nmatrix 0.1.0.rc1 → 0.1.0.rc2
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/.travis.yml +4 -1
- data/Gemfile +1 -4
- data/History.txt +64 -2
- data/Manifest.txt +6 -4
- data/README.rdoc +8 -5
- data/Rakefile +0 -2
- data/ext/nmatrix/data/data.cpp +2 -1
- data/ext/nmatrix/data/data.h +3 -2
- data/ext/nmatrix/extconf.rb +4 -9
- data/ext/nmatrix/math.cpp +65 -0
- data/ext/nmatrix/math/math.h +1 -0
- data/ext/nmatrix/nmatrix.h +2 -2
- data/ext/nmatrix/ruby_constants.cpp +3 -1
- data/ext/nmatrix/ruby_constants.h +3 -1
- data/ext/nmatrix/ruby_nmatrix.c +153 -8
- data/ext/nmatrix/util/sl_list.cpp +6 -2
- data/lib/nmatrix/io/point_cloud.rb +182 -0
- data/lib/nmatrix/math.rb +35 -5
- data/lib/nmatrix/nmatrix.rb +70 -26
- data/lib/nmatrix/shortcuts.rb +18 -1
- data/lib/nmatrix/version.rb +1 -1
- data/nmatrix.gemspec +2 -2
- data/spec/00_nmatrix_spec.rb +220 -176
- data/spec/01_enum_spec.rb +29 -29
- data/spec/02_slice_spec.rb +85 -85
- data/spec/blas_spec.rb +18 -18
- data/spec/elementwise_spec.rb +44 -44
- data/spec/io_spec.rb +31 -24
- data/spec/lapack_spec.rb +34 -34
- data/spec/math_spec.rb +61 -46
- data/spec/nmatrix_yale_spec.rb +35 -35
- data/spec/rspec_spec.rb +2 -2
- data/spec/shortcuts_spec.rb +66 -48
- data/spec/slice_set_spec.rb +31 -31
- data/spec/stat_spec.rb +40 -40
- data/spec/test.pcd +20 -0
- metadata +5 -2
data/lib/nmatrix/version.rb
CHANGED
data/nmatrix.gemspec
CHANGED
@@ -6,8 +6,8 @@ require 'nmatrix/version'
|
|
6
6
|
Gem::Specification.new do |gem|
|
7
7
|
gem.name = "nmatrix"
|
8
8
|
gem.version = NMatrix::VERSION::STRING
|
9
|
-
gem.summary = "NMatrix is an experimental linear algebra library for Ruby, written mostly in C."
|
10
|
-
gem.description = "NMatrix is an experimental linear algebra library for Ruby, written mostly in C."
|
9
|
+
gem.summary = "NMatrix is an experimental linear algebra library for Ruby, written mostly in C."
|
10
|
+
gem.description = "NMatrix is an experimental linear algebra library for Ruby, written mostly in C."
|
11
11
|
gem.homepage = 'http://sciruby.com'
|
12
12
|
gem.authors = ['John Woods', 'Chris Wailes', 'Aleksey Timin']
|
13
13
|
gem.email = ['john.o.woods@gmail.com']
|
data/spec/00_nmatrix_spec.rb
CHANGED
@@ -35,32 +35,35 @@ describe NMatrix do
|
|
35
35
|
|
36
36
|
it "creates a matrix with the new constructor" do
|
37
37
|
n = NMatrix.new([2,2], [0,1,2,3], dtype: :int64)
|
38
|
+
expect(n.shape).to eq([2,2])
|
39
|
+
expect(n.entries).to eq([0,1,2,3])
|
40
|
+
expect(n.dtype).to eq(:int64)
|
38
41
|
end
|
39
42
|
|
40
43
|
it "adequately requires information to access a single entry of a dense matrix" do
|
41
44
|
n = NMatrix.new(:dense, 4, [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], :float64)
|
42
|
-
n[0,0].
|
45
|
+
expect(n[0,0]).to eq(0)
|
43
46
|
expect { n[0] }.to raise_error(ArgumentError)
|
44
47
|
end
|
45
48
|
|
46
49
|
it "calculates exact determinants on small square matrices" do
|
47
|
-
NMatrix.new(2, [1,2,3,4], stype: :dense, dtype: :int64).det_exact.
|
50
|
+
expect(NMatrix.new(2, [1,2,3,4], stype: :dense, dtype: :int64).det_exact).to eq(-2)
|
48
51
|
end
|
49
52
|
|
50
53
|
it "calculates determinants" do
|
51
|
-
NMatrix.new(3, [-2,2,3,-1,1,3,2,0,-1], stype: :dense, dtype: :int64).det.
|
54
|
+
expect(NMatrix.new(3, [-2,2,3,-1,1,3,2,0,-1], stype: :dense, dtype: :int64).det).to eq(6)
|
52
55
|
end
|
53
56
|
|
54
57
|
it "allows casting to Ruby objects" do
|
55
58
|
m = NMatrix.new([3,3], [0,0,1,0,2,0,3,4,5], dtype: :int64, stype: :dense)
|
56
59
|
n = m.cast(:dense, :object)
|
57
|
-
n.
|
60
|
+
expect(n).to eq(m)
|
58
61
|
end
|
59
62
|
|
60
63
|
it "allows casting from Ruby objects" do
|
61
64
|
m = NMatrix.new(:dense, [3,3], [0,0,1,0,2,0,3,4,5], :object)
|
62
65
|
n = m.cast(:dense, :int64)
|
63
|
-
m.
|
66
|
+
expect(m).to eq(n)
|
64
67
|
end
|
65
68
|
|
66
69
|
it "allows stype casting of a dim 2 matrix between dense, sparse, and list (different dtypes)" do
|
@@ -78,10 +81,9 @@ describe NMatrix do
|
|
78
81
|
# work at all in IRB, but work fine when run in a regular Ruby session.
|
79
82
|
end
|
80
83
|
|
81
|
-
|
82
84
|
it "fills dense Ruby object matrix with nil" do
|
83
85
|
n = NMatrix.new([4,3], dtype: :object)
|
84
|
-
n[0,0].
|
86
|
+
expect(n[0,0]).to eq(nil)
|
85
87
|
end
|
86
88
|
|
87
89
|
it "fills dense with individual assignments" do
|
@@ -99,87 +101,85 @@ describe NMatrix do
|
|
99
101
|
n[3,1] = 2.0
|
100
102
|
n[3,2] = 3.0
|
101
103
|
|
102
|
-
n[0,0].
|
103
|
-
n[0,1].
|
104
|
-
n[0,2].
|
105
|
-
n[1,0].
|
106
|
-
n[1,1].
|
107
|
-
n[1,2].
|
108
|
-
n[2,0].
|
109
|
-
n[2,1].
|
110
|
-
n[2,2].
|
111
|
-
n[3,0].
|
112
|
-
n[3,1].
|
113
|
-
n[3,2].
|
104
|
+
expect(n[0,0]).to eq(14.0)
|
105
|
+
expect(n[0,1]).to eq(9.0)
|
106
|
+
expect(n[0,2]).to eq(3.0)
|
107
|
+
expect(n[1,0]).to eq(2.0)
|
108
|
+
expect(n[1,1]).to eq(11.0)
|
109
|
+
expect(n[1,2]).to eq(15.0)
|
110
|
+
expect(n[2,0]).to eq(0.0)
|
111
|
+
expect(n[2,1]).to eq(12.0)
|
112
|
+
expect(n[2,2]).to eq(17.0)
|
113
|
+
expect(n[3,0]).to eq(5.0)
|
114
|
+
expect(n[3,1]).to eq(2.0)
|
115
|
+
expect(n[3,2]).to eq(3.0)
|
114
116
|
end
|
115
117
|
|
116
118
|
it "fills dense with a single mass assignment" do
|
117
119
|
n = NMatrix.new([4,3], [14.0, 9.0, 3.0, 2.0, 11.0, 15.0, 0.0, 12.0, 17.0, 5.0, 2.0, 3.0])
|
118
120
|
|
119
|
-
n[0,0].
|
120
|
-
n[0,1].
|
121
|
-
n[0,2].
|
122
|
-
n[1,0].
|
123
|
-
n[1,1].
|
124
|
-
n[1,2].
|
125
|
-
n[2,0].
|
126
|
-
n[2,1].
|
127
|
-
n[2,2].
|
128
|
-
n[3,0].
|
129
|
-
n[3,1].
|
130
|
-
n[3,2].
|
121
|
+
expect(n[0,0]).to eq(14.0)
|
122
|
+
expect(n[0,1]).to eq(9.0)
|
123
|
+
expect(n[0,2]).to eq(3.0)
|
124
|
+
expect(n[1,0]).to eq(2.0)
|
125
|
+
expect(n[1,1]).to eq(11.0)
|
126
|
+
expect(n[1,2]).to eq(15.0)
|
127
|
+
expect(n[2,0]).to eq(0.0)
|
128
|
+
expect(n[2,1]).to eq(12.0)
|
129
|
+
expect(n[2,2]).to eq(17.0)
|
130
|
+
expect(n[3,0]).to eq(5.0)
|
131
|
+
expect(n[3,1]).to eq(2.0)
|
132
|
+
expect(n[3,2]).to eq(3.0)
|
131
133
|
end
|
132
134
|
|
133
135
|
it "fills dense with a single mass assignment, with dtype specified" do
|
134
136
|
m = NMatrix.new([4,3], [14.0, 9.0, 3.0, 2.0, 11.0, 15.0, 0.0, 12.0, 17.0, 5.0, 2.0, 3.0], dtype: :float32)
|
135
|
-
m[0,0].should == 14.0
|
136
|
-
m[0,1].should == 9.0
|
137
|
-
m[0,2].should == 3.0
|
138
|
-
m[1,0].should == 2.0
|
139
|
-
m[1,1].should == 11.0
|
140
|
-
m[1,2].should == 15.0
|
141
|
-
m[2,0].should == 0.0
|
142
|
-
m[2,1].should == 12.0
|
143
|
-
m[2,2].should == 17.0
|
144
|
-
m[3,0].should == 5.0
|
145
|
-
m[3,1].should == 2.0
|
146
|
-
m[3,2].should == 3.0
|
147
|
-
end
|
148
137
|
|
138
|
+
expect(m[0,0]).to eq(14.0)
|
139
|
+
expect(m[0,1]).to eq(9.0)
|
140
|
+
expect(m[0,2]).to eq(3.0)
|
141
|
+
expect(m[1,0]).to eq(2.0)
|
142
|
+
expect(m[1,1]).to eq(11.0)
|
143
|
+
expect(m[1,2]).to eq(15.0)
|
144
|
+
expect(m[2,0]).to eq(0.0)
|
145
|
+
expect(m[2,1]).to eq(12.0)
|
146
|
+
expect(m[2,2]).to eq(17.0)
|
147
|
+
expect(m[3,0]).to eq(5.0)
|
148
|
+
expect(m[3,1]).to eq(2.0)
|
149
|
+
expect(m[3,2]).to eq(3.0)
|
150
|
+
end
|
149
151
|
|
150
152
|
it "dense handles missing initialization value" do
|
151
153
|
n = NMatrix.new(3, dtype: :int8)
|
152
|
-
n.stype.
|
153
|
-
n.dtype.
|
154
|
+
expect(n.stype).to eq(:dense)
|
155
|
+
expect(n.dtype).to eq(:int8)
|
154
156
|
|
155
157
|
m = NMatrix.new(4, dtype: :float64)
|
156
|
-
m.stype.
|
157
|
-
m.dtype.
|
158
|
+
expect(m.stype).to eq(:dense)
|
159
|
+
expect(m.dtype).to eq(:float64)
|
158
160
|
end
|
159
161
|
|
160
|
-
|
161
162
|
[:dense, :list, :yale].each do |storage_type|
|
162
163
|
context storage_type do
|
163
164
|
it "can be duplicated" do
|
164
165
|
n = NMatrix.new([2,3], 1.1, stype: storage_type, dtype: :float64)
|
165
|
-
n.stype.
|
166
|
+
expect(n.stype).to eq(storage_type)
|
166
167
|
|
167
168
|
n[0,0] = 0.0
|
168
169
|
n[0,1] = 0.1
|
169
170
|
n[1,0] = 1.0
|
170
171
|
|
171
172
|
m = n.dup
|
172
|
-
m.shape.
|
173
|
-
m.dim.
|
174
|
-
m.object_id.
|
175
|
-
m.stype.
|
176
|
-
m[0,0].
|
173
|
+
expect(m.shape).to eq(n.shape)
|
174
|
+
expect(m.dim).to eq(n.dim)
|
175
|
+
expect(m.object_id).not_to eq(n.object_id)
|
176
|
+
expect(m.stype).to eq(storage_type)
|
177
|
+
expect(m[0,0]).to eq(n[0,0])
|
177
178
|
m[0,0] = 3.0
|
178
|
-
m[0,0].
|
179
|
+
expect(m[0,0]).not_to eq(n[0,0])
|
179
180
|
end
|
180
181
|
|
181
182
|
it "enforces shape boundaries" do
|
182
|
-
expect { NMatrix.new([1,10], 0, dtype: :int8, stype: storage_type, default: 0)[-1,0] }.to raise_error
|
183
183
|
expect { NMatrix.new([1,10], 0, dtype: :int8, stype: storage_type, default: 0)[1,0] }.to raise_error(RangeError)
|
184
184
|
expect { NMatrix.new([1,10], 0, dtype: :int8, stype: storage_type, default: 0)[0,10] }.to raise_error(RangeError)
|
185
185
|
end
|
@@ -187,16 +187,16 @@ describe NMatrix do
|
|
187
187
|
it "sets and gets" do
|
188
188
|
n = NMatrix.new(2, 0, stype: storage_type, dtype: :int8)
|
189
189
|
n[0,1] = 1
|
190
|
-
n[0,0].
|
191
|
-
n[1,0].
|
192
|
-
n[0,1].
|
193
|
-
n[1,1].
|
190
|
+
expect(n[0,0]).to eq(0)
|
191
|
+
expect(n[1,0]).to eq(0)
|
192
|
+
expect(n[0,1]).to eq(1)
|
193
|
+
expect(n[1,1]).to eq(0)
|
194
194
|
end
|
195
195
|
|
196
196
|
it "sets and gets references" do
|
197
197
|
n = NMatrix.new(2, stype: storage_type, dtype: :int8, default: 0)
|
198
|
-
(n[0,1] = 1).
|
199
|
-
n[0,1].
|
198
|
+
expect(n[0,1] = 1).to eq(1)
|
199
|
+
expect(n[0,1]).to eq(1)
|
200
200
|
end
|
201
201
|
|
202
202
|
# Tests Ruby object versus any C dtype (in this case we use :int64)
|
@@ -221,9 +221,9 @@ describe NMatrix do
|
|
221
221
|
end
|
222
222
|
|
223
223
|
if storage_type == :dense
|
224
|
-
ary.
|
224
|
+
expect(ary).to eq([1,2,3,4,5,6,7,8,9])
|
225
225
|
else
|
226
|
-
ary.
|
226
|
+
expect(ary).to eq([1,2,0,0,0,0,0,0,3,0,0,4])
|
227
227
|
end
|
228
228
|
end
|
229
229
|
|
@@ -247,50 +247,48 @@ describe NMatrix do
|
|
247
247
|
js << j
|
248
248
|
end
|
249
249
|
|
250
|
-
|
251
250
|
if storage_type == :yale
|
252
|
-
is.
|
253
|
-
js.
|
254
|
-
values.
|
251
|
+
expect(is).to eq([0,1,2,0,2,2])
|
252
|
+
expect(js).to eq([0,1,2,1,0,1])
|
253
|
+
expect(values).to eq([1,0,3,2,5,4])
|
255
254
|
elsif storage_type == :list
|
256
|
-
values.
|
257
|
-
is.
|
258
|
-
js.
|
255
|
+
expect(values).to eq([1,2,4,3])
|
256
|
+
expect(is).to eq([0,0,2,2])
|
257
|
+
expect(js).to eq([0,1,1,2])
|
259
258
|
elsif storage_type == :dense
|
260
|
-
values.
|
261
|
-
is.
|
262
|
-
js.
|
259
|
+
expect(values).to eq([1,2,0,0,0,0,0,4,3])
|
260
|
+
expect(is).to eq([0,0,0,1,1,1,2,2,2])
|
261
|
+
expect(js).to eq([0,1,2,0,1,2,0,1,2])
|
263
262
|
end
|
264
263
|
end
|
265
264
|
end
|
266
265
|
end
|
267
|
-
|
268
266
|
end
|
269
267
|
|
270
268
|
# dense and list, not yale
|
271
269
|
context "(storage: #{storage_type})" do
|
272
270
|
it "gets default value" do
|
273
|
-
NMatrix.new(3, 0, stype: storage_type)[1,1].
|
274
|
-
NMatrix.new(3, 0.1, stype: storage_type)[1,1].
|
275
|
-
NMatrix.new(3, 1, stype: storage_type)[1,1].
|
276
|
-
end
|
271
|
+
expect(NMatrix.new(3, 0, stype: storage_type)[1,1]).to eq(0)
|
272
|
+
expect(NMatrix.new(3, 0.1, stype: storage_type)[1,1]).to eq(0.1)
|
273
|
+
expect(NMatrix.new(3, 1, stype: storage_type)[1,1]).to eq(1)
|
277
274
|
|
275
|
+
end
|
278
276
|
it "returns shape and dim" do
|
279
|
-
NMatrix.new([3,2,8], 0, stype: storage_type).shape.
|
280
|
-
NMatrix.new([3,2,8], 0, stype: storage_type).dim.
|
277
|
+
expect(NMatrix.new([3,2,8], 0, stype: storage_type).shape).to eq([3,2,8])
|
278
|
+
expect(NMatrix.new([3,2,8], 0, stype: storage_type).dim).to eq(3)
|
281
279
|
end
|
282
280
|
|
283
281
|
it "returns number of rows and columns" do
|
284
|
-
NMatrix.new([7, 4], 3, stype: storage_type).rows.
|
285
|
-
NMatrix.new([7, 4], 3, stype: storage_type).cols.
|
282
|
+
expect(NMatrix.new([7, 4], 3, stype: storage_type).rows).to eq(7)
|
283
|
+
expect(NMatrix.new([7, 4], 3, stype: storage_type).cols).to eq(4)
|
286
284
|
end
|
287
285
|
end unless storage_type == :yale
|
288
286
|
end
|
289
287
|
|
290
288
|
|
291
289
|
it "handles dense construction" do
|
292
|
-
NMatrix.new(3,0)[1,1].
|
293
|
-
lambda { NMatrix.new(3,dtype: :int8)[1,1] }.
|
290
|
+
expect(NMatrix.new(3,0)[1,1]).to eq(0)
|
291
|
+
expect(lambda { NMatrix.new(3,dtype: :int8)[1,1] }).to_not raise_error
|
294
292
|
end
|
295
293
|
|
296
294
|
it "calculates the complex conjugate in-place" do
|
@@ -309,15 +307,15 @@ describe NMatrix do
|
|
309
307
|
#puts n.yale_ija.inspect
|
310
308
|
#puts n.yale_a.inspect
|
311
309
|
|
312
|
-
n[0,0].
|
313
|
-
n[0,1].
|
314
|
-
n[0,2].
|
315
|
-
n[1,0].
|
316
|
-
n[1,1].
|
317
|
-
n[1,2].
|
318
|
-
n[2,0].
|
319
|
-
n[2,1].
|
320
|
-
n[2,2].
|
310
|
+
expect(n[0,0]).to eq(0)
|
311
|
+
expect(n[0,1]).to eq(0)
|
312
|
+
expect(n[0,2]).to eq(333)
|
313
|
+
expect(n[1,0]).to eq(0)
|
314
|
+
expect(n[1,1]).to eq(0)
|
315
|
+
expect(n[1,2]).to eq(0)
|
316
|
+
expect(n[2,0]).to eq(0)
|
317
|
+
expect(n[2,1]).to eq(0)
|
318
|
+
expect(n[2,2]).to eq(777)
|
321
319
|
end
|
322
320
|
|
323
321
|
it "should return an enumerator when each is called without a block" do
|
@@ -336,13 +334,13 @@ describe NMatrix do
|
|
336
334
|
it "should return the matrix being iterated over when each is called with a block" do
|
337
335
|
a = NMatrix.new(2, 1)
|
338
336
|
val = (a.each { })
|
339
|
-
val.
|
337
|
+
expect(val).to eq(a)
|
340
338
|
end
|
341
339
|
|
342
340
|
it "should return the matrix being iterated over when each_stored_with_indices is called with a block" do
|
343
341
|
a = NMatrix.new(2,1)
|
344
342
|
val = (a.each_stored_with_indices { })
|
345
|
-
val.
|
343
|
+
expect(val).to eq(a)
|
346
344
|
end
|
347
345
|
end
|
348
346
|
|
@@ -351,15 +349,14 @@ describe NMatrix do
|
|
351
349
|
it "should return the matrix being iterated over when each_stored_with_indices is called with a block" do
|
352
350
|
n = NMatrix.new([2,3], 1.1, stype: storage_type, dtype: :float64, default: 0)
|
353
351
|
val = (n.each_stored_with_indices { })
|
354
|
-
val.
|
352
|
+
expect(val).to eq(n)
|
355
353
|
end
|
356
354
|
|
357
355
|
it "should return an enumerator when each_stored_with_indices is called without a block" do
|
358
356
|
n = NMatrix.new([2,3], 1.1, stype: storage_type, dtype: :float64, default: 0)
|
359
357
|
val = n.each_stored_with_indices
|
360
|
-
val.
|
358
|
+
expect(val).to be_a Enumerator
|
361
359
|
end
|
362
|
-
|
363
360
|
end
|
364
361
|
end
|
365
362
|
|
@@ -367,112 +364,159 @@ describe NMatrix do
|
|
367
364
|
t = NVector.random(256)
|
368
365
|
t.each { |x| x + 0 }
|
369
366
|
end
|
370
|
-
|
371
367
|
end
|
372
368
|
|
373
369
|
|
374
|
-
describe
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
370
|
+
describe 'NMatrix' do
|
371
|
+
context "#upper_triangle" do
|
372
|
+
it "should create a copy with the lower corner set to zero" do
|
373
|
+
n = NMatrix.seq(4)+1
|
374
|
+
expect(n.upper_triangle).to eq(NMatrix.new(4, [1,2,3,4,0,6,7,8,0,0,11,12,0,0,0,16]))
|
375
|
+
expect(n.upper_triangle(2)).to eq(NMatrix.new(4, [1,2,3,4,5,6,7,8,9,10,11,12,0,14,15,16]))
|
376
|
+
end
|
379
377
|
end
|
380
|
-
end
|
381
378
|
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
379
|
+
context "#lower_triangle" do
|
380
|
+
it "should create a copy with the lower corner set to zero" do
|
381
|
+
n = NMatrix.seq(4)+1
|
382
|
+
expect(n.lower_triangle).to eq(NMatrix.new(4, [1,0,0,0,5,6,0,0,9,10,11,0,13,14,15,16]))
|
383
|
+
expect(n.lower_triangle(2)).to eq(NMatrix.new(4, [1,2,3,0,5,6,7,8,9,10,11,12,13,14,15,16]))
|
384
|
+
end
|
387
385
|
end
|
388
|
-
end
|
389
386
|
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
387
|
+
context "#upper_triangle!" do
|
388
|
+
it "should create a copy with the lower corner set to zero" do
|
389
|
+
n = NMatrix.seq(4)+1
|
390
|
+
expect(n.upper_triangle!).to eq(NMatrix.new(4, [1,2,3,4,0,6,7,8,0,0,11,12,0,0,0,16]))
|
391
|
+
n = NMatrix.seq(4)+1
|
392
|
+
expect(n.upper_triangle!(2)).to eq(NMatrix.new(4, [1,2,3,4,5,6,7,8,9,10,11,12,0,14,15,16]))
|
393
|
+
end
|
396
394
|
end
|
397
|
-
end
|
398
395
|
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
396
|
+
context "#lower_triangle!" do
|
397
|
+
it "should create a copy with the lower corner set to zero" do
|
398
|
+
n = NMatrix.seq(4)+1
|
399
|
+
expect(n.lower_triangle!).to eq(NMatrix.new(4, [1,0,0,0,5,6,0,0,9,10,11,0,13,14,15,16]))
|
400
|
+
n = NMatrix.seq(4)+1
|
401
|
+
expect(n.lower_triangle!(2)).to eq(NMatrix.new(4, [1,2,3,0,5,6,7,8,9,10,11,12,13,14,15,16]))
|
402
|
+
end
|
405
403
|
end
|
406
|
-
end
|
407
404
|
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
405
|
+
context "#reshape" do
|
406
|
+
it "should change the shape of a matrix without the contents changing" do
|
407
|
+
n = NMatrix.seq(4)+1
|
408
|
+
expect(n.reshape([8,2]).to_flat_array).to eq(n.to_flat_array)
|
409
|
+
end
|
413
410
|
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
411
|
+
it "should permit a change of dimensionality" do
|
412
|
+
n = NMatrix.seq(4)+1
|
413
|
+
expect(n.reshape([8,1,2]).to_flat_array).to eq(n.to_flat_array)
|
414
|
+
end
|
415
|
+
|
416
|
+
it "should prevent a resize" do
|
417
|
+
n = NMatrix.seq(4)+1
|
418
|
+
expect { n.reshape([5,2]) }.to raise_error(ArgumentError)
|
419
|
+
end
|
420
|
+
|
421
|
+
it "should do the reshape operation in place" do
|
422
|
+
n = NMatrix.seq(4)+1
|
423
|
+
expect(n.reshape!([8,2]).eql?(n)).to eq(true) # because n itself changes
|
424
|
+
end
|
425
|
+
|
426
|
+
it "reshape and reshape! must produce same result" do
|
427
|
+
n = NMatrix.seq(4)+1
|
428
|
+
a = NMatrix.seq(4)+1
|
429
|
+
expect(n.reshape!([8,2])==a.reshape(8,2)).to eq(true) # because n itself changes
|
430
|
+
end
|
418
431
|
|
419
|
-
|
420
|
-
|
421
|
-
|
432
|
+
it "should prevent a resize in place" do
|
433
|
+
n = NMatrix.seq(4)+1
|
434
|
+
expect { n.reshape([5,2]) }.to raise_error(ArgumentError)
|
435
|
+
end
|
422
436
|
end
|
423
|
-
end
|
424
437
|
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
438
|
+
context "#transpose" do
|
439
|
+
[:dense, :list, :yale].each do |stype|
|
440
|
+
context(stype) do
|
441
|
+
it "should transpose a #{stype} matrix (2-dimensional)" do
|
442
|
+
n = NMatrix.seq(4, stype: stype)
|
443
|
+
expect(n.transpose.to_a.flatten).to eq([0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15])
|
444
|
+
end
|
431
445
|
end
|
432
446
|
end
|
433
|
-
end
|
434
447
|
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
448
|
+
[:dense, :list].each do |stype|
|
449
|
+
context(stype) do
|
450
|
+
it "should transpose a #{stype} matrix (3-dimensional)" do
|
451
|
+
n = NMatrix.new([4,4,1], [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], stype: stype)
|
452
|
+
expect(n.transpose([2,1,0]).to_flat_array).to eq([0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15])
|
453
|
+
expect(n.transpose([1,0,2]).to_flat_array).to eq([0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15])
|
454
|
+
expect(n.transpose([0,2,1]).to_flat_array).to eq(n.to_flat_array) # for dense, make this reshape!
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
it "should just copy a 1-dimensional #{stype} matrix" do
|
459
|
+
n = NMatrix.new([3], [1,2,3], stype: stype)
|
460
|
+
expect(n.transpose).to eq n
|
461
|
+
expect(n.transpose).not_to be n
|
442
462
|
end
|
443
463
|
end
|
444
464
|
end
|
445
465
|
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
context ("#{left}?#{right}") do
|
453
|
-
it "should compare two matrices of differing stypes" do
|
454
|
-
n = NMatrix.new([3,4], [0,0,1,2,0,0,3,4,0,0,0,0,5,6,7,0], stype: left)
|
455
|
-
m = NMatrix.new([3,4], [0,0,1,2,0,0,3,4,0,0,0,0,5,6,7,0], stype: right)
|
456
|
-
n.should == m
|
466
|
+
context "#dot_product" do
|
467
|
+
[:dense].each do |stype| # list storage transpose not yet implemented
|
468
|
+
context(stype) do # yale support only 2-dim matrix
|
469
|
+
it "should work like vector product on a #{stype} (1-dimensional)" do
|
470
|
+
m = NMatrix.new([3], [1,2,3], stype: stype)
|
471
|
+
expect(m.dot(m)).to eq (NMatrix.new([1],[14]))
|
457
472
|
end
|
458
473
|
end
|
459
474
|
end
|
460
475
|
end
|
461
|
-
end
|
462
476
|
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
477
|
+
context "#==" do
|
478
|
+
[:dense, :list, :yale].each do |left|
|
479
|
+
[:dense, :list, :yale].each do |right|
|
480
|
+
next if left == right
|
481
|
+
context ("#{left}?#{right}") do
|
482
|
+
it "should compare two matrices of differing stypes" do
|
483
|
+
n = NMatrix.new([3,4], [0,0,1,2,0,0,3,4,0,0,0,0,5,6,7,0], stype: left)
|
484
|
+
m = NMatrix.new([3,4], [0,0,1,2,0,0,3,4,0,0,0,0,5,6,7,0], stype: right)
|
485
|
+
expect(n).to eq(m)
|
486
|
+
end
|
487
|
+
end
|
488
|
+
end
|
489
|
+
end
|
467
490
|
end
|
468
491
|
|
469
|
-
|
470
|
-
|
471
|
-
|
492
|
+
context "#concat" do
|
493
|
+
it "should default to horizontal concatenation" do
|
494
|
+
n = NMatrix.new([1,3], [1,2,3])
|
495
|
+
expect(n.concat(n)).to eq(NMatrix.new([1,6], [1,2,3,1,2,3]))
|
496
|
+
end
|
497
|
+
|
498
|
+
it "should permit vertical concatenation" do
|
499
|
+
n = NMatrix.new([1,3], [1,2,3])
|
500
|
+
expect(n.vconcat(n)).to eq(NMatrix.new([2,3], [1,2,3]))
|
501
|
+
end
|
502
|
+
|
503
|
+
it "should permit depth concatenation on tensors" do
|
504
|
+
n = NMatrix.new([1,3,1], [1,2,3])
|
505
|
+
expect(n.dconcat(n)).to eq(NMatrix.new([1,3,2], [1,1,2,2,3,3]))
|
506
|
+
end
|
472
507
|
end
|
473
508
|
|
474
|
-
|
475
|
-
|
476
|
-
|
509
|
+
context "#[]" do
|
510
|
+
it "should return values based on indices" do
|
511
|
+
n = NMatrix.new([2,5], [1,2,3,4,5,6,7,8,9,0])
|
512
|
+
expect(n[1,0]).to eq 6
|
513
|
+
expect(n[1,0..3]).to eq NMatrix.new([1,4],[6,7,8,9])
|
514
|
+
end
|
515
|
+
|
516
|
+
it "should work for negative indices" do
|
517
|
+
n = NMatrix.new([1,5], [1,2,3,4,5])
|
518
|
+
expect(n[-1]).to eq(5)
|
519
|
+
expect(n[0,0..-2]).to eq(NMatrix.new([1,4],[1,2,3,4]))
|
520
|
+
end
|
477
521
|
end
|
478
522
|
end
|