nmatrix 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/Gemfile +5 -0
  4. data/History.txt +97 -0
  5. data/Manifest.txt +34 -7
  6. data/README.rdoc +13 -13
  7. data/Rakefile +36 -26
  8. data/ext/nmatrix/data/data.cpp +15 -2
  9. data/ext/nmatrix/data/data.h +4 -0
  10. data/ext/nmatrix/data/ruby_object.h +5 -14
  11. data/ext/nmatrix/extconf.rb +3 -2
  12. data/ext/nmatrix/{util/math.cpp → math.cpp} +296 -6
  13. data/ext/nmatrix/math/asum.h +143 -0
  14. data/ext/nmatrix/math/geev.h +82 -0
  15. data/ext/nmatrix/math/gemm.h +267 -0
  16. data/ext/nmatrix/math/gemv.h +208 -0
  17. data/ext/nmatrix/math/ger.h +96 -0
  18. data/ext/nmatrix/math/gesdd.h +80 -0
  19. data/ext/nmatrix/math/gesvd.h +78 -0
  20. data/ext/nmatrix/math/getf2.h +86 -0
  21. data/ext/nmatrix/math/getrf.h +240 -0
  22. data/ext/nmatrix/math/getri.h +107 -0
  23. data/ext/nmatrix/math/getrs.h +125 -0
  24. data/ext/nmatrix/math/idamax.h +86 -0
  25. data/ext/nmatrix/{util → math}/lapack.h +60 -356
  26. data/ext/nmatrix/math/laswp.h +165 -0
  27. data/ext/nmatrix/math/long_dtype.h +52 -0
  28. data/ext/nmatrix/math/math.h +1154 -0
  29. data/ext/nmatrix/math/nrm2.h +181 -0
  30. data/ext/nmatrix/math/potrs.h +125 -0
  31. data/ext/nmatrix/math/rot.h +141 -0
  32. data/ext/nmatrix/math/rotg.h +115 -0
  33. data/ext/nmatrix/math/scal.h +73 -0
  34. data/ext/nmatrix/math/swap.h +73 -0
  35. data/ext/nmatrix/math/trsm.h +383 -0
  36. data/ext/nmatrix/nmatrix.cpp +176 -152
  37. data/ext/nmatrix/nmatrix.h +1 -2
  38. data/ext/nmatrix/ruby_constants.cpp +9 -4
  39. data/ext/nmatrix/ruby_constants.h +1 -0
  40. data/ext/nmatrix/storage/dense.cpp +57 -41
  41. data/ext/nmatrix/storage/list.cpp +52 -50
  42. data/ext/nmatrix/storage/storage.cpp +59 -43
  43. data/ext/nmatrix/storage/yale.cpp +352 -333
  44. data/ext/nmatrix/storage/yale.h +4 -0
  45. data/lib/nmatrix.rb +2 -2
  46. data/lib/nmatrix/blas.rb +4 -4
  47. data/lib/nmatrix/enumerate.rb +241 -0
  48. data/lib/nmatrix/lapack.rb +54 -1
  49. data/lib/nmatrix/math.rb +462 -0
  50. data/lib/nmatrix/nmatrix.rb +210 -486
  51. data/lib/nmatrix/nvector.rb +0 -62
  52. data/lib/nmatrix/rspec.rb +75 -0
  53. data/lib/nmatrix/shortcuts.rb +136 -108
  54. data/lib/nmatrix/version.rb +1 -1
  55. data/spec/blas_spec.rb +20 -12
  56. data/spec/elementwise_spec.rb +22 -13
  57. data/spec/io_spec.rb +1 -0
  58. data/spec/lapack_spec.rb +197 -0
  59. data/spec/nmatrix_spec.rb +39 -38
  60. data/spec/nvector_spec.rb +3 -9
  61. data/spec/rspec_monkeys.rb +29 -0
  62. data/spec/rspec_spec.rb +34 -0
  63. data/spec/shortcuts_spec.rb +14 -16
  64. data/spec/slice_spec.rb +242 -186
  65. data/spec/spec_helper.rb +19 -0
  66. metadata +33 -5
  67. data/ext/nmatrix/util/math.h +0 -2612
data/spec/nvector_spec.rb CHANGED
@@ -49,13 +49,6 @@ describe NVector do
49
49
  v[0].should == 1.555
50
50
  end
51
51
 
