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/blas_spec.rb CHANGED
@@ -55,7 +55,7 @@ describe NMatrix::BLAS do
55
55
  end
56
56
  end
57
57
 
58
- [:rational32,:rational64,:rational128,:complex64,:complex128].each do |dtype|
58
+ [:rational32,:rational64,:rational128].each do |dtype|
59
59
  context dtype do
60
60
  it "exposes cblas rot"
61
61
  end
@@ -65,13 +65,13 @@ describe NMatrix::BLAS do
65
65
  end
66
66
  end
67
67
 
68
- [:float32, :float64].each do |dtype|
68
+ [:float32, :float64, :complex64, :complex128, :object].each do |dtype|
69
69
  context dtype do
70
70
 
71
71
  it "exposes cblas rot" do
72
72
  x = NVector.new(5, [1,2,3,4,5], dtype)
73
73
  y = NVector.new(5, [-5,-4,-3,-2,-1], dtype)
74
- x, y = NMatrix::BLAS::rot(x, y, 0.5, Math.sqrt(3)/2, -1)
74
+ x, y = NMatrix::BLAS::rot(x, y, 1.quo(2), Math.sqrt(3).quo(2), -1)
75
75
 
76
76
  x[0].should be_within(1e-4).of(-0.3660254037844386)
77
77
  x[1].should be_within(1e-4).of(-0.7320508075688772)
@@ -86,21 +86,29 @@ describe NMatrix::BLAS do
86
86
  y[4].should be_within(1e-4).of(-1.3660254037844386)
87
87
  end
88
88
 
89
+ end
90
+ end
91
+
92
+ [:float32, :float64, :complex64, :complex128, :object].each do |dtype|
93
+ context dtype do
94
+
89
95
  it "exposes cblas rotg" do
96
+ pending("broken for :object") if dtype == :object
90
97
  ab = NVector.new(2, [6,-8], dtype)
91
98
  c,s = NMatrix::BLAS::rotg(ab)
92
- ab[0].should be_within(1e-6).of(-10)
93
- ab[1].should be_within(1e-6).of(-5.quo(3))
94
- c.should be_within(1e-6).of(-3.quo(5))
99
+
100
+ if [:float32, :float64].include?(dtype)
101
+ ab[0].should be_within(1e-6).of(-10)
102
+ ab[1].should be_within(1e-6).of(-5.quo(3))
103
+ c.should be_within(1e-6).of(-3.quo(5))
104
+ else
105
+ ab[0].should be_within(1e-6).of(10)
106
+ ab[1].should be_within(1e-6).of(5.quo(3))
107
+ c.should be_within(1e-6).of(3.quo(5))
108
+ end
95
109
  s.should be_within(1e-6).of(4.quo(5))
96
110
  end
97
111
 
98
- end
99
- end
100
-
101
- [:float32, :float64, :complex64, :complex128].each do |dtype|
102
- context dtype do
103
-
104
112
  # Note: this exposes gemm, not cblas_gemm (which is the unfriendly CBLAS no-error-checking version)
105
113
  it "exposes gemm" do
106
114
  #STDERR.puts "dtype=#{dtype.to_s}"
@@ -65,11 +65,7 @@ describe NMatrix do
65
65
  end
66
66
 
67
67
  it "should perform element-wise addition" do
68
- r = NMatrix.new(:dense, 3, [52,30,0,0,-8,0,6,0,0], :int64).cast(:yale, :int64)
69
- r[0,0] = 52
70
- r[1,1] = -8
71
- q = @n + @m
72
- q.should == r
68
+ (@n+@m).should == NMatrix.new(:dense, 3, [52,30,0,0,-8,0,6,0,0], :int64).cast(:yale, :int64)
73
69
  end
74
70
 
75
71
  it "should perform element-wise subtraction" do
@@ -213,6 +209,21 @@ describe NMatrix do
213
209
  end
214
210
 
215
211
  context "dense" do
