nmatrix 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -8
  3. data/.rspec +1 -1
  4. data/.travis.yml +12 -0
  5. data/CONTRIBUTING.md +27 -12
  6. data/Gemfile +1 -0
  7. data/History.txt +38 -0
  8. data/Manifest.txt +15 -15
  9. data/README.rdoc +7 -6
  10. data/Rakefile +40 -5
  11. data/ext/nmatrix/data/data.cpp +2 -37
  12. data/ext/nmatrix/data/data.h +19 -121
  13. data/ext/nmatrix/data/meta.h +70 -0
  14. data/ext/nmatrix/extconf.rb +40 -12
  15. data/ext/nmatrix/math/math.h +13 -103
  16. data/ext/nmatrix/nmatrix.cpp +10 -2018
  17. data/ext/nmatrix/nmatrix.h +16 -13
  18. data/ext/nmatrix/ruby_constants.cpp +12 -1
  19. data/ext/nmatrix/ruby_constants.h +7 -1
  20. data/ext/nmatrix/ruby_nmatrix.c +2169 -0
  21. data/ext/nmatrix/storage/dense.cpp +123 -14
  22. data/ext/nmatrix/storage/dense.h +10 -4
  23. data/ext/nmatrix/storage/list.cpp +265 -48
  24. data/ext/nmatrix/storage/list.h +6 -9
  25. data/ext/nmatrix/storage/storage.cpp +44 -54
  26. data/ext/nmatrix/storage/storage.h +2 -2
  27. data/ext/nmatrix/storage/yale/class.h +1070 -0
  28. data/ext/nmatrix/storage/yale/iterators/base.h +142 -0
  29. data/ext/nmatrix/storage/yale/iterators/iterator.h +130 -0
  30. data/ext/nmatrix/storage/yale/iterators/row.h +449 -0
  31. data/ext/nmatrix/storage/yale/iterators/row_stored.h +139 -0
  32. data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +167 -0
  33. data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +123 -0
  34. data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
  35. data/ext/nmatrix/storage/yale/yale.cpp +1785 -0
  36. data/ext/nmatrix/storage/{yale.h → yale/yale.h} +23 -55
  37. data/ext/nmatrix/types.h +2 -0
  38. data/ext/nmatrix/util/io.cpp +27 -45
  39. data/ext/nmatrix/util/io.h +0 -2
  40. data/ext/nmatrix/util/sl_list.cpp +169 -28
  41. data/ext/nmatrix/util/sl_list.h +9 -3
  42. data/lib/nmatrix/blas.rb +20 -20
  43. data/lib/nmatrix/enumerate.rb +1 -1
  44. data/lib/nmatrix/io/mat5_reader.rb +8 -14
  45. data/lib/nmatrix/lapack.rb +3 -3
  46. data/lib/nmatrix/math.rb +3 -3
  47. data/lib/nmatrix/nmatrix.rb +19 -5
  48. data/lib/nmatrix/nvector.rb +2 -0
  49. data/lib/nmatrix/shortcuts.rb +90 -125
  50. data/lib/nmatrix/version.rb +1 -1
  51. data/nmatrix.gemspec +7 -8
  52. data/spec/{nmatrix_spec.rb → 00_nmatrix_spec.rb} +45 -208
  53. data/spec/01_enum_spec.rb +184 -0
  54. data/spec/{slice_spec.rb → 02_slice_spec.rb} +55 -39
  55. data/spec/blas_spec.rb +22 -54
  56. data/spec/elementwise_spec.rb +9 -8
  57. data/spec/io_spec.rb +6 -4
  58. data/spec/lapack_spec.rb +26 -26
  59. data/spec/math_spec.rb +9 -5
  60. data/spec/nmatrix_yale_spec.rb +29 -61
  61. data/spec/shortcuts_spec.rb +34 -22
  62. data/spec/slice_set_spec.rb +157 -0
  63. data/spec/spec_helper.rb +42 -2
  64. data/spec/stat_spec.rb +192 -0
  65. metadata +52 -55
  66. data/ext/nmatrix/storage/yale.cpp +0 -2284
  67. data/spec/nmatrix_list_spec.rb +0 -113
  68. data/spec/nvector_spec.rb +0 -112
