nmatrix 0.0.9 → 0.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/History.txt +95 -1
  4. data/LICENSE.txt +2 -2
  5. data/README.rdoc +24 -26
  6. data/Rakefile +32 -16
  7. data/ext/nmatrix/data/complex.h +2 -2
  8. data/ext/nmatrix/data/data.cpp +27 -51
  9. data/ext/nmatrix/data/data.h +92 -4
  10. data/ext/nmatrix/data/meta.h +2 -2
  11. data/ext/nmatrix/data/rational.h +2 -2
  12. data/ext/nmatrix/data/ruby_object.h +2 -2
  13. data/ext/nmatrix/extconf.rb +87 -86
  14. data/ext/nmatrix/math.cpp +45 -40
  15. data/ext/nmatrix/math/asum.h +3 -3
  16. data/ext/nmatrix/math/geev.h +2 -2
  17. data/ext/nmatrix/math/gemm.h +6 -2
  18. data/ext/nmatrix/math/gemv.h +6 -2
  19. data/ext/nmatrix/math/ger.h +2 -2
  20. data/ext/nmatrix/math/gesdd.h +2 -2
  21. data/ext/nmatrix/math/gesvd.h +2 -2
  22. data/ext/nmatrix/math/getf2.h +2 -2
  23. data/ext/nmatrix/math/getrf.h +2 -2
  24. data/ext/nmatrix/math/getri.h +2 -2
  25. data/ext/nmatrix/math/getrs.h +7 -3
  26. data/ext/nmatrix/math/idamax.h +2 -2
  27. data/ext/nmatrix/math/inc.h +12 -6
  28. data/ext/nmatrix/math/laswp.h +2 -2
  29. data/ext/nmatrix/math/long_dtype.h +2 -2
  30. data/ext/nmatrix/math/math.h +16 -10
  31. data/ext/nmatrix/math/nrm2.h +3 -3
  32. data/ext/nmatrix/math/potrs.h +7 -3
  33. data/ext/nmatrix/math/rot.h +2 -2
  34. data/ext/nmatrix/math/rotg.h +2 -2
  35. data/ext/nmatrix/math/scal.h +2 -2
  36. data/ext/nmatrix/math/swap.h +2 -2
  37. data/ext/nmatrix/math/trsm.h +7 -3
  38. data/ext/nmatrix/nm_memory.h +60 -0
  39. data/ext/nmatrix/nmatrix.cpp +13 -47
  40. data/ext/nmatrix/nmatrix.h +37 -12
  41. data/ext/nmatrix/ruby_constants.cpp +4 -2
  42. data/ext/nmatrix/ruby_constants.h +4 -2
  43. data/ext/nmatrix/ruby_nmatrix.c +937 -170
  44. data/ext/nmatrix/storage/common.cpp +2 -2
  45. data/ext/nmatrix/storage/common.h +2 -2
  46. data/ext/nmatrix/storage/{dense.cpp → dense/dense.cpp} +253 -100
  47. data/ext/nmatrix/storage/{dense.h → dense/dense.h} +6 -5
  48. data/ext/nmatrix/storage/{list.cpp → list/list.cpp} +517 -98
  49. data/ext/nmatrix/storage/{list.h → list/list.h} +13 -6
  50. data/ext/nmatrix/storage/storage.cpp +48 -19
  51. data/ext/nmatrix/storage/storage.h +4 -4
  52. data/ext/nmatrix/storage/yale/class.h +112 -43
  53. data/ext/nmatrix/storage/yale/iterators/base.h +2 -2
  54. data/ext/nmatrix/storage/yale/iterators/iterator.h +2 -2
  55. data/ext/nmatrix/storage/yale/iterators/row.h +2 -2
  56. data/ext/nmatrix/storage/yale/iterators/row_stored.h +2 -2
  57. data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +4 -3
  58. data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +2 -2
  59. data/ext/nmatrix/storage/yale/math/transpose.h +2 -2
  60. data/ext/nmatrix/storage/yale/yale.cpp +343 -52
  61. data/ext/nmatrix/storage/yale/yale.h +7 -3
  62. data/ext/nmatrix/types.h +2 -2
  63. data/ext/nmatrix/util/io.cpp +5 -5
  64. data/ext/nmatrix/util/io.h +2 -2
  65. data/ext/nmatrix/util/sl_list.cpp +40 -27
  66. data/ext/nmatrix/util/sl_list.h +3 -3
  67. data/ext/nmatrix/util/util.h +2 -2
  68. data/lib/nmatrix.rb +2 -2
  69. data/lib/nmatrix/blas.rb +2 -2
  70. data/lib/nmatrix/enumerate.rb +17 -6
  71. data/lib/nmatrix/io/market.rb +2 -3
  72. data/lib/nmatrix/io/mat5_reader.rb +2 -2
  73. data/lib/nmatrix/io/mat_reader.rb +2 -2
  74. data/lib/nmatrix/lapack.rb +46 -46
  75. data/lib/nmatrix/math.rb +213 -20
  76. data/lib/nmatrix/monkeys.rb +24 -2
  77. data/lib/nmatrix/nmatrix.rb +394 -9
  78. data/lib/nmatrix/nvector.rb +2 -64
  79. data/lib/nmatrix/rspec.rb +2 -2
  80. data/lib/nmatrix/shortcuts.rb +14 -61
  81. data/lib/nmatrix/version.rb +11 -3
  82. data/lib/nmatrix/yale_functions.rb +4 -4
  83. data/nmatrix.gemspec +2 -7
  84. data/scripts/mac-brew-gcc.sh +11 -8
  85. data/scripts/mac-mavericks-brew-gcc.sh +22 -0
  86. data/spec/00_nmatrix_spec.rb +116 -7
  87. data/spec/01_enum_spec.rb +17 -3
  88. data/spec/02_slice_spec.rb +11 -3
  89. data/spec/blas_spec.rb +5 -2
  90. data/spec/elementwise_spec.rb +5 -2
  91. data/spec/io_spec.rb +27 -17
  92. data/spec/lapack_spec.rb +157 -9
  93. data/spec/math_spec.rb +95 -4
  94. data/spec/nmatrix_yale_spec.rb +21 -26
  95. data/spec/rspec_monkeys.rb +27 -0
  96. data/spec/rspec_spec.rb +2 -2
  97. data/spec/shortcuts_spec.rb +5 -10
  98. data/spec/slice_set_spec.rb +6 -2
  99. data/spec/spec_helper.rb +3 -2
  100. data/spec/stat_spec.rb +174 -158
  101. metadata +15 -15
