pnmatrix 1.2.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/ext/nmatrix/binary_format.txt +53 -0
  3. data/ext/nmatrix/data/complex.h +388 -0
  4. data/ext/nmatrix/data/data.cpp +274 -0
  5. data/ext/nmatrix/data/data.h +651 -0
  6. data/ext/nmatrix/data/meta.h +64 -0
  7. data/ext/nmatrix/data/ruby_object.h +386 -0
  8. data/ext/nmatrix/extconf.rb +70 -0
  9. data/ext/nmatrix/math/asum.h +99 -0
  10. data/ext/nmatrix/math/cblas_enums.h +36 -0
  11. data/ext/nmatrix/math/cblas_templates_core.h +507 -0
  12. data/ext/nmatrix/math/gemm.h +241 -0
  13. data/ext/nmatrix/math/gemv.h +178 -0
  14. data/ext/nmatrix/math/getrf.h +255 -0
  15. data/ext/nmatrix/math/getrs.h +121 -0
  16. data/ext/nmatrix/math/imax.h +82 -0
  17. data/ext/nmatrix/math/laswp.h +165 -0
  18. data/ext/nmatrix/math/long_dtype.h +62 -0
  19. data/ext/nmatrix/math/magnitude.h +54 -0
  20. data/ext/nmatrix/math/math.h +751 -0
  21. data/ext/nmatrix/math/nrm2.h +165 -0
  22. data/ext/nmatrix/math/rot.h +117 -0
  23. data/ext/nmatrix/math/rotg.h +106 -0
  24. data/ext/nmatrix/math/scal.h +71 -0
  25. data/ext/nmatrix/math/trsm.h +336 -0
  26. data/ext/nmatrix/math/util.h +162 -0
  27. data/ext/nmatrix/math.cpp +1368 -0
  28. data/ext/nmatrix/nm_memory.h +60 -0
  29. data/ext/nmatrix/nmatrix.cpp +285 -0
  30. data/ext/nmatrix/nmatrix.h +476 -0
  31. data/ext/nmatrix/ruby_constants.cpp +151 -0
  32. data/ext/nmatrix/ruby_constants.h +106 -0
  33. data/ext/nmatrix/ruby_nmatrix.c +3130 -0
  34. data/ext/nmatrix/storage/common.cpp +77 -0
  35. data/ext/nmatrix/storage/common.h +183 -0
  36. data/ext/nmatrix/storage/dense/dense.cpp +1096 -0
  37. data/ext/nmatrix/storage/dense/dense.h +129 -0
  38. data/ext/nmatrix/storage/list/list.cpp +1628 -0
  39. data/ext/nmatrix/storage/list/list.h +138 -0
  40. data/ext/nmatrix/storage/storage.cpp +730 -0
  41. data/ext/nmatrix/storage/storage.h +99 -0
  42. data/ext/nmatrix/storage/yale/class.h +1139 -0
  43. data/ext/nmatrix/storage/yale/iterators/base.h +143 -0
  44. data/ext/nmatrix/storage/yale/iterators/iterator.h +131 -0
  45. data/ext/nmatrix/storage/yale/iterators/row.h +450 -0
  46. data/ext/nmatrix/storage/yale/iterators/row_stored.h +140 -0
  47. data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +169 -0
  48. data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +124 -0
  49. data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
  50. data/ext/nmatrix/storage/yale/yale.cpp +2074 -0
  51. data/ext/nmatrix/storage/yale/yale.h +203 -0
  52. data/ext/nmatrix/types.h +55 -0
  53. data/ext/nmatrix/util/io.cpp +279 -0
  54. data/ext/nmatrix/util/io.h +115 -0
  55. data/ext/nmatrix/util/sl_list.cpp +627 -0
  56. data/ext/nmatrix/util/sl_list.h +144 -0
  57. data/ext/nmatrix/util/util.h +78 -0
  58. data/lib/nmatrix/blas.rb +378 -0
  59. data/lib/nmatrix/cruby/math.rb +744 -0
  60. data/lib/nmatrix/enumerate.rb +253 -0
  61. data/lib/nmatrix/homogeneous.rb +241 -0
  62. data/lib/nmatrix/io/fortran_format.rb +138 -0
  63. data/lib/nmatrix/io/harwell_boeing.rb +221 -0
  64. data/lib/nmatrix/io/market.rb +263 -0
  65. data/lib/nmatrix/io/point_cloud.rb +189 -0
  66. data/lib/nmatrix/jruby/decomposition.rb +24 -0
  67. data/lib/nmatrix/jruby/enumerable.rb +13 -0
  68. data/lib/nmatrix/jruby/error.rb +4 -0
  69. data/lib/nmatrix/jruby/math.rb +501 -0
  70. data/lib/nmatrix/jruby/nmatrix_java.rb +840 -0
  71. data/lib/nmatrix/jruby/operators.rb +283 -0
  72. data/lib/nmatrix/jruby/slice.rb +264 -0
  73. data/lib/nmatrix/lapack_core.rb +181 -0
  74. data/lib/nmatrix/lapack_plugin.rb +44 -0
  75. data/lib/nmatrix/math.rb +953 -0
  76. data/lib/nmatrix/mkmf.rb +100 -0
  77. data/lib/nmatrix/monkeys.rb +137 -0
  78. data/lib/nmatrix/nmatrix.rb +1172 -0
  79. data/lib/nmatrix/rspec.rb +75 -0
  80. data/lib/nmatrix/shortcuts.rb +1163 -0
  81. data/lib/nmatrix/version.rb +39 -0
  82. data/lib/nmatrix/yale_functions.rb +118 -0
  83. data/lib/nmatrix.rb +28 -0
  84. data/spec/00_nmatrix_spec.rb +892 -0
  85. data/spec/01_enum_spec.rb +196 -0
  86. data/spec/02_slice_spec.rb +407 -0
  87. data/spec/03_nmatrix_monkeys_spec.rb +80 -0
  88. data/spec/2x2_dense_double.mat +0 -0
  89. data/spec/4x4_sparse.mat +0 -0
  90. data/spec/4x5_dense.mat +0 -0
  91. data/spec/blas_spec.rb +215 -0
  92. data/spec/elementwise_spec.rb +311 -0
  93. data/spec/homogeneous_spec.rb +100 -0
  94. data/spec/io/fortran_format_spec.rb +88 -0
  95. data/spec/io/harwell_boeing_spec.rb +98 -0
  96. data/spec/io/test.rua +9 -0
  97. data/spec/io_spec.rb +159 -0
  98. data/spec/lapack_core_spec.rb +482 -0
  99. data/spec/leakcheck.rb +16 -0
  100. data/spec/math_spec.rb +1363 -0
  101. data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
  102. data/spec/nmatrix_yale_spec.rb +286 -0
  103. data/spec/rspec_monkeys.rb +56 -0
  104. data/spec/rspec_spec.rb +35 -0
  105. data/spec/shortcuts_spec.rb +474 -0
  106. data/spec/slice_set_spec.rb +162 -0
  107. data/spec/spec_helper.rb +172 -0
  108. data/spec/stat_spec.rb +214 -0
  109. data/spec/test.pcd +20 -0
  110. data/spec/utm5940.mtx +83844 -0
  111. metadata +295 -0