@@ -26,6 +26,6 @@ class NMatrix
26
26
  # Note that the format of the VERSION string is needed for NMatrix
27
27
  # native IO. If you change the format, please make sure that native
28
28
  # IO can still understand NMatrix::VERSION.
29
- VERSION = "0.0.8"
29
+ VERSION = "0.0.9"
30
30
  end
31
31
 
@@ -27,9 +27,8 @@ which improve the portability of this project.
27
27
 
28
28
  Also required is ATLAS. Most Linux distributions and Mac
29
29
  versions include ATLAS, but you may wish to compile it
30
- yourself. Rumor has it that the Ubuntu/Debian apt package
31
- for ATLAS WILL NOT WORK with NMatrix. Please install it
32
- manually if you are using apt.
30
+ yourself. The Ubuntu/Debian apt package for ATLAS WILL
31
+ NOT WORK with NMatrix if LAPACK is also installed.
33
32
 
34
33
  More explicit instructions for NMatrix and SciRuby should
35
34
  be available on the SciRuby website, sciruby.com, or
@@ -47,15 +46,15 @@ EOF
47
46
  gem.extensions = ['ext/nmatrix/extconf.rb']
48
47
  gem.require_paths = ["lib"]
49
48
 
50
- gem.required_ruby_version = '>= 1.9.2'
49
+ gem.required_ruby_version = '>= 1.9'
51
50
 
52
51
  gem.add_dependency 'rdoc', '>=4.0.1'
53
-
54
- gem.add_development_dependency 'rake', '~>0.9'
52
+ #gem.add_dependency 'yard'
53
+ gem.add_development_dependency 'rake'
55
54
  gem.add_development_dependency 'bundler'
56
- gem.add_development_dependency 'rspec', '~>2.9.0'
55
+ gem.add_development_dependency 'rspec'
56
+ gem.add_development_dependency 'rspec-longrun'
57
57
  gem.add_development_dependency 'pry'
58
- gem.add_development_dependency 'guard-rspec', '~>0.7.0'
59
58
  gem.add_development_dependency 'rake-compiler', '~>0.8.1'
60
59
  end
61
60
 
@@ -20,19 +20,23 @@
20
20
  #
21
21
  # * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
22
22
  #
23
- # == nmatrix_spec.rb
23
+ # == 00_nmatrix_spec.rb
24
24
  #
25
- # Basic tests for NMatrix.
25
+ # Basic tests for NMatrix. These should load first, as they're
26
+ # essential to NMatrix operation.
26
27
  #
27
28
 
28
29
  require File.dirname(__FILE__) + "/spec_helper.rb"
29
30
 
30
31
  describe NMatrix do
32
+ it "creates a matrix with the new constructor" do
33
+ n = NMatrix.new([2,2], [0,1,2,3], dtype: :int64)
34
+ end
31
35
 
32
36
  it "adequately requires information to access a single entry of a dense matrix" do
33
37
  n = NMatrix.new(:dense, 4, [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], :float64)
34
38
  n[0,0].should == 0
35
- expect { n[0] }.should raise_error(ArgumentError)
39
+ expect { n[0] }.to raise_error(ArgumentError)
36
40
  end
37
41
 
38
42
  it "calculates exact determinants on small square matrices" do
@@ -41,7 +45,7 @@ describe NMatrix do
41
45
  end
42
46
 
43
47
  it "calculates determinants" do
44
- m = NMatrix.new(:dense, 3, [-2,2,3,-1,1,3,2,0,-1])
48
+ m = NMatrix.new(3, [-2,2,3,-1,1,3,2,0,-1])
45
49
  m.det.should == 6
46
50
  end
47
51
 
@@ -74,12 +78,12 @@ describe NMatrix do
74
78
 
75
79
 
76
80
  it "fills dense Ruby object matrix with nil" do