52
- it "transpose!() changes destructively its raw and column stored structure" do
53
- v = NVector.new 5, :float64
54
- v.transpose!
55
- v.shape[0].should == 5
56
- v.shape[1].should == 1
57
- end
58
-
59
52
  it "dot() multiples itself by another NVector" do
60
53
  v1 = NVector.new(2, :float64)
61
54
  v2 = NVector.new(2, :float64).transpose
@@ -63,10 +56,11 @@ describe NVector do
63
56
  v1[1] = 2.3
64
57
  v2[0] = 1.3
65
58
  v2[1] = 2.5
66
- v1.dot(v2).should == 12.0
59
+ v1.dot(v2).should be_within(0.000000001).of(7.7)
67
60
  end
68
61
 
69
62
  it "dot!() multiples itself destructively by another NVector" do
63
+ pending "dot! not yet implemented"
70
64
  v1 = NVector.new 2, :float64
71
65
  v2 = NVector.new(2, :float64).transpose
72
66
  v1[0] = 1.5
@@ -74,7 +68,7 @@ describe NVector do
74
68
  v2[0] = 1.3
75
69
  v2[1] = 2.5
76
70
  v1.dot!(v2)
77
- v1.should == 12.0
71
+ v1.should be_within(0.000000001).of(7.7)
78
72
  end
79
73
 
80
74
  it "pretty_print() prints values to standard output with a pretty format" do
@@ -0,0 +1,29 @@
1
+ module RSpec::Matchers::BuiltIn
2
+ class BeWithin
3
+
4
+ def of(expected)
5
+ @expected = expected
6
+ @unit = ''
7
+ if expected.is_a?(NMatrix)
8
+ @tolerance = if @delta.is_a?(NMatrix)
9
+ @delta.clone
10
+ elsif @delta.is_a?(Array)
11
+ NMatrix.new(:dense, expected.shape, @delta, expected.dtype)
12
+ else
13
+ NMatrix.ones_like(expected) * @delta
14
+ end
15
+ else
16
+ @tolerance = @delta
17
+ end
18
+
19
+ self
20
+ end
21
+
22
+ def percent_of(expected)
23
+ @expected = expected
24
+ @unit = '%'
25
+ @tolerance = @expected.abs * @delta / 100.0 # <- only change is to reverse abs and @delta
26
+ self
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,34 @@
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 - 2012, Ruby Science Foundation
12
+ # NMatrix is Copyright (c) 2012, 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
+ # == rspec_spec.rb
24
+ #
25
+ # A spec for testing monkey patches to RSpec for NMatrix.
26
+ #
27
+ require File.join(File.dirname(__FILE__), "spec_helper.rb")
28
+
29
+ describe "RSpec" do
30
+ it "should permit #be_within to be used on a dense NMatrix" do
31
+ (NMatrix.new(:dense, [4,1], 1.0, :complex128) / 10000.0).should be_within(0.00000001).of(NMatrix.new(:dense, [4,1], 0.0001, :float64))
32
+ (NMatrix.new(:dense, [4,1], 1.0, :complex128) / 10000.0).should_not be_within(0.00000001).of(NMatrix.new(:dense, [4,1], 1.0, :float64))
33
+ end
34
+ end
@@ -165,29 +165,27 @@ describe NMatrix do
165
165
  m.column(2).is_a?(NMatrix).should be_true
166
166
  end
167
167
 
168
- it "column() accepts a second parameter (only :copy or :reference)" do
169
- m = NMatrix.random(3)
170
-
171
- expect { m.column(1, :copy) }.to_not raise_error
172
- expect { m.column(1, :reference) }.to_not raise_error
173
-
174
- expect { m.column(1, :derp) }.to raise_error
175
- end
176
-
177
168
  it "row() returns a NMatrix" do
178
169
  m = NMatrix.random(3)
179
170
 
180
171
  m.row(2).is_a?(NMatrix).should be_true
181
172
  end
182
173
 
183
- it "row() accepts a second parameter (only :copy or :reference)" do
184
- m = NMatrix.random(3)
185
-
186
- expect { m.row(1, :copy) }.to_not raise_error
187
- expect { m.row(1, :reference) }.to_not raise_error
174
+ it "diagonals() creates an NMatrix" do
175
+ arr = [1,2,3,4]
176
+ m = NMatrix.diagonals(arr)
177
+ m.is_a?(NMatrix).should be_true
178
+ end
188
179
 