212
+ context "scalar arithmetic" do
213
+ before :each do
214
+ @n = NMatrix.new(:dense, 2, [1,2,3,4], :int64)
215
+ end
216
+
217
+ it "works for integers" do
218
+ (@n+1).should == NMatrix.new(:dense, 2, [2,3,4,5], :int64)
219
+ end
220
+
221
+ #it "works for complex64" do
222
+ # n = @n.cast(:dtype => :complex64)
223
+ # (n + 10.0).to_a.should == [Complex(11.0), Complex(12.0), Complex(13.0), Complex(14.0)]
224
+ #end
225
+ end
226
+
216
227
  context "elementwise arithmetic" do
217
228
  before :each do
218
229
  @n = NMatrix.new(:dense, 2, [1,2,3,4], :int64)
@@ -241,16 +252,14 @@ describe NMatrix do
241
252
  r.should == NMatrix.new(:dense, [2,2], [-1, -2, 1, 0], :int64)
242
253
  end
243
254
 
244
- #it "exponentiates" do
245
- # r = @n ** 2
246
- # # TODO: We might have problems with the dtype.
247
- # r.should == NMatrix.new(:dense, [2,2], [1, 4, 9, 16], :int64)
248
- #end
255
+ it "exponentiates" do
256
+ r = @n ** 2
257
+ # TODO: We might have problems with the dtype.
258
+ r.should == NMatrix.new(:dense, [2,2], [1, 4, 9, 16], :int64)
259
+ end
249
260
 
250
261
  it "modulo" do
251
- pending "% operator not yet implemented"
252
- r = @n % @m
253
- r.should == NMatrix.new(:dense, [2,2], [0, 1, 2, 3], :int64)
262
+ (@n % (@m + 2)).should == NMatrix.new(:dense, [2,2], [-1, 0, 1, 4], :int64)
254
263
  end
255
264
  end
256
265
 
data/spec/io_spec.rb CHANGED
@@ -65,6 +65,7 @@ describe NMatrix::IO do
65
65
  end
66
66
 
67
67
  it "loads and saves MatrixMarket .mtx file containing a single large sparse double matrix" do
68
+ pending "spec disabled because it's so slow"
68
69
  n = NMatrix::IO::Market.load("spec/utm5940.mtx")
69
70
  NMatrix::IO::Market.save(n, "spec/utm5940.saved.mtx")
70
71
  `wc -l spec/utm5940.mtx`.split[0].should == `wc -l spec/utm5940.saved.mtx`.split[0]
data/spec/lapack_spec.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'pry'
1
2
  # = NMatrix
2
3
  #
3
4
  # A linear algebra library for scientific computation in Ruby.
@@ -38,6 +39,17 @@ describe NMatrix::LAPACK do
38
39
  b = NMatrix.new(:dense, [3,4], [3,2,4,1,7,6,8,5,11,10,12,9], dtype)
39
40
  a.should == b
40
41
  end
42
+
43
+ it "exposes NMatrix#permute_columns and #permute_columns! (user-friendly laswp)" do
44
+ a = NMatrix.new(:dense, [3,4], [1,2,3,4,5,6,7,8,9,10,11,12], dtype)
45
+ b = NMatrix.new(:dense, [3,4], [3,2,4,1,7,6,8,5,11,10,12,9], dtype)
46
+ piv = [2,1,3,0]
47
+ r = a.permute_columns(piv)
48
+ r.should_not == a
49
+ r.should == b
50
+ a.permute_columns!(piv)
51
+ a.should == b
52
+ end
41
53
  end
42
54
  end
43
55
 
@@ -114,7 +126,192 @@ describe NMatrix::LAPACK do
114
126
  end
115
127
  end
116
128
 