77
- n = NMatrix.new([4,3], :object)
81
+ n = NMatrix.new([4,3], dtype: :object)
78
82
  n[0,0].should == nil
79
83
  end
80
84
 
81
85
  it "fills dense with individual assignments" do
82
- n = NMatrix.new([4,3], :float64)
86
+ n = NMatrix.new([4,3], dtype: :float64)
83
87
  n[0,0] = 14.0
84
88
  n[0,1] = 9.0
85
89
  n[0,2] = 3.0
@@ -125,7 +129,7 @@ describe NMatrix do
125
129
  end
126
130
 
127
131
  it "fills dense with a single mass assignment, with dtype specified" do
128
- m = NMatrix.new([4,3], [14.0, 9.0, 3.0, 2.0, 11.0, 15.0, 0.0, 12.0, 17.0, 5.0, 2.0, 3.0], :float32)
132
+ m = NMatrix.new([4,3], [14.0, 9.0, 3.0, 2.0, 11.0, 15.0, 0.0, 12.0, 17.0, 5.0, 2.0, 3.0], dtype: :float32)
129
133
  m[0,0].should == 14.0
130
134
  m[0,1].should == 9.0
131
135
  m[0,2].should == 3.0
@@ -142,11 +146,11 @@ describe NMatrix do
142
146
 
143
147
 
144
148
  it "dense handles missing initialization value" do
145
- n = NMatrix.new(3, :int8)
149
+ n = NMatrix.new(3, dtype: :int8)
146
150
  n.stype.should == :dense
147
151
  n.dtype.should == :int8
148
152
 
149
- m = NMatrix.new(4, :float64)
153
+ m = NMatrix.new(4, dtype: :float64)
150
154
  m.stype.should == :dense
151
155
  m.dtype.should == :float64
152
156
  end
@@ -155,7 +159,7 @@ describe NMatrix do
155
159
  [:dense, :list, :yale].each do |storage_type|
156
160
  context storage_type do
157
161
  it "can be duplicated" do
158
- n = NMatrix.new(storage_type, [2,3], storage_type == :yale ? :float64 : 1.1)
162
+ n = NMatrix.new([2,3], 1.1, stype: storage_type, dtype: :float64)
159
163
  n.stype.should equal(storage_type)
160
164
 
161
165
  n[0,0] = 0.0
@@ -173,13 +177,13 @@ describe NMatrix do
173
177
  end
174
178
 
175
179
  it "enforces shape boundaries" do
176
- expect { NMatrix.new(storage_type, [1,10], storage_type == :yale ? :int8 : 0)[-1,0] }.should raise_error
177
- expect { NMatrix.new(storage_type, [1,10], storage_type == :yale ? :int8 : 0)[1,0] }.should raise_error(RangeError)
178
- expect { NMatrix.new(storage_type, [1,10], storage_type == :yale ? :int8 : 0)[0,10] }.should raise_error(RangeError)
180
+ expect { NMatrix.new([1,10], 0, dtype: :int8, stype: storage_type, default: 0)[-1,0] }.to raise_error
181
+ expect { NMatrix.new([1,10], 0, dtype: :int8, stype: storage_type, default: 0)[1,0] }.to raise_error(RangeError)
182
+ expect { NMatrix.new([1,10], 0, dtype: :int8, stype: storage_type, default: 0)[0,10] }.to raise_error(RangeError)
179
183
  end
180
184
 
181
185
  it "sets and gets" do
182
- n = NMatrix.new(storage_type, 2, storage_type == :yale ? :int8 : 0)
186
+ n = NMatrix.new(2, 0, stype: storage_type, dtype: :int8)
183
187
  n[0,1] = 1
184
188
  n[0,0].should == 0
185
189
  n[1,0].should == 0
@@ -188,7 +192,7 @@ describe NMatrix do
188
192
  end
189
193
 
190
194
  it "sets and gets references" do
191
- n = NMatrix.new(storage_type, 2, storage_type == :yale ? :int8 : 0)
195
+ n = NMatrix.new(2, stype: storage_type, dtype: :int8, default: 0)
192
196
  (n[0,1] = 1).should == 1