189
- expect { m.row(1, :derp) }.to raise_error
180
+ it "diagonals() contains the seeded values on the diagonal" do
181
+ arr = [1,2,3,4]
182
+ m = NMatrix.diagonals(arr)
183
+ m[0,0].should eq(arr[0])
184
+ m[1,1].should eq(arr[1])
185
+ m[2,2].should eq(arr[2])
186
+ m[3,3].should eq(arr[3])
190
187
  end
188
+
191
189
  end
192
190
 
193
191
  describe "NVector" do
@@ -261,7 +259,7 @@ describe "Inline constructor" do
261
259
 
262
260
  it "creates a NMatrix with the given values" do
263
261
  m = NMatrix.new([2, 2], [1, 4, 6, 7])
264
- n = N[[1, 4], [6, 7]]
262
+ n = NMatrix[[1, 4], [6, 7]]
265
263
 
266
264
  m.should.eql? n
267
265
  end
data/spec/slice_spec.rb CHANGED
@@ -27,29 +27,118 @@
27
27
  require File.dirname(__FILE__) + "/spec_helper.rb"
28
28
 
29
29
  describe "Slice operation" do
30
+
30
31
  [:dense, :list, :yale].each do |stype|
31
32
  context "for #{stype}" do
32
33
  before :each do
33
34
  @m = create_matrix(stype)
34
35
  end
35
36
 
36
- unless stype == :yale
37
- it "should have #is_ref? method" do
38
- a = @m[0..1, 0..1]
39
- b = @m.slice(0..1, 0..1)
37
+ if stype == :yale
38
+ it "should binary search for the left boundary of a partial row of stored indices correctly" do
39
+ n = NMatrix.new(:yale, 10, :int32)
40
+ n[3,0] = 1
41
+ #n[3,2] = 2
42
+ n[3,3] = 3
43
+ n[3,4] = 4
44
+ n[3,6] = 5
45
+ n[3,8] = 6
46
+ n[3,9] = 7
47
+ vs = []
48
+ is = []
49
+ js = []
50
+ n[3,1..9].each_stored_with_indices do |v,i,j|
51
+ vs << v
52
+ is << i
53
+ js << j
54
+ end
40
55
 
56
+ vs.should == [3,4,5,6,7]
57
+ js.should == [2,3,5,7,8]
58
+ is.should == [0,0,0,0,0]
59
+ end
60
+ elsif stype == :list
61
+ it "should iterate across a partial row of stored indices" do
62
+ vs = []
63
+ is = []
64
+ js = []
65
+
66
+ STDERR.puts("now") if stype == :yale
67
+ @m[2,1..2].each_stored_with_indices do |v,i,j|
68
+ vs << v
69
+ is << i
70
+ js << j
71
+ end
41
72
 
42
- @m.is_ref?.should be_false
43
- a.is_ref?.should be_true
44
- b.is_ref?.should be_false
73
+ vs.should == [7,8]
74
+ is.should == [0,0]
75
+ js.should == [0,1]
45
76
  end
77
+ end
78
+
79
+ unless stype == :dense
80
+ it "should iterate across a row of stored indices" do
81
+
82
+ vs = []
83
+ is = []
84
+ js = []
85
+ @m[2,0..2].each_stored_with_indices do |v,i,j|
86
+ vs << v
87
+ is << i
88
+ js << j
89
+ end
90
+ vs.should == (stype == :yale ? [8,6,7] : [6,7,8])
91
+ is.should == [0,0,0]
92
+ js.should == (stype == :yale ? [2,0,1] : [0,1,2])
93
+ end
94
+
95
+ it "should iterate across a submatrix of stored indices" do
96
+ vs = []
97
+ is = []
98
+ js = []
99
+ @m[0..1,1..2].each_stored_with_indices do |v,i,j|
100
+ vs << v
101
+ is << i
102
+ js << j
103
+ end
46
104
 
47
- it "reference should compare with non-reference" do
48
- @m.slice(1..2,0..1).should == @m[1..2, 0..1]
49
- @m[1..2,0..1].should == @m.slice(1..2, 0..1)
50
- @m[1..2,0..1].should == @m[1..2, 0..1]
105
+ vs.should == (stype == :yale ? [4,1,2,5] : [1,2,4,5])
106
+ is.should == (stype == :yale ? [1,0,0,1] : [0,0,1,1])
107
+ js.should == (stype == :yale ? [0,0,1,1] : [0,1,0,1])
51
108
  end