129
+ it "exposes gesdd" do
130
+ if [:float32, :float64].include? dtype
131
+ a = NMatrix.new([5,6], %w|8.79 9.93 9.83 5.45 3.16
132
+ 6.11 6.91 5.04 -0.27 7.98
133
+ -9.15 -7.93 4.86 4.85 3.01
134
+ 9.57 1.64 8.83 0.74 5.80
135
+ -3.49 4.02 9.80 10.00 4.27
136
+ 9.84 0.15 -8.99 -6.02 -5.31|.map(&:to_f), dtype)
137
+ s_true = NMatrix.new([1,5], [27.468732418221848, 22.643185009774697, 8.558388228482576, 5.985723201512133, 2.014899658715756], dtype)
138
+ right_true = NMatrix.new([5,6], [0.5911423764124365, 0.2631678147140568, 0.35543017386282716, 0.3142643627269275, 0.2299383153647484, 0.0, 0.39756679420242547, 0.24379902792633046, -0.22239000068544604, -0.7534661509534584, -0.36358968669749664, 0.0, 0.03347896906244727, -0.6002725806935828, -0.45083926892230763, 0.23344965724471425, -0.3054757327479317, 0.0, 0.4297069031370182, 0.23616680628112555, -0.6858628638738117, 0.3318600182003095, 0.1649276348845103, 0.0, 0.4697479215666587, -0.350891398883702, 0.38744460309967327, 0.15873555958215635, -0.5182574373535355, 0.0, -0.29335875846440357, 0.57626211913389, -0.020852917980871258, 0.3790776670601607, -0.6525516005923976, 0.0], dtype)
139
+ #right_true = NMatrix.new([5,6],
140
+ # %w|-0.59 0.26 0.36 0.31 0.23
141
+ # -0.40 0.24 -0.22 -0.75 -0.36
142
+ # -0.03 -0.60 -0.45 0.23 -0.31
143
+ # -0.43 0.24 -0.69 0.33 0.16
144
+ # -0.47 -0.35 0.39 0.16 -0.52
145
+ # 0.29 0.58 -0.02 0.38 -0.65|.map(&:to_f),
146
+ # dtype)
147
+ left_true = NMatrix.new([5,5], [0.25138279272049635, 0.3968455517769292, 0.6921510074703637, 0.3661704447722309, 0.4076352386533525, 0.814836686086339, 0.3586615001880027, -0.24888801115928438, -0.3685935379446176, -0.09796256926688672, -0.2606185055842211, 0.7007682094072526, -0.22081144672043734, 0.38593848318854174, -0.49325014285102375, 0.3967237771305971, -0.4507112412166429, 0.2513211496937535, 0.4342486014366711, -0.6226840720358049, -0.21802776368654594, 0.14020994987112056, 0.5891194492399431, -0.6265282503648172, -0.4395516923423326], dtype)
148
+ #left_true = NMatrix.new([5,5],
149
+ # %w|-0.25 -0.40 -0.69 -0.37 -0.41
150
+ # 0.81 0.36 -0.25 -0.37 -0.10
151
+ # -0.26 0.70 -0.22 0.39 -0.49
152
+ # 0.40 -0.45 0.25 0.43 -0.62
153
+ # -0.22 0.14 0.59 -0.63 -0.44|.map(&:to_f),
154
+ # dtype)
155
+ s = NMatrix.new([5,1], 0, dtype)
156
+ u = NMatrix.new([5,5], 0, dtype)
157
+ ldu = 5
158
+ vt = NMatrix.new([6,6], 0, dtype)
159
+ ldvt= 6
160
+ elsif [:complex64, :complex128].include? dtype
161
+ #http://software.intel.com/sites/products/documentation/doclib/mkl_sa/11/mkl_lapack_examples/cgesvd_ex.c.htm
162
+ pending "Example may be wrong"
163
+ else
164
+ a = NMatrix.new([4,3], dtype)
165
+ end
166
+ err = case dtype
167
+ when :float32, :complex64
168
+ 1e-6
169
+ when :float64, :complex128
170
+ 1e-15
171
+ else
172
+ 1e-64 # FIXME: should be 0, but be_within(0) does not work.
173
+ end
174
+ err = err *5e1
175
+ begin
117
176
 