193
197
  n[0,1].should == 1
194
198
  end
@@ -202,12 +206,13 @@ describe NMatrix do
202
206
  if storage_type == :dense
203
207
  n = NMatrix.new(:dense, [3,3], [1,2,3,4,5,6,7,8,9], dtype)
204
208
  else
205
- n = storage_type == :yale ? NMatrix.new(storage_type, [3,4], dtype) : NMatrix.new(storage_type, [3,4], 0, dtype)
209
+ n = NMatrix.new([3,4], 0, stype: storage_type, dtype: dtype)
206
210
  n[0,0] = 1
207
211
  n[0,1] = 2
208
212
  n[2,3] = 4
209
213
  n[2,0] = 3
210
214
  end
215
+
211
216
  ary = []
212
217
  n.each do |x|
213
218
  ary << x
@@ -223,25 +228,28 @@ describe NMatrix do
223
228
  it "allows storage-based iteration of matrices" do
224
229
  STDERR.puts storage_type.inspect
225
230
  STDERR.puts dtype.inspect
226
- n = storage_type == :yale ? NMatrix.new(storage_type, [3,3], dtype) : NMatrix.new(storage_type, [3,3], 0, dtype)
231
+ n = NMatrix.new([3,3], 0, stype: storage_type, dtype: dtype)
227
232
  n[0,0] = 1
228
233
  n[0,1] = 2
229
- n[2,2] = 3
234
+ n[2,0] = 5 if storage_type == :yale
230
235
  n[2,1] = 4
236
+ n[2,2] = 3
231
237
 
232
238
  values = []
233
239
  is = []
234
240
  js = []
241
+
235
242
  n.each_stored_with_indices do |v,i,j|
236
243
  values << v
237
244
  is << i
238
245
  js << j
239
246
  end
240
247
 
248
+
241
249
  if storage_type == :yale
242
- values.should == [1,0,3,2,4]
243
- is.should == [0,1,2,0,2]
244
- js.should == [0,1,2,1,1]
250
+ is.should == [0,1,2,0,2,2]
251
+ js.should == [0,1,2,1,0,1]
252
+ values.should == [1,0,3,2,5,4]
245
253
  elsif storage_type == :list
246
254
  values.should == [1,2,4,3]
247
255
  is.should == [0,0,2,2]
@@ -260,19 +268,19 @@ describe NMatrix do
260
268
  # dense and list, not yale
261
269
  context "(storage: #{storage_type})" do
262
270
  it "gets default value" do
263
- NMatrix.new(storage_type, 3, 0)[1,1].should == 0
264
- NMatrix.new(storage_type, 3, 0.1)[1,1].should == 0.1
265
- NMatrix.new(storage_type, 3, 1)[1,1].should == 1
271
+ NMatrix.new(3, 0, stype: storage_type)[1,1].should == 0
272
+ NMatrix.new(3, 0.1, stype: storage_type)[1,1].should == 0.1
273
+ NMatrix.new(3, 1, stype: storage_type)[1,1].should == 1
266
274
  end
267
275
 
268
276
  it "returns shape and dim" do
269
- NMatrix.new(storage_type, [3,2,8], 0).shape.should == [3,2,8]
270
- NMatrix.new(storage_type, [3,2,8], 0).dim.should == 3
277
+ NMatrix.new([3,2,8], 0, stype: storage_type).shape.should == [3,2,8]
278
+ NMatrix.new([3,2,8], 0, stype: storage_type).dim.should == 3
271
279
  end
272
280
 
273
281
  it "returns number of rows and columns" do
274
- NMatrix.new(storage_type, [7, 4], 3).rows.should == 7
275
- NMatrix.new(storage_type, [7, 4], 3).cols.should == 4
282
+ NMatrix.new([7, 4], 3, stype: storage_type).rows.should == 7
283
+ NMatrix.new([7, 4], 3, stype: storage_type).cols.should == 4
276
284
  end
