pnmatrix 1.2.4

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 (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