177
+ info = NMatrix::LAPACK::lapack_gesvd(:a, :a, a.shape[0], a.shape[1], a, a.shape[0], s, u, ldu, vt, ldvt, 500)
178
+
179
+ rescue NotImplementedError => e
180
+ pending e.to_s
181
+ end
182
+
183
+ u.should be_within(err).of(left_true)
184
+ #FIXME: Is the next line correct?
185
+ vt[0...right_true.shape[0], 0...right_true.shape[1]-1].should be_within(err).of(right_true[0...right_true.shape[0],0...right_true.shape[1]-1])
186
+ s.transpose.should be_within(err).of(s_true.row(0))
187
+ end
188
+
189
+
190
+ it "exposes gesvd" do
191
+ # http://software.intel.com/sites/products/documentation/doclib/mkl_sa/11/mkl_lapack_examples/dgesvd_ex.c.htm
192
+ if [:float32, :float64].include? dtype
193
+ a = NMatrix.new([5,6], %w|8.79 9.93 9.83 5.45 3.16
194
+ 6.11 6.91 5.04 -0.27 7.98
195
+ -9.15 -7.93 4.86 4.85 3.01
196
+ 9.57 1.64 8.83 0.74 5.80
197
+ -3.49 4.02 9.80 10.00 4.27
198
+ 9.84 0.15 -8.99 -6.02 -5.31|.map(&:to_f), dtype)
199
+ s_true = NMatrix.new([1,5], [27.468732418221848, 22.643185009774697, 8.558388228482576, 5.985723201512133, 2.014899658715756], dtype)
200
+ right_true = NMatrix.new([5,6], [0.5911423764124365, 0.2631678147140568, 0.35543017386282716, 0.3142643627269275, 0.2299383153647484, 0.0, 0.39756679420242547, 0.24379902792633046, -0.22239000068544604, -0.7534661509534584, -0.36358968669749664, 0.0, 0.03347896906244727, -0.6002725806935828, -0.45083926892230763, 0.23344965724471425, -0.3054757327479317, 0.0, 0.4297069031370182, 0.23616680628112555, -0.6858628638738117, 0.3318600182003095, 0.1649276348845103, 0.0, 0.4697479215666587, -0.350891398883702, 0.38744460309967327, 0.15873555958215635, -0.5182574373535355, 0.0, -0.29335875846440357, 0.57626211913389, -0.020852917980871258, 0.3790776670601607, -0.6525516005923976, 0.0], dtype)
201
+ #right_true = NMatrix.new([5,6],
202
+ # %w|-0.59 0.26 0.36 0.31 0.23
203
+ # -0.40 0.24 -0.22 -0.75 -0.36
204
+ # -0.03 -0.60 -0.45 0.23 -0.31
205
+ # -0.43 0.24 -0.69 0.33 0.16
206
+ # -0.47 -0.35 0.39 0.16 -0.52
207
+ # 0.29 0.58 -0.02 0.38 -0.65|.map(&:to_f),
208
+ # dtype)
209
+ left_true = NMatrix.new([5,5], [0.25138279272049635, 0.3968455517769292, 0.6921510074703637, 0.3661704447722309, 0.4076352386533525, 0.814836686086339, 0.3586615001880027, -0.24888801115928438, -0.3685935379446176, -0.09796256926688672, -0.2606185055842211, 0.7007682094072526, -0.22081144672043734, 0.38593848318854174, -0.49325014285102375, 0.3967237771305971, -0.4507112412166429, 0.2513211496937535, 0.4342486014366711, -0.6226840720358049, -0.21802776368654594, 0.14020994987112056, 0.5891194492399431, -0.6265282503648172, -0.4395516923423326], dtype)
210
+ #left_true = NMatrix.new([5,5],
211
+ # %w|-0.25 -0.40 -0.69 -0.37 -0.41
212
+ # 0.81 0.36 -0.25 -0.37 -0.10
213
+ # -0.26 0.70 -0.22 0.39 -0.49
214
+ # 0.40 -0.45 0.25 0.43 -0.62
215
+ # -0.22 0.14 0.59 -0.63 -0.44|.map(&:to_f),
216
+ # dtype)
217
+ s = NMatrix.new([5,1], 0, dtype)
218
+ u = NMatrix.new([5,5], 0, dtype)
219
+ ldu = 5
220
+ vt = NMatrix.new([6,6], 0, dtype)
221
+ ldvt= 6
222
+ elsif [:complex64, :complex128].include? dtype
223
+ #http://software.intel.com/sites/products/documentation/doclib/mkl_sa/11/mkl_lapack_examples/cgesvd_ex.c.htm
224
+ pending "Example may be wrong"
225
+ a = NMatrix.new([4,3], [[ 5.91, -5.69], [ 7.09, 2.72], [ 7.78, -4.06], [ -0.79, -7.21], [ -3.15, -4.08], [ -1.89, 3.27], [ 4.57, -2.07], [ -3.88, -3.30], [ -4.89, 4.20], [ 4.10, -6.70], [ 3.28, -3.84], [ 3.84, 1.19]].map {|e| Complex(*e) } , dtype)
226
+ s_true = NMatrix.new([3,1], [17.63, 11.61, 6.78], dtype)
227
+ left_true = NMatrix.new([4,4], [[-0.86, 0.0], [0.4, 0.0], [0.32, 0.0], [-0.35, 0.13], [-0.24, -0.21], [-0.63, 0.6], [0.15, 0.32], [0.61, 0.61], [-0.36, 0.1]].map {|e| Complex(*e)}, dtype)
228
+ right_true = NMatrix.new([4,3], [[ -0.22, 0.51], [ -0.37, -0.32], [ -0.53, 0.11], [ 0.15, 0.38], [ 0.31, 0.31], [ 0.09, -0.57], [ 0.18, -0.39], [ 0.38, -0.39], [ 0.53, 0.24], [ 0.49, 0.28], [ -0.47, -0.25], [ -0.15, 0.19]].map {|e| Complex *e} , dtype)
229
+
230
+ s = NMatrix.new([3,1], 0, dtype)
231
+ u = NMatrix.new([4,4], 0, dtype)
232
+ ldu = 4
233
+ vt = NMatrix.new([3,3], 0, dtype)
234
+ ldvt= 3
235
+ else
236
+ a = NMatrix.new([4,3], dtype)
237
+ end
238
+ err = case dtype
239
+ when :float32, :complex64
240
+ 1e-6
241
+ when :float64, :complex128
242
+ 1e-15
243
+ else
244
+ 1e-64 # FIXME: should be 0, but be_within(0) does not work.
245
+ end
246
+ err = err *5e1
247
+ begin
248
+
249
+ info = NMatrix::LAPACK::lapack_gesvd(:a, :a, a.shape[0], a.shape[1], a, a.shape[0], s, u, ldu, vt, ldvt, 500)
250
+
251
+ rescue NotImplementedError => e
252
+ pending e.to_s
253
+ end
254
+
255
+ u.should be_within(err).of(left_true)
256
+ #FIXME: Is the next line correct?
257
+ vt[0...right_true.shape[0], 0...right_true.shape[1]-1].should be_within(err).of(right_true[0...right_true.shape[0],0...right_true.shape[1]-1])
258
+ s.transpose.should be_within(err).of(s_true.row(0))
259
+
260
+ end
261
+
262
+
263
+ it "exposes geev" do
264
+ pending("needs rational implementation") if dtype.to_s =~ /rational/
265
+ ary = %w|-1.01 0.86 -4.60 3.31 -4.81
266
+ 3.98 0.53 -7.04 5.29 3.55
267
+ 3.30 8.26 -3.89 8.20 -1.51
268
+ 4.43 4.96 -7.66 -7.33 6.18
269
+ 7.31 -6.43 -6.16 2.47 5.58|
270
+ ary = dtype.to_s =~ /complex/ ? ary.map(&:to_c) : ary.map(&:to_f)
271
+
272
+ a = NMatrix.new(:dense, 5, ary, dtype).transpose
273
+ lda = 5
274
+ n = 5
275
+
276
+ wr = NMatrix.new(:dense, [n,1], 0, dtype)
277
+ wi = dtype.to_s =~ /complex/ ? nil : NMatrix.new(:dense, [n,1], 0, dtype)
278
+ vl = NMatrix.new(:dense, n, 0, dtype)
279
+ vr = NMatrix.new(:dense, n, 0, dtype)
280
+ ldvr = n
281
+ ldvl = n
282
+
283
+ info = NMatrix::LAPACK::lapack_geev(:left, :right, n, a.clone, lda, wr.clone, wi.nil? ? nil : wi.clone, vl.clone, ldvl, vr.clone, ldvr, -1)
284
+ info.should == 0
285
+
286
+ info = NMatrix::LAPACK::lapack_geev(:left, :right, n, a, lda, wr, wi, vl, ldvl, vr, ldvr, 2*n)
287
+
288
+ # Negate these and we get a correct result:
289
+ vr = vr.transpose
290
+ vl = vl.transpose
291
+
292
+ pending("Need complex example") if dtype.to_s =~ /complex/
293
+ vl_true = NMatrix.new(:dense, 5, [0.04, 0.29, 0.13, 0.33, -0.04,
294
+ 0.62, 0.0, -0.69, 0.0, -0.56,
295
+ -0.04, -0.58, 0.39, 0.07, 0.13,
296
+ 0.28, 0.01, 0.02, 0.19, 0.80,
297
+ -0.04, 0.34, 0.40, -0.22, -0.18 ], :float64)
298
+
299
+ vl.abs.should be_within(1e-2).of(vl_true.abs)
300
+ # Not checking vr_true.
301
+ # Example from:
302
+ # http://software.intel.com/sites/products/documentation/doclib/mkl_sa/11/mkl_lapack_examples/lapacke_dgeev_row.c.htm
303
+ #
304
+ # This is what the result should look like:
305
+ # [
306
+ # [0.10806497186422348, 0.16864821314811707, 0.7322341203689575, 0.0, -0.46064677834510803]
307
+ # [0.40631288290023804, -0.25900983810424805, -0.02646319754421711, -0.01694658398628235, -0.33770373463630676]
308
+ # [0.10235744714736938, -0.5088024139404297, 0.19164878129959106, -0.29256555438041687, -0.3087439239025116]
309
+ # [0.39863115549087524, -0.0913335531949997, -0.07901126891374588, -0.07807594537734985, 0.7438457012176514]
310
+ # [ 0.5395349860191345, 0.0, -0.29160499572753906, -0.49310219287872314, -0.15852922201156616]
311
+ # ]
312
+ #
313
+
314
+ end
118
315
  end