277
285
  end unless storage_type == :yale
278
286
  end
@@ -280,7 +288,7 @@ describe NMatrix do
280
288
 
281
289
  it "handles dense construction" do
282
290
  NMatrix.new(3,0)[1,1].should == 0
283
- lambda { NMatrix.new(3,:int8)[1,1] }.should_not raise_error
291
+ lambda { NMatrix.new(3,dtype: :int8)[1,1] }.should_not raise_error
284
292
  end
285
293
 
286
294
  it "calculates the complex conjugate in-place" do
@@ -290,14 +298,15 @@ describe NMatrix do
290
298
  end
291
299
 
292
300
  it "converts from list to yale properly" do
293
- m = NMatrix.new(:list, 3, 0)
301
+ m = NMatrix.new(3, 0, stype: :list)
294
302
  m[0,2] = 333
295
303
  m[2,2] = 777
296
304
  n = m.cast(:yale, :int32)
297
- puts n.capacity
298
- n.extend NMatrix::YaleFunctions
299
- puts n.yale_ija.inspect
300
- puts n.yale_a.inspect
305
+ #puts n.capacity
306
+ #n.extend NMatrix::YaleFunctions
307
+ #puts n.yale_ija.inspect
308
+ #puts n.yale_a.inspect
309
+
301
310
  n[0,0].should == 0
302
311
  n[0,1].should == 0
303
312
  n[0,2].should == 333
@@ -338,13 +347,13 @@ describe NMatrix do
338
347
  [:list, :yale].each do |storage_type|
339
348
  context storage_type do
340
349
  it "should return the matrix being iterated over when each_stored_with_indices is called with a block" do
341
- n = NMatrix.new(storage_type, [2,3], storage_type == :yale ? :float64 : 1.1)
350
+ n = NMatrix.new([2,3], 1.1, stype: storage_type, dtype: :float64, default: 0)
342
351
  val = (n.each_stored_with_indices { })
343
352
  val.should eq n
344
353
  end
345
354
 
346
355
  it "should return an enumerator when each_stored_with_indices is called without a block" do
347
- n = NMatrix.new(storage_type, [2,3], storage_type == :yale ? :float64 : 1.1)
356
+ n = NMatrix.new([2,3], 1.1, stype: storage_type, dtype: :float64, default: 0)
348
357
  val = n.each_stored_with_indices
349
358
  val.should be_a Enumerator
350
359
  end
@@ -357,176 +366,4 @@ describe NMatrix do
357
366
  t.each { |x| x + 0 }
358
367
  end
359
368
 