52
- end # unless stype == :yale
109
+ end
110
+
111
+ it "should return correct shape and 1st-order supershape" do
112
+ x = NMatrix.random([10,12])
113
+ y = x[0...8,5...12]
114
+ y.shape.should == [8,7]
115
+ y.supershape.should == [10,12]
116
+ end
117
+
118
+ it "should return correct 1st- and 2nd-order supershape" do
119
+ pending "Not yet sure if we ever want to enable reference slices of reference slices"
120
+ x = NMatrix.random([10,12])
121
+ y = x[0...8,5...12]
122
+ z = y[0...3,0...4]
123
+ z.supershape(2).should == y.supershape(1)
124
+ z.supershape(1).should == [8,7]
125
+ end
126
+
127
+ it "should have #is_ref? method" do
128
+ a = @m[0..1, 0..1]
129
+ b = @m.slice(0..1, 0..1)
130
+
131
+
132
+ @m.is_ref?.should be_false
133
+ a.is_ref?.should be_true
134
+ b.is_ref?.should be_false
135
+ end
136
+
137
+ it "reference should compare with non-reference" do
138
+ @m.slice(1..2,0..1).should == @m[1..2, 0..1]
139
+ @m[1..2,0..1].should == @m.slice(1..2, 0..1)
140
+ @m[1..2,0..1].should == @m[1..2, 0..1]
141
+ end
53
142
 
54
143
  context "with copying" do
55
144
  it 'should return an NMatrix' do
@@ -66,7 +155,7 @@ describe "Slice operation" do
66
155
  @m[2,1].should eql(7)
67
156
  end
68
157
 
69
- it 'should return a 1x2 vector with refs to self elements' do
158
+ it 'should return a 1x2 matrix with refs to self elements' do
70
159
  n = @m.slice(0,1..2)
71
160
  n.shape.should eql([1,2])
72
161
 
@@ -105,211 +194,178 @@ describe "Slice operation" do
105
194
  end
106
195
  end
107
196
 
108
-
109
-
110
- if stype == :yale
111
- context "by reference" do
112
- it "should raise an error" do
113
- expect{ @m[1..2,1..2] }.to raise_error(NotImplementedError)
114
- end
197
+ # Yale:
198
+ #context "by copy" do
199
+ #it "should correctly preserve zeros" do
200
+ # @m = NMatrix.new(:yale, 3, :int64)
201
+ # column_slice = @m.column(2, :copy)
202
+ # column_slice[0].should == 0
203
+ # column_slice[1].should == 0
204
+ # column_slice[2].should == 0
205
+ #end
206
+ #end
207
+
208
+ context "by reference" do
209
+ it 'should return an NMatrix' do
210
+ n = @m[0..1,0..1]
211
+ nm_eql(n, NMatrix.new([2,2], [0,1,3,4], :int32)).should be_true
115
212
  end
116
213
 
117
- context "by copy" do
118
- it "should correctly preserve zeros" do
119
- @m = NMatrix.new(:yale, 3, :int64)
120
- column_slice = @m.column(2, :copy)
121
- column_slice[0].should == 0
122
- column_slice[1].should == 0
123
- column_slice[2].should == 0
124
- end
125
- end
126
- else
127
- context "by reference" do
128
- it 'should return an NMatrix' do
129
- n = @m[0..1,0..1]
130
- nm_eql(n, NMatrix.new([2,2], [0,1,3,4], :int32)).should be_true
131
- end
214
+ it 'should return a 2x2 matrix with refs to self elements' do
215
+ n = @m[1..2,0..1]
216
+ n.shape.should eql([2,2])
132
217
 
133
- it 'should return a 2x2 matrix with refs to self elements' do
134
- n = @m[1..2,0..1]
135
- n.shape.should eql([2,2])
218
+ n[0,0].should == @m[1,0]
219
+ n[0,0] = -9
220
+ @m[1,0].should eql(-9)
221
+ end
136
222
 
137
- n[0,0].should == @m[1,0]
138
- n[0,0] = -9
139
- @m[1,0].should eql(-9)
140
- end
223
+ it 'should return a 1x2 vector with refs to self elements' do
224
+ n = @m[0,1..2]
225
+ n.shape.should eql([1,2])
141
226
 