119
316
  end
120
317
  end
data/spec/nmatrix_spec.rb CHANGED
@@ -29,6 +29,12 @@ require File.dirname(__FILE__) + "/spec_helper.rb"
29
29
 
30
30
  describe NMatrix do
31
31
 
32
+ it "adequately requires information to access a single entry of a dense matrix" do
33
+ n = NMatrix.new(:dense, 4, [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], :float64)
34
+ n[0,0].should == 0
35
+ expect { n[0] }.should raise_error(ArgumentError)
36
+ end
37
+
32
38
  it "calculates exact determinants on small square matrices" do
33
39
  a = NMatrix.new(:dense, 2, [1,2,3,4], :int64)
34
40
  a.det_exact.should == -2
@@ -145,11 +151,6 @@ describe NMatrix do
145
151
  m.dtype.should == :float64
146
152
  end
147
153
 
148
- it "dense pretty_prints complex values" do
149
- n = NMatrix.new([4,3], COMPLEX_MATRIX43A_ARRAY, :complex128)
150
- n.pretty_print
151
- end
152
-
153
154
 
154
155
  [:dense, :list, :yale].each do |storage_type|
155
156
  context storage_type do
@@ -172,9 +173,9 @@ describe NMatrix do
172
173
  end
173
174
 
174
175
  it "enforces shape boundaries" do