data/spec/math_spec.rb CHANGED
@@ -8,8 +8,8 @@
8
8
  #
9
9
  # == Copyright Information
10
10
  #
11
- # SciRuby is Copyright (c) 2010 - 2012, Ruby Science Foundation
12
- # NMatrix is Copyright (c) 2012, Ruby Science Foundation
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
13
  #
14
14
  # Please see LICENSE.txt for additional copyright notices.
15
15
  #
@@ -26,10 +26,101 @@
26
26
  # versions of unfriendly BLAS and LAPACK functions.
27
27
  #
28
28
 
29
- # Can we use require_relative here instead?
30
- require File.join(File.dirname(__FILE__), "spec_helper.rb")
29
+ require 'spec_helper'
31
30
 
32
31
  describe "math" do
32
+ #after :each do
33
+ # GC.start
34
+ #end
35
+
36
+ context "elementwise math functions" do
37
+
38
+ [:dense,:list,:yale].each do |stype|
39
+ context stype do
40
+
41
+ [:int64,:float64,:rational128].each do |dtype|
42
+ context dtype do
43
+ before :each do
44
+ @size = [2,2]
45
+ @m = NMatrix.seq(@size, dtype: dtype, stype: stype)+1
46
+ @a = @m.to_a.flatten
47
+ end
48
+
49
+ NMatrix::NMMath::METHODS_ARITY_1.each do |meth|
50
+ #skip inverse regular trig functions
51
+ next if meth.to_s.start_with?('a') and (not meth.to_s.end_with?('h')) \
52
+ and NMatrix::NMMath::METHODS_ARITY_1.include?(
53
+ meth.to_s[1...meth.to_s.length].to_sym)
54
+ next if meth == :atanh
55
+
56
+ it "should correctly apply elementwise #{meth}" do
57
+
58
+ @m.send(meth).should eq N.new(@size, @a.map{ |e| Math.send(meth, e) },
59
+ dtype: :float64, stype: stype)
60
+ end
61
+ end
62
+
63
+ NMatrix::NMMath::METHODS_ARITY_2.each do |meth|
64
+ next if meth == :atan2
65
+ it "should correctly apply elementwise #{meth}" do
66
+ @m.send(meth, @m).should eq N.new(@size, @a.map{ |e|
67
+ Math.send(meth, e, e) },
68
+ dtype: :float64,
69
+ stype: stype)
70
+ end
71
+
72
+ it "should correctly apply elementwise #{meth} with a scalar first arg" do
73
+ Math.send(meth, 1, @m).should eq N.new(@size, @a.map { |e| Math.send(meth, 1, e) }, dtype: :float64, stype: stype)
74
+ end
75
+
76
+ it "should correctly apply elementwise #{meth} with a scalar second arg" do
77
+ @m.send(meth, 1).should eq N.new(@size, @a.map { |e| Math.send(meth, e, 1) }, dtype: :float64, stype: stype)
78
+ end
79
+ end
80
+
81
+ it "should correctly apply elementwise natural log" do
82
+ @m.log.should eq N.new(@size, [0, Math.log(2), Math.log(3), Math.log(4)],
83
+ dtype: :float64, stype: stype)
84
+ end
85
+
86
+ it "should correctly apply elementwise log with arbitrary base" do
87
+ @m.log(3).should eq N.new(@size, [0, Math.log(2,3), 1, Math.log(4,3)],
88
+ dtype: :float64, stype: stype)
89
+ end
90
+
91
+ context "inverse trig functions" do
92
+ before :each do
93
+ @m = NMatrix.seq(@size, dtype: dtype, stype: stype)/4
94
+ @a = @m.to_a.flatten
95
+ end
96
+ [:asin, :acos, :atan, :atanh].each do |atf|
97
+
98
+ it "should correctly apply elementwise #{atf}" do
99
+ @m.send(atf).should eq N.new(@size,
100
+ @a.map{ |e| Math.send(atf, e) },
101
+ dtype: :float64, stype: stype)
102
+ end
103
+ end
104
+
105
+ it "should correctly apply elementtwise atan2" do
106
+ @m.atan2(@m*0+1).should eq N.new(@size,
107
+ @a.map { |e| Math.send(:atan2, e, 1) }, dtype: :float64, stype: stype)
108
+ end
109
+
110
+ it "should correctly apply elementwise atan2 with a scalar first arg" do
111
+ Math.atan2(1, @m).should eq N.new(@size, @a.map { |e| Math.send(:atan2, 1, e) }, dtype: :float64, stype: stype)
112
+ end
113
+
114
+ it "should correctly apply elementwise atan2 with a scalar second arg" do
115
+ @m.atan2(1).should eq N.new(@size, @a.map { |e| Math.send(:atan2, e, 1) }, dtype: :float64, stype: stype)
116
+ end
117
+ end
118
+ end
119
+ end
120
+
121
+ end
122
+ end
123
+ end
33
124
 