142
- it 'should return a 1x2 vector with refs to self elements' do
143
- n = @m[0,1..2]
144
- n.shape.should eql([1,2])
227
+ n[0].should == @m[0,1]
228
+ n[0] = -9
229
+ @m[0,1].should eql(-9)
230
+ end
145
231
 
146
- n[0].should == @m[0,1]
147
- n[0] = -9
148
- @m[0,1].should eql(-9)
149
- end
232
+ it 'should return a 2x1 vector with refs to self elements' do
233
+ n = @m[0..1,1]
234
+ n.shape.should eql([2,1])
150
235
 
151
- it 'should return a 2x1 vector with refs to self elements' do
152
- n = @m[0..1,1]
153
- n.shape.should eql([2,1])
236
+ n[0].should == @m[0,1]
237
+ n[0] = -9
238
+ @m[0,1].should eql(-9)
239
+ end
154
240
 
155
- n[0].should == @m[0,1]
156
- n[0] = -9
157
- @m[0,1].should eql(-9)
158
- end
241
+ it 'should slice again' do
242
+ n = @m[1..2, 1..2]
243
+ nm_eql(n[1,0..1], NVector.new(2, [7,8], :int32).transpose).should be_true
244
+ end
159
245
 
160
- it 'should slice again' do
161
- n = @m[1..2, 1..2]
162
- nm_eql(n[1,0..1], NVector.new(2, [7,8], :int32).transpose).should be_true
163
- end
246
+ it 'should be correct slice for range 0..2 and 0...3' do
247
+ @m[0..2,0..2].should == @m[0...3,0...3]
248
+ end
164
249
 
165
- it 'should be correct slice for range 0..2 and 0...3' do
166
- @m[0..2,0..2].should == @m[0...3,0...3]
167
- end
250
+ if stype == :dense
251
+ [:byte,:int8,:int16,:int32,:int64,:float32,:float64,:rational64,:rational128].each do |left_dtype|
252
+ [:byte,:int8,:int16,:int32,:int64,:float32,:float64,:rational64,:rational128].each do |right_dtype|
253
+
254
+ # Won't work if they're both 1-byte, due to overflow.
255
+ next if [:byte,:int8].include?(left_dtype) && [:byte,:int8].include?(right_dtype)
256
+
257
+ # For now, don't bother testing int-int mult.
258
+ #next if [:int8,:int16,:int32,:int64].include?(left_dtype) && [:int8,:int16,:int32,:int64].include?(right_dtype)
259
+ it "handles #{left_dtype.to_s} dot #{right_dtype.to_s} matrix multiplication" do
260
+ #STDERR.puts "dtype=#{dtype.to_s}"
261
+ #STDERR.puts "2"
262
+
263
+ nary = if left_dtype.to_s =~ /complex/
264
+ COMPLEX_MATRIX43A_ARRAY
265
+ elsif left_dtype.to_s =~ /rational/
266
+ RATIONAL_MATRIX43A_ARRAY
267
+ else
268
+ MATRIX43A_ARRAY
269
+ end
270
+
271
+ mary = if right_dtype.to_s =~ /complex/
272
+ COMPLEX_MATRIX32A_ARRAY
273
+ elsif right_dtype.to_s =~ /rational/
274
+ RATIONAL_MATRIX32A_ARRAY
275
+ else
276
+ MATRIX32A_ARRAY
277
+ end
278
+
279
+ n = NMatrix.new([4,3], nary, left_dtype)[1..3,1..2]
280
+ m = NMatrix.new([3,2], mary, right_dtype)[1..2,0..1]
281
+
282
+ r = n.dot m
283
+ r.shape.should eql([3,2])
284
+
285
+ r[0,0].should == 219.0
286
+ r[0,1].should == 185.0
287
+ r[1,0].should == 244.0
288
+ r[1,1].should == 205.0
289
+ r[2,0].should == 42.0
290
+ r[2,1].should == 35.0
168
291
 