175
- lambda { NMatrix.new(storage_type, [1,10], storage_type == :yale ? :int8 : 0)[-1,0] }.should raise_error
176
- lambda { NMatrix.new(storage_type, [1,10], storage_type == :yale ? :int8 : 0)[1,0] }.should raise_error(ArgumentError, "out of range")
177
- lambda { NMatrix.new(storage_type, [1,10], storage_type == :yale ? :int8 : 0)[0,10] }.should raise_error(ArgumentError, "out of range")
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)
178
179
  end
179
180
 
180
181
  it "sets and gets" do
@@ -359,53 +360,53 @@ describe NMatrix do
359
360
  context "mapping and reduction related functions" do
360
361
 
361
362
  before :each do
362
- @nm_1d = N[5.0,0.0,1.0,2.0,3.0]
363
- @nm_2d = N[[0.0,1.0],[2.0,3.0]]
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]]
364
365
  end
365
366
 
366
367
  it "behaves like Enumerable#reduce with no argument to reduce" do
367
368
  @nm_1d.reduce_along_dim(0) { |acc, el| acc + el }.to_f.should eq 11
368
- @nm_2d.reduce_along_dim(1) { |acc, el| acc + el }.should eq N[[1, 5]]
369
+ @nm_2d.reduce_along_dim(1) { |acc, el| acc + el }.should eq NMatrix[[1, 5]]
369
370
  end