34
125
  [:float32, :float64, :complex64, :complex128, :rational32, :rational64, :rational128].each do |dtype|
35
126
  context dtype do
@@ -8,8 +8,8 @@
8
8
  #
9
9
  # == Copyright Information
10
10
  #
11
- # SciRuby is Copyright (c) 2010 - 2012, Ruby Science Foundation
12
- # NMatrix is Copyright (c) 2012, Ruby Science Foundation
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
13
  #
14
14
  # Please see LICENSE.txt for additional copyright notices.
15
15
  #
@@ -27,6 +27,10 @@
27
27
  require "./lib/nmatrix"
28
28
 
29
29
  describe NMatrix do
30
+ #after :each do
31
+ # GC.start
32
+ #end
33
+
30
34
  context :yale do
31
35
 
32
36
  it "compares two empty matrices" do
@@ -106,8 +110,8 @@ describe NMatrix do
106
110
  n[0,0] = 0.1
107
111
  n[0,1] = 0.2
108
112
  n[1,0] = 0.3
109
- n.yale_a == [0.1, 0.0, 0.0, 0.2, 0.3]
110
- n.yale_ija == [3,4,5,1,0]
113
+ n.yale_a.should == [0.1, 0.0, 0.0, 0.2, 0.3]
114
+ n.yale_ija.should == [3,4,5,1,0]
111
115
  end
112
116
 
113
117
  it "sets when resizing" do
@@ -267,28 +271,19 @@ describe NMatrix do
267
271
  mn[0,0].should == 541
268
272
  end
269
273
 
