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.
Files changed (91) hide show
  1. data/.gitignore +27 -0
  2. data/.rspec +2 -0
  3. data/Gemfile +3 -5
  4. data/Guardfile +6 -0
  5. data/History.txt +33 -0
  6. data/Manifest.txt +41 -38
  7. data/README.rdoc +88 -11
  8. data/Rakefile +35 -53
  9. data/ext/nmatrix/data/complex.h +372 -0
  10. data/ext/nmatrix/data/data.cpp +275 -0
  11. data/ext/nmatrix/data/data.h +707 -0
  12. data/ext/nmatrix/data/rational.h +421 -0
  13. data/ext/nmatrix/data/ruby_object.h +446 -0
  14. data/ext/nmatrix/extconf.rb +101 -51
  15. data/ext/nmatrix/new_extconf.rb +56 -0
  16. data/ext/nmatrix/nmatrix.cpp +1609 -0
  17. data/ext/nmatrix/nmatrix.h +265 -849
  18. data/ext/nmatrix/ruby_constants.cpp +134 -0
  19. data/ext/nmatrix/ruby_constants.h +103 -0
  20. data/ext/nmatrix/storage/common.cpp +70 -0
  21. data/ext/nmatrix/storage/common.h +170 -0
  22. data/ext/nmatrix/storage/dense.cpp +665 -0
  23. data/ext/nmatrix/storage/dense.h +116 -0
  24. data/ext/nmatrix/storage/list.cpp +1088 -0
  25. data/ext/nmatrix/storage/list.h +129 -0
  26. data/ext/nmatrix/storage/storage.cpp +658 -0
  27. data/ext/nmatrix/storage/storage.h +99 -0
  28. data/ext/nmatrix/storage/yale.cpp +1601 -0
  29. data/ext/nmatrix/storage/yale.h +208 -0
  30. data/ext/nmatrix/ttable_helper.rb +126 -0
  31. data/ext/nmatrix/{yale/smmp1_header.template.c → types.h} +36 -9
  32. data/ext/nmatrix/util/io.cpp +295 -0
  33. data/ext/nmatrix/util/io.h +117 -0
  34. data/ext/nmatrix/util/lapack.h +1175 -0
  35. data/ext/nmatrix/util/math.cpp +557 -0
  36. data/ext/nmatrix/util/math.h +1363 -0
  37. data/ext/nmatrix/util/sl_list.cpp +475 -0
  38. data/ext/nmatrix/util/sl_list.h +255 -0
  39. data/ext/nmatrix/util/util.h +78 -0
  40. data/lib/nmatrix/blas.rb +70 -0
  41. data/lib/nmatrix/io/mat5_reader.rb +567 -0
  42. data/lib/nmatrix/io/mat_reader.rb +162 -0
  43. data/lib/{string.rb → nmatrix/monkeys.rb} +49 -2
  44. data/lib/nmatrix/nmatrix.rb +199 -0
  45. data/lib/nmatrix/nvector.rb +103 -0
  46. data/lib/nmatrix/version.rb +27 -0
  47. data/lib/nmatrix.rb +22 -230
  48. data/nmatrix.gemspec +59 -0
  49. data/scripts/mac-brew-gcc.sh +47 -0
  50. data/spec/4x4_sparse.mat +0 -0
  51. data/spec/4x5_dense.mat +0 -0
  52. data/spec/blas_spec.rb +47 -0
  53. data/spec/elementwise_spec.rb +164 -0
  54. data/spec/io_spec.rb +60 -0
  55. data/spec/lapack_spec.rb +52 -0
  56. data/spec/math_spec.rb +96 -0
  57. data/spec/nmatrix_spec.rb +93 -89
  58. data/spec/nmatrix_yale_spec.rb +52 -36
  59. data/spec/nvector_spec.rb +1 -1
  60. data/spec/slice_spec.rb +257 -0
  61. data/spec/spec_helper.rb +51 -0
  62. data/spec/utm5940.mtx +83844 -0
  63. metadata +113 -71
  64. data/.autotest +0 -23
  65. data/.gemtest +0 -0
  66. data/ext/nmatrix/cblas.c +0 -150
  67. data/ext/nmatrix/dense/blas_header.template.c +0 -52
  68. data/ext/nmatrix/dense/elementwise.template.c +0 -107
  69. data/ext/nmatrix/dense/gemm.template.c +0 -159
  70. data/ext/nmatrix/dense/gemv.template.c +0 -130
  71. data/ext/nmatrix/dense/rationalmath.template.c +0 -68
  72. data/ext/nmatrix/dense.c +0 -307
  73. data/ext/nmatrix/depend +0 -18
  74. data/ext/nmatrix/generator/syntax_tree.rb +0 -481
  75. data/ext/nmatrix/generator.rb +0 -594
  76. data/ext/nmatrix/list.c +0 -774
  77. data/ext/nmatrix/nmatrix.c +0 -1977
  78. data/ext/nmatrix/rational.c +0 -98
  79. data/ext/nmatrix/yale/complexmath.template.c +0 -71
  80. data/ext/nmatrix/yale/elementwise.template.c +0 -46
  81. data/ext/nmatrix/yale/elementwise_op.template.c +0 -73
  82. data/ext/nmatrix/yale/numbmm.template.c +0 -94
  83. data/ext/nmatrix/yale/smmp1.template.c +0 -21
  84. data/ext/nmatrix/yale/smmp2.template.c +0 -43
  85. data/ext/nmatrix/yale/smmp2_header.template.c +0 -46
  86. data/ext/nmatrix/yale/sort_columns.template.c +0 -56
  87. data/ext/nmatrix/yale/symbmm.template.c +0 -54
  88. data/ext/nmatrix/yale/transp.template.c +0 -68
  89. data/ext/nmatrix/yale.c +0 -726
  90. data/lib/array.rb +0 -67
  91. data/spec/syntax_tree_spec.rb +0 -46
@@ -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
@@ -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