370
371
 
371
372
  it "should calculate the mean along the specified dimension" do
372
- @nm_1d.mean.should eq N[2.2]
373
- @nm_2d.mean.should eq N[[1.0,2.0]]
373
+ @nm_1d.mean.should eq NMatrix[2.2]
374
+ @nm_2d.mean.should eq NMatrix[[1.0,2.0]]
374
375
  end
375
376
 
376
377
  it "should calculate the minimum along the specified dimension" do
377
378
  @nm_1d.min.should eq 0.0
378
- @nm_2d.min.should eq N[[0.0, 1.0]]
379
- @nm_2d.min(1).should eq N[[0.0], [2.0]]
379
+ @nm_2d.min.should eq NMatrix[[0.0, 1.0]]
380
+ @nm_2d.min(1).should eq NMatrix[[0.0], [2.0]]
380
381
  end
381
382
 
382
383
  it "should calculate the maximum along the specified dimension" do
383
384
  @nm_1d.max.should eq 5.0
384
- @nm_2d.max.should eq N[[2.0, 3.0]]
385
+ @nm_2d.max.should eq NMatrix[[2.0, 3.0]]
385
386
  end
386
387
 
387
388
  it "should calculate the variance along the specified dimension" do
388
- @nm_1d.variance.should eq N[3.7]
389
- @nm_2d.variance(1).should eq N[[0.5], [0.5]]
389
+ @nm_1d.variance.should eq NMatrix[3.7]
390
+ @nm_2d.variance(1).should eq NMatrix[[0.5], [0.5]]
390
391
  end
391
392
 
392
393
  it "should calculate the sum along the specified dimension" do
393
- @nm_1d.sum.should eq N[11]
394
- @nm_2d.sum.should eq N[[2], [4]]
394
+ @nm_1d.sum.should eq NMatrix[11]
395
+ @nm_2d.sum.should eq NMatrix[[2], [4]]
395
396
  end
396
397
 
397
398
  it "should calculate the standard deviation along the specified dimension" do
398
- @nm_1d.std.should eq N[Math.sqrt(3.7)]
399
- @nm_2d.std(1).should eq N[[Math.sqrt(0.5)], [Math.sqrt(0.5)]]
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)]]
400
401
  end
401
402
 
402
403
  it "should raise an ArgumentError when any invalid dimension is provided" do
403
- expect { @nm_1d.mean(3) }.to raise_exception(ArgumentError)
404
+ expect { @nm_1d.mean(3) }.to raise_exception(RangeError)
404
405
  end
405
406
 
406
407
  it "should convert to float if it contains only a single element" do
407
- N[4.0].to_f.should eq 4.0
408
- N[[[[4.0]]]].to_f.should eq 4.0
408
+ NMatrix[4.0].to_f.should eq 4.0
409
+ NMatrix[[[[4.0]]]].to_f.should eq 4.0
409
410
  end
410
411
 
411
412
  it "should raise an index error if it contains more than a single element" do
@@ -413,8 +414,8 @@ describe NMatrix do
413
414
  end
414
415
 
415
416
  it "should map a block to all elements" do