360
- context "mapping and reduction related functions" do
361
-
362
- before :each do
363
- @nm_1d = NMatrix[5.0,0.0,1.0,2.0,3.0]
364
- @nm_2d = NMatrix[[0.0,1.0],[2.0,3.0]]
365
- end
366
-
367
- it "behaves like Enumerable#reduce with no argument to reduce" do
368
- @nm_1d.reduce_along_dim(0) { |acc, el| acc + el }.to_f.should eq 11
369
- @nm_2d.reduce_along_dim(1) { |acc, el| acc + el }.should eq NMatrix[[1, 5]]
370
- end
371
-
372
- it "should calculate the mean along the specified dimension" do
373
- @nm_1d.mean.should eq NMatrix[2.2]
374
- @nm_2d.mean.should eq NMatrix[[1.0,2.0]]
375
- end
376
-
377
- it "should calculate the minimum along the specified dimension" do
378
- @nm_1d.min.should eq 0.0
379
- @nm_2d.min.should eq NMatrix[[0.0, 1.0]]
380
- @nm_2d.min(1).should eq NMatrix[[0.0], [2.0]]
381
- end
382
-
383
- it "should calculate the maximum along the specified dimension" do
384
- @nm_1d.max.should eq 5.0
385
- @nm_2d.max.should eq NMatrix[[2.0, 3.0]]
386
- end
387
-
388
- it "should calculate the variance along the specified dimension" do
389
- @nm_1d.variance.should eq NMatrix[3.7]
390
- @nm_2d.variance(1).should eq NMatrix[[0.5], [0.5]]
391
- end
392
-
393
- it "should calculate the sum along the specified dimension" do
394
- @nm_1d.sum.should eq NMatrix[11]
395
- @nm_2d.sum.should eq NMatrix[[2], [4]]
396
- end
397
-
398
- it "should calculate the standard deviation along the specified dimension" do
399
- @nm_1d.std.should eq NMatrix[Math.sqrt(3.7)]
400
- @nm_2d.std(1).should eq NMatrix[[Math.sqrt(0.5)], [Math.sqrt(0.5)]]
401
- end
402
-
403
- it "should raise an ArgumentError when any invalid dimension is provided" do
404
- expect { @nm_1d.mean(3) }.to raise_exception(RangeError)
405
- end
406
-
407
- it "should convert to float if it contains only a single element" do
408
- NMatrix[4.0].to_f.should eq 4.0
409
- NMatrix[[[[4.0]]]].to_f.should eq 4.0
410
- end
411
-
412
- it "should raise an index error if it contains more than a single element" do
413
- expect { @nm_1d.to_f }.to raise_error(IndexError)
414
- end
415
-
416
- it "should map a block to all elements" do
417
- @nm_1d.map { |e| e ** 2 }.should eq NMatrix[25.0,0.0,1.0,4.0,9.0]
418
- @nm_2d.map { |e| e ** 2 }.should eq NMatrix[[0.0,1.0],[4.0,9.0]]
419
- end
420
-
421
- it "should map! a block to all elements in place" do
422
- fct = Proc.new { |e| e ** 2 }
423
- expected1 = @nm_1d.map &fct
424
- expected2 = @nm_2d.map &fct
425
- @nm_1d.map! &fct
426
- @nm_1d.should eq expected1
427
- @nm_2d.map! &fct
428
- @nm_2d.should eq expected2
429
- end
430
-
431
- it "should return an enumerator for map without a block" do
432
- @nm_1d.map.should be_a Enumerator
433
- end
434
-
435
- it "should return an enumerator for reduce without a block" do
436
- @nm_1d.reduce_along_dim(0).should be_a Enumerator
437
- end
438
-
439
- it "should return an enumerator for each_along_dim without a block" do
440
- @nm_1d.each_along_dim(0).should be_a Enumerator
441
- end
442
-
443
- it "should iterate correctly for map without a block" do
444
- en = @nm_1d.map
445
- en.each { |e| e**2 }.should eq @nm_1d.map { |e| e**2 }
446
- en = @nm_2d.map
447
- en.each { |e| e**2 }.should eq @nm_2d.map { |e| e**2 }
448
- end
449
-
450
- it "should iterate correctly for reduce without a block" do
451
- en = @nm_1d.reduce_along_dim(0, 1.0)
452
- en.each { |a, e| a+e }.to_f.should eq 12
453
- en = @nm_2d.reduce_along_dim(1, 1.0)
454
- en.each { |a, e| a+e }.should eq NMatrix[[2.0],[6.0]]
455
- end
456
-
457
- it "should iterate correctly for each_along_dim without a block" do
458
- res = NMatrix.zeros_like(@nm_1d[0...1])
459
- en = @nm_1d.each_along_dim(0)
460
- en.each { |e| res += e }
461
- res.to_f.should eq 11
462
-
463
- res = NMatrix.zeros_like (@nm_2d[0...2, 0])
464
- en = @nm_2d.each_along_dim(1)
465
- en.each { |e| res += e }
466
- res.should eq NMatrix[[1.0], [5.0]]
467
- end
468
-
469
- it "should yield matrices of matching dtype for each_along_dim" do
470
- m = NMatrix.new([2,3], [1,2,3,3,4,5], :complex128)
471
- m.each_along_dim(1) do |sub_m|
472
- sub_m.dtype.should eq :complex128
473
- end
474
- end
475
-
476
- it "should reduce to a matrix of matching dtype for reduce_along_dim" do
477
- m = NMatrix.new([2,3], [1,2,3,3,4,5], :complex128)
478
- m.reduce_along_dim(1) do |acc, sub_m|
479
- sub_m.dtype.should eq :complex128
480
- acc
481
- end
482
-
483
- m = NMatrix.new([2,3], [1,2,3,3,4,5], :complex128)
484
- m.reduce_along_dim(1, 0.0) do |acc, sub_m|
485
- sub_m.dtype.should eq :complex128
486
- acc
487
- end
488
- end
489
-
490
- it "should allow overriding the dtype for reduce_along_dim" do
491
- m = NMatrix[[1,2,3], [3,4,5], :complex128]
492
- m.reduce_along_dim(1, 0.0, :float64) do |acc, sub_m|
493
- acc.dtype.should eq :float64
494
- acc
495
- end
496
-
497
- m = NMatrix[[1,2,3], [3,4,5], :complex128]
498
- m.reduce_along_dim(1, nil, :float64) do |acc, sub_m|
499
- acc.dtype.should eq :float64
500
- acc
501
- end
502
- end
503
-
504
- it "should convert integer dtypes to float when calculating mean" do
505
- m = NMatrix[[1,2,3], [3,4,5], :int32]
506
- m.mean(0).dtype.should eq :float64
507
- end
508
-
509
- it "should convert integer dtypes to float when calculating variance" do
510
- m = NMatrix[[1,2,3], [3,4,5], :int32]
511
- m.variance(0).dtype.should eq :float64
512
- end
513
-
514
- it "should convert integer dtypes to float when calculating standard deviation" do
515
- m = NMatrix[[1,2,3], [3,4,5], :int32]
516
- m.std(0).dtype.should eq :float64
517
- end
518
-
519
- context "_like constructors" do
520
-
521
- it "should create an nmatrix of ones with dimensions and type the same as its argument" do
522
- NMatrix.ones_like(@nm_1d).should eq NMatrix[1.0, 1.0, 1.0, 1.0, 1.0]
523
- NMatrix.ones_like(@nm_2d).should eq NMatrix[[1.0, 1.0], [1.0, 1.0]]
524
- end
525
-
526
- it "should create an nmatrix of zeros with dimensions and type the same as its argument" do
527
- NMatrix.zeros_like(@nm_1d).should eq NMatrix[0.0, 0.0, 0.0, 0.0, 0.0]
528
- NMatrix.zeros_like(@nm_2d).should eq NMatrix[[0.0, 0.0], [0.0, 0.0]]
529
- end
530
- end
531
- end
532
369
  end