169
- if stype == :dense
170
- [:byte,:int8,:int16,:int32,:int64,:float32,:float64,:rational64,:rational128].each do |left_dtype|
171
- [:byte,:int8,:int16,:int32,:int64,:float32,:float64,:rational64,:rational128].each do |right_dtype|
172
-
173
- # Won't work if they're both 1-byte, due to overflow.
174
- next if [:byte,:int8].include?(left_dtype) && [:byte,:int8].include?(right_dtype)
175
-
176
- # For now, don't bother testing int-int mult.
177
- #next if [:int8,:int16,:int32,:int64].include?(left_dtype) && [:int8,:int16,:int32,:int64].include?(right_dtype)
178
- it "handles #{left_dtype.to_s} dot #{right_dtype.to_s} matrix multiplication" do
179
- #STDERR.puts "dtype=#{dtype.to_s}"
180
- #STDERR.puts "2"
181
-
182
- nary = if left_dtype.to_s =~ /complex/
183
- COMPLEX_MATRIX43A_ARRAY
184
- elsif left_dtype.to_s =~ /rational/
185
- RATIONAL_MATRIX43A_ARRAY
186
- else
187
- MATRIX43A_ARRAY
188
- end
189
-
190
- mary = if right_dtype.to_s =~ /complex/
191
- COMPLEX_MATRIX32A_ARRAY
192
- elsif right_dtype.to_s =~ /rational/
193
- RATIONAL_MATRIX32A_ARRAY
194
- else
195
- MATRIX32A_ARRAY
196
- end
197
-
198
- n = NMatrix.new([4,3], nary, left_dtype)[1..3,1..2]
199
- m = NMatrix.new([3,2], mary, right_dtype)[1..2,0..1]
200
-
201
- r = n.dot m
202
- r.shape.should eql([3,2])
203
-
204
- r[0,0].should == 219.0
205
- r[0,1].should == 185.0
206
- r[1,0].should == 244.0
207
- r[1,1].should == 205.0
208
- r[2,0].should == 42.0
209
- r[2,1].should == 35.0
210
-
211
- end
212
292
  end
213
293
  end
294
+ end
214
295
 
215
- context "operations" do
216
-
217
- it "correctly transposes slices" do
218
- @m[0...3,0].transpose.should eq N[[0, 3, 6]]
219
- end
296
+ context "operations" do
220
297
 
221
- it "adds slices" do
222
- (N[[0,0,0]] + @m[1,0..2]).should eq N[[3, 4, 5]]
223
- end
298
+ it "correctly transposes slices" do
299
+ @m[0...3,0].transpose.should eq NMatrix[[0, 3, 6]]
300
+ end
224
301
 
225
- it "scalar adds to slices" do
226
- (@m[1,0..2]+1).should eq N[[4, 5, 6]]
227
- end
302
+ it "adds slices" do
303
+ (NMatrix[[0,0,0]] + @m[1,0..2]).should eq NMatrix[[3, 4, 5]]
304
+ end
228
305
 
229
- it "compares slices to scalars" do
230
- (@m[1, 0..2] > 2).each { |e| (e != 0).should be_true }
231
- end
306
+ it "scalar adds to slices" do
307
+ (@m[1,0..2]+1).should eq NMatrix[[4, 5, 6]]
308
+ end
232
309
 
233
- it "iterates only over elements in the slice" do
234
- els = []
235
- @m[1, 0..2].each { |e| els << e }
236
- els.size.should eq 3
237
- els[0].should eq 3
238
- els[1].should eq 4
239
- els[2].should eq 5
240
- end
310
+ it "compares slices to scalars" do
311
+ (@m[1, 0..2] > 2).each { |e| (e != 0).should be_true }
312
+ end
241
313
 
242
- it "iterates with index only over elements in the slice" do
243
- els = []
244
- @m[1, 0..2].each_stored_with_indices { |a| els << a }
245
- els.size.should eq 3
246
- els[0].should eq [3, 0, 0]
247
- els[1].should eq [4, 0, 1]
248
- els[2].should eq [5, 0, 2]
249
- end
314
+ it "iterates only over elements in the slice" do
315
+ els = []
316
+ @m[1, 0..2].each { |e| els << e }
317
+ els.size.should eq 3
318
+ els[0].should eq 3
319
+ els[1].should eq 4
320
+ els[2].should eq 5
321
+ end
250
322
 
323
+ it "iterates with index only over elements in the slice" do
324
+ els = []
325
+ @m[1, 0..2].each_stored_with_indices { |a| els << a }
326
+ els.size.should eq 3
327
+ els[0].should eq [3, 0, 0]
328
+ els[1].should eq [4, 0, 1]
329
+ els[2].should eq [5, 0, 2]
251
330
  end
252
331
 
253
332
  end
254
333
 