416
- @nm_1d.map { |e| e ** 2 }.should eq N[25.0,0.0,1.0,4.0,9.0]
417
- @nm_2d.map { |e| e ** 2 }.should eq N[[0.0,1.0],[4.0,9.0]]
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]]
418
419
  end
419
420
 
420
421
  it "should map! a block to all elements in place" do
@@ -450,7 +451,7 @@ describe NMatrix do
450
451
  en = @nm_1d.reduce_along_dim(0, 1.0)
451
452
  en.each { |a, e| a+e }.to_f.should eq 12
452
453
  en = @nm_2d.reduce_along_dim(1, 1.0)
453
- en.each { |a, e| a+e }.should eq N[[2.0],[6.0]]
454
+ en.each { |a, e| a+e }.should eq NMatrix[[2.0],[6.0]]
454
455
  end
455
456
 
456
457
  it "should iterate correctly for each_along_dim without a block" do
@@ -462,7 +463,7 @@ describe NMatrix do
462
463
  res = NMatrix.zeros_like (@nm_2d[0...2, 0])
463
464
  en = @nm_2d.each_along_dim(1)
464
465
  en.each { |e| res += e }
465
- res.should eq N[[1.0], [5.0]]
466
+ res.should eq NMatrix[[1.0], [5.0]]
466
467
  end
467
468
 
468
469
  it "should yield matrices of matching dtype for each_along_dim" do
@@ -487,13 +488,13 @@ describe NMatrix do
487
488
  end
488
489
 
489
490
  it "should allow overriding the dtype for reduce_along_dim" do
490
- m = N[[1,2,3], [3,4,5], :complex128]
491
+ m = NMatrix[[1,2,3], [3,4,5], :complex128]
491
492
  m.reduce_along_dim(1, 0.0, :float64) do |acc, sub_m|
492
493
  acc.dtype.should eq :float64
493
494
  acc
494
495
  end
495
496
 
496
- m = N[[1,2,3], [3,4,5], :complex128]
497
+ m = NMatrix[[1,2,3], [3,4,5], :complex128]
497
498
  m.reduce_along_dim(1, nil, :float64) do |acc, sub_m|
498
499
  acc.dtype.should eq :float64
499
500
  acc
@@ -501,30 +502,30 @@ describe NMatrix do
501
502
  end
502
503
 
503
504
  it "should convert integer dtypes to float when calculating mean" do
504
- m = N[[1,2,3], [3,4,5], :int32]
505
+ m = NMatrix[[1,2,3], [3,4,5], :int32]
505
506
  m.mean(0).dtype.should eq :float64
506
507
  end
507
508
 
508
509
  it "should convert integer dtypes to float when calculating variance" do
509
- m = N[[1,2,3], [3,4,5], :int32]
510
+ m = NMatrix[[1,2,3], [3,4,5], :int32]
510
511
  m.variance(0).dtype.should eq :float64
511
512
  end
512
513
 
513
514
  it "should convert integer dtypes to float when calculating standard deviation" do
514
- m = N[[1,2,3], [3,4,5], :int32]
515
+ m = NMatrix[[1,2,3], [3,4,5], :int32]
515
516
  m.std(0).dtype.should eq :float64
516
517
  end
517
518
 
518
519
  context "_like constructors" do
519
520
 
520
521
  it "should create an nmatrix of ones with dimensions and type the same as its argument" do
521
- NMatrix.ones_like(@nm_1d).should eq N[1.0, 1.0, 1.0, 1.0, 1.0]
522
- NMatrix.ones_like(@nm_2d).should eq N[[1.0, 1.0], [1.0, 1.0]]
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]]
523
524
  end
524
525
 
525
526
  it "should create an nmatrix of zeros with dimensions and type the same as its argument" do
526
- NMatrix.zeros_like(@nm_1d).should eq N[0.0, 0.0, 0.0, 0.0, 0.0]
527
- NMatrix.zeros_like(@nm_2d).should eq N[[0.0, 0.0], [0.0, 0.0]]
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]]
528
529
  end
529
530
  end
530
531
  end