@@ -0,0 +1,196 @@
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
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
39
+ vv = []
40
+ ii = []
41
+ jj = []
42
+ m.extend NMatrix::YaleFunctions
43
+ m.each_row do |row|
44
+ row.each_with_indices do |v,i,j|
45
+ vv << v
46
+ ii << i
47
+ jj << j
48
+ end
49
+ end
50
+
51
+ expect(vv).to eq([7,8,9, 12,13,0, 0,0,0, 0,17,18])
52
+ expect(ii).to eq([0]*12)
53
+ expect(jj).to eq([0,1,2]*4)
54
+ end
55
+
56
+ it "should iterate along diagonal portion of A array" do
57
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
58
+ vv = []
59
+ ii = []
60
+ jj = []
61
+ n.send :__yale_stored_diagonal_each_with_indices__ do |v,i,j|
62
+ vv << v
63
+ ii << i
64
+ jj << j
65
+ end
66
+ expect(vv).to eq([1,7,13,0,19])
67
+ expect(ii).to eq([0,1,2,3,4])
68
+ expect(jj).to eq(ii)
69
+ end
70
+
71
+ it "should iterate along non-diagonal portion of A array" do
72
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
73
+ vv = []
74
+ ii = []
75
+ jj = []
76
+ n.send :__yale_stored_nondiagonal_each_with_indices__ do |v,i,j|
77
+ vv << v
78
+ ii << i
79
+ jj << j
80
+ end
81
+
82
+ expect(vv).to eq([2,3,4,5, 6,8,9,10, 11,12,14,15, 16,17,18,20])
83
+ expect(ii).to eq([[0]*4, [1]*4, [2]*4, [4]*4].flatten)
84
+ expect(jj).to eq([1,2,3,4, 0,2,3,5, 0,1,4,5, 0,2,3,5])
85
+ end
86
+
87
+ it "should iterate along a sliced diagonal portion of an A array" do
88
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
89
+ m = n[0..3,1..3]
90
+ vv = []
91
+ ii = []
92
+ jj = []
93
+ m.send :__yale_stored_diagonal_each_with_indices__ do |v,i,j|
94
+ vv << v
95
+ ii << i
96
+ jj << j
97
+ end
98
+ expect(vv).to eq([7,13,0])
99
+ expect(ii).to eq([1,2,3])
100
+ expect(jj).to eq([0,1,2])
101
+ end
102
+
103
+ it "should iterate along a sliced non-diagonal portion of a sliced A array" do
104
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
105
+ vv = []
106
+ ii = []
107
+ jj = []
108
+ n.extend NMatrix::YaleFunctions
109
+ m.extend NMatrix::YaleFunctions
110
+ m.send :__yale_stored_nondiagonal_each_with_indices__ do |v,i,j|
111
+ vv << v
112
+ ii << i
113
+ jj << j
114
+ end
115
+
116
+ expect(ii).to eq([0,0, 1, 3,3 ])
117
+ expect(jj).to eq([1,2, 0, 1,2 ])
118
+ expect(vv).to eq([8,9, 12, 17,18])
119
+ end
120
+
121
+ it "should visit each stored element of the matrix in order by indices" do
122
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
123
+ vv = []
124
+ ii = []
125
+ jj = []
126
+ n.each_ordered_stored_with_indices do |v,i,j|
127
+ vv << v
128
+ ii << i
129
+ jj << j
130
+ end
131
+
132
+ 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])
133
+ expect(ii).to eq([[0]*5, [1]*5, [2]*5, [3]*1, [4]*5].flatten)
134
+ 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])
135
+ end
136
+
137
+ it "should visit each stored element of the slice in order by indices" do
138
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
139
+ vv = []
140
+ ii = []
141
+ jj = []
142
+ m.each_ordered_stored_with_indices do |v,i,j|
143
+ vv << v
144
+ ii << i
145
+ jj << j
146
+ end
147
+ expect(ii).to eq([0,0,0, 1,1, 2, 3,3 ])
148
+ expect(jj).to eq([0,1,2, 0,1, 2, 1,2 ])
149
+ expect(vv).to eq([7,8,9, 12,13, 0, 17,18 ])
150
+ end
151
+ end
152
+
153
+ it "should visit each cell in the matrix as if dense, making indices available" do
154
+ vv = []
155
+ ii = []
156
+ jj = []
157
+ n.each_with_indices do |v,i,j|
158
+ vv << v
159
+ ii << i
160
+ jj << j
161
+ end
162
+
163
+ 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])
164
+ expect(ii).to eq([[0]*6, [1]*6, [2]*6, [3]*6, [4]*6].flatten)
165
+ expect(jj).to eq([0,1,2,3,4,5]*5)
166
+ end
167
+
168
+ it "should visit each cell in the slice as if dense, making indices available" do
169
+ vv = []
170
+ ii = []
171
+ jj = []
172
+ m.each_with_indices do |v,i,j|
173
+ vv << v
174
+ ii << i
175
+ jj << j
176
+ end
177
+ expect(jj).to eq([0,1,2]*4)
178
+ expect(ii).to eq([[0]*3, [1]*3, [2]*3, [3]*3].flatten)
179
+ expect(vv).to eq([7,8,9,12,13,0,0,0,0,0,17,18])
180
+
181
+ end
182
+
183
+ if stype == :list or stype == :dense then
184
+ it "should correctly map to a matrix with a single element" do
185
+ nm = N.new([1], [2.0], stype: stype)
186
+ expect(nm.map { |e| e**2 }).to eq N.new([1], [4.0], stype: stype)
187
+ end
188
+
189
+ it "should correctly map to a matrix with multiple elements" do
190
+ nm = N.new([2], [2.0, 2.0], stype: stype)
191
+ expect(nm.map { |e| e**2 }).to eq N.new([2], [4.0, 4.0], stype: stype)
192
+ end
193
+ end
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,407 @@
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
+ #FIXME
48
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
49
+ n = NMatrix.new(10, stype: :yale, dtype: :int32)
50
+ n[3,0] = 1
51
+ #n[3,2] = 2
52
+ n[3,3] = 3
53
+ n[3,4] = 4
54
+ n[3,6] = 5
55
+ n[3,8] = 6
56
+ n[3,9] = 7
57
+ vs = []
58
+ is = []
59
+ js = []
60
+
61
+ n[3,1..9].each_stored_with_indices do |v,i,j|
62
+ vs << v
63
+ is << i
64
+ js << j
65
+ end
66
+
67
+ expect(vs).to eq([3,4,5,6,7])
68
+ expect(js).to eq([2,3,5,7,8])
69
+ expect(is).to eq([0,0,0,0,0])
70
+ end
71
+ elsif stype == :list
72
+ it "should iterate across a partial row of stored indices" do
73
+ vs = []
74
+ is = []
75
+ js = []
76
+
77
+ STDERR.puts("now") if stype == :yale
78
+ stype_matrix[2,1..2].each_stored_with_indices do |v,i,j|
79
+ vs << v
80
+ is << i
81
+ js << j
82
+ end
83
+
84
+ expect(vs).to eq([7,8])
85
+ expect(is).to eq([0,0])
86
+ expect(js).to eq([0,1])
87
+ end
88
+ end
89
+
90
+ unless stype == :dense
91
+ it "should iterate across a row of stored indices" do
92
+ #FIXME
93
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
94
+ vs = []
95
+ is = []
96
+ js = []
97
+ stype_matrix[2,0..2].each_stored_with_indices do |v,i,j|
98
+ vs << v
99
+ is << i
100
+ js << j
101
+ end
102
+ expect(vs).to eq(stype == :yale ? [8,6,7] : [6,7,8])
103
+ expect(is).to eq([0,0,0])
104
+ expect(js).to eq(stype == :yale ? [2,0,1] : [0,1,2])
105
+ end
106
+
107
+ it "should iterate across a submatrix of stored indices" do
108
+ #FIXME
109
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
110
+ vs = []
111
+ is = []
112
+ js = []
113
+ stype_matrix[0..1,1..2].each_stored_with_indices do |v,i,j|
114
+ vs << v
115
+ is << i
116
+ js << j
117
+ end
118
+
119
+ expect(vs).to eq(stype == :yale ? [4,1,2,5] : [1,2,4,5])
120
+ expect(is).to eq(stype == :yale ? [1,0,0,1] : [0,0,1,1])
121
+ expect(js).to eq(stype == :yale ? [0,0,1,1] : [0,1,0,1])
122
+ end
123
+ end
124
+
125
+ it "should return correct supershape" do
126
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
127
+ x = NMatrix.random([10,12])
128
+ y = x[0...8,5...12]
129
+ expect(y.shape).to eq([8,7])
130
+ expect(y.supershape).to eq([10,12])
131
+ end
132
+
133
+ it "should have #is_ref? method" do
134
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
135
+ a = stype_matrix[0..1, 0..1]
136
+ b = stype_matrix.slice(0..1, 0..1)
137
+ expect(stype_matrix.is_ref?).to be false
138
+ expect(a.is_ref?).to be true
139
+ expect(b.is_ref?).to be false
140
+ end
141
+
142
+ it "reference should compare with non-reference" do
143
+ expect(stype_matrix.slice(1..2,0..1)).to eq(stype_matrix[1..2, 0..1])
144
+ expect(stype_matrix[1..2,0..1]).to eq(stype_matrix.slice(1..2, 0..1))
145
+ expect(stype_matrix[1..2,0..1]).to eq(stype_matrix[1..2, 0..1])
146
+ end
147
+
148
+ context "with copying" do
149
+ it 'should return an NMatrix' do
150
+ n = stype_matrix.slice(0..1,0..1)
151
+ expect(nm_eql(n, NMatrix.new([2,2], [0,1,3,4], dtype: :int32))).to be true
152
+ end
153
+
154
+ it 'should return a copy of 2x2 matrix to self elements' do
155
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
156
+ n = stype_matrix.slice(1..2,0..1)
157
+ expect(n.shape).to eql([2,2])
158
+
159
+ expect(n[1,1]).to eq(stype_matrix[2,1])
160
+ n[1,1] = -9
161
+ expect(stype_matrix[2,1]).to eql(7)
162
+ end
163
+
164
+ it 'should return a 1x2 matrix without refs to self elements' do
165
+ #FIXME
166
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
167
+ n = stype_matrix.slice(0,1..2)
168
+ expect(n.shape).to eql([1,2])
169
+
170
+ expect(n[0]).to eq(stype_matrix[0,1])
171
+ expect(n[1]).to eq(stype_matrix[0,2])
172
+ n[0] = -9
173
+ expect(stype_matrix[0,1]).to eql(1)
174
+ expect(stype_matrix[0,2]).to eql(2)
175
+ end
176
+
177
+ it 'should return a 2x1 matrix without refs to self elements' do
178
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
179
+ stype_matrix.extend NMatrix::YaleFunctions
180
+
181
+ n = stype_matrix.slice(0..1,1)
182
+ expect(n.shape).to eql([2,1])
183
+
184
+ expect(n[0]).to eq(stype_matrix[0,1])
185
+ expect(n[1]).to eq(stype_matrix[1,1])
186
+ n[0] = -9
187
+ expect(stype_matrix[0,1]).to eql(1)
188
+ expect(stype_matrix[1,1]).to eql(4)
189
+ end
190
+
191
+ it 'should be correct slice for range 0..2 and 0...3' do
192
+ expect(stype_matrix.slice(0..2,0..2)).to eq(stype_matrix.slice(0...3,0...3))
193
+ end
194
+
195
+ [:dense, :list, :yale].each do |cast_type|
196
+ it "should cast copied slice from #{stype.upcase} to #{cast_type.upcase}" do
197
+ expect(nm_eql(stype_matrix.slice(1..2, 1..2).cast(cast_type, :int32), stype_matrix.slice(1..2,1..2))).to be true
198
+ expect(nm_eql(stype_matrix.slice(0..1, 1..2).cast(cast_type, :int32), stype_matrix.slice(0..1,1..2))).to be true
199
+ expect(nm_eql(stype_matrix.slice(1..2, 0..1).cast(cast_type, :int32), stype_matrix.slice(1..2,0..1))).to be true
200
+ expect(nm_eql(stype_matrix.slice(0..1, 0..1).cast(cast_type, :int32), stype_matrix.slice(0..1,0..1))).to be true
201
+
202
+ # Non square
203
+ expect(nm_eql(stype_matrix.slice(0..2, 1..2).cast(cast_type, :int32), stype_matrix.slice(0..2,1..2))).to be true
204
+ #require 'pry'
205
+ #binding.pry if cast_type == :yale
206
+ expect(nm_eql(stype_matrix.slice(1..2, 0..2).cast(cast_type, :int32), stype_matrix.slice(1..2,0..2))).to be true
207
+
208
+ # Full
209
+ expect(nm_eql(stype_matrix.slice(0..2, 0..2).cast(cast_type, :int32), stype_matrix)).to be true
210
+ end
211
+ end
212
+ end
213
+
214
+ # Yale:
215
+ #context "by copy" do
216
+ #it "should correctly preserve zeros" do
217
+ # stype_matrix = NMatrix.new(:yale, 3, :int64)
218
+ # column_slice = stype_matrix.column(2, :copy)
219
+ # column_slice[0].should == 0
220
+ # column_slice[1].should == 0
221
+ # column_slice[2].should == 0
222
+ #end
223
+ #end
224
+
225
+ context "by reference" do
226
+ it 'should return an NMatrix' do
227
+ n = stype_matrix[0..1,0..1]
228
+ expect(nm_eql(n, NMatrix.new([2,2], [0,1,3,4], dtype: :int32))).to be true
229
+ end
230
+
231
+ it 'should return a 2x2 matrix with refs to self elements' do
232
+ #FIXME
233
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby? # and :cast_type != :dense
234
+ n = stype_matrix[1..2,0..1]
235
+ expect(n.shape).to eql([2,2])
236
+
237
+ expect(n[0,0]).to eq(stype_matrix[1,0])
238
+ n[0,0] = -9
239
+ expect(stype_matrix[1,0]).to eql(-9)
240
+ end
241
+
242
+ it 'should return a 1x2 vector with refs to self elements' do
243
+ #FIXME
244
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby? # and :cast_type != :dense
245
+ n = stype_matrix[0,1..2]
246
+ expect(n.shape).to eql([1,2])
247
+
248
+ expect(n[0]).to eq(stype_matrix[0,1])
249
+ n[0] = -9
250
+ expect(stype_matrix[0,1]).to eql(-9)
251
+ end
252
+
253
+ it 'should return a 2x1 vector with refs to self elements' do
254
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
255
+ n = stype_matrix[0..1,1]
256
+ expect(n.shape).to eql([2,1])
257
+
258
+ expect(n[0]).to eq(stype_matrix[0,1])
259
+ n[0] = -9
260
+ expect(stype_matrix[0,1]).to eql(-9)
261
+ end
262
+
263
+ it 'should slice again' do
264
+ n = stype_matrix[1..2, 1..2]
265
+ expect(nm_eql(n[1,0..1], NVector.new(2, [7,8], dtype: :int32).transpose)).to be true
266
+ end
267
+
268
+ it 'should be correct slice for range 0..2 and 0...3' do
269
+ expect(stype_matrix[0..2,0..2]).to eq(stype_matrix[0...3,0...3])
270
+ end
271
+
272
+ it 'should correctly handle :* slice notation' do
273
+ expect(stype_matrix[:*,0]).to eq stype_matrix[0...stype_matrix.shape[0], 0]
274
+ end
275
+
276
+ if stype == :dense
277
+ [:byte,:int8,:int16,:int32,:int64,:float32,:float64].each do |left_dtype|
278
+ [:byte,:int8,:int16,:int32,:int64,:float32,:float64].each do |right_dtype|
279
+
280
+ # Won't work if they're both 1-byte, due to overflow.
281
+ next if [:byte,:int8].include?(left_dtype) && [:byte,:int8].include?(right_dtype)
282
+
283
+ # For now, don't bother testing int-int mult.
284
+ #next if [:int8,:int16,:int32,:int64].include?(left_dtype) && [:int8,:int16,:int32,:int64].include?(right_dtype)
285
+ it "handles #{left_dtype.to_s} dot #{right_dtype.to_s} matrix multiplication" do
286
+ #STDERR.puts "dtype=#{dtype.to_s}"
287
+ #STDERR.puts "2"
288
+
289
+ nary = if left_dtype.to_s =~ /complex/
290
+ COMPLEX_MATRIX43A_ARRAY
291
+ else
292
+ MATRIX43A_ARRAY
293
+ end
294
+
295
+ mary = if right_dtype.to_s =~ /complex/
296
+ COMPLEX_MATRIX32A_ARRAY
297
+ else
298
+ MATRIX32A_ARRAY
299
+ end
300
+
301
+ n = NMatrix.new([4,3], nary, dtype: left_dtype)[1..3,1..2]
302
+ m = NMatrix.new([3,2], mary, dtype: right_dtype)[1..2,0..1]
303
+
304
+ r = n.dot m
305
+ expect(r.shape).to eql([3,2])
306
+
307
+ expect(r[0,0]).to eq(219.0)
308
+ expect(r[0,1]).to eq(185.0)
309
+ expect(r[1,0]).to eq(244.0)
310
+ expect(r[1,1]).to eq(205.0)
311
+ expect(r[2,0]).to eq(42.0)
312
+ expect(r[2,1]).to eq(35.0)
313
+
314
+ end
315
+ end
316
+ end
317
+
318
+ context "operations" do
319
+
320
+ it "correctly transposes slices" do
321
+ expect(stype_matrix[0...3,0].transpose).to eq NMatrix[[0, 3, 6]]
322
+ expect(stype_matrix[0...3,1].transpose).to eq NMatrix[[1, 4, 7]]
323
+ expect(stype_matrix[0...3,2].transpose).to eq NMatrix[[2, 5, 8]]
324
+ expect(stype_matrix[0,0...3].transpose).to eq NMatrix[[0], [1], [2]]
325
+ expect(stype_matrix[1,0...3].transpose).to eq NMatrix[[3], [4], [5]]
326
+ expect(stype_matrix[2,0...3].transpose).to eq NMatrix[[6], [7], [8]]
327
+ expect(stype_matrix[1..2,1..2].transpose).to eq NMatrix[[4, 7], [5, 8]]
328
+ end
329
+
330
+ it "adds slices" do
331
+ expect(NMatrix[[0,0,0]] + stype_matrix[1,0..2]).to eq NMatrix[[3, 4, 5]]
332
+ end
333
+
334
+ it "scalar adds to slices" do
335
+ expect(stype_matrix[1,0..2]+1).to eq NMatrix[[4, 5, 6]]
336
+ end
337
+
338
+ it "compares slices to scalars" do
339
+ #FIXME
340
+ pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
341
+ (stype_matrix[1, 0..2] > 2).each { |e| expect(e != 0).to be true }
342
+ end
343
+
344
+ it "iterates only over elements in the slice" do
345
+ els = []
346
+ stype_matrix[1, 0..2].each { |e| els << e }
347
+ expect(els.size).to eq 3
348
+ expect(els[0]).to eq 3
349
+ expect(els[1]).to eq 4
350
+ expect(els[2]).to eq 5
351
+ end
352
+
353
+ it "iterates with index only over elements in the slice" do
354
+ els = []
355
+ stype_matrix[1, 0..2].each_stored_with_indices { |a| els << a }
356
+ expect(els.size).to eq 3
357
+ expect(els[0]).to eq [3, 0, 0]
358
+ expect(els[1]).to eq [4, 0, 1]
359
+ expect(els[2]).to eq [5, 0, 2]
360
+ end
361
+
362
+ end
363
+
364
+ end
365
+
366
+ example 'should be cleaned up by garbage collector without errors' do
367
+ step "reference slice" do
368
+ 1.times do
369
+ n = stype_matrix[1..2,0..1]
370
+ end
371
+ GC.start
372
+ end
373
+
374
+ step "reference slice of casted-copy" do
375
+ expect(stype_matrix).to eq(NMatrix.new([3,3], (0..9).to_a, dtype: :int32).cast(stype, :int32))
376
+ n = nil
377
+ 1.times do
378
+ m = NMatrix.new([2,2], [1,2,3,4]).cast(stype, :int32)
379
+ n = m[0..1,0..1]
380
+ end
381
+ GC.start
382
+ expect(n).to eq(NMatrix.new([2,2], [1,2,3,4]).cast(stype, :int32))
383
+ end
384
+ end
385
+
386
+ [:dense, :list, :yale].each do |cast_type|
387
+ it "should cast a square reference-slice from #{stype.upcase} to #{cast_type.upcase}" do
388
+ expect(nm_eql(stype_matrix[1..2, 1..2].cast(cast_type), stype_matrix[1..2,1..2])).to be true
389
+ expect(nm_eql(stype_matrix[0..1, 1..2].cast(cast_type), stype_matrix[0..1,1..2])).to be true
390
+ expect(nm_eql(stype_matrix[1..2, 0..1].cast(cast_type), stype_matrix[1..2,0..1])).to be true
391
+ expect(nm_eql(stype_matrix[0..1, 0..1].cast(cast_type), stype_matrix[0..1,0..1])).to be true
392
+ end
393
+
394
+ it "should cast a rectangular reference-slice from #{stype.upcase} to #{cast_type.upcase}" do
395
+ # Non square
396
+ expect(nm_eql(stype_matrix[0..2, 1..2].cast(cast_type), stype_matrix[0..2,1..2])).to be true # FIXME: memory problem.
397
+ 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
398
+ end
399
+
400
+ it "should cast a square full-matrix reference-slice from #{stype.upcase} to #{cast_type.upcase}" do
401
+ expect(nm_eql(stype_matrix[0..2, 0..2].cast(cast_type), stype_matrix)).to be true
402
+ end
403
+ end
404
+ end
405
+ end
406
+ end
407
+ end
@@ -0,0 +1,80 @@
1
+ require 'spec_helper'
2
+
3
+ describe NMatrix do
4
+ describe "#to_a" do
5
+ it "creates an Array with the same dimensions" do
6
+ n = NMatrix.seq([3,2])
7
+ expect(n.to_a).to eq([[0, 1], [2, 3], [4, 5]])
8
+ end
9
+
10
+ it "creates an Array with the proper element type" do
11
+ n = NMatrix.seq([3,2], dtype: :float64)
12
+ expect(n.to_a).to eq([[0.0, 1.0], [2.0, 3.0], [4.0, 5.0]])
13
+ end
14
+
15
+ it "properly interprets list matrices" do
16
+ n = NMatrix.seq([3,2], stype: :list)
17
+ expect(n.to_a).to eq([[0, 1], [2, 3], [4, 5]])
18
+ end
19
+
20
+ it "properly interprets yale matrices" do
21
+ n = NMatrix.seq([3,2], stype: :yale)
22
+ expect(n.to_a).to eq([[0, 1], [2, 3], [4, 5]])
23
+ end
24
+ end
25
+ end
26
+
27
+ describe Array do
28
+ describe "#to_nm" do
29
+ # [0, 1, 2, 3, 4, 5]
30
+ let(:a) {(0..5).to_a}
31
+
32
+ it "uses a given shape and type" do
33
+ expect(a.to_nm([3,2]).dtype).to eq :int64
34
+ expect(a.to_nm([3,2])).to eq(NMatrix.seq([3,2]))
35
+ end
36
+
37
+ it "guesses dtype based on first element" do
38
+ a[0] = 0.0
39
+ expect(a.to_nm([3,2]).dtype).to eq :float64
40
+ end
41
+
42
+ it "defaults to dtype :object if necessary" do
43
+ #FIXME
44
+ pending("not yet implemented for object dtype for NMatrix-JRuby") if jruby?
45
+ a = %w(this is an array of strings)
46
+ expect(a.to_nm([3,2]).dtype).to eq :object
47
+ expect(a.to_nm([3,2])).to eq(NMatrix.new([3,2], a, dtype: :object))
48
+ end
49
+
50
+ it "attempts to intuit the shape of the Array" do
51
+ a = [[0, 1], [2, 3], [4, 5]]
52
+ expect(a.to_nm).to eq(NMatrix.new([3,2], a.flatten))
53
+ expect(a.to_nm.dtype).to eq :int64
54
+ end
55
+
56
+ it "creates an object Array for inconsistent dimensions" do
57
+ a = [[0, 1, 2], [3], [4, 5]]
58
+ expect(a.to_nm).to eq(NMatrix.new([3], a, dtype: :object))
59
+ expect(a.to_nm.dtype).to eq :object
60
+ end
61
+
62
+ it "intuits shape of Array into multiple dimensions" do
63
+ a = [[[0], [1]], [[2], [3]], [[4], [5]]]
64
+ expect(a.to_nm).to eq(NMatrix.new([3,2,1], a.flatten))
65
+ expect(a).to eq(a.to_nm.to_a)
66
+ end
67
+
68
+ it "is reflective with NMatrix#to_a" do
69
+ a = [[0, 1, 2], [3], [4, 5]]
70
+ expect(a).to eq(a.to_nm.to_a)
71
+ end
72
+
73
+ it "does not permanently alter the Array" do
74
+ a = [[0, 1], [2, 3], [4, 5]]
75
+ expect(a.to_nm).to eq(NMatrix.new([3,2], a.flatten))
76
+ expect(a).to eq([[0, 1], [2, 3], [4, 5]])
77
+ end
78
+ end
79
+ end
80
+
Binary file
Binary file
Binary file