255
- it 'should be cleaned up by garbage collector without errors' do
256
- 1.times do
257
- n = @m[1..2,0..1]
258
- end
259
- GC.start
260
- @m.should == NMatrix.new(:dense, [3,3], (0..9).to_a, :int32).cast(stype, :int32)
261
- n = nil
262
- 1.times do
263
- m = NMatrix.new(:dense, [2,2], [1,2,3,4]).cast(stype, :int32)
264
- n = m[0..1,0..1]
265
- end
266
- GC.start
267
- n.should == NMatrix.new(:dense, [2,2], [1,2,3,4]).cast(stype, :int32)
334
+ end
335
+
336
+ it 'should be cleaned up by garbage collector without errors' do
337
+ 1.times do
338
+ n = @m[1..2,0..1]
339
+ end
340
+ GC.start
341
+ @m.should == NMatrix.new(:dense, [3,3], (0..9).to_a, :int32).cast(stype, :int32)
342
+ n = nil
343
+ 1.times do
344
+ m = NMatrix.new(:dense, [2,2], [1,2,3,4]).cast(stype, :int32)
345
+ n = m[0..1,0..1]
268
346
  end
347
+ GC.start
348
+ n.should == NMatrix.new(:dense, [2,2], [1,2,3,4]).cast(stype, :int32)
349
+ end
269
350
 
270
- [:dense, :list, :yale].each do |cast_type|
271
- it "should cast from #{stype.upcase} to #{cast_type.upcase}" do
272
- nm_eql(@m[1..2, 1..2].cast(cast_type, :int32), @m[1..2,1..2]).should be_true
273
- nm_eql(@m[0..1, 1..2].cast(cast_type, :int32), @m[0..1,1..2]).should be_true
274
- nm_eql(@m[1..2, 0..1].cast(cast_type, :int32), @m[1..2,0..1]).should be_true
275
- nm_eql(@m[0..1, 0..1].cast(cast_type, :int32), @m[0..1,0..1]).should be_true
351
+ [:dense, :list, :yale].each do |cast_type|
352
+ it "should cast from #{stype.upcase} to #{cast_type.upcase}" do
276
353
 
277
- # Non square
278
- nm_eql(@m[0..2, 1..2].cast(cast_type, :int32), @m[0..2,1..2]).should be_true
279
- nm_eql(@m[1..2, 0..2].cast(cast_type, :int32), @m[1..2,0..2]).should be_true
354
+ nm_eql(@m[1..2, 1..2].cast(cast_type), @m[1..2,1..2]).should be_true
355
+ nm_eql(@m[0..1, 1..2].cast(cast_type), @m[0..1,1..2]).should be_true
356
+ nm_eql(@m[1..2, 0..1].cast(cast_type), @m[1..2,0..1]).should be_true
357
+ nm_eql(@m[0..1, 0..1].cast(cast_type), @m[0..1,0..1]).should be_true
280
358
 
281
- # Full
282
- nm_eql(@m[0..2, 0..2].cast(cast_type, :int32), @m).should be_true
283
- end
284
- end
285
- end
286
- end
287
- end # unless stype == :yale
288
- end
359
+ # Non square
360
+ nm_eql(@m[0..2, 1..2].cast(cast_type), @m[0..2,1..2]).should be_true
361
+ nm_eql(@m[1..2, 0..2].cast(cast_type), @m[1..2,0..2]).should be_true
289
362
 
290
- # Stupid but independent comparison
291
- def nm_eql(n, m) #:nodoc:
292
- if n.shape != m.shape
293
- false
294
- elsif n.is_a?(NVector)
295
- return false unless m.is_a?(NVector) # don't compare NV to NM
296
- long_shape = n.shape[0] == 1 ? n.shape[1] : n.shape[0]
297
- long_shape.times do |j|
298
- if n[j] != m[j]
299
- puts "n[#{j}] != m[#{j}] (#{n[j]} != #{m[j]})"
300
- return false
301
- end
302
- end
303
- else # NMatrix
304
- n.shape[0].times do |i|
305
- n.shape[1].times do |j|
306
- if n[i,j] != m[i,j]
307
- puts "n[#{i},#{j}] != m[#{i},#{j}] (#{n[i,j]} != #{m[i,j]})"
308
- return false
363
+ # Full
364
+ nm_eql(@m[0..2, 0..2].cast(cast_type), @m).should be_true
309
365
  end
310
366
  end
311
367
  end
368
+
312
369
  end
313
- true
314
370
  end
315
371
  end