nmatrix 0.0.6 → 0.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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