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.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/ext/nmatrix/data/complex.h +364 -0
  3. data/ext/nmatrix/data/data.h +638 -0
  4. data/ext/nmatrix/data/meta.h +64 -0
  5. data/ext/nmatrix/data/ruby_object.h +389 -0
  6. data/ext/nmatrix/math/asum.h +120 -0
  7. data/ext/nmatrix/math/cblas_enums.h +36 -0
  8. data/ext/nmatrix/math/cblas_templates_core.h +507 -0
  9. data/ext/nmatrix/math/gemm.h +241 -0
  10. data/ext/nmatrix/math/gemv.h +178 -0
  11. data/ext/nmatrix/math/getrf.h +255 -0
  12. data/ext/nmatrix/math/getrs.h +121 -0
  13. data/ext/nmatrix/math/imax.h +79 -0
  14. data/ext/nmatrix/math/laswp.h +165 -0
  15. data/ext/nmatrix/math/long_dtype.h +49 -0
  16. data/ext/nmatrix/math/math.h +744 -0
  17. data/ext/nmatrix/math/nrm2.h +160 -0
  18. data/ext/nmatrix/math/rot.h +117 -0
  19. data/ext/nmatrix/math/rotg.h +106 -0
  20. data/ext/nmatrix/math/scal.h +71 -0
  21. data/ext/nmatrix/math/trsm.h +332 -0
  22. data/ext/nmatrix/math/util.h +148 -0
  23. data/ext/nmatrix/nm_memory.h +60 -0
  24. data/ext/nmatrix/nmatrix.h +408 -0
  25. data/ext/nmatrix/ruby_constants.h +106 -0
  26. data/ext/nmatrix/storage/common.h +176 -0
  27. data/ext/nmatrix/storage/dense/dense.h +128 -0
  28. data/ext/nmatrix/storage/list/list.h +137 -0
  29. data/ext/nmatrix/storage/storage.h +98 -0
  30. data/ext/nmatrix/storage/yale/class.h +1139 -0
  31. data/ext/nmatrix/storage/yale/iterators/base.h +142 -0
  32. data/ext/nmatrix/storage/yale/iterators/iterator.h +130 -0
  33. data/ext/nmatrix/storage/yale/iterators/row.h +449 -0
  34. data/ext/nmatrix/storage/yale/iterators/row_stored.h +139 -0
  35. data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +168 -0
  36. data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +123 -0
  37. data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
  38. data/ext/nmatrix/storage/yale/yale.h +202 -0
  39. data/ext/nmatrix/types.h +54 -0
  40. data/ext/nmatrix/util/io.h +115 -0
  41. data/ext/nmatrix/util/sl_list.h +143 -0
  42. data/ext/nmatrix/util/util.h +78 -0
  43. data/ext/nmatrix_atlas/extconf.rb +250 -0
  44. data/ext/nmatrix_atlas/math_atlas.cpp +1206 -0
  45. data/ext/nmatrix_atlas/math_atlas/cblas_templates_atlas.h +72 -0
  46. data/ext/nmatrix_atlas/math_atlas/clapack_templates.h +332 -0
  47. data/ext/nmatrix_atlas/math_atlas/geev.h +82 -0
  48. data/ext/nmatrix_atlas/math_atlas/gesdd.h +83 -0
  49. data/ext/nmatrix_atlas/math_atlas/gesvd.h +81 -0
  50. data/ext/nmatrix_atlas/math_atlas/inc.h +47 -0
  51. data/ext/nmatrix_atlas/nmatrix_atlas.cpp +44 -0
  52. data/lib/nmatrix/atlas.rb +213 -0
  53. data/lib/nmatrix/lapack_ext_common.rb +69 -0
  54. data/spec/00_nmatrix_spec.rb +730 -0
  55. data/spec/01_enum_spec.rb +190 -0
  56. data/spec/02_slice_spec.rb +389 -0
  57. data/spec/03_nmatrix_monkeys_spec.rb +78 -0
  58. data/spec/2x2_dense_double.mat +0 -0
  59. data/spec/4x4_sparse.mat +0 -0
  60. data/spec/4x5_dense.mat +0 -0
  61. data/spec/blas_spec.rb +193 -0
  62. data/spec/elementwise_spec.rb +303 -0
  63. data/spec/homogeneous_spec.rb +99 -0
  64. data/spec/io/fortran_format_spec.rb +88 -0
  65. data/spec/io/harwell_boeing_spec.rb +98 -0
  66. data/spec/io/test.rua +9 -0
  67. data/spec/io_spec.rb +149 -0
  68. data/spec/lapack_core_spec.rb +482 -0
  69. data/spec/leakcheck.rb +16 -0
  70. data/spec/math_spec.rb +730 -0
  71. data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
  72. data/spec/nmatrix_yale_spec.rb +286 -0
  73. data/spec/plugins/atlas/atlas_spec.rb +242 -0
  74. data/spec/rspec_monkeys.rb +56 -0
  75. data/spec/rspec_spec.rb +34 -0
  76. data/spec/shortcuts_spec.rb +310 -0
  77. data/spec/slice_set_spec.rb +157 -0
  78. data/spec/spec_helper.rb +140 -0
  79. data/spec/stat_spec.rb +203 -0
  80. data/spec/test.pcd +20 -0
  81. data/spec/utm5940.mtx +83844 -0
  82. 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