270
- it "transposes" do
271
- a = NMatrix.new(4, 0.0, stype: :yale)
272
- a[0,0] = 1.0
273
- a[0,1] = 4.0
274
- a[1,2] = 2.0
275
- a[1,3] = -4.0
276
- a[3,1] = 5.0
277
- a[3,3] = 6.0
278
- b = a.transpose
279
-
280
- b[0,0].should == 1.0
281
- b[1,0].should == 4.0
282
- b[2,0].should == 0.0
283
- b[3,0].should == 0.0
284
- b[0,1].should == 0.0
285
- b[1,1].should == 0.0
286
- b[2,1].should == 2.0
287
- b[3,1].should == -4.0
288
- b[0,3].should == 0.0
289
- b[1,3].should == 5.0
290
- b[2,3].should == 0.0
291
- b[3,3].should == 6.0
274
+ it "calculates the row key intersections of two matrices" do
275
+ a = NMatrix.new([3,9], [0,1], stype: :yale, dtype: :byte, default: 0)
276
+ b = NMatrix.new([3,9], [0,0,1,0,1], stype: :yale, dtype: :byte, default: 0)
277
+ a.extend NMatrix::YaleFunctions
278
+ b.extend NMatrix::YaleFunctions
279
+
280
+ (0...3).each do |ai|
281
+ (0...3).each do |bi|
282
+ STDERR.puts (a.yale_ja_d_keys_at(ai) & b.yale_ja_d_keys_at(bi)).inspect
283
+ (a.yale_ja_d_keys_at(ai) & b.yale_ja_d_keys_at(bi)).should == a.yale_row_keys_intersection(ai, b, bi)
284
+ end
285
+ end
286
+
292
287
  end
293
288
  end
294
289
  end
@@ -1,3 +1,30 @@
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
+ # == rspec_monkeys.rb
24
+ #
25
+ # A set of monkey patches for RSpec allowing checks of NMatrix types
26
+ #
27
+
1
28
  module RSpec::Matchers::BuiltIn
2
29
  class BeWithin
3
30
 
data/spec/rspec_spec.rb CHANGED
@@ -8,8 +8,8 @@
8
8
  #
9
9
  # == Copyright Information
10
10
  #
11
- # SciRuby is Copyright (c) 2010 - 2012, Ruby Science Foundation
12
- # NMatrix is Copyright (c) 2012, Ruby Science Foundation
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
13
  #
14
14
  # Please see LICENSE.txt for additional copyright notices.
15
15
  #
@@ -8,8 +8,8 @@
8
8
  #
9
9
  # == Copyright Information
10
10
  #
11
- # SciRuby is Copyright (c) 2010 - 2012, Ruby Science Foundation
12
- # NMatrix is Copyright (c) 2012, Ruby Science Foundation
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
13
  #
14
14
  # Please see LICENSE.txt for additional copyright notices.
15
15
  #
@@ -30,6 +30,9 @@ require File.join(File.dirname(__FILE__), "spec_helper.rb")
30
30
  require 'pry'
31
31
 
32
32
  describe NMatrix do
33
+ #after :each do
34
+ # GC.start
35
+ #end
33
36
 
34
37
  it "zeros() creates a matrix of zeros" do
35
38
  m = NMatrix.zeros(3)
@@ -175,13 +178,8 @@ describe NMatrix do
175
178
 
176
179
  context "_like constructors" do
177
180
  before :each do
178
- STDERR.puts "starting GC"
179
- GC.start
180
- STDERR.puts "GC finished"
181
181
  @nm_1d = NMatrix[5.0,0.0,1.0,2.0,3.0]
182
- STDERR.puts "@nm_1d"
183
182
  @nm_2d = NMatrix[[0.0,1.0],[2.0,3.0]]
184
- STDERR.puts "@nm_2d"
185
183
  end
186
184
 
187
185
  it "should create an nmatrix of ones with dimensions and type the same as its argument" do
@@ -190,11 +188,8 @@ describe NMatrix do
190
188
  end
191
189
 
192
190
  it "should create an nmatrix of zeros with dimensions and type the same as its argument" do
193
- STDERR.puts "A"
194
191
  NMatrix.zeros_like(@nm_1d).should eq NMatrix[0.0, 0.0, 0.0, 0.0, 0.0]
195
- STDERR.puts "B"
196
192
  NMatrix.zeros_like(@nm_2d).should eq NMatrix[[0.0, 0.0], [0.0, 0.0]]
197
- STDERR.puts "C"
198
193
  end
199
194
  end
200
195
 
@@ -8,8 +8,8 @@
8
8
  #
9
9
  # == Copyright Information
10
10
  #
11
- # SciRuby is Copyright (c) 2010 - 2012, Ruby Science Foundation
12
- # NMatrix is Copyright (c) 2012, Ruby Science Foundation
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
13
  #
14
14
  # Please see LICENSE.txt for additional copyright notices.
15
15
  #
