nmatrix-atlas 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ext/nmatrix/data/complex.h +364 -0
- data/ext/nmatrix/data/data.h +638 -0
- data/ext/nmatrix/data/meta.h +64 -0
- data/ext/nmatrix/data/ruby_object.h +389 -0
- data/ext/nmatrix/math/asum.h +120 -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 +79 -0
- data/ext/nmatrix/math/laswp.h +165 -0
- data/ext/nmatrix/math/long_dtype.h +49 -0
- data/ext/nmatrix/math/math.h +744 -0
- data/ext/nmatrix/math/nrm2.h +160 -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 +332 -0
- data/ext/nmatrix/math/util.h +148 -0
- data/ext/nmatrix/nm_memory.h +60 -0
- data/ext/nmatrix/nmatrix.h +408 -0
- data/ext/nmatrix/ruby_constants.h +106 -0
- data/ext/nmatrix/storage/common.h +176 -0
- data/ext/nmatrix/storage/dense/dense.h +128 -0
- data/ext/nmatrix/storage/list/list.h +137 -0
- data/ext/nmatrix/storage/storage.h +98 -0
- data/ext/nmatrix/storage/yale/class.h +1139 -0
- data/ext/nmatrix/storage/yale/iterators/base.h +142 -0
- data/ext/nmatrix/storage/yale/iterators/iterator.h +130 -0
- data/ext/nmatrix/storage/yale/iterators/row.h +449 -0
- data/ext/nmatrix/storage/yale/iterators/row_stored.h +139 -0
- data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +168 -0
- data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +123 -0
- data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
- data/ext/nmatrix/storage/yale/yale.h +202 -0
- data/ext/nmatrix/types.h +54 -0
- data/ext/nmatrix/util/io.h +115 -0
- data/ext/nmatrix/util/sl_list.h +143 -0
- data/ext/nmatrix/util/util.h +78 -0
- data/ext/nmatrix_atlas/extconf.rb +250 -0
- data/ext/nmatrix_atlas/math_atlas.cpp +1206 -0
- data/ext/nmatrix_atlas/math_atlas/cblas_templates_atlas.h +72 -0
- data/ext/nmatrix_atlas/math_atlas/clapack_templates.h +332 -0
- data/ext/nmatrix_atlas/math_atlas/geev.h +82 -0
- data/ext/nmatrix_atlas/math_atlas/gesdd.h +83 -0
- data/ext/nmatrix_atlas/math_atlas/gesvd.h +81 -0
- data/ext/nmatrix_atlas/math_atlas/inc.h +47 -0
- data/ext/nmatrix_atlas/nmatrix_atlas.cpp +44 -0
- data/lib/nmatrix/atlas.rb +213 -0
- data/lib/nmatrix/lapack_ext_common.rb +69 -0
- data/spec/00_nmatrix_spec.rb +730 -0
- data/spec/01_enum_spec.rb +190 -0
- data/spec/02_slice_spec.rb +389 -0
- data/spec/03_nmatrix_monkeys_spec.rb +78 -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 +193 -0
- data/spec/elementwise_spec.rb +303 -0
- data/spec/homogeneous_spec.rb +99 -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 +149 -0
- data/spec/lapack_core_spec.rb +482 -0
- data/spec/leakcheck.rb +16 -0
- data/spec/math_spec.rb +730 -0
- data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
- data/spec/nmatrix_yale_spec.rb +286 -0
- data/spec/plugins/atlas/atlas_spec.rb +242 -0
- data/spec/rspec_monkeys.rb +56 -0
- data/spec/rspec_spec.rb +34 -0
- data/spec/shortcuts_spec.rb +310 -0
- data/spec/slice_set_spec.rb +157 -0
- data/spec/spec_helper.rb +140 -0
- data/spec/stat_spec.rb +203 -0
- data/spec/test.pcd +20 -0
- data/spec/utm5940.mtx +83844 -0
- metadata +159 -0
@@ -0,0 +1,190 @@
|
|
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
|
+
vv = []
|
39
|
+
ii = []
|
40
|
+
jj = []
|
41
|
+
m.extend NMatrix::YaleFunctions
|
42
|
+
m.each_row do |row|
|
43
|
+
row.each_with_indices do |v,i,j|
|
44
|
+
vv << v
|
45
|
+
ii << i
|
46
|
+
jj << j
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
expect(vv).to eq([7,8,9, 12,13,0, 0,0,0, 0,17,18])
|
51
|
+
expect(ii).to eq([0]*12)
|
52
|
+
expect(jj).to eq([0,1,2]*4)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should iterate along diagonal portion of A array" do
|
56
|
+
vv = []
|
57
|
+
ii = []
|
58
|
+
jj = []
|
59
|
+
n.send :__yale_stored_diagonal_each_with_indices__ do |v,i,j|
|
60
|
+
vv << v
|
61
|
+
ii << i
|
62
|
+
jj << j
|
63
|
+
end
|
64
|
+
expect(vv).to eq([1,7,13,0,19])
|
65
|
+
expect(ii).to eq([0,1,2,3,4])
|
66
|
+
expect(jj).to eq(ii)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should iterate along non-diagonal portion of A array" do
|
70
|
+
vv = []
|
71
|
+
ii = []
|
72
|
+
jj = []
|
73
|
+
n.send :__yale_stored_nondiagonal_each_with_indices__ do |v,i,j|
|
74
|
+
vv << v
|
75
|
+
ii << i
|
76
|
+
jj << j
|
77
|
+
end
|
78
|
+
|
79
|
+
expect(vv).to eq([2,3,4,5, 6,8,9,10, 11,12,14,15, 16,17,18,20])
|
80
|
+
expect(ii).to eq([[0]*4, [1]*4, [2]*4, [4]*4].flatten)
|
81
|
+
expect(jj).to eq([1,2,3,4, 0,2,3,5, 0,1,4,5, 0,2,3,5])
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should iterate along a sliced diagonal portion of an A array" do
|
85
|
+
m = n[0..3,1..3]
|
86
|
+
vv = []
|
87
|
+
ii = []
|
88
|
+
jj = []
|
89
|
+
m.send :__yale_stored_diagonal_each_with_indices__ do |v,i,j|
|
90
|
+
vv << v
|
91
|
+
ii << i
|
92
|
+
jj << j
|
93
|
+
end
|
94
|
+
expect(vv).to eq([7,13,0])
|
95
|
+
expect(ii).to eq([1,2,3])
|
96
|
+
expect(jj).to eq([0,1,2])
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should iterate along a sliced non-diagonal portion of a sliced A array" do
|
100
|
+
vv = []
|
101
|
+
ii = []
|
102
|
+
jj = []
|
103
|
+
n.extend NMatrix::YaleFunctions
|
104
|
+
m.extend NMatrix::YaleFunctions
|
105
|
+
m.send :__yale_stored_nondiagonal_each_with_indices__ do |v,i,j|
|
106
|
+
vv << v
|
107
|
+
ii << i
|
108
|
+
jj << j
|
109
|
+
end
|
110
|
+
|
111
|
+
expect(ii).to eq([0,0, 1, 3,3 ])
|
112
|
+
expect(jj).to eq([1,2, 0, 1,2 ])
|
113
|
+
expect(vv).to eq([8,9, 12, 17,18])
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should visit each stored element of the matrix in order by indices" do
|
117
|
+
vv = []
|
118
|
+
ii = []
|
119
|
+
jj = []
|
120
|
+
n.each_ordered_stored_with_indices do |v,i,j|
|
121
|
+
vv << v
|
122
|
+
ii << i
|
123
|
+
jj << j
|
124
|
+
end
|
125
|
+
|
126
|
+
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])
|
127
|
+
expect(ii).to eq([[0]*5, [1]*5, [2]*5, [3]*1, [4]*5].flatten)
|
128
|
+
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])
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should visit each stored element of the slice in order by indices" do
|
132
|
+
|
133
|
+
vv = []
|
134
|
+
ii = []
|
135
|
+
jj = []
|
136
|
+
m.each_ordered_stored_with_indices do |v,i,j|
|
137
|
+
vv << v
|
138
|
+
ii << i
|
139
|
+
jj << j
|
140
|
+
end
|
141
|
+
expect(ii).to eq([0,0,0, 1,1, 2, 3,3 ])
|
142
|
+
expect(jj).to eq([0,1,2, 0,1, 2, 1,2 ])
|
143
|
+
expect(vv).to eq([7,8,9, 12,13, 0, 17,18 ])
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should visit each cell in the matrix as if dense, making indices available" do
|
148
|
+
vv = []
|
149
|
+
ii = []
|
150
|
+
jj = []
|
151
|
+
n.each_with_indices do |v,i,j|
|
152
|
+
vv << v
|
153
|
+
ii << i
|
154
|
+
jj << j
|
155
|
+
end
|
156
|
+
|
157
|
+
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])
|
158
|
+
expect(ii).to eq([[0]*6, [1]*6, [2]*6, [3]*6, [4]*6].flatten)
|
159
|
+
expect(jj).to eq([0,1,2,3,4,5]*5)
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should visit each cell in the slice as if dense, making indices available" do
|
163
|
+
vv = []
|
164
|
+
ii = []
|
165
|
+
jj = []
|
166
|
+
m.each_with_indices do |v,i,j|
|
167
|
+
vv << v
|
168
|
+
ii << i
|
169
|
+
jj << j
|
170
|
+
end
|
171
|
+
expect(jj).to eq([0,1,2]*4)
|
172
|
+
expect(ii).to eq([[0]*3, [1]*3, [2]*3, [3]*3].flatten)
|
173
|
+
expect(vv).to eq([7,8,9,12,13,0,0,0,0,0,17,18])
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
if stype == :list or stype == :dense then
|
178
|
+
it "should correctly map to a matrix with a single element" do
|
179
|
+
nm = N.new([1], [2.0], stype: stype)
|
180
|
+
expect(nm.map { |e| e**2 }).to eq N.new([1], [4.0], stype: stype)
|
181
|
+
end
|
182
|
+
|
183
|
+
it "should correctly map to a matrix with multiple elements" do
|
184
|
+
nm = N.new([2], [2.0, 2.0], stype: stype)
|
185
|
+
expect(nm.map { |e| e**2 }).to eq N.new([2], [4.0, 4.0], stype: stype)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
end
|
190
|
+
end
|
@@ -0,0 +1,389 @@
|
|
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
|
+
n = NMatrix.new(10, stype: :yale, dtype: :int32)
|
48
|
+
n[3,0] = 1
|
49
|
+
#n[3,2] = 2
|
50
|
+
n[3,3] = 3
|
51
|
+
n[3,4] = 4
|
52
|
+
n[3,6] = 5
|
53
|
+
n[3,8] = 6
|
54
|
+
n[3,9] = 7
|
55
|
+
vs = []
|
56
|
+
is = []
|
57
|
+
js = []
|
58
|
+
|
59
|
+
n[3,1..9].each_stored_with_indices do |v,i,j|
|
60
|
+
vs << v
|
61
|
+
is << i
|
62
|
+
js << j
|
63
|
+
end
|
64
|
+
|
65
|
+
expect(vs).to eq([3,4,5,6,7])
|
66
|
+
expect(js).to eq([2,3,5,7,8])
|
67
|
+
expect(is).to eq([0,0,0,0,0])
|
68
|
+
end
|
69
|
+
elsif stype == :list
|
70
|
+
it "should iterate across a partial row of stored indices" do
|
71
|
+
vs = []
|
72
|
+
is = []
|
73
|
+
js = []
|
74
|
+
|
75
|
+
STDERR.puts("now") if stype == :yale
|
76
|
+
stype_matrix[2,1..2].each_stored_with_indices do |v,i,j|
|
77
|
+
vs << v
|
78
|
+
is << i
|
79
|
+
js << j
|
80
|
+
end
|
81
|
+
|
82
|
+
expect(vs).to eq([7,8])
|
83
|
+
expect(is).to eq([0,0])
|
84
|
+
expect(js).to eq([0,1])
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
unless stype == :dense
|
89
|
+
it "should iterate across a row of stored indices" do
|
90
|
+
|
91
|
+
vs = []
|
92
|
+
is = []
|
93
|
+
js = []
|
94
|
+
stype_matrix[2,0..2].each_stored_with_indices do |v,i,j|
|
95
|
+
vs << v
|
96
|
+
is << i
|
97
|
+
js << j
|
98
|
+
end
|
99
|
+
expect(vs).to eq(stype == :yale ? [8,6,7] : [6,7,8])
|
100
|
+
expect(is).to eq([0,0,0])
|
101
|
+
expect(js).to eq(stype == :yale ? [2,0,1] : [0,1,2])
|
102
|
+
end
|
103
|
+
|
104
|
+
it "should iterate across a submatrix of stored indices" do
|
105
|
+
vs = []
|
106
|
+
is = []
|
107
|
+
js = []
|
108
|
+
stype_matrix[0..1,1..2].each_stored_with_indices do |v,i,j|
|
109
|
+
vs << v
|
110
|
+
is << i
|
111
|
+
js << j
|
112
|
+
end
|
113
|
+
|
114
|
+
expect(vs).to eq(stype == :yale ? [4,1,2,5] : [1,2,4,5])
|
115
|
+
expect(is).to eq(stype == :yale ? [1,0,0,1] : [0,0,1,1])
|
116
|
+
expect(js).to eq(stype == :yale ? [0,0,1,1] : [0,1,0,1])
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
it "should return correct supershape" do
|
121
|
+
x = NMatrix.random([10,12])
|
122
|
+
y = x[0...8,5...12]
|
123
|
+
expect(y.shape).to eq([8,7])
|
124
|
+
expect(y.supershape).to eq([10,12])
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should have #is_ref? method" do
|
128
|
+
a = stype_matrix[0..1, 0..1]
|
129
|
+
b = stype_matrix.slice(0..1, 0..1)
|
130
|
+
expect(stype_matrix.is_ref?).to be_false
|
131
|
+
expect(a.is_ref?).to be_true
|
132
|
+
expect(b.is_ref?).to be_false
|
133
|
+
end
|
134
|
+
|
135
|
+
it "reference should compare with non-reference" do
|
136
|
+
expect(stype_matrix.slice(1..2,0..1)).to eq(stype_matrix[1..2, 0..1])
|
137
|
+
expect(stype_matrix[1..2,0..1]).to eq(stype_matrix.slice(1..2, 0..1))
|
138
|
+
expect(stype_matrix[1..2,0..1]).to eq(stype_matrix[1..2, 0..1])
|
139
|
+
end
|
140
|
+
|
141
|
+
context "with copying" do
|
142
|
+
it 'should return an NMatrix' do
|
143
|
+
n = stype_matrix.slice(0..1,0..1)
|
144
|
+
expect(nm_eql(n, NMatrix.new([2,2], [0,1,3,4], dtype: :int32))).to be_true
|
145
|
+
end
|
146
|
+
|
147
|
+
it 'should return a copy of 2x2 matrix to self elements' do
|
148
|
+
n = stype_matrix.slice(1..2,0..1)
|
149
|
+
expect(n.shape).to eql([2,2])
|
150
|
+
|
151
|
+
expect(n[1,1]).to eq(stype_matrix[2,1])
|
152
|
+
n[1,1] = -9
|
153
|
+
expect(stype_matrix[2,1]).to eql(7)
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'should return a 1x2 matrix without refs to self elements' do
|
157
|
+
n = stype_matrix.slice(0,1..2)
|
158
|
+
expect(n.shape).to eql([1,2])
|
159
|
+
|
160
|
+
expect(n[0]).to eq(stype_matrix[0,1])
|
161
|
+
expect(n[1]).to eq(stype_matrix[0,2])
|
162
|
+
n[0] = -9
|
163
|
+
expect(stype_matrix[0,1]).to eql(1)
|
164
|
+
expect(stype_matrix[0,2]).to eql(2)
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'should return a 2x1 matrix without refs to self elements' do
|
168
|
+
stype_matrix.extend NMatrix::YaleFunctions
|
169
|
+
|
170
|
+
n = stype_matrix.slice(0..1,1)
|
171
|
+
expect(n.shape).to eql([2,1])
|
172
|
+
|
173
|
+
expect(n[0]).to eq(stype_matrix[0,1])
|
174
|
+
expect(n[1]).to eq(stype_matrix[1,1])
|
175
|
+
n[0] = -9
|
176
|
+
expect(stype_matrix[0,1]).to eql(1)
|
177
|
+
expect(stype_matrix[1,1]).to eql(4)
|
178
|
+
end
|
179
|
+
|
180
|
+
it 'should be correct slice for range 0..2 and 0...3' do
|
181
|
+
expect(stype_matrix.slice(0..2,0..2)).to eq(stype_matrix.slice(0...3,0...3))
|
182
|
+
end
|
183
|
+
|
184
|
+
[:dense, :list, :yale].each do |cast_type|
|
185
|
+
it "should cast copied slice from #{stype.upcase} to #{cast_type.upcase}" do
|
186
|
+
expect(nm_eql(stype_matrix.slice(1..2, 1..2).cast(cast_type, :int32), stype_matrix.slice(1..2,1..2))).to be_true
|
187
|
+
expect(nm_eql(stype_matrix.slice(0..1, 1..2).cast(cast_type, :int32), stype_matrix.slice(0..1,1..2))).to be_true
|
188
|
+
expect(nm_eql(stype_matrix.slice(1..2, 0..1).cast(cast_type, :int32), stype_matrix.slice(1..2,0..1))).to be_true
|
189
|
+
expect(nm_eql(stype_matrix.slice(0..1, 0..1).cast(cast_type, :int32), stype_matrix.slice(0..1,0..1))).to be_true
|
190
|
+
|
191
|
+
# Non square
|
192
|
+
expect(nm_eql(stype_matrix.slice(0..2, 1..2).cast(cast_type, :int32), stype_matrix.slice(0..2,1..2))).to be_true
|
193
|
+
#require 'pry'
|
194
|
+
#binding.pry if cast_type == :yale
|
195
|
+
expect(nm_eql(stype_matrix.slice(1..2, 0..2).cast(cast_type, :int32), stype_matrix.slice(1..2,0..2))).to be_true
|
196
|
+
|
197
|
+
# Full
|
198
|
+
expect(nm_eql(stype_matrix.slice(0..2, 0..2).cast(cast_type, :int32), stype_matrix)).to be_true
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
# Yale:
|
204
|
+
#context "by copy" do
|
205
|
+
#it "should correctly preserve zeros" do
|
206
|
+
# stype_matrix = NMatrix.new(:yale, 3, :int64)
|
207
|
+
# column_slice = stype_matrix.column(2, :copy)
|
208
|
+
# column_slice[0].should == 0
|
209
|
+
# column_slice[1].should == 0
|
210
|
+
# column_slice[2].should == 0
|
211
|
+
#end
|
212
|
+
#end
|
213
|
+
|
214
|
+
context "by reference" do
|
215
|
+
it 'should return an NMatrix' do
|
216
|
+
n = stype_matrix[0..1,0..1]
|
217
|
+
expect(nm_eql(n, NMatrix.new([2,2], [0,1,3,4], dtype: :int32))).to be_true
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'should return a 2x2 matrix with refs to self elements' do
|
221
|
+
n = stype_matrix[1..2,0..1]
|
222
|
+
expect(n.shape).to eql([2,2])
|
223
|
+
|
224
|
+
expect(n[0,0]).to eq(stype_matrix[1,0])
|
225
|
+
n[0,0] = -9
|
226
|
+
expect(stype_matrix[1,0]).to eql(-9)
|
227
|
+
end
|
228
|
+
|
229
|
+
it 'should return a 1x2 vector with refs to self elements' do
|
230
|
+
n = stype_matrix[0,1..2]
|
231
|
+
expect(n.shape).to eql([1,2])
|
232
|
+
|
233
|
+
expect(n[0]).to eq(stype_matrix[0,1])
|
234
|
+
n[0] = -9
|
235
|
+
expect(stype_matrix[0,1]).to eql(-9)
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'should return a 2x1 vector with refs to self elements' do
|
239
|
+
n = stype_matrix[0..1,1]
|
240
|
+
expect(n.shape).to eql([2,1])
|
241
|
+
|
242
|
+
expect(n[0]).to eq(stype_matrix[0,1])
|
243
|
+
n[0] = -9
|
244
|
+
expect(stype_matrix[0,1]).to eql(-9)
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'should slice again' do
|
248
|
+
n = stype_matrix[1..2, 1..2]
|
249
|
+
expect(nm_eql(n[1,0..1], NVector.new(2, [7,8], dtype: :int32).transpose)).to be_true
|
250
|
+
end
|
251
|
+
|
252
|
+
it 'should be correct slice for range 0..2 and 0...3' do
|
253
|
+
expect(stype_matrix[0..2,0..2]).to eq(stype_matrix[0...3,0...3])
|
254
|
+
end
|
255
|
+
|
256
|
+
it 'should correctly handle :* slice notation' do
|
257
|
+
expect(stype_matrix[:*,0]).to eq stype_matrix[0...stype_matrix.shape[0], 0]
|
258
|
+
end
|
259
|
+
|
260
|
+
if stype == :dense
|
261
|
+
[:byte,:int8,:int16,:int32,:int64,:float32,:float64].each do |left_dtype|
|
262
|
+
[:byte,:int8,:int16,:int32,:int64,:float32,:float64].each do |right_dtype|
|
263
|
+
|
264
|
+
# Won't work if they're both 1-byte, due to overflow.
|
265
|
+
next if [:byte,:int8].include?(left_dtype) && [:byte,:int8].include?(right_dtype)
|
266
|
+
|
267
|
+
# For now, don't bother testing int-int mult.
|
268
|
+
#next if [:int8,:int16,:int32,:int64].include?(left_dtype) && [:int8,:int16,:int32,:int64].include?(right_dtype)
|
269
|
+
it "handles #{left_dtype.to_s} dot #{right_dtype.to_s} matrix multiplication" do
|
270
|
+
#STDERR.puts "dtype=#{dtype.to_s}"
|
271
|
+
#STDERR.puts "2"
|
272
|
+
|
273
|
+
nary = if left_dtype.to_s =~ /complex/
|
274
|
+
COMPLEX_MATRIX43A_ARRAY
|
275
|
+
else
|
276
|
+
MATRIX43A_ARRAY
|
277
|
+
end
|
278
|
+
|
279
|
+
mary = if right_dtype.to_s =~ /complex/
|
280
|
+
COMPLEX_MATRIX32A_ARRAY
|
281
|
+
else
|
282
|
+
MATRIX32A_ARRAY
|
283
|
+
end
|
284
|
+
|
285
|
+
n = NMatrix.new([4,3], nary, dtype: left_dtype)[1..3,1..2]
|
286
|
+
m = NMatrix.new([3,2], mary, dtype: right_dtype)[1..2,0..1]
|
287
|
+
|
288
|
+
r = n.dot m
|
289
|
+
expect(r.shape).to eql([3,2])
|
290
|
+
|
291
|
+
expect(r[0,0]).to eq(219.0)
|
292
|
+
expect(r[0,1]).to eq(185.0)
|
293
|
+
expect(r[1,0]).to eq(244.0)
|
294
|
+
expect(r[1,1]).to eq(205.0)
|
295
|
+
expect(r[2,0]).to eq(42.0)
|
296
|
+
expect(r[2,1]).to eq(35.0)
|
297
|
+
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
context "operations" do
|
303
|
+
|
304
|
+
it "correctly transposes slices" do
|
305
|
+
expect(stype_matrix[0...3,0].transpose).to eq NMatrix[[0, 3, 6]]
|
306
|
+
expect(stype_matrix[0...3,1].transpose).to eq NMatrix[[1, 4, 7]]
|
307
|
+
expect(stype_matrix[0...3,2].transpose).to eq NMatrix[[2, 5, 8]]
|
308
|
+
expect(stype_matrix[0,0...3].transpose).to eq NMatrix[[0], [1], [2]]
|
309
|
+
expect(stype_matrix[1,0...3].transpose).to eq NMatrix[[3], [4], [5]]
|
310
|
+
expect(stype_matrix[2,0...3].transpose).to eq NMatrix[[6], [7], [8]]
|
311
|
+
expect(stype_matrix[1..2,1..2].transpose).to eq NMatrix[[4, 7], [5, 8]]
|
312
|
+
end
|
313
|
+
|
314
|
+
it "adds slices" do
|
315
|
+
expect(NMatrix[[0,0,0]] + stype_matrix[1,0..2]).to eq NMatrix[[3, 4, 5]]
|
316
|
+
end
|
317
|
+
|
318
|
+
it "scalar adds to slices" do
|
319
|
+
expect(stype_matrix[1,0..2]+1).to eq NMatrix[[4, 5, 6]]
|
320
|
+
end
|
321
|
+
|
322
|
+
it "compares slices to scalars" do
|
323
|
+
(stype_matrix[1, 0..2] > 2).each { |e| expect(e != 0).to be_true }
|
324
|
+
end
|
325
|
+
|
326
|
+
it "iterates only over elements in the slice" do
|
327
|
+
els = []
|
328
|
+
stype_matrix[1, 0..2].each { |e| els << e }
|
329
|
+
expect(els.size).to eq 3
|
330
|
+
expect(els[0]).to eq 3
|
331
|
+
expect(els[1]).to eq 4
|
332
|
+
expect(els[2]).to eq 5
|
333
|
+
end
|
334
|
+
|
335
|
+
it "iterates with index only over elements in the slice" do
|
336
|
+
els = []
|
337
|
+
stype_matrix[1, 0..2].each_stored_with_indices { |a| els << a }
|
338
|
+
expect(els.size).to eq 3
|
339
|
+
expect(els[0]).to eq [3, 0, 0]
|
340
|
+
expect(els[1]).to eq [4, 0, 1]
|
341
|
+
expect(els[2]).to eq [5, 0, 2]
|
342
|
+
end
|
343
|
+
|
344
|
+
end
|
345
|
+
|
346
|
+
end
|
347
|
+
|
348
|
+
example 'should be cleaned up by garbage collector without errors' do
|
349
|
+
step "reference slice" do
|
350
|
+
1.times do
|
351
|
+
n = stype_matrix[1..2,0..1]
|
352
|
+
end
|
353
|
+
GC.start
|
354
|
+
end
|
355
|
+
|
356
|
+
step "reference slice of casted-copy" do
|
357
|
+
expect(stype_matrix).to eq(NMatrix.new([3,3], (0..9).to_a, dtype: :int32).cast(stype, :int32))
|
358
|
+
n = nil
|
359
|
+
1.times do
|
360
|
+
m = NMatrix.new([2,2], [1,2,3,4]).cast(stype, :int32)
|
361
|
+
n = m[0..1,0..1]
|
362
|
+
end
|
363
|
+
GC.start
|
364
|
+
expect(n).to eq(NMatrix.new([2,2], [1,2,3,4]).cast(stype, :int32))
|
365
|
+
end
|
366
|
+
end
|
367
|
+
|
368
|
+
[:dense, :list, :yale].each do |cast_type|
|
369
|
+
it "should cast a square reference-slice from #{stype.upcase} to #{cast_type.upcase}" do
|
370
|
+
expect(nm_eql(stype_matrix[1..2, 1..2].cast(cast_type), stype_matrix[1..2,1..2])).to be_true
|
371
|
+
expect(nm_eql(stype_matrix[0..1, 1..2].cast(cast_type), stype_matrix[0..1,1..2])).to be_true
|
372
|
+
expect(nm_eql(stype_matrix[1..2, 0..1].cast(cast_type), stype_matrix[1..2,0..1])).to be_true
|
373
|
+
expect(nm_eql(stype_matrix[0..1, 0..1].cast(cast_type), stype_matrix[0..1,0..1])).to be_true
|
374
|
+
end
|
375
|
+
|
376
|
+
it "should cast a rectangular reference-slice from #{stype.upcase} to #{cast_type.upcase}" do
|
377
|
+
# Non square
|
378
|
+
expect(nm_eql(stype_matrix[0..2, 1..2].cast(cast_type), stype_matrix[0..2,1..2])).to be_true # FIXME: memory problem.
|
379
|
+
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
|
380
|
+
end
|
381
|
+
|
382
|
+
it "should cast a square full-matrix reference-slice from #{stype.upcase} to #{cast_type.upcase}" do
|
383
|
+
expect(nm_eql(stype_matrix[0..2, 0..2].cast(cast_type), stype_matrix)).to be_true
|
384
|
+
end
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|