@@ -0,0 +1,184 @@
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
+ # == 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
+
29
+ require File.dirname(__FILE__) + "/spec_helper.rb"
30
+
31
+ describe "NMatrix enumeration for" do
32
+ [:dense, :yale, :list].each do |stype|
33
+ context stype do
34
+
35
+ before :each do
36
+ @n = create_rectangular_matrix(stype)
37
+ @m = @n[1..4,1..3]
38
+ end
39
+
40
+ if stype == :yale
41
+ it "should iterate properly along each row of a slice" do
42
+ vv = []
43
+ ii = []
44
+ jj = []
45
+ @m.extend NMatrix::YaleFunctions
46
+ @m.each_row do |row|
47
+ row.each_with_indices do |v,i,j|
48
+ vv << v
49
+ ii << i
50
+ jj << j
51
+ end
52
+ end
53
+
54
+ vv.should == [7,8,9, 12,13,0, 0,0,0, 0,17,18]
55
+ ii.should == [0]*12
56
+ jj.should == [0,1,2]*4
57
+ end
58
+
59
+ it "should iterate along diagonal portion of A array" do
60
+ vv = []
61
+ ii = []
62
+ jj = []
63
+ @n.send :__yale_stored_diagonal_each_with_indices__ do |v,i,j|
64
+ vv << v
65
+ ii << i
66
+ jj << j
67
+ end
68
+ vv.should == [1,7,13,0,19]
69
+ ii.should == [0,1,2,3,4]
70
+ jj.should == ii
71
+ end
72
+
73
+ it "should iterate along non-diagonal portion of A array" do
74
+ vv = []
75
+ ii = []
76
+ jj = []
77
+ @n.send :__yale_stored_nondiagonal_each_with_indices__ do |v,i,j|
78
+ vv << v
79
+ ii << i
80
+ jj << j
81
+ end
82
+
83
+ vv.should == [2,3,4,5, 6,8,9,10, 11,12,14,15, 16,17,18,20]
84
+ ii.should == [[0]*4, [1]*4, [2]*4, [4]*4].flatten
85
+ jj.should == [1,2,3,4, 0,2,3,5, 0,1,4,5, 0,2,3,5]
86
+ end
87
+
88
+ it "should iterate along a sliced diagonal portion of an A array" do
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
+ vv.should == [7,13,0]
99
+ ii.should == [1,2,3]
100
+ jj.should == [0,1,2]
101
+ end
102
+
103
+ it "should iterate along a sliced non-diagonal portion of a sliced A array" do
104
+ vv = []
105
+ ii = []
106
+ jj = []
107
+ @n.extend NMatrix::YaleFunctions
108
+ @m.extend NMatrix::YaleFunctions
109
+ @m.send :__yale_stored_nondiagonal_each_with_indices__ do |v,i,j|
110
+ vv << v
111
+ ii << i
112
+ jj << j
113
+ end
114
+
115
+ ii.should == [0,0, 1, 3,3 ]
116
+ jj.should == [1,2, 0, 1,2 ]
117
+ vv.should == [8,9, 12, 17,18]
118
+ end
119
+
120
+ it "should visit each stored element of the matrix in order by indices" do
121
+ vv = []
122
+ ii = []
123
+ jj = []
124
+ @n.each_ordered_stored_with_indices do |v,i,j|
125
+ vv << v
126
+ ii << i
127
+ jj << j
128
+ end
129
+
130
+ vv.should == [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 16, 17, 18, 19, 20]
131
+ ii.should == [[0]*5, [1]*5, [2]*5, [3]*1, [4]*5].flatten
132
+ jj.should == [0,1,2,3,4, 0,1,2,3,5, 0,1,2,4,5, 3, 0,2,3,4,5]
133
+ end
134
+
135
+ it "should visit each stored element of the slice in order by indices" do
136
+
137
+ vv = []
138
+ ii = []
139
+ jj = []
140
+ @m.each_ordered_stored_with_indices do |v,i,j|
141
+ vv << v
142
+ ii << i
143
+ jj << j
144
+ end
145
+ ii.should == [0,0,0, 1,1, 2, 3,3 ]
146
+ jj.should == [0,1,2, 0,1, 2, 1,2 ]
147
+ vv.should == [7,8,9, 12,13, 0, 17,18 ]
148
+ end
149
+ end
150
+
151
+ it "should visit each cell in the matrix as if dense, making indices available" do
152
+ vv = []
153
+ ii = []
154
+ jj = []
155
+ @n.each_with_indices do |v,i,j|
156
+ vv << v
157
+ ii << i
158
+ jj << j
159
+ end
160
+
161
+ vv.should == [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]
162
+ ii.should == [[0]*6, [1]*6, [2]*6, [3]*6, [4]*6].flatten
163
+ jj.should == [0,1,2,3,4,5]*5
164
+ end
165
+
166
+ it "should visit each cell in the slice as if dense, making indices available" do
167
+ vv = []
168
+ ii = []
169
+ jj = []
170
+ @m.each_with_indices do |v,i,j|
171
+ vv << v
172
+ ii << i
173
+ jj << j
174
+ end
175
+ jj.should == [0,1,2]*4
176
+ ii.should == [[0]*3, [1]*3, [2]*3, [3]*3].flatten
177
+ vv.should == [7,8,9,12,13,0,0,0,0,0,17,18]
178
+
179
+ end
180
+
181
+
182
+ end
183
+ end
184
+ end