@@ -30,6 +30,10 @@ require File.dirname(__FILE__) + "/spec_helper.rb"
30
30
  describe "Set slice operation" do
31
31
  include RSpec::Longrun::DSL
32
32
 
33
+ #after :each do
34
+ # GC.start
35
+ #end
36
+
33
37
  [:dense, :yale, :list].each do |stype|
34
38
  context "for #{stype}" do
35
39
  before :each do
data/spec/spec_helper.rb CHANGED
@@ -8,8 +8,8 @@
8
8
  #
9
9
  # == Copyright Information
10
10
  #
11
- # SciRuby is Copyright (c) 2010 - 2012, Ruby Science Foundation
12
- # NMatrix is Copyright (c) 2012, Ruby Science Foundation
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
13
  #
14
14
  # Please see LICENSE.txt for additional copyright notices.
15
15
  #
@@ -25,6 +25,7 @@
25
25
  # Common data and helper functions for testing.
26
26
 
27
27
  require "rspec/longrun"
28
+ #require "narray/narray"
28
29
 
29
30
  require "./lib/nmatrix"
30
31
  require "./lib/nmatrix/rspec"
data/spec/stat_spec.rb CHANGED
@@ -8,8 +8,8 @@
8
8
  #
9
9
  # == Copyright Information
10
10
  #
11
- # SciRuby is Copyright (c) 2010 - 2012, Ruby Science Foundation
12
- # NMatrix is Copyright (c) 2012, Ruby Science Foundation
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
13
  #
14
14
  # Please see LICENSE.txt for additional copyright notices.
15
15
  #
@@ -31,162 +31,178 @@ require 'pry'
31
31
 
32
32
  describe "Statistical functions" do
33
33
  context "mapping and reduction related functions" do
