nmatrix-atlas 0.2.0
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/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
|