nmatrix 0.0.1 → 0.0.2
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.
- 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/slice_spec.rb
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
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
|
+
# == slec_spec.rb
|
|
24
|
+
#
|
|
25
|
+
# Test of slice operations.
|
|
26
|
+
#
|
|
27
|
+
require File.dirname(__FILE__) + "/spec_helper.rb"
|
|
28
|
+
|
|
29
|
+
describe "Slice operation" do
|
|
30
|
+
[:dense, :list, :yale].each do |stype|
|
|
31
|
+
context "for #{stype}" do
|
|
32
|
+
before :each do
|
|
33
|
+
@m = create_matrix(stype)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
unless stype == :yale
|
|
37
|
+
it "should have #is_ref? method" do
|
|
38
|
+
a = @m[0..1, 0..1]
|
|
39
|
+
b = @m.slice(0..1, 0..1)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@m.is_ref?.should be_false
|
|
43
|
+
a.is_ref?.should be_true
|
|
44
|
+
b.is_ref?.should be_false
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "reference should compare with non-reference" do
|
|
48
|
+
@m.slice(1..2,0..1).should == @m[1..2, 0..1]
|
|
49
|
+
@m[1..2,0..1].should == @m.slice(1..2, 0..1)
|
|
50
|
+
@m[1..2,0..1].should == @m[1..2, 0..1]
|
|
51
|
+
end
|
|
52
|
+
end # unless stype == :yale
|
|
53
|
+
|
|
54
|
+
context "with copying" do
|
|
55
|
+
it 'should return an NMatrix' do
|
|
56
|
+
n = @m.slice(0..1,0..1)
|
|
57
|
+
nm_eql(n, NMatrix.new([2,2], [0,1,3,4], :int32)).should be_true
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
it 'should return a copy of 2x2 matrix to self elements' do
|
|
61
|
+
n = @m.slice(1..2,0..1)
|
|
62
|
+
n.shape.should eql([2,2])
|
|
63
|
+
|
|
64
|
+
n[1,1].should == @m[2,1]
|
|
65
|
+
n[1,1] = -9
|
|
66
|
+
@m[2,1].should eql(7)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'should return a 1x2 matrix with refs to self elements' do
|
|
70
|
+
n = @m.slice(0,1..2)
|
|
71
|
+
n.shape.should eql([1,2])
|
|
72
|
+
|
|
73
|
+
n[0,0].should == @m[0,1]
|
|
74
|
+
n[0,0] = -9
|
|
75
|
+
@m[0,1].should eql(1)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
it 'should return a 2x1 matrix with refs to self elements' do
|
|
79
|
+
n = @m.slice(0..1,1)
|
|
80
|
+
n.shape.should eql([2,1])
|
|
81
|
+
|
|
82
|
+
n[0,0].should == @m[0,1]
|
|
83
|
+
n[0,0] = -9
|
|
84
|
+
@m[0,1].should eql(1)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
it 'should be correct slice for range 0..2 and 0...3' do
|
|
88
|
+
@m.slice(0..2,0..2).should == @m.slice(0...3,0...3)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
[:dense, :list, :yale].each do |cast_type|
|
|
92
|
+
it "should cast from #{stype.upcase} to #{cast_type.upcase}" do
|
|
93
|
+
nm_eql(@m.slice(1..2, 1..2).cast(cast_type, :int32), @m.slice(1..2,1..2)).should be_true
|
|
94
|
+
nm_eql(@m.slice(0..1, 1..2).cast(cast_type, :int32), @m.slice(0..1,1..2)).should be_true
|
|
95
|
+
nm_eql(@m.slice(1..2, 0..1).cast(cast_type, :int32), @m.slice(1..2,0..1)).should be_true
|
|
96
|
+
nm_eql(@m.slice(0..1, 0..1).cast(cast_type, :int32), @m.slice(0..1,0..1)).should be_true
|
|
97
|
+
|
|
98
|
+
# Non square
|
|
99
|
+
nm_eql(@m.slice(0..2, 1..2).cast(cast_type, :int32), @m.slice(0..2,1..2)).should be_true
|
|
100
|
+
nm_eql(@m.slice(1..2, 0..2).cast(cast_type, :int32), @m.slice(1..2,0..2)).should be_true
|
|
101
|
+
|
|
102
|
+
# Full
|
|
103
|
+
nm_eql(@m.slice(0..2, 0..2).cast(cast_type, :int32), @m).should be_true
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
if stype == :yale
|
|
109
|
+
context "by reference" do
|
|
110
|
+
it "should be raise error" do
|
|
111
|
+
expect{ @m[1..2,1..2] }.to raise_error(NotImplementedError)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
else
|
|
115
|
+
context "by reference" do
|
|
116
|
+
it 'should return an NMatrix' do
|
|
117
|
+
n = @m[0..1,0..1]
|
|
118
|
+
nm_eql(n, NMatrix.new([2,2], [0,1,3,4], :int32)).should be_true
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it 'should return a 2x2 matrix with refs to self elements' do
|
|
122
|
+
n = @m[1..2,0..1]
|
|
123
|
+
n.shape.should eql([2,2])
|
|
124
|
+
|
|
125
|
+
n[0,0].should == @m[1,0]
|
|
126
|
+
n[0,0] = -9
|
|
127
|
+
@m[1,0].should eql(-9)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
it 'should return a 1x2 matrix with refs to self elements' do
|
|
131
|
+
n = @m[0,1..2]
|
|
132
|
+
n.shape.should eql([1,2])
|
|
133
|
+
|
|
134
|
+
n[0,0].should == @m[0,1]
|
|
135
|
+
n[0,0] = -9
|
|
136
|
+
@m[0,1].should eql(-9)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it 'should return a 2x1 matrix with refs to self elements' do
|
|
140
|
+
n = @m[0..1,1]
|
|
141
|
+
n.shape.should eql([2,1])
|
|
142
|
+
|
|
143
|
+
n[0,0].should == @m[0,1]
|
|
144
|
+
n[0,0] = -9
|
|
145
|
+
@m[0,1].should eql(-9)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it 'should set value from NMatrix'
|
|
149
|
+
|
|
150
|
+
it 'should slice again' do
|
|
151
|
+
n = @m[1..2, 1..2]
|
|
152
|
+
nm_eql(n[1,0..1], NMatrix.new([1,2], [7,8])).should be_true
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
it 'should be correct slice for range 0..2 and 0...3' do
|
|
156
|
+
@m[0..2,0..2].should == @m[0...3,0...3]
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
if stype == :dense
|
|
160
|
+
[:byte,:int8,:int16,:int32,:int64,:float32,:float64,:rational64,:rational128].each do |left_dtype|
|
|
161
|
+
[:byte,:int8,:int16,:int32,:int64,:float32,:float64,:rational64,:rational128].each do |right_dtype|
|
|
162
|
+
|
|
163
|
+
# Won't work if they're both 1-byte, due to overflow.
|
|
164
|
+
next if [:byte,:int8].include?(left_dtype) && [:byte,:int8].include?(right_dtype)
|
|
165
|
+
|
|
166
|
+
# For now, don't bother testing int-int mult.
|
|
167
|
+
#next if [:int8,:int16,:int32,:int64].include?(left_dtype) && [:int8,:int16,:int32,:int64].include?(right_dtype)
|
|
168
|
+
it "handles #{left_dtype.to_s} dot #{right_dtype.to_s} matrix multiplication" do
|
|
169
|
+
#STDERR.puts "dtype=#{dtype.to_s}"
|
|
170
|
+
#STDERR.puts "2"
|
|
171
|
+
|
|
172
|
+
nary = if left_dtype.to_s =~ /complex/
|
|
173
|
+
COMPLEX_MATRIX43A_ARRAY
|
|
174
|
+
elsif left_dtype.to_s =~ /rational/
|
|
175
|
+
RATIONAL_MATRIX43A_ARRAY
|
|
176
|
+
else
|
|
177
|
+
MATRIX43A_ARRAY
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
mary = if right_dtype.to_s =~ /complex/
|
|
181
|
+
COMPLEX_MATRIX32A_ARRAY
|
|
182
|
+
elsif right_dtype.to_s =~ /rational/
|
|
183
|
+
RATIONAL_MATRIX32A_ARRAY
|
|
184
|
+
else
|
|
185
|
+
MATRIX32A_ARRAY
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
n = NMatrix.new([4,3], nary, left_dtype)[1..3,1..2]
|
|
189
|
+
m = NMatrix.new([3,2], mary, right_dtype)[1..2,0..1]
|
|
190
|
+
|
|
191
|
+
r = n.dot m
|
|
192
|
+
r.shape.should eql([3,2])
|
|
193
|
+
|
|
194
|
+
r[0,0].should == 219.0
|
|
195
|
+
r[0,1].should == 185.0
|
|
196
|
+
r[1,0].should == 244.0
|
|
197
|
+
r[1,1].should == 205.0
|
|
198
|
+
r[2,0].should == 42.0
|
|
199
|
+
r[2,1].should == 35.0
|
|
200
|
+
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it 'should be cleaned up by garbage collector without errors' do
|
|
207
|
+
1.times do
|
|
208
|
+
n = @m[1..2,0..1]
|
|
209
|
+
end
|
|
210
|
+
GC.start
|
|
211
|
+
@m.should == NMatrix.new(:dense, [3,3], (0..9).to_a, :int32).cast(stype, :int32)
|
|
212
|
+
n = nil
|
|
213
|
+
1.times do
|
|
214
|
+
m = NMatrix.new(:dense, [2,2], [1,2,3,4]).cast(stype, :int32)
|
|
215
|
+
n = m[0..1,0..1]
|
|
216
|
+
end
|
|
217
|
+
GC.start
|
|
218
|
+
n.should == NMatrix.new(:dense, [2,2], [1,2,3,4]).cast(stype, :int32)
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
[:dense, :list, :yale].each do |cast_type|
|
|
222
|
+
it "should cast from #{stype.upcase} to #{cast_type.upcase}" do
|
|
223
|
+
nm_eql(@m[1..2, 1..2].cast(cast_type, :int32), @m[1..2,1..2]).should be_true
|
|
224
|
+
nm_eql(@m[0..1, 1..2].cast(cast_type, :int32), @m[0..1,1..2]).should be_true
|
|
225
|
+
nm_eql(@m[1..2, 0..1].cast(cast_type, :int32), @m[1..2,0..1]).should be_true
|
|
226
|
+
nm_eql(@m[0..1, 0..1].cast(cast_type, :int32), @m[0..1,0..1]).should be_true
|
|
227
|
+
|
|
228
|
+
# Non square
|
|
229
|
+
nm_eql(@m[0..2, 1..2].cast(cast_type, :int32), @m[0..2,1..2]).should be_true
|
|
230
|
+
nm_eql(@m[1..2, 0..2].cast(cast_type, :int32), @m[1..2,0..2]).should be_true
|
|
231
|
+
|
|
232
|
+
# Full
|
|
233
|
+
nm_eql(@m[0..2, 0..2].cast(cast_type, :int32), @m).should be_true
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
end # unless stype == :yale
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# Stupid but independent comparison
|
|
242
|
+
def nm_eql(n, m)
|
|
243
|
+
if n.shape != m.shape
|
|
244
|
+
false
|
|
245
|
+
else
|
|
246
|
+
n.shape[0].times do |i|
|
|
247
|
+
n.shape[1].times do |j|
|
|
248
|
+
if n[i,j] != m[i,j]
|
|
249
|
+
puts "n[#{i},#{j}] != m[#{i},#{j}] (#{n[i,j]} != #{m[i,j]})"
|
|
250
|
+
return false
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
true
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
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
|
+
# == spec_helper.rb
|
|
24
|
+
#
|
|
25
|
+
# Common data for testing.
|
|
26
|
+
require "./lib/nmatrix"
|
|
27
|
+
|
|
28
|
+
MATRIX43A_ARRAY = [14.0, 9.0, 3.0, 2.0, 11.0, 15.0, 0.0, 12.0, 17.0, 5.0, 2.0, 3.0]
|
|
29
|
+
MATRIX32A_ARRAY = [12.0, 25.0, 9.0, 10.0, 8.0, 5.0]
|
|
30
|
+
|
|
31
|
+
COMPLEX_MATRIX43A_ARRAY = MATRIX43A_ARRAY.zip(MATRIX43A_ARRAY.reverse).collect { |ary| Complex(ary[0], ary[1]) }
|
|
32
|
+
COMPLEX_MATRIX32A_ARRAY = MATRIX32A_ARRAY.zip(MATRIX32A_ARRAY.reverse).collect { |ary| Complex(ary[0], -ary[1]) }
|
|
33
|
+
|
|
34
|
+
RATIONAL_MATRIX43A_ARRAY = MATRIX43A_ARRAY.collect { |x| x.to_r }
|
|
35
|
+
RATIONAL_MATRIX32A_ARRAY = MATRIX32A_ARRAY.collect { |x| x.to_r }
|
|
36
|
+
|
|
37
|
+
def create_matrix(stype)
|
|
38
|
+
m = NMatrix.new(stype, [3,3], 0, :int32)
|
|
39
|
+
|
|
40
|
+
m[0,0] = 0
|
|
41
|
+
m[0,1] = 1
|
|
42
|
+
m[0,2] = 2
|
|
43
|
+
m[1,0] = 3
|
|
44
|
+
m[1,1] = 4
|
|
45
|
+
m[1,2] = 5
|
|
46
|
+
m[2,0] = 6
|
|
47
|
+
m[2,1] = 7
|
|
48
|
+
m[2,2] = 8
|
|
49
|
+
|
|
50
|
+
m
|
|
51
|
+
end
|