nmatrix 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +27 -0
- data/.rspec +2 -0
- data/Gemfile +3 -5
- data/Guardfile +6 -0
- data/History.txt +33 -0
- data/Manifest.txt +41 -38
- data/README.rdoc +88 -11
- data/Rakefile +35 -53
- data/ext/nmatrix/data/complex.h +372 -0
- data/ext/nmatrix/data/data.cpp +275 -0
- data/ext/nmatrix/data/data.h +707 -0
- data/ext/nmatrix/data/rational.h +421 -0
- data/ext/nmatrix/data/ruby_object.h +446 -0
- data/ext/nmatrix/extconf.rb +101 -51
- data/ext/nmatrix/new_extconf.rb +56 -0
- data/ext/nmatrix/nmatrix.cpp +1609 -0
- data/ext/nmatrix/nmatrix.h +265 -849
- data/ext/nmatrix/ruby_constants.cpp +134 -0
- data/ext/nmatrix/ruby_constants.h +103 -0
- data/ext/nmatrix/storage/common.cpp +70 -0
- data/ext/nmatrix/storage/common.h +170 -0
- data/ext/nmatrix/storage/dense.cpp +665 -0
- data/ext/nmatrix/storage/dense.h +116 -0
- data/ext/nmatrix/storage/list.cpp +1088 -0
- data/ext/nmatrix/storage/list.h +129 -0
- data/ext/nmatrix/storage/storage.cpp +658 -0
- data/ext/nmatrix/storage/storage.h +99 -0
- data/ext/nmatrix/storage/yale.cpp +1601 -0
- data/ext/nmatrix/storage/yale.h +208 -0
- data/ext/nmatrix/ttable_helper.rb +126 -0
- data/ext/nmatrix/{yale/smmp1_header.template.c → types.h} +36 -9
- data/ext/nmatrix/util/io.cpp +295 -0
- data/ext/nmatrix/util/io.h +117 -0
- data/ext/nmatrix/util/lapack.h +1175 -0
- data/ext/nmatrix/util/math.cpp +557 -0
- data/ext/nmatrix/util/math.h +1363 -0
- data/ext/nmatrix/util/sl_list.cpp +475 -0
- data/ext/nmatrix/util/sl_list.h +255 -0
- data/ext/nmatrix/util/util.h +78 -0
- data/lib/nmatrix/blas.rb +70 -0
- data/lib/nmatrix/io/mat5_reader.rb +567 -0
- data/lib/nmatrix/io/mat_reader.rb +162 -0
- data/lib/{string.rb → nmatrix/monkeys.rb} +49 -2
- data/lib/nmatrix/nmatrix.rb +199 -0
- data/lib/nmatrix/nvector.rb +103 -0
- data/lib/nmatrix/version.rb +27 -0
- data/lib/nmatrix.rb +22 -230
- data/nmatrix.gemspec +59 -0
- data/scripts/mac-brew-gcc.sh +47 -0
- data/spec/4x4_sparse.mat +0 -0
- data/spec/4x5_dense.mat +0 -0
- data/spec/blas_spec.rb +47 -0
- data/spec/elementwise_spec.rb +164 -0
- data/spec/io_spec.rb +60 -0
- data/spec/lapack_spec.rb +52 -0
- data/spec/math_spec.rb +96 -0
- data/spec/nmatrix_spec.rb +93 -89
- data/spec/nmatrix_yale_spec.rb +52 -36
- data/spec/nvector_spec.rb +1 -1
- data/spec/slice_spec.rb +257 -0
- data/spec/spec_helper.rb +51 -0
- data/spec/utm5940.mtx +83844 -0
- metadata +113 -71
- data/.autotest +0 -23
- data/.gemtest +0 -0
- data/ext/nmatrix/cblas.c +0 -150
- data/ext/nmatrix/dense/blas_header.template.c +0 -52
- data/ext/nmatrix/dense/elementwise.template.c +0 -107
- data/ext/nmatrix/dense/gemm.template.c +0 -159
- data/ext/nmatrix/dense/gemv.template.c +0 -130
- data/ext/nmatrix/dense/rationalmath.template.c +0 -68
- data/ext/nmatrix/dense.c +0 -307
- data/ext/nmatrix/depend +0 -18
- data/ext/nmatrix/generator/syntax_tree.rb +0 -481
- data/ext/nmatrix/generator.rb +0 -594
- data/ext/nmatrix/list.c +0 -774
- data/ext/nmatrix/nmatrix.c +0 -1977
- data/ext/nmatrix/rational.c +0 -98
- data/ext/nmatrix/yale/complexmath.template.c +0 -71
- data/ext/nmatrix/yale/elementwise.template.c +0 -46
- data/ext/nmatrix/yale/elementwise_op.template.c +0 -73
- data/ext/nmatrix/yale/numbmm.template.c +0 -94
- data/ext/nmatrix/yale/smmp1.template.c +0 -21
- data/ext/nmatrix/yale/smmp2.template.c +0 -43
- data/ext/nmatrix/yale/smmp2_header.template.c +0 -46
- data/ext/nmatrix/yale/sort_columns.template.c +0 -56
- data/ext/nmatrix/yale/symbmm.template.c +0 -54
- data/ext/nmatrix/yale/transp.template.c +0 -68
- data/ext/nmatrix/yale.c +0 -726
- data/lib/array.rb +0 -67
- data/spec/syntax_tree_spec.rb +0 -46
data/spec/math_spec.rb
ADDED
@@ -0,0 +1,96 @@
|
|
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
|
+
# == math_spec.rb
|
24
|
+
#
|
25
|
+
# Tests for non-BLAS and non-LAPACK math functions, or for simplified
|
26
|
+
# versions of unfriendly BLAS and LAPACK functions.
|
27
|
+
#
|
28
|
+
|
29
|
+
# Can we use require_relative here instead?
|
30
|
+
require File.join(File.dirname(__FILE__), "spec_helper.rb")
|
31
|
+
|
32
|
+
describe "math" do
|
33
|
+
|
34
|
+
[:float32, :float64, :complex64, :complex128, :rational32, :rational64, :rational128].each do |dtype|
|
35
|
+
context dtype do
|
36
|
+
it "should correctly factorize a matrix" do
|
37
|
+
m = NMatrix.new(:dense, 3, [4,9,2,3,5,7,8,1,6], dtype)
|
38
|
+
a = m.factorize_lu
|
39
|
+
a[0,0].should == 8
|
40
|
+
a[0,1].should == 1
|
41
|
+
a[0,2].should == 6
|
42
|
+
a[1,0].should == 0.5
|
43
|
+
a[1,1].should == 8.5
|
44
|
+
a[1,2].should == -1
|
45
|
+
a[2,0].should == 0.375
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
[:float32, :float64, :complex64, :complex128].each do |dtype|
|
51
|
+
context dtype do
|
52
|
+
|
53
|
+
# Note: this exposes gemm, not cblas_gemm (which is the unfriendly CBLAS no-error-checking version)
|
54
|
+
it "exposes gemm" do
|
55
|
+
#STDERR.puts "dtype=#{dtype.to_s}"
|
56
|
+
#STDERR.puts "1"
|
57
|
+
n = NMatrix.new([4,3], dtype)
|
58
|
+
n[0,0] = 14.0
|
59
|
+
n[0,1] = 9.0
|
60
|
+
n[0,2] = 3.0
|
61
|
+
n[1,0] = 2.0
|
62
|
+
n[1,1] = 11.0
|
63
|
+
n[1,2] = 15.0
|
64
|
+
n[2,0] = 0.0
|
65
|
+
n[2,1] = 12.0
|
66
|
+
n[2,2] = 17.0
|
67
|
+
n[3,0] = 5.0
|
68
|
+
n[3,1] = 2.0
|
69
|
+
n[3,2] = 3.0
|
70
|
+
|
71
|
+
m = NMatrix.new([3,2], dtype)
|
72
|
+
|
73
|
+
m[0,0] = 12.0
|
74
|
+
m[0,1] = 25.0
|
75
|
+
m[1,0] = 9.0
|
76
|
+
m[1,1] = 10.0
|
77
|
+
m[2,0] = 8.0
|
78
|
+
m[2,1] = 5.0
|
79
|
+
|
80
|
+
#c = NMatrix.new([4,2], dtype)
|
81
|
+
r = NMatrix::BLAS.gemm(n, m) #, c)
|
82
|
+
#c.should equal(r) # check that both are same memory address
|
83
|
+
|
84
|
+
r[0,0].should == 273.0
|
85
|
+
r[0,1].should == 455.0
|
86
|
+
r[1,0].should == 243.0
|
87
|
+
r[1,1].should == 235.0
|
88
|
+
r[2,0].should == 244.0
|
89
|
+
r[2,1].should == 205.0
|
90
|
+
r[3,0].should == 102.0
|
91
|
+
r[3,1].should == 160.0
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
data/spec/nmatrix_spec.rb
CHANGED
@@ -24,20 +24,18 @@
|
|
24
24
|
#
|
25
25
|
# Basic tests for NMatrix.
|
26
26
|
#
|
27
|
-
require "./lib/nmatrix"
|
28
27
|
|
29
|
-
|
30
|
-
|
31
|
-
MATRIX32A_ARRAY = [12.0, 25.0, 9.0, 10.0, 8.0, 5.0]
|
32
|
-
|
33
|
-
COMPLEX_MATRIX43A_ARRAY = MATRIX43A_ARRAY.zip(MATRIX43A_ARRAY.reverse).collect { |ary| Complex(ary[0], ary[1]) }
|
34
|
-
COMPLEX_MATRIX32A_ARRAY = MATRIX32A_ARRAY.zip(MATRIX32A_ARRAY.reverse).collect { |ary| Complex(ary[0], -ary[1]) }
|
28
|
+
# Can we use require_relative here instead?
|
29
|
+
require File.join(File.dirname(__FILE__), "spec_helper.rb")
|
35
30
|
|
36
|
-
|
37
|
-
RATIONAL_MATRIX32A_ARRAY = MATRIX32A_ARRAY.collect { |x| x.to_r }
|
31
|
+
describe NMatrix do
|
38
32
|
|
33
|
+
it "calculates exact determinants on small square matrices" do
|
34
|
+
a = NMatrix.new(:dense, 2, [1,2,3,4], :int64)
|
35
|
+
x = a.det_exact
|
36
|
+
end
|
39
37
|
|
40
|
-
it "allows stype casting of a
|
38
|
+
it "allows stype casting of a dim 2 matrix between dense, sparse, and list (different dtypes)" do
|
41
39
|
m = NMatrix.new(:dense, [3,3], [0,0,1,0,2,0,3,4,5], :int64).
|
42
40
|
cast(:yale, :int32).
|
43
41
|
cast(:dense, :float64).
|
@@ -53,27 +51,27 @@ describe NMatrix do
|
|
53
51
|
end
|
54
52
|
|
55
53
|
|
56
|
-
it "
|
54
|
+
it "compares two list matrices" do
|
57
55
|
n = NMatrix.new(:list, [3,3,3], :int64)
|
58
56
|
m = NMatrix.new(:list, [3,3,3], :int64)
|
59
|
-
n.should
|
57
|
+
n.should == m
|
60
58
|
n[0,0,0] = 5
|
61
|
-
n.should_not
|
59
|
+
n.should_not == m
|
62
60
|
n[0,0,1] = 52
|
63
61
|
n[1,2,1] = -4
|
64
62
|
|
65
63
|
m[0,0,0] = 5
|
66
64
|
m[0,0,1] = 52
|
67
65
|
m[1,2,1] = -4
|
68
|
-
n.should
|
66
|
+
n.should == m
|
69
67
|
end
|
70
68
|
|
71
|
-
it "
|
69
|
+
it "fills dense Ruby object matrix with nil" do
|
72
70
|
n = NMatrix.new([4,3], :object)
|
73
71
|
n[0,0].should == nil
|
74
72
|
end
|
75
73
|
|
76
|
-
it "
|
74
|
+
it "fills dense with individual assignments" do
|
77
75
|
n = NMatrix.new([4,3], :float64)
|
78
76
|
n[0,0] = 14.0
|
79
77
|
n[0,1] = 9.0
|
@@ -102,7 +100,7 @@ describe NMatrix do
|
|
102
100
|
n[3,2].should == 3.0
|
103
101
|
end
|
104
102
|
|
105
|
-
it "
|
103
|
+
it "fills dense with a single mass assignment" do
|
106
104
|
n = 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])
|
107
105
|
|
108
106
|
n[0,0].should == 14.0
|
@@ -119,7 +117,7 @@ describe NMatrix do
|
|
119
117
|
n[3,2].should == 3.0
|
120
118
|
end
|
121
119
|
|
122
|
-
it "
|
120
|
+
it "fills dense with a single mass assignment, with dtype specified" do
|
123
121
|
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)
|
124
122
|
m[0,0].should == 14.0
|
125
123
|
m[0,1].should == 9.0
|
@@ -135,56 +133,26 @@ describe NMatrix do
|
|
135
133
|
m[3,2].should == 3.0
|
136
134
|
end
|
137
135
|
|
138
|
-
[:float32, :float64].each do |dtype|
|
139
|
-
it "correctly exposes cblas_xgemm" do
|
140
|
-
#STDERR.puts "dtype=#{dtype.to_s}"
|
141
|
-
#STDERR.puts "1"
|
142
|
-
n = NMatrix.new([4,3], dtype)
|
143
|
-
n[0,0] = 14.0
|
144
|
-
n[0,1] = 9.0
|
145
|
-
n[0,2] = 3.0
|
146
|
-
n[1,0] = 2.0
|
147
|
-
n[1,1] = 11.0
|
148
|
-
n[1,2] = 15.0
|
149
|
-
n[2,0] = 0.0
|
150
|
-
n[2,1] = 12.0
|
151
|
-
n[2,2] = 17.0
|
152
|
-
n[3,0] = 5.0
|
153
|
-
n[3,1] = 2.0
|
154
|
-
n[3,2] = 3.0
|
155
|
-
|
156
|
-
m = NMatrix.new([3,2], dtype)
|
157
|
-
|
158
|
-
m[0,0] = 12.0
|
159
|
-
m[0,1] = 25.0
|
160
|
-
m[1,0] = 9.0
|
161
|
-
m[1,1] = 10.0
|
162
|
-
m[2,0] = 8.0
|
163
|
-
m[2,1] = 5.0
|
164
|
-
|
165
|
-
#c = NMatrix.new([4,2], dtype)
|
166
|
-
r = NMatrix.cblas_gemm(n, m) #, c)
|
167
|
-
#c.should equal(r) # check that both are same memory address
|
168
|
-
|
169
|
-
r[0,0].should == 273.0
|
170
|
-
r[0,1].should == 455.0
|
171
|
-
r[1,0].should == 243.0
|
172
|
-
r[1,1].should == 235.0
|
173
|
-
r[2,0].should == 244.0
|
174
|
-
r[2,1].should == 205.0
|
175
|
-
r[3,0].should == 102.0
|
176
|
-
r[3,1].should == 160.0
|
177
|
-
end
|
178
|
-
end
|
179
136
|
|
180
|
-
it "list
|
137
|
+
it "list handles missing initialization value" do
|
181
138
|
NMatrix.new(:list, 3, :int8)[0,0].should == 0
|
182
139
|
NMatrix.new(:list, 4, :float64)[0,0].should == 0.0
|
183
140
|
end
|
184
141
|
|
142
|
+
it "should allow conversion of list storage to a Ruby Hash" do
|
143
|
+
n = NMatrix.new(:list, 3, 1, :int64)
|
144
|
+
n[0,1] = 50
|
145
|
+
h = n.to_h
|
146
|
+
h.size.should == 1
|
147
|
+
h[0].size.should == 1
|
148
|
+
h[0][1].should == 50
|
149
|
+
h[0][2].should == 1
|
150
|
+
h[1][0].should == 1
|
151
|
+
end
|
152
|
+
|
185
153
|
|
186
154
|
##TODO: Make this test better. It's not nearly exhaustive enough as is.
|
187
|
-
it "list
|
155
|
+
it "list handles recursive removal" do
|
188
156
|
n = NMatrix.new(:list, [3,3,3], 0)
|
189
157
|
n[0,0,0] = 2
|
190
158
|
n[1,1,1] = 1
|
@@ -204,7 +172,7 @@ describe NMatrix do
|
|
204
172
|
end
|
205
173
|
|
206
174
|
|
207
|
-
it "dense
|
175
|
+
it "dense handles missing initialization value" do
|
208
176
|
n = NMatrix.new(3, :int8)
|
209
177
|
n.stype.should == :dense
|
210
178
|
n.dtype.should == :int8
|
@@ -214,29 +182,21 @@ describe NMatrix do
|
|
214
182
|
m.dtype.should == :float64
|
215
183
|
end
|
216
184
|
|
217
|
-
it "dense
|
185
|
+
it "dense pretty_prints complex values" do
|
218
186
|
n = NMatrix.new([4,3], COMPLEX_MATRIX43A_ARRAY, :complex128)
|
219
187
|
n.pretty_print
|
220
188
|
end
|
221
189
|
|
222
|
-
it "dense correctly handles elementwise addition" do
|
223
|
-
n = NMatrix.new(:dense, [2,2], [1,2,3,4], :int64)
|
224
|
-
m = NMatrix.new(:dense, [2,2], [-4,-1,0,66], :int64)
|
225
|
-
rcorrect = NMatrix.new(:dense, [2,2], [-3, 1, 3, 70], :int64)
|
226
|
-
r = n+m
|
227
|
-
r.should.eql? rcorrect
|
228
|
-
end
|
229
|
-
|
230
190
|
# TODO: Get it working with ROBJ too
|
231
|
-
[:byte,:int8,:int16,:int32,:int64,:float32,:float64,:rational64,:rational128
|
232
|
-
[:byte,:int8,:int16,:int32,:int64,:float32,:float64,:rational64,:rational128
|
191
|
+
[:byte,:int8,:int16,:int32,:int64,:float32,:float64,:rational64,:rational128].each do |left_dtype|
|
192
|
+
[:byte,:int8,:int16,:int32,:int64,:float32,:float64,:rational64,:rational128].each do |right_dtype|
|
233
193
|
|
234
194
|
# Won't work if they're both 1-byte, due to overflow.
|
235
195
|
next if [:byte,:int8].include?(left_dtype) && [:byte,:int8].include?(right_dtype)
|
236
196
|
|
237
197
|
# For now, don't bother testing int-int mult.
|
238
198
|
#next if [:int8,:int16,:int32,:int64].include?(left_dtype) && [:int8,:int16,:int32,:int64].include?(right_dtype)
|
239
|
-
it "dense
|
199
|
+
it "dense handles #{left_dtype.to_s} dot #{right_dtype.to_s} matrix multiplication" do
|
240
200
|
#STDERR.puts "dtype=#{dtype.to_s}"
|
241
201
|
#STDERR.puts "2"
|
242
202
|
|
@@ -261,11 +221,11 @@ describe NMatrix do
|
|
261
221
|
|
262
222
|
m.shape[0].should == 3
|
263
223
|
m.shape[1].should == 2
|
264
|
-
m.
|
224
|
+
m.dim.should == 2
|
265
225
|
|
266
226
|
n.shape[0].should == 4
|
267
227
|
n.shape[1].should == 3
|
268
|
-
n.
|
228
|
+
n.dim.should == 2
|
269
229
|
|
270
230
|
n.shape[1].should == m.shape[0]
|
271
231
|
|
@@ -291,7 +251,7 @@ describe NMatrix do
|
|
291
251
|
# Won't work if they're both 1-byte, due to overflow.
|
292
252
|
next if [:byte,:int8].include?(left_dtype) && [:byte,:int8].include?(right_dtype)
|
293
253
|
|
294
|
-
it "dense
|
254
|
+
it "dense handles #{left_dtype.to_s} dot #{right_dtype.to_s} vector multiplication" do
|
295
255
|
#STDERR.puts "dtype=#{dtype.to_s}"
|
296
256
|
#STDERR.puts "2"
|
297
257
|
n = NMatrix.new([4,3], [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0], left_dtype)
|
@@ -303,7 +263,7 @@ describe NMatrix do
|
|
303
263
|
|
304
264
|
n.shape[0].should == 4
|
305
265
|
n.shape[1].should == 3
|
306
|
-
n.
|
266
|
+
n.dim.should == 2
|
307
267
|
|
308
268
|
n.shape[1].should == m.shape[0]
|
309
269
|
|
@@ -322,7 +282,7 @@ describe NMatrix do
|
|
322
282
|
|
323
283
|
|
324
284
|
[:dense, :list, :yale].each do |storage_type|
|
325
|
-
context
|
285
|
+
context storage_type do
|
326
286
|
it "can be duplicated" do
|
327
287
|
n = NMatrix.new(storage_type, [2,3], storage_type == :yale ? :float64 : 1.1)
|
328
288
|
n.stype.should equal(storage_type)
|
@@ -333,7 +293,7 @@ describe NMatrix do
|
|
333
293
|
|
334
294
|
m = n.dup
|
335
295
|
m.shape.should == n.shape
|
336
|
-
m.
|
296
|
+
m.dim.should == n.dim
|
337
297
|
m.object_id.should_not == n.object_id
|
338
298
|
m.stype.should equal(storage_type)
|
339
299
|
m[0,0].should == n[0,0]
|
@@ -347,49 +307,93 @@ describe NMatrix do
|
|
347
307
|
lambda { NMatrix.new(storage_type, [1,10], storage_type == :yale ? :int8 : 0)[0,10] }.should raise_error(ArgumentError, "out of range")
|
348
308
|
end
|
349
309
|
|
350
|
-
it "
|
310
|
+
it "sets and gets" do
|
351
311
|
n = NMatrix.new(storage_type, 2, storage_type == :yale ? :int8 : 0)
|
352
|
-
|
312
|
+
n[0,1] = 1
|
353
313
|
n[0,0].should == 0
|
354
314
|
n[1,0].should == 0
|
355
315
|
n[0,1].should == 1
|
356
316
|
n[1,1].should == 0
|
357
317
|
end
|
318
|
+
|
319
|
+
it "sets and gets references" do
|
320
|
+
n = NMatrix.new(storage_type, 2, storage_type == :yale ? :int8 : 0)
|
321
|
+
(n[0,1] = 1).should == 1
|
322
|
+
n[0,1].should == 1
|
323
|
+
end
|
324
|
+
|
358
325
|
end
|
359
326
|
|
360
327
|
# dense and list, not yale
|
361
328
|
context "(storage: #{storage_type})" do
|
362
|
-
it "
|
329
|
+
it "gets default value" do
|
363
330
|
NMatrix.new(storage_type, 3, 0)[1,1].should == 0
|
364
331
|
NMatrix.new(storage_type, 3, 0.1)[1,1].should == 0.1
|
365
332
|
NMatrix.new(storage_type, 3, 1)[1,1].should == 1
|
366
333
|
end
|
367
334
|
|
368
|
-
it "returns
|
335
|
+
it "returns shape and dim" do
|
369
336
|
NMatrix.new(storage_type, [3,2,8], 0).shape.should == [3,2,8]
|
370
|
-
NMatrix.new(storage_type, [3,2,8], 0).
|
337
|
+
NMatrix.new(storage_type, [3,2,8], 0).dim.should == 3
|
371
338
|
end
|
372
339
|
end unless storage_type == :yale
|
373
340
|
end
|
374
341
|
|
375
342
|
|
376
|
-
it "
|
343
|
+
it "handles dense construction" do
|
377
344
|
NMatrix.new(3,0)[1,1].should == 0
|
378
345
|
lambda { NMatrix.new(3,:int8)[1,1] }.should_not raise_error
|
379
346
|
end
|
380
347
|
|
381
|
-
it "
|
348
|
+
it "allows iteration of Ruby object matrices" do
|
382
349
|
n = NMatrix.new(:dense, [3,3], [1,2,3,4,5,6,7,8,9], :object)
|
383
350
|
n.each do |x|
|
384
351
|
puts x
|
385
352
|
end
|
386
353
|
end
|
387
354
|
|
388
|
-
it "
|
355
|
+
it "allows iteration of non-Ruby object matrices" do
|
389
356
|
n = NMatrix.new(:dense, [3,3], [1,2,3,4,5,6,7,8,9], :int64)
|
390
357
|
n.each do |x|
|
391
358
|
puts x
|
392
359
|
end
|
393
360
|
end
|
394
361
|
|
395
|
-
|
362
|
+
it "calculates the complex conjugate in-place" do
|
363
|
+
n = NMatrix.new(:dense, 3, [1,2,3,4,5,6,7,8,9], :complex128)
|
364
|
+
n.complex_conjugate!
|
365
|
+
# FIXME: Actually test that values are correct.
|
366
|
+
end
|
367
|
+
|
368
|
+
it "converts from list to yale properly" do
|
369
|
+
m = NMatrix.new(:list, 3, 0)
|
370
|
+
m[0,2] = 333
|
371
|
+
m[2,2] = 777
|
372
|
+
n = m.cast(:yale, :int32)
|
373
|
+
puts n.capacity
|
374
|
+
n.extend NMatrix::YaleFunctions
|
375
|
+
puts n.yale_ija.inspect
|
376
|
+
puts n.yale_a.inspect
|
377
|
+
n[0,0].should == 0
|
378
|
+
n[0,1].should == 0
|
379
|
+
n[0,2].should == 333
|
380
|
+
n[1,0].should == 0
|
381
|
+
n[1,1].should == 0
|
382
|
+
n[1,2].should == 0
|
383
|
+
n[2,0].should == 0
|
384
|
+
n[2,1].should == 0
|
385
|
+
n[2,2].should == 777
|
386
|
+
end
|
387
|
+
|
388
|
+
it "should return an enumerator when each is called without a block" do
|
389
|
+
a = NMatrix.new(2, 1)
|
390
|
+
b = NMatrix.new(2, [-1,0,1,0])
|
391
|
+
enums = [a.each, b.each]
|
392
|
+
|
393
|
+
begin
|
394
|
+
atans = []
|
395
|
+
atans << Math.atan2(*enums.map(&:next)) while true
|
396
|
+
rescue StopIteration
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|
data/spec/nmatrix_yale_spec.rb
CHANGED
@@ -27,85 +27,96 @@
|
|
27
27
|
require "./lib/nmatrix"
|
28
28
|
|
29
29
|
describe NMatrix do
|
30
|
-
it "
|
30
|
+
it "calculates itype" do
|
31
|
+
NMatrix.itype_by_shape([4,4]).should == :uint8
|
32
|
+
NMatrix.itype_by_shape(4).should == :uint8
|
33
|
+
## FIXME: Check larger shapes for correct itype
|
34
|
+
end
|
35
|
+
|
36
|
+
it "compares two empty yale matrices" do
|
31
37
|
n = NMatrix.new(:yale, [4,4], :float64)
|
32
38
|
m = NMatrix.new(:yale, [4,4], :float64)
|
33
|
-
n.should
|
39
|
+
n.should == m
|
34
40
|
end
|
35
41
|
|
36
|
-
it "
|
42
|
+
it "compares two yale matrices following basic assignments" do
|
37
43
|
n = NMatrix.new(:yale, [2,2], :float64)
|
38
44
|
m = NMatrix.new(:yale, [2,2], :float64)
|
39
45
|
m[0,0] = 1
|
40
46
|
m[0,1] = 1
|
41
|
-
n.should_not
|
47
|
+
n.should_not == m
|
42
48
|
n[0,0] = 1
|
43
|
-
n.should_not
|
49
|
+
n.should_not == m
|
44
50
|
n[0,1] = 1
|
45
|
-
n.should
|
51
|
+
n.should == m
|
46
52
|
end
|
47
53
|
|
48
|
-
it "
|
54
|
+
it "compares two yale matrices following elementwise operations" do
|
49
55
|
n = NMatrix.new(:yale, [2,2], :float64)
|
50
56
|
n[0,1] = 1
|
51
57
|
m = NMatrix.new(:yale, [2,2], :float64)
|
52
58
|
m[0,1] = -1
|
53
59
|
r = NMatrix.new(:yale, [2,2], :float64)
|
54
60
|
r[0,1] = 0
|
55
|
-
(n+m).should
|
61
|
+
(n+m).should == r
|
56
62
|
end
|
57
63
|
|
58
|
-
it "
|
64
|
+
it "sets diagonal values in yale" do
|
59
65
|
n = NMatrix.new(:yale, [2,3], :float64)
|
66
|
+
n.extend(NMatrix::YaleFunctions)
|
60
67
|
n[1,1] = 0.1
|
61
68
|
n[0,0] = 0.2
|
62
|
-
n.
|
69
|
+
n.yale_d.should == [0.2, 0.1]
|
63
70
|
end
|
64
71
|
|
65
72
|
it "does not resize yale until necessary" do
|
66
73
|
n = NMatrix.new(:yale, [2,3], :float64)
|
67
|
-
n.
|
74
|
+
n.extend(NMatrix::YaleFunctions)
|
75
|
+
n.yale_size.should == 3
|
68
76
|
n.capacity.should == 5
|
69
77
|
n[0,0] = 0.1
|
70
78
|
n[0,1] = 0.2
|
71
79
|
n[1,0] = 0.3
|
72
|
-
n.
|
80
|
+
n.yale_size.should == 5
|
73
81
|
n.capacity.should == 5
|
74
82
|
end
|
75
83
|
|
76
84
|
|
77
|
-
it "
|
85
|
+
it "sets when not resizing (yale)" do
|
78
86
|
n = NMatrix.new(:yale, [2,3], :float64)
|
87
|
+
n.extend(NMatrix::YaleFunctions)
|
79
88
|
n[0,0] = 0.1
|
80
89
|
n[0,1] = 0.2
|
81
90
|
n[1,0] = 0.3
|
82
|
-
n.
|
83
|
-
n.
|
91
|
+
n.yale_a == [0.1, 0.0, 0.0, 0.2, 0.3]
|
92
|
+
n.yale_ija == [3,4,5,1,0]
|
84
93
|
end
|
85
94
|
|
86
|
-
it "
|
95
|
+
it "sets when resizing (yale)" do
|
87
96
|
n = NMatrix.new(:yale, [2,3], :float64)
|
97
|
+
n.extend(NMatrix::YaleFunctions)
|
88
98
|
n[0,0] = 0.01
|
89
99
|
n[1,1] = 0.1
|
90
100
|
n[0,1] = 0.2
|
91
101
|
n[1,0] = 0.3
|
92
102
|
n[1,2] = 0.4
|
93
|
-
n.
|
94
|
-
n.
|
95
|
-
n.
|
96
|
-
n.
|
103
|
+
n.yale_d.should == [0.01, 0.1]
|
104
|
+
n.yale_ia.should == [3,4,6]
|
105
|
+
n.yale_ja.should == [1,0,2,nil]
|
106
|
+
n.yale_lu.should == [0.2, 0.3, 0.4, nil]
|
97
107
|
end
|
98
108
|
|
99
|
-
it "
|
109
|
+
it "sets values within rows of yale" do
|
100
110
|
n = NMatrix.new(:yale, [3,20], :float64)
|
111
|
+
n.extend(NMatrix::YaleFunctions)
|
101
112
|
n[2,1] = 1.0
|
102
113
|
n[2,0] = 1.5
|
103
114
|
n[2,15] = 2.0
|
104
|
-
n.
|
105
|
-
n.
|
115
|
+
n.yale_lu.should == [1.5, 1.0, 2.0]
|
116
|
+
n.yale_ja.should == [0, 1, 15]
|
106
117
|
end
|
107
118
|
|
108
|
-
it "
|
119
|
+
it "gets values within rows of yale" do
|
109
120
|
n = NMatrix.new(:yale, [3,20], :float64)
|
110
121
|
n[2,1] = 1.0
|
111
122
|
n[2,0] = 1.5
|
@@ -115,8 +126,9 @@ describe NMatrix do
|
|
115
126
|
n[2,15].should == 2.0
|
116
127
|
end
|
117
128
|
|
118
|
-
it "
|
129
|
+
it "sets values within large rows of yale" do
|
119
130
|
n = NMatrix.new(:yale, [10,300], :float64)
|
131
|
+
n.extend(NMatrix::YaleFunctions)
|
120
132
|
n[5,1] = 1.0
|
121
133
|
n[5,0] = 1.5
|
122
134
|
n[5,15] = 2.0
|
@@ -127,12 +139,13 @@ describe NMatrix do
|
|
127
139
|
n[5,293] = 2.0
|
128
140
|
n[5,299] = 7.0
|
129
141
|
n[5,100] = 8.0
|
130
|
-
n.
|
131
|
-
n.
|
142
|
+
n.yale_lu.should == [1.5, 1.0, 2.0, 8.0, 5.0, 6.0, 3.0, 4.0, 2.0, 7.0]
|
143
|
+
n.yale_ja.should == [0, 1, 15, 100, 289, 290, 291, 292, 293, 299]
|
132
144
|
end
|
133
145
|
|
134
|
-
it "
|
146
|
+
it "gets values within large rows of yale" do
|
135
147
|
n = NMatrix.new(:yale, [10,300], :float64)
|
148
|
+
n.extend(NMatrix::YaleFunctions)
|
136
149
|
n[5,1] = 1.0
|
137
150
|
n[5,0] = 1.5
|
138
151
|
n[5,15] = 2.0
|
@@ -144,13 +157,13 @@ describe NMatrix do
|
|
144
157
|
n[5,299] = 7.0
|
145
158
|
n[5,100] = 8.0
|
146
159
|
|
147
|
-
n.
|
148
|
-
j = n.
|
149
|
-
n[5,j].should == n.
|
160
|
+
n.yale_ja.each_index do |idx|
|
161
|
+
j = n.yale_ja[idx]
|
162
|
+
n[5,j].should == n.yale_lu[idx]
|
150
163
|
end
|
151
164
|
end
|
152
165
|
|
153
|
-
it "
|
166
|
+
it "dots two identical yale matrices" do
|
154
167
|
a = NMatrix.new(:yale, 4, :float64)
|
155
168
|
a[0,1] = 4.0
|
156
169
|
a[1,2] = 1.0
|
@@ -178,8 +191,9 @@ describe NMatrix do
|
|
178
191
|
c[3,3].should == 2.0
|
179
192
|
end
|
180
193
|
|
181
|
-
it "
|
194
|
+
it "dots two identical yale matrices where a positive and negative partial sum cancel on the diagonal" do
|
182
195
|
a = NMatrix.new(:yale, 4, :float64)
|
196
|
+
|
183
197
|
a[0,0] = 1.0
|
184
198
|
a[0,1] = 4.0
|
185
199
|
a[1,2] = 2.0
|
@@ -207,12 +221,14 @@ describe NMatrix do
|
|
207
221
|
#c[3,2].should == 8.0
|
208
222
|
#c[3,3].should == 0.0 # this is the positive and negative partial sum cancel
|
209
223
|
|
210
|
-
c.
|
211
|
-
|
224
|
+
c.extend(NMatrix::YaleFunctions)
|
225
|
+
|
226
|
+
c.yale_ija.reject { |i| i.nil? }.should == [5,8,9,9,11,1,2,3,3,1,2]
|
227
|
+
c.yale_a.reject { |i| i.nil? }.should == [1.0, -16.0, 0.0, 0.0, 0.0, 4.0, 8.0, -16.0, -16.0, 16.0, 8.0]
|
212
228
|
|
213
229
|
end
|
214
230
|
|
215
|
-
it "
|
231
|
+
it "transposes yale" do
|
216
232
|
a = NMatrix.new(:yale, 4, :float64)
|
217
233
|
a[0,0] = 1.0
|
218
234
|
a[0,1] = 4.0
|