nmatrix 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/Gemfile +5 -0
- data/History.txt +97 -0
- data/Manifest.txt +34 -7
- data/README.rdoc +13 -13
- data/Rakefile +36 -26
- data/ext/nmatrix/data/data.cpp +15 -2
- data/ext/nmatrix/data/data.h +4 -0
- data/ext/nmatrix/data/ruby_object.h +5 -14
- data/ext/nmatrix/extconf.rb +3 -2
- data/ext/nmatrix/{util/math.cpp → math.cpp} +296 -6
- data/ext/nmatrix/math/asum.h +143 -0
- data/ext/nmatrix/math/geev.h +82 -0
- data/ext/nmatrix/math/gemm.h +267 -0
- data/ext/nmatrix/math/gemv.h +208 -0
- data/ext/nmatrix/math/ger.h +96 -0
- data/ext/nmatrix/math/gesdd.h +80 -0
- data/ext/nmatrix/math/gesvd.h +78 -0
- data/ext/nmatrix/math/getf2.h +86 -0
- data/ext/nmatrix/math/getrf.h +240 -0
- data/ext/nmatrix/math/getri.h +107 -0
- data/ext/nmatrix/math/getrs.h +125 -0
- data/ext/nmatrix/math/idamax.h +86 -0
- data/ext/nmatrix/{util → math}/lapack.h +60 -356
- data/ext/nmatrix/math/laswp.h +165 -0
- data/ext/nmatrix/math/long_dtype.h +52 -0
- data/ext/nmatrix/math/math.h +1154 -0
- data/ext/nmatrix/math/nrm2.h +181 -0
- data/ext/nmatrix/math/potrs.h +125 -0
- data/ext/nmatrix/math/rot.h +141 -0
- data/ext/nmatrix/math/rotg.h +115 -0
- data/ext/nmatrix/math/scal.h +73 -0
- data/ext/nmatrix/math/swap.h +73 -0
- data/ext/nmatrix/math/trsm.h +383 -0
- data/ext/nmatrix/nmatrix.cpp +176 -152
- data/ext/nmatrix/nmatrix.h +1 -2
- data/ext/nmatrix/ruby_constants.cpp +9 -4
- data/ext/nmatrix/ruby_constants.h +1 -0
- data/ext/nmatrix/storage/dense.cpp +57 -41
- data/ext/nmatrix/storage/list.cpp +52 -50
- data/ext/nmatrix/storage/storage.cpp +59 -43
- data/ext/nmatrix/storage/yale.cpp +352 -333
- data/ext/nmatrix/storage/yale.h +4 -0
- data/lib/nmatrix.rb +2 -2
- data/lib/nmatrix/blas.rb +4 -4
- data/lib/nmatrix/enumerate.rb +241 -0
- data/lib/nmatrix/lapack.rb +54 -1
- data/lib/nmatrix/math.rb +462 -0
- data/lib/nmatrix/nmatrix.rb +210 -486
- data/lib/nmatrix/nvector.rb +0 -62
- data/lib/nmatrix/rspec.rb +75 -0
- data/lib/nmatrix/shortcuts.rb +136 -108
- data/lib/nmatrix/version.rb +1 -1
- data/spec/blas_spec.rb +20 -12
- data/spec/elementwise_spec.rb +22 -13
- data/spec/io_spec.rb +1 -0
- data/spec/lapack_spec.rb +197 -0
- data/spec/nmatrix_spec.rb +39 -38
- data/spec/nvector_spec.rb +3 -9
- data/spec/rspec_monkeys.rb +29 -0
- data/spec/rspec_spec.rb +34 -0
- data/spec/shortcuts_spec.rb +14 -16
- data/spec/slice_spec.rb +242 -186
- data/spec/spec_helper.rb +19 -0
- metadata +33 -5
- data/ext/nmatrix/util/math.h +0 -2612
data/spec/nvector_spec.rb
CHANGED
@@ -49,13 +49,6 @@ describe NVector do
|
|
49
49
|
v[0].should == 1.555
|
50
50
|
end
|
51
51
|
|
52
|
-
it "transpose!() changes destructively its raw and column stored structure" do
|
53
|
-
v = NVector.new 5, :float64
|
54
|
-
v.transpose!
|
55
|
-
v.shape[0].should == 5
|
56
|
-
v.shape[1].should == 1
|
57
|
-
end
|
58
|
-
|
59
52
|
it "dot() multiples itself by another NVector" do
|
60
53
|
v1 = NVector.new(2, :float64)
|
61
54
|
v2 = NVector.new(2, :float64).transpose
|
@@ -63,10 +56,11 @@ describe NVector do
|
|
63
56
|
v1[1] = 2.3
|
64
57
|
v2[0] = 1.3
|
65
58
|
v2[1] = 2.5
|
66
|
-
v1.dot(v2).should
|
59
|
+
v1.dot(v2).should be_within(0.000000001).of(7.7)
|
67
60
|
end
|
68
61
|
|
69
62
|
it "dot!() multiples itself destructively by another NVector" do
|
63
|
+
pending "dot! not yet implemented"
|
70
64
|
v1 = NVector.new 2, :float64
|
71
65
|
v2 = NVector.new(2, :float64).transpose
|
72
66
|
v1[0] = 1.5
|
@@ -74,7 +68,7 @@ describe NVector do
|
|
74
68
|
v2[0] = 1.3
|
75
69
|
v2[1] = 2.5
|
76
70
|
v1.dot!(v2)
|
77
|
-
v1.should
|
71
|
+
v1.should be_within(0.000000001).of(7.7)
|
78
72
|
end
|
79
73
|
|
80
74
|
it "pretty_print() prints values to standard output with a pretty format" do
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module RSpec::Matchers::BuiltIn
|
2
|
+
class BeWithin
|
3
|
+
|
4
|
+
def of(expected)
|
5
|
+
@expected = expected
|
6
|
+
@unit = ''
|
7
|
+
if expected.is_a?(NMatrix)
|
8
|
+
@tolerance = if @delta.is_a?(NMatrix)
|
9
|
+
@delta.clone
|
10
|
+
elsif @delta.is_a?(Array)
|
11
|
+
NMatrix.new(:dense, expected.shape, @delta, expected.dtype)
|
12
|
+
else
|
13
|
+
NMatrix.ones_like(expected) * @delta
|
14
|
+
end
|
15
|
+
else
|
16
|
+
@tolerance = @delta
|
17
|
+
end
|
18
|
+
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
def percent_of(expected)
|
23
|
+
@expected = expected
|
24
|
+
@unit = '%'
|
25
|
+
@tolerance = @expected.abs * @delta / 100.0 # <- only change is to reverse abs and @delta
|
26
|
+
self
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/spec/rspec_spec.rb
ADDED
@@ -0,0 +1,34 @@
|
|
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 - 2012, Ruby Science Foundation
|
12
|
+
# NMatrix is Copyright (c) 2012, 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
|
+
# == rspec_spec.rb
|
24
|
+
#
|
25
|
+
# A spec for testing monkey patches to RSpec for NMatrix.
|
26
|
+
#
|
27
|
+
require File.join(File.dirname(__FILE__), "spec_helper.rb")
|
28
|
+
|
29
|
+
describe "RSpec" do
|
30
|
+
it "should permit #be_within to be used on a dense NMatrix" do
|
31
|
+
(NMatrix.new(:dense, [4,1], 1.0, :complex128) / 10000.0).should be_within(0.00000001).of(NMatrix.new(:dense, [4,1], 0.0001, :float64))
|
32
|
+
(NMatrix.new(:dense, [4,1], 1.0, :complex128) / 10000.0).should_not be_within(0.00000001).of(NMatrix.new(:dense, [4,1], 1.0, :float64))
|
33
|
+
end
|
34
|
+
end
|
data/spec/shortcuts_spec.rb
CHANGED
@@ -165,29 +165,27 @@ describe NMatrix do
|
|
165
165
|
m.column(2).is_a?(NMatrix).should be_true
|
166
166
|
end
|
167
167
|
|
168
|
-
it "column() accepts a second parameter (only :copy or :reference)" do
|
169
|
-
m = NMatrix.random(3)
|
170
|
-
|
171
|
-
expect { m.column(1, :copy) }.to_not raise_error
|
172
|
-
expect { m.column(1, :reference) }.to_not raise_error
|
173
|
-
|
174
|
-
expect { m.column(1, :derp) }.to raise_error
|
175
|
-
end
|
176
|
-
|
177
168
|
it "row() returns a NMatrix" do
|
178
169
|
m = NMatrix.random(3)
|
179
170
|
|
180
171
|
m.row(2).is_a?(NMatrix).should be_true
|
181
172
|
end
|
182
173
|
|
183
|
-
it "
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
174
|
+
it "diagonals() creates an NMatrix" do
|
175
|
+
arr = [1,2,3,4]
|
176
|
+
m = NMatrix.diagonals(arr)
|
177
|
+
m.is_a?(NMatrix).should be_true
|
178
|
+
end
|
188
179
|
|
189
|
-
|
180
|
+
it "diagonals() contains the seeded values on the diagonal" do
|
181
|
+
arr = [1,2,3,4]
|
182
|
+
m = NMatrix.diagonals(arr)
|
183
|
+
m[0,0].should eq(arr[0])
|
184
|
+
m[1,1].should eq(arr[1])
|
185
|
+
m[2,2].should eq(arr[2])
|
186
|
+
m[3,3].should eq(arr[3])
|
190
187
|
end
|
188
|
+
|
191
189
|
end
|
192
190
|
|
193
191
|
describe "NVector" do
|
@@ -261,7 +259,7 @@ describe "Inline constructor" do
|
|
261
259
|
|
262
260
|
it "creates a NMatrix with the given values" do
|
263
261
|
m = NMatrix.new([2, 2], [1, 4, 6, 7])
|
264
|
-
n =
|
262
|
+
n = NMatrix[[1, 4], [6, 7]]
|
265
263
|
|
266
264
|
m.should.eql? n
|
267
265
|
end
|
data/spec/slice_spec.rb
CHANGED
@@ -27,29 +27,118 @@
|
|
27
27
|
require File.dirname(__FILE__) + "/spec_helper.rb"
|
28
28
|
|
29
29
|
describe "Slice operation" do
|
30
|
+
|
30
31
|
[:dense, :list, :yale].each do |stype|
|
31
32
|
context "for #{stype}" do
|
32
33
|
before :each do
|
33
34
|
@m = create_matrix(stype)
|
34
35
|
end
|
35
36
|
|
36
|
-
|
37
|
-
it "should
|
38
|
-
|
39
|
-
|
37
|
+
if stype == :yale
|
38
|
+
it "should binary search for the left boundary of a partial row of stored indices correctly" do
|
39
|
+
n = NMatrix.new(:yale, 10, :int32)
|
40
|
+
n[3,0] = 1
|
41
|
+
#n[3,2] = 2
|
42
|
+
n[3,3] = 3
|
43
|
+
n[3,4] = 4
|
44
|
+
n[3,6] = 5
|
45
|
+
n[3,8] = 6
|
46
|
+
n[3,9] = 7
|
47
|
+
vs = []
|
48
|
+
is = []
|
49
|
+
js = []
|
50
|
+
n[3,1..9].each_stored_with_indices do |v,i,j|
|
51
|
+
vs << v
|
52
|
+
is << i
|
53
|
+
js << j
|
54
|
+
end
|
40
55
|
|
56
|
+
vs.should == [3,4,5,6,7]
|
57
|
+
js.should == [2,3,5,7,8]
|
58
|
+
is.should == [0,0,0,0,0]
|
59
|
+
end
|
60
|
+
elsif stype == :list
|
61
|
+
it "should iterate across a partial row of stored indices" do
|
62
|
+
vs = []
|
63
|
+
is = []
|
64
|
+
js = []
|
65
|
+
|
66
|
+
STDERR.puts("now") if stype == :yale
|
67
|
+
@m[2,1..2].each_stored_with_indices do |v,i,j|
|
68
|
+
vs << v
|
69
|
+
is << i
|
70
|
+
js << j
|
71
|
+
end
|
41
72
|
|
42
|
-
|
43
|
-
|
44
|
-
|
73
|
+
vs.should == [7,8]
|
74
|
+
is.should == [0,0]
|
75
|
+
js.should == [0,1]
|
45
76
|
end
|
77
|
+
end
|
78
|
+
|
79
|
+
unless stype == :dense
|
80
|
+
it "should iterate across a row of stored indices" do
|
81
|
+
|
82
|
+
vs = []
|
83
|
+
is = []
|
84
|
+
js = []
|
85
|
+
@m[2,0..2].each_stored_with_indices do |v,i,j|
|
86
|
+
vs << v
|
87
|
+
is << i
|
88
|
+
js << j
|
89
|
+
end
|
90
|
+
vs.should == (stype == :yale ? [8,6,7] : [6,7,8])
|
91
|
+
is.should == [0,0,0]
|
92
|
+
js.should == (stype == :yale ? [2,0,1] : [0,1,2])
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should iterate across a submatrix of stored indices" do
|
96
|
+
vs = []
|
97
|
+
is = []
|
98
|
+
js = []
|
99
|
+
@m[0..1,1..2].each_stored_with_indices do |v,i,j|
|
100
|
+
vs << v
|
101
|
+
is << i
|
102
|
+
js << j
|
103
|
+
end
|
46
104
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
@m[1..2,0..1].should == @m[1..2, 0..1]
|
105
|
+
vs.should == (stype == :yale ? [4,1,2,5] : [1,2,4,5])
|
106
|
+
is.should == (stype == :yale ? [1,0,0,1] : [0,0,1,1])
|
107
|
+
js.should == (stype == :yale ? [0,0,1,1] : [0,1,0,1])
|
51
108
|
end
|
52
|
-
end
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should return correct shape and 1st-order supershape" do
|
112
|
+
x = NMatrix.random([10,12])
|
113
|
+
y = x[0...8,5...12]
|
114
|
+
y.shape.should == [8,7]
|
115
|
+
y.supershape.should == [10,12]
|
116
|
+
end
|
117
|
+
|
118
|
+
it "should return correct 1st- and 2nd-order supershape" do
|
119
|
+
pending "Not yet sure if we ever want to enable reference slices of reference slices"
|
120
|
+
x = NMatrix.random([10,12])
|
121
|
+
y = x[0...8,5...12]
|
122
|
+
z = y[0...3,0...4]
|
123
|
+
z.supershape(2).should == y.supershape(1)
|
124
|
+
z.supershape(1).should == [8,7]
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should have #is_ref? method" do
|
128
|
+
a = @m[0..1, 0..1]
|
129
|
+
b = @m.slice(0..1, 0..1)
|
130
|
+
|
131
|
+
|
132
|
+
@m.is_ref?.should be_false
|
133
|
+
a.is_ref?.should be_true
|
134
|
+
b.is_ref?.should be_false
|
135
|
+
end
|
136
|
+
|
137
|
+
it "reference should compare with non-reference" do
|
138
|
+
@m.slice(1..2,0..1).should == @m[1..2, 0..1]
|
139
|
+
@m[1..2,0..1].should == @m.slice(1..2, 0..1)
|
140
|
+
@m[1..2,0..1].should == @m[1..2, 0..1]
|
141
|
+
end
|
53
142
|
|
54
143
|
context "with copying" do
|
55
144
|
it 'should return an NMatrix' do
|
@@ -66,7 +155,7 @@ describe "Slice operation" do
|
|
66
155
|
@m[2,1].should eql(7)
|
67
156
|
end
|
68
157
|
|
69
|
-
it 'should return a 1x2
|
158
|
+
it 'should return a 1x2 matrix with refs to self elements' do
|
70
159
|
n = @m.slice(0,1..2)
|
71
160
|
n.shape.should eql([1,2])
|
72
161
|
|
@@ -105,211 +194,178 @@ describe "Slice operation" do
|
|
105
194
|
end
|
106
195
|
end
|
107
196
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
197
|
+
# Yale:
|
198
|
+
#context "by copy" do
|
199
|
+
#it "should correctly preserve zeros" do
|
200
|
+
# @m = NMatrix.new(:yale, 3, :int64)
|
201
|
+
# column_slice = @m.column(2, :copy)
|
202
|
+
# column_slice[0].should == 0
|
203
|
+
# column_slice[1].should == 0
|
204
|
+
# column_slice[2].should == 0
|
205
|
+
#end
|
206
|
+
#end
|
207
|
+
|
208
|
+
context "by reference" do
|
209
|
+
it 'should return an NMatrix' do
|
210
|
+
n = @m[0..1,0..1]
|
211
|
+
nm_eql(n, NMatrix.new([2,2], [0,1,3,4], :int32)).should be_true
|
115
212
|
end
|
116
213
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
column_slice = @m.column(2, :copy)
|
121
|
-
column_slice[0].should == 0
|
122
|
-
column_slice[1].should == 0
|
123
|
-
column_slice[2].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
|
214
|
+
it 'should return a 2x2 matrix with refs to self elements' do
|
215
|
+
n = @m[1..2,0..1]
|
216
|
+
n.shape.should eql([2,2])
|
132
217
|
|
133
|
-
|
134
|
-
|
135
|
-
|
218
|
+
n[0,0].should == @m[1,0]
|
219
|
+
n[0,0] = -9
|
220
|
+
@m[1,0].should eql(-9)
|
221
|
+
end
|
136
222
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
end
|
223
|
+
it 'should return a 1x2 vector with refs to self elements' do
|
224
|
+
n = @m[0,1..2]
|
225
|
+
n.shape.should eql([1,2])
|
141
226
|
|
142
|
-
|
143
|
-
|
144
|
-
|
227
|
+
n[0].should == @m[0,1]
|
228
|
+
n[0] = -9
|
229
|
+
@m[0,1].should eql(-9)
|
230
|
+
end
|
145
231
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
end
|
232
|
+
it 'should return a 2x1 vector with refs to self elements' do
|
233
|
+
n = @m[0..1,1]
|
234
|
+
n.shape.should eql([2,1])
|
150
235
|
|
151
|
-
|
152
|
-
|
153
|
-
|
236
|
+
n[0].should == @m[0,1]
|
237
|
+
n[0] = -9
|
238
|
+
@m[0,1].should eql(-9)
|
239
|
+
end
|
154
240
|
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
241
|
+
it 'should slice again' do
|
242
|
+
n = @m[1..2, 1..2]
|
243
|
+
nm_eql(n[1,0..1], NVector.new(2, [7,8], :int32).transpose).should be_true
|
244
|
+
end
|
159
245
|
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
end
|
246
|
+
it 'should be correct slice for range 0..2 and 0...3' do
|
247
|
+
@m[0..2,0..2].should == @m[0...3,0...3]
|
248
|
+
end
|
164
249
|
|
165
|
-
|
166
|
-
|
167
|
-
|
250
|
+
if stype == :dense
|
251
|
+
[:byte,:int8,:int16,:int32,:int64,:float32,:float64,:rational64,:rational128].each do |left_dtype|
|
252
|
+
[:byte,:int8,:int16,:int32,:int64,:float32,:float64,:rational64,:rational128].each do |right_dtype|
|
253
|
+
|
254
|
+
# Won't work if they're both 1-byte, due to overflow.
|
255
|
+
next if [:byte,:int8].include?(left_dtype) && [:byte,:int8].include?(right_dtype)
|
256
|
+
|
257
|
+
# For now, don't bother testing int-int mult.
|
258
|
+
#next if [:int8,:int16,:int32,:int64].include?(left_dtype) && [:int8,:int16,:int32,:int64].include?(right_dtype)
|
259
|
+
it "handles #{left_dtype.to_s} dot #{right_dtype.to_s} matrix multiplication" do
|
260
|
+
#STDERR.puts "dtype=#{dtype.to_s}"
|
261
|
+
#STDERR.puts "2"
|
262
|
+
|
263
|
+
nary = if left_dtype.to_s =~ /complex/
|
264
|
+
COMPLEX_MATRIX43A_ARRAY
|
265
|
+
elsif left_dtype.to_s =~ /rational/
|
266
|
+
RATIONAL_MATRIX43A_ARRAY
|
267
|
+
else
|
268
|
+
MATRIX43A_ARRAY
|
269
|
+
end
|
270
|
+
|
271
|
+
mary = if right_dtype.to_s =~ /complex/
|
272
|
+
COMPLEX_MATRIX32A_ARRAY
|
273
|
+
elsif right_dtype.to_s =~ /rational/
|
274
|
+
RATIONAL_MATRIX32A_ARRAY
|
275
|
+
else
|
276
|
+
MATRIX32A_ARRAY
|
277
|
+
end
|
278
|
+
|
279
|
+
n = NMatrix.new([4,3], nary, left_dtype)[1..3,1..2]
|
280
|
+
m = NMatrix.new([3,2], mary, right_dtype)[1..2,0..1]
|
281
|
+
|
282
|
+
r = n.dot m
|
283
|
+
r.shape.should eql([3,2])
|
284
|
+
|
285
|
+
r[0,0].should == 219.0
|
286
|
+
r[0,1].should == 185.0
|
287
|
+
r[1,0].should == 244.0
|
288
|
+
r[1,1].should == 205.0
|
289
|
+
r[2,0].should == 42.0
|
290
|
+
r[2,1].should == 35.0
|
168
291
|
|
169
|
-
if stype == :dense
|
170
|
-
[:byte,:int8,:int16,:int32,:int64,:float32,:float64,:rational64,:rational128].each do |left_dtype|
|
171
|
-
[:byte,:int8,:int16,:int32,:int64,:float32,:float64,:rational64,:rational128].each do |right_dtype|
|
172
|
-
|
173
|
-
# Won't work if they're both 1-byte, due to overflow.
|
174
|
-
next if [:byte,:int8].include?(left_dtype) && [:byte,:int8].include?(right_dtype)
|
175
|
-
|
176
|
-
# For now, don't bother testing int-int mult.
|
177
|
-
#next if [:int8,:int16,:int32,:int64].include?(left_dtype) && [:int8,:int16,:int32,:int64].include?(right_dtype)
|
178
|
-
it "handles #{left_dtype.to_s} dot #{right_dtype.to_s} matrix multiplication" do
|
179
|
-
#STDERR.puts "dtype=#{dtype.to_s}"
|
180
|
-
#STDERR.puts "2"
|
181
|
-
|
182
|
-
nary = if left_dtype.to_s =~ /complex/
|
183
|
-
COMPLEX_MATRIX43A_ARRAY
|
184
|
-
elsif left_dtype.to_s =~ /rational/
|
185
|
-
RATIONAL_MATRIX43A_ARRAY
|
186
|
-
else
|
187
|
-
MATRIX43A_ARRAY
|
188
|
-
end
|
189
|
-
|
190
|
-
mary = if right_dtype.to_s =~ /complex/
|
191
|
-
COMPLEX_MATRIX32A_ARRAY
|
192
|
-
elsif right_dtype.to_s =~ /rational/
|
193
|
-
RATIONAL_MATRIX32A_ARRAY
|
194
|
-
else
|
195
|
-
MATRIX32A_ARRAY
|
196
|
-
end
|
197
|
-
|
198
|
-
n = NMatrix.new([4,3], nary, left_dtype)[1..3,1..2]
|
199
|
-
m = NMatrix.new([3,2], mary, right_dtype)[1..2,0..1]
|
200
|
-
|
201
|
-
r = n.dot m
|
202
|
-
r.shape.should eql([3,2])
|
203
|
-
|
204
|
-
r[0,0].should == 219.0
|
205
|
-
r[0,1].should == 185.0
|
206
|
-
r[1,0].should == 244.0
|
207
|
-
r[1,1].should == 205.0
|
208
|
-
r[2,0].should == 42.0
|
209
|
-
r[2,1].should == 35.0
|
210
|
-
|
211
|
-
end
|
212
292
|
end
|
213
293
|
end
|
294
|
+
end
|
214
295
|
|
215
|
-
|
216
|
-
|
217
|
-
it "correctly transposes slices" do
|
218
|
-
@m[0...3,0].transpose.should eq N[[0, 3, 6]]
|
219
|
-
end
|
296
|
+
context "operations" do
|
220
297
|
|
221
|
-
|
222
|
-
|
223
|
-
|
298
|
+
it "correctly transposes slices" do
|
299
|
+
@m[0...3,0].transpose.should eq NMatrix[[0, 3, 6]]
|
300
|
+
end
|
224
301
|
|
225
|
-
|
226
|
-
|
227
|
-
|
302
|
+
it "adds slices" do
|
303
|
+
(NMatrix[[0,0,0]] + @m[1,0..2]).should eq NMatrix[[3, 4, 5]]
|
304
|
+
end
|
228
305
|
|
229
|
-
|
230
|
-
|
231
|
-
|
306
|
+
it "scalar adds to slices" do
|
307
|
+
(@m[1,0..2]+1).should eq NMatrix[[4, 5, 6]]
|
308
|
+
end
|
232
309
|
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
els.size.should eq 3
|
237
|
-
els[0].should eq 3
|
238
|
-
els[1].should eq 4
|
239
|
-
els[2].should eq 5
|
240
|
-
end
|
310
|
+
it "compares slices to scalars" do
|
311
|
+
(@m[1, 0..2] > 2).each { |e| (e != 0).should be_true }
|
312
|
+
end
|
241
313
|
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
314
|
+
it "iterates only over elements in the slice" do
|
315
|
+
els = []
|
316
|
+
@m[1, 0..2].each { |e| els << e }
|
317
|
+
els.size.should eq 3
|
318
|
+
els[0].should eq 3
|
319
|
+
els[1].should eq 4
|
320
|
+
els[2].should eq 5
|
321
|
+
end
|
250
322
|
|
323
|
+
it "iterates with index only over elements in the slice" do
|
324
|
+
els = []
|
325
|
+
@m[1, 0..2].each_stored_with_indices { |a| els << a }
|
326
|
+
els.size.should eq 3
|
327
|
+
els[0].should eq [3, 0, 0]
|
328
|
+
els[1].should eq [4, 0, 1]
|
329
|
+
els[2].should eq [5, 0, 2]
|
251
330
|
end
|
252
331
|
|
253
332
|
end
|
254
333
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
n.should == NMatrix.new(:dense, [2,2], [1,2,3,4]).cast(stype, :int32)
|
334
|
+
end
|
335
|
+
|
336
|
+
it 'should be cleaned up by garbage collector without errors' do
|
337
|
+
1.times do
|
338
|
+
n = @m[1..2,0..1]
|
339
|
+
end
|
340
|
+
GC.start
|
341
|
+
@m.should == NMatrix.new(:dense, [3,3], (0..9).to_a, :int32).cast(stype, :int32)
|
342
|
+
n = nil
|
343
|
+
1.times do
|
344
|
+
m = NMatrix.new(:dense, [2,2], [1,2,3,4]).cast(stype, :int32)
|
345
|
+
n = m[0..1,0..1]
|
268
346
|
end
|
347
|
+
GC.start
|
348
|
+
n.should == NMatrix.new(:dense, [2,2], [1,2,3,4]).cast(stype, :int32)
|
349
|
+
end
|
269
350
|
|
270
|
-
|
271
|
-
|
272
|
-
nm_eql(@m[1..2, 1..2].cast(cast_type, :int32), @m[1..2,1..2]).should be_true
|
273
|
-
nm_eql(@m[0..1, 1..2].cast(cast_type, :int32), @m[0..1,1..2]).should be_true
|
274
|
-
nm_eql(@m[1..2, 0..1].cast(cast_type, :int32), @m[1..2,0..1]).should be_true
|
275
|
-
nm_eql(@m[0..1, 0..1].cast(cast_type, :int32), @m[0..1,0..1]).should be_true
|
351
|
+
[:dense, :list, :yale].each do |cast_type|
|
352
|
+
it "should cast from #{stype.upcase} to #{cast_type.upcase}" do
|
276
353
|
|
277
|
-
|
278
|
-
|
279
|
-
|
354
|
+
nm_eql(@m[1..2, 1..2].cast(cast_type), @m[1..2,1..2]).should be_true
|
355
|
+
nm_eql(@m[0..1, 1..2].cast(cast_type), @m[0..1,1..2]).should be_true
|
356
|
+
nm_eql(@m[1..2, 0..1].cast(cast_type), @m[1..2,0..1]).should be_true
|
357
|
+
nm_eql(@m[0..1, 0..1].cast(cast_type), @m[0..1,0..1]).should be_true
|
280
358
|
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
end
|
285
|
-
end
|
286
|
-
end
|
287
|
-
end # unless stype == :yale
|
288
|
-
end
|
359
|
+
# Non square
|
360
|
+
nm_eql(@m[0..2, 1..2].cast(cast_type), @m[0..2,1..2]).should be_true
|
361
|
+
nm_eql(@m[1..2, 0..2].cast(cast_type), @m[1..2,0..2]).should be_true
|
289
362
|
|
290
|
-
|
291
|
-
|
292
|
-
if n.shape != m.shape
|
293
|
-
false
|
294
|
-
elsif n.is_a?(NVector)
|
295
|
-
return false unless m.is_a?(NVector) # don't compare NV to NM
|
296
|
-
long_shape = n.shape[0] == 1 ? n.shape[1] : n.shape[0]
|
297
|
-
long_shape.times do |j|
|
298
|
-
if n[j] != m[j]
|
299
|
-
puts "n[#{j}] != m[#{j}] (#{n[j]} != #{m[j]})"
|
300
|
-
return false
|
301
|
-
end
|
302
|
-
end
|
303
|
-
else # NMatrix
|
304
|
-
n.shape[0].times do |i|
|
305
|
-
n.shape[1].times do |j|
|
306
|
-
if n[i,j] != m[i,j]
|
307
|
-
puts "n[#{i},#{j}] != m[#{i},#{j}] (#{n[i,j]} != #{m[i,j]})"
|
308
|
-
return false
|
363
|
+
# Full
|
364
|
+
nm_eql(@m[0..2, 0..2].cast(cast_type), @m).should be_true
|
309
365
|
end
|
310
366
|
end
|
311
367
|
end
|
368
|
+
|
312
369
|
end
|
313
|
-
true
|
314
370
|
end
|
315
371
|
end
|