34
-
35
- before :each do
36
- @nm_1d = NMatrix[5.0,0.0,1.0,2.0,3.0]
37
- @nm_2d = NMatrix[[0.0,1.0],[2.0,3.0]]
38
- end
39
-
40
- it "behaves like Enumerable#reduce with no argument to reduce" do
41
- @nm_1d.reduce_along_dim(0) { |acc, el| acc + el }.to_f.should eq 11
42
- @nm_2d.reduce_along_dim(1) { |acc, el| acc + el }.should eq NMatrix[[1, 5]]
43
- end
44
-
45
- it "should calculate the mean along the specified dimension" do
46
- @nm_1d.mean.should eq NMatrix[2.2]
47
- @nm_2d.mean.should eq NMatrix[[1.0,2.0]]
48
- end
49
-
50
- it "should calculate the minimum along the specified dimension" do
51
- @nm_1d.min.should eq 0.0
52
- @nm_2d.min.should eq NMatrix[[0.0, 1.0]]
53
- @nm_2d.min(1).should eq NMatrix[[0.0], [2.0]]
54
- end
55
-
56
- it "should calculate the maximum along the specified dimension" do
57
- @nm_1d.max.should eq 5.0
58
- @nm_2d.max.should eq NMatrix[[2.0, 3.0]]
59
- end
60
-
61
- it "should calculate the variance along the specified dimension" do
62
- @nm_1d.variance.should eq NMatrix[3.7]
63
- @nm_2d.variance(1).should eq NMatrix[[0.5], [0.5]]
64
- end
65
-
66
- it "should calculate the sum along the specified dimension" do
67
- @nm_1d.sum.should eq NMatrix[11]
68
- @nm_2d.sum.should eq NMatrix[[2], [4]]
69
- end
70
-
71
- it "should calculate the standard deviation along the specified dimension" do
72
- @nm_1d.std.should eq NMatrix[Math.sqrt(3.7)]
73
- @nm_2d.std(1).should eq NMatrix[[Math.sqrt(0.5)], [Math.sqrt(0.5)]]
74
- end
75
-
76
- it "should raise an ArgumentError when any invalid dimension is provided" do
77
- expect { @nm_1d.mean(3) }.to raise_exception(RangeError)
78
- end
79
-
80
- it "should convert to float if it contains only a single element" do
81
- NMatrix[4.0].to_f.should eq 4.0
82
- NMatrix[[[[4.0]]]].to_f.should eq 4.0
83
- end
84
-
85
- it "should raise an index error if it contains more than a single element" do
86
- expect { @nm_1d.to_f }.to raise_error(IndexError)
87
- end
88
-
89
- it "should map a block to all elements" do
90
- @nm_1d.map { |e| e ** 2 }.should eq NMatrix[25.0,0.0,1.0,4.0,9.0]
91
- @nm_2d.map { |e| e ** 2 }.should eq NMatrix[[0.0,1.0],[4.0,9.0]]
92
- end
93
-
94
- it "should map! a block to all elements in place" do
95
- fct = Proc.new { |e| e ** 2 }
96
- expected1 = @nm_1d.map &fct
97
- expected2 = @nm_2d.map &fct
98
- @nm_1d.map! &fct
99
- @nm_1d.should eq expected1
100
- @nm_2d.map! &fct
101
- @nm_2d.should eq expected2
102
- end
103
-
104
- it "should return an enumerator for map without a block" do
105
- @nm_1d.map.should be_a Enumerator
106
- end
107
-
108
- it "should return an enumerator for reduce without a block" do
109
- @nm_1d.reduce_along_dim(0).should be_a Enumerator
110
- end
111
-
112
- it "should return an enumerator for each_along_dim without a block" do
113
- @nm_1d.each_along_dim(0).should be_a Enumerator
114
- end
115
-
116
- it "should iterate correctly for map without a block" do
117
- en = @nm_1d.map
118
- en.each { |e| e**2 }.should eq @nm_1d.map { |e| e**2 }
119
- en = @nm_2d.map
120
- en.each { |e| e**2 }.should eq @nm_2d.map { |e| e**2 }
121
- end
122
-
123
- it "should iterate correctly for reduce without a block" do
124
- en = @nm_1d.reduce_along_dim(0, 1.0)
125
- en.each { |a, e| a+e }.to_f.should eq 12
126
- en = @nm_2d.reduce_along_dim(1, 1.0)
127
- en.each { |a, e| a+e }.should eq NMatrix[[2.0],[6.0]]
128
- end
129
-
130
- it "should iterate correctly for each_along_dim without a block" do
131
- res = NMatrix.zeros_like(@nm_1d[0...1])
132
- en = @nm_1d.each_along_dim(0)
133
- en.each { |e| res += e }
134
- res.to_f.should eq 11
135
-
136
- res = NMatrix.zeros_like (@nm_2d[0...2, 0])
137
- en = @nm_2d.each_along_dim(1)
138
- en.each { |e| res += e }
139
- res.should eq NMatrix[[1.0], [5.0]]
140
- end
141
-
142
- it "should yield matrices of matching dtype for each_along_dim" do
143
- m = NMatrix.new([2,3], [1,2,3,3,4,5], dtype: :complex128)
144
- m.each_along_dim(1) do |sub_m|
145
- sub_m.dtype.should eq :complex128
146
- end
147
- end
148
-
149
- it "should reduce to a matrix of matching dtype for reduce_along_dim" do
150
- m = NMatrix.new([2,3], [1,2,3,3,4,5], dtype: :complex128)
151
- m.reduce_along_dim(1) do |acc, sub_m|
152
- sub_m.dtype.should eq :complex128
153
- acc
154
- end
155
-
156
- m = NMatrix.new([2,3], [1,2,3,3,4,5], dtype: :complex128)
157
- m.reduce_along_dim(1, 0.0) do |acc, sub_m|
158
- sub_m.dtype.should eq :complex128
159
- acc
160
- end
161
- end
162
-
163
- it "should allow overriding the dtype for reduce_along_dim" do
164
- m = NMatrix[[1,2,3], [3,4,5], dtype: :complex128]
165
- m.reduce_along_dim(1, 0.0, :float64) do |acc, sub_m|
166
- acc.dtype.should eq :float64
167
- acc
168
- end
169
-
170
- m = NMatrix[[1,2,3], [3,4,5], dtype: :complex128]
171
- m.reduce_along_dim(1, nil, :float64) do |acc, sub_m|
172
- acc.dtype.should eq :float64
173
- acc
34
+ [:dense, :yale, :list].each do |stype|
35
+ context "on #{stype} matrices" do
36
+ before :each do
37
+ @nm_1d = NMatrix.new([5], [5.0,0.0,1.0,2.0,3.0], stype: stype) unless stype == :yale
38
+ @nm_2d = NMatrix.new([2,2], [0.0, 1.0, 2.0, 3.0], stype: stype)
39
+ end
40
+
41
+ it "behaves like Enumerable#reduce with no argument to reduce" do
42
+ @nm_1d.reduce_along_dim(0) { |acc, el| acc + el }.to_f.should eq 11 unless stype == :yale
43
+ @nm_2d.reduce_along_dim(1) { |acc, el| acc + el }.should eq NMatrix.new([2,1], [1.0, 5.0], stype: stype)
44
+ end
45
+
46
+ it "should calculate the mean along the specified dimension" do
47
+ unless stype == :yale then
48
+ puts @nm_1d.mean
49
+ @nm_1d.mean.should eq NMatrix.new([1], [2.2], stype: stype, dtype: :float64)
50
+ end
51
+ @nm_2d.mean.should eq NMatrix[[1.0,2.0], stype: stype]
52
+ @nm_2d.mean(1).should eq NMatrix[[0.5], [2.5], stype: stype]
53
+ end
54
+
55
+ it "should calculate the minimum along the specified dimension" do
56
+ @nm_1d.min.should eq 0.0 unless stype == :yale
57
+ @nm_2d.min.should eq NMatrix[[0.0, 1.0], stype: stype]
58
+ @nm_2d.min(1).should eq NMatrix[[0.0], [2.0], stype: stype]
59
+ end
60
+
61
+ it "should calculate the maximum along the specified dimension" do
62
+ @nm_1d.max.should eq 5.0 unless stype == :yale
63
+ @nm_2d.max.should eq NMatrix[[2.0, 3.0], stype: stype]
64
+ end
65
+
66
+ it "should calculate the variance along the specified dimension" do
67
+ @nm_1d.variance.should eq NMatrix[3.7, stype: stype] unless stype == :yale
68
+ @nm_2d.variance(1).should eq NMatrix[[0.5], [0.5], stype: stype]
69
+ end
70
+
71
+ it "should calculate the sum along the specified dimension" do
72
+ @nm_1d.sum.should eq NMatrix[11.0, stype: stype] unless stype == :yale
73
+ @nm_2d.sum.should eq NMatrix[[2.0, 4.0], stype: stype]
74
+ end
75
+
76
+ it "should calculate the standard deviation along the specified dimension" do
77
+ @nm_1d.std.should eq NMatrix[Math.sqrt(3.7), stype: stype] unless stype == :yale
78
+ @nm_2d.std(1).should eq NMatrix[[Math.sqrt(0.5)], [Math.sqrt(0.5)], stype: stype]
79
+ end
80
+
81
+ it "should raise an ArgumentError when any invalid dimension is provided" do
82
+ expect { @nm_1d.mean(3) }.to raise_exception(RangeError) unless stype == :yale
83
+ expect { @nm_2d.mean(3) }.to raise_exception(RangeError)
84
+ end
85
+
86
+ it "should convert to float if it contains only a single element" do
87
+ NMatrix[4.0, stype: stype].to_f.should eq 4.0 unless stype == :yale
88
+ NMatrix[[[[4.0]]], stype: stype].to_f.should eq 4.0 unless stype == :yale
89
+ NMatrix[[4.0], stype: stype].to_f.should eq 4.0
90
+ end
91
+
92
+ it "should raise an index error if it contains more than a single element" do
93
+ expect { @nm_1d.to_f }.to raise_error(IndexError) unless stype == :yale
94
+ expect { @nm_2d.to_f }.to raise_error(IndexError)
95
+ end
96
+
97
+ it "should map a block to all elements" do
98
+ #binding.pry if stype == :list
99
+ @nm_1d.map { |e| e ** 2 }.should eq NMatrix[25.0,0.0,1.0,4.0,9.0, stype: stype] unless stype == :yale
100
+ @nm_2d.map { |e| e ** 2 }.should eq NMatrix[[0.0,1.0],[4.0,9.0], stype: stype]
101
+ end
102
+
103
+ it "should map! a block to all elements in place" do
104
+ fct = Proc.new { |e| e ** 2 }
105
+ unless stype == :yale then
106
+ expected1 = @nm_1d.map &fct
107
+ @nm_1d.map! &fct
108
+ @nm_1d.should eq expected1
109
+ end
110
+ expected2 = @nm_2d.map &fct
111
+ @nm_2d.map! &fct
112
+ @nm_2d.should eq expected2
113
+ end
114
+
115
+ it "should return an enumerator for map without a block" do
116
+ @nm_2d.map.should be_a Enumerator
117
+ end
118
+
119
+ it "should return an enumerator for reduce without a block" do
120
+ @nm_2d.reduce_along_dim(0).should be_a Enumerator
121
+ end
122
+
123
+ it "should return an enumerator for each_along_dim without a block" do
124
+ @nm_2d.each_along_dim(0).should be_a Enumerator
125
+ end
126
+
127
+ it "should iterate correctly for map without a block" do
128
+ en = @nm_1d.map unless stype == :yale
129
+ en.each { |e| e**2 }.should eq @nm_1d.map { |e| e**2 } unless stype == :yale
130
+ en = @nm_2d.map
131
+ en.each { |e| e**2 }.should eq @nm_2d.map { |e| e**2 }
132
+ end
133
+
134
+ it "should iterate correctly for reduce without a block" do
135
+ unless stype == :yale then
136
+ en = @nm_1d.reduce_along_dim(0, 1.0)
137
+ en.each { |a, e| a+e }.to_f.should eq 12
138
+ end
139
+ en = @nm_2d.reduce_along_dim(1, 1.0)
140
+ en.each { |a, e| a+e }.should eq NMatrix[[2.0],[6.0], stype: stype]
141
+ end
142
+
143
+ it "should iterate correctly for each_along_dim without a block" do
144
+ unless stype == :yale then
145
+ res = NMatrix.zeros_like(@nm_1d[0...1])
146
+ en = @nm_1d.each_along_dim(0)
147
+ en.each { |e| res += e }
148
+ res.to_f.should eq 11
149
+ end
150
+ res = NMatrix.zeros_like (@nm_2d[0...2, 0])
151
+ en = @nm_2d.each_along_dim(1)
152
+ en.each { |e| res += e }
153
+ res.should eq NMatrix[[1.0], [5.0], stype: stype]
154
+ end
155
+
156
+ it "should yield matrices of matching dtype for each_along_dim" do
157
+ m = NMatrix.new([2,3], [1,2,3,3,4,5], dtype: :complex128, stype: stype)
158
+ m.each_along_dim(1) do |sub_m|
159
+ sub_m.dtype.should eq :complex128
160
+ end
161
+ end
162
+
163
+ it "should reduce to a matrix of matching dtype for reduce_along_dim" do
164
+ m = NMatrix.new([2,3], [1,2,3,3,4,5], dtype: :complex128, stype: stype)
165
+ m.reduce_along_dim(1) do |acc, sub_m|
166
+ sub_m.dtype.should eq :complex128
167
+ acc
168
+ end
169
+
170
+ m = NMatrix.new([2,3], [1,2,3,3,4,5], dtype: :complex128, stype: stype)
171
+ m.reduce_along_dim(1, 0.0) do |acc, sub_m|
172
+ sub_m.dtype.should eq :complex128
173
+ acc
174
+ end
175
+ end
176
+
177
+ it "should allow overriding the dtype for reduce_along_dim" do
178
+ m = NMatrix[[1,2,3], [3,4,5], dtype: :complex128]
179
+ m.reduce_along_dim(1, 0.0, :float64) do |acc, sub_m|
180
+ acc.dtype.should eq :float64
181
+ acc
182
+ end
183
+
184
+ m = NMatrix[[1,2,3], [3,4,5], dtype: :complex128, stype: stype]
185
+ m.reduce_along_dim(1, nil, :float64) do |acc, sub_m|
186
+ acc.dtype.should eq :float64
187
+ acc
188
+ end
189
+ end
190
+
191
+ it "should convert integer dtypes to float when calculating mean" do
192
+ m = NMatrix[[1,2,3], [3,4,5], dtype: :int32, stype: stype]
193
+ m.mean(0).dtype.should eq :float64
194
+ end
195
+
196
+ it "should convert integer dtypes to float when calculating variance" do
197
+ m = NMatrix[[1,2,3], [3,4,5], dtype: :int32, stype: stype]
198
+ m.variance(0).dtype.should eq :float64
199
+ end
200
+
201
+ it "should convert integer dtypes to float when calculating standard deviation" do
202
+ m = NMatrix[[1,2,3], [3,4,5], dtype: :int32, stype: stype]
203
+ m.std(0).dtype.should eq :float64
204
+ end
174
205
  end
175
206
  end
176
-
177
- it "should convert integer dtypes to float when calculating mean" do
178
- m = NMatrix[[1,2,3], [3,4,5], dtype: :int32]
179
- m.mean(0).dtype.should eq :float64
180
- end
181
-
182
- it "should convert integer dtypes to float when calculating variance" do
183
- m = NMatrix[[1,2,3], [3,4,5], dtype: :int32]
184
- m.variance(0).dtype.should eq :float64
185
- end
186
-
187
- it "should convert integer dtypes to float when calculating standard deviation" do
188
- m = NMatrix[[1,2,3], [3,4,5], dtype: :int32]
189
- m.std(0).dtype.should eq :float64
190
- end
191
207
  end
192
- end
208
+ end