nmatrix-lapacke 0.2.3 → 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/nmatrix/data/ruby_object.h +1 -1
- data/ext/nmatrix/math/math.h +8 -2
- data/lib/nmatrix/lapacke.rb +2 -2
- data/spec/00_nmatrix_spec.rb +110 -3
- data/spec/01_enum_spec.rb +7 -1
- data/spec/02_slice_spec.rb +19 -1
- data/spec/03_nmatrix_monkeys_spec.rb +2 -0
- data/spec/elementwise_spec.rb +10 -2
- data/spec/homogeneous_spec.rb +1 -0
- data/spec/io_spec.rb +11 -1
- data/spec/math_spec.rb +346 -102
- data/spec/rspec_spec.rb +1 -0
- data/spec/shortcuts_spec.rb +47 -23
- data/spec/slice_set_spec.rb +7 -2
- data/spec/stat_spec.rb +11 -0
- metadata +5 -15
@@ -40,6 +40,8 @@ describe Array do
|
|
40
40
|
end
|
41
41
|
|
42
42
|
it "defaults to dtype :object if necessary" do
|
43
|
+
#FIXME
|
44
|
+
pending("not yet implemented for object dtype for NMatrix-JRuby") if jruby?
|
43
45
|
a = %w(this is an array of strings)
|
44
46
|
expect(a.to_nm([3,2]).dtype).to eq :object
|
45
47
|
expect(a.to_nm([3,2])).to eq(NMatrix.new([3,2], a, dtype: :object))
|
data/spec/elementwise_spec.rb
CHANGED
@@ -31,7 +31,7 @@ describe NMatrix do
|
|
31
31
|
context "yale" do
|
32
32
|
before :each do
|
33
33
|
@n = NMatrix.new(3, stype: :yale, dtype: :int64)
|
34
|
-
@n.extend NMatrix::YaleFunctions
|
34
|
+
@n.extend NMatrix::YaleFunctions unless jruby?
|
35
35
|
@m = NMatrix.new(3, stype: :yale, dtype: :int64)
|
36
36
|
@n[0,0] = 52
|
37
37
|
@n[0,2] = 5
|
@@ -40,10 +40,11 @@ describe NMatrix do
|
|
40
40
|
@n[2,0] = 6
|
41
41
|
@m[1,1] = -48
|
42
42
|
@m[0,2] = -5
|
43
|
-
@n.extend NMatrix::YaleFunctions
|
43
|
+
@n.extend NMatrix::YaleFunctions unless jruby?
|
44
44
|
end
|
45
45
|
|
46
46
|
it "should perform scalar math" do
|
47
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
47
48
|
x = @n * 3
|
48
49
|
expect(x[0,0]).to eq(52 * 3)
|
49
50
|
expect(x[0,1]).to eq(30 * 3)
|
@@ -57,6 +58,7 @@ describe NMatrix do
|
|
57
58
|
end
|
58
59
|
|
59
60
|
it "should refuse to perform a dot operation on a yale with non-zero default" do
|
61
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
60
62
|
r = NMatrix.new(3, stype: :yale, dtype: :int64)
|
61
63
|
y = r + 3
|
62
64
|
expect { y.dot(r) }.to raise_error
|
@@ -78,11 +80,13 @@ describe NMatrix do
|
|
78
80
|
end
|
79
81
|
|
80
82
|
it "should perform element-wise division" do
|
83
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
81
84
|
r = NMatrix.new(:dense, 3, [52, 30, -2, 0, -1, 0, 6, 0, 0], :int64).cast(:yale, :int64)
|
82
85
|
expect(@n/(@m+1)).to eq(r)
|
83
86
|
end
|
84
87
|
|
85
88
|
it "should perform element-wise modulo" do
|
89
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
86
90
|
m = NMatrix.new(3, stype: :yale, dtype: :int64, default: 0) + 5
|
87
91
|
expect(@n % m).to eq(NMatrix.new(:dense, 3, [2,0,0,0,0,0,1,0,0], :int64).cast(:yale, :int64))
|
88
92
|
end
|
@@ -124,6 +128,7 @@ describe NMatrix do
|
|
124
128
|
end
|
125
129
|
|
126
130
|
it "should perform scalar math" do
|
131
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
127
132
|
x = @n * 3
|
128
133
|
expect(x[0,0]).to eq(52 * 3)
|
129
134
|
expect(x[1,1]).to eq(40 * 3)
|
@@ -162,6 +167,7 @@ describe NMatrix do
|
|
162
167
|
end
|
163
168
|
|
164
169
|
it "should perform element-wise modulo" do
|
170
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
165
171
|
m = NMatrix.new(:list, 2, 1, :int64)
|
166
172
|
m[0,0] = 50
|
167
173
|
m[1,1] = 40
|
@@ -245,6 +251,7 @@ describe NMatrix do
|
|
245
251
|
end
|
246
252
|
|
247
253
|
it "divides in the Ruby way" do
|
254
|
+
pending("not yet implemented int dtype for NMatrix-JRuby") if jruby?
|
248
255
|
m = @m.clone
|
249
256
|
m[1,0] = 3
|
250
257
|
r = @n/m
|
@@ -258,6 +265,7 @@ describe NMatrix do
|
|
258
265
|
end
|
259
266
|
|
260
267
|
it "modulo" do
|
268
|
+
pending("not yet implemented int dtype for NMatrix-JRuby") if jruby?
|
261
269
|
expect(@n % (@m + 2)).to eq(NMatrix.new(:dense, [2,2], [-1, 0, 1, 4], :int64))
|
262
270
|
end
|
263
271
|
end
|
data/spec/homogeneous_spec.rb
CHANGED
@@ -80,6 +80,7 @@ describe 'NMatrix' do
|
|
80
80
|
end
|
81
81
|
|
82
82
|
it "should generate a translation matrix from an NMatrix with correctly inferred dtype" do
|
83
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
83
84
|
t = NMatrix.translation(NMatrix.new([3,1], [4,5,6], dtype: :float64) )
|
84
85
|
expect(t).to be_within(1e-8).of(NMatrix.new([4,4], [1, 0, 0, 4,
|
85
86
|
0, 1, 0, 5,
|
data/spec/io_spec.rb
CHANGED
@@ -33,10 +33,12 @@ describe NMatrix::IO do
|
|
33
33
|
let(:test_out) { File.join(tmp_dir, 'test-out') }
|
34
34
|
|
35
35
|
it "repacks a string" do
|
36
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
36
37
|
expect(NMatrix::IO::Matlab.repack("hello", :miUINT8, :byte)).to eq("hello")
|
37
38
|
end
|
38
39
|
|
39
40
|
it "creates yale from internal byte-string function" do
|
41
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
40
42
|
ia = NMatrix::IO::Matlab.repack("\0\1\3\3\4", :miUINT8, :itype)
|
41
43
|
ja = NMatrix::IO::Matlab.repack("\0\1\3\0\0\0\0\0\0\0\0", :miUINT8, :itype)
|
42
44
|
n = NMatrix.new(:yale, [4,4], :byte, ia, ja, "\2\3\5\4", :byte)
|
@@ -49,7 +51,7 @@ describe NMatrix::IO do
|
|
49
51
|
end
|
50
52
|
|
51
53
|
it "reads MATLAB .mat file containing a single square sparse matrix" do
|
52
|
-
|
54
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
53
55
|
n = NMatrix::IO::Matlab.load_mat("spec/4x4_sparse.mat")
|
54
56
|
expect(n[0,0]).to eq(2)
|
55
57
|
expect(n[1,1]).to eq(3)
|
@@ -79,6 +81,7 @@ describe NMatrix::IO do
|
|
79
81
|
end
|
80
82
|
|
81
83
|
it "loads a Point Cloud Library PCD file" do
|
84
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
82
85
|
n = NMatrix::IO::PointCloud.load("spec/test.pcd")
|
83
86
|
expect(n.column(0).sort.uniq.size).to eq(1)
|
84
87
|
expect(n.column(0).sort.uniq.first).to eq(207.008)
|
@@ -86,6 +89,7 @@ describe NMatrix::IO do
|
|
86
89
|
end
|
87
90
|
|
88
91
|
it "raises an error when reading a non-existent file" do
|
92
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
89
93
|
fn = rand(10000000).to_i.to_s
|
90
94
|
while File.exist?(fn)
|
91
95
|
fn = rand(10000000).to_i.to_s
|
@@ -94,6 +98,7 @@ describe NMatrix::IO do
|
|
94
98
|
end
|
95
99
|
|
96
100
|
it "reads and writes NMatrix dense" do
|
101
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
97
102
|
n = NMatrix.new(:dense, [4,3], [0,1,2,3,4,5,6,7,8,9,10,11], :int32)
|
98
103
|
n.write(test_out)
|
99
104
|
|
@@ -102,6 +107,7 @@ describe NMatrix::IO do
|
|
102
107
|
end
|
103
108
|
|
104
109
|
it "reads and writes NMatrix dense as symmetric" do
|
110
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
105
111
|
n = NMatrix.new(:dense, 3, [0,1,2,1,3,4,2,4,5], :int16)
|
106
112
|
n.write(test_out, :symmetric)
|
107
113
|
|
@@ -110,6 +116,7 @@ describe NMatrix::IO do
|
|
110
116
|
end
|
111
117
|
|
112
118
|
it "reads and writes NMatrix dense as skew" do
|
119
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
113
120
|
n = NMatrix.new(:dense, 3, [0,1,2,-1,3,4,-2,-4,5], :float64)
|
114
121
|
n.write(test_out, :skew)
|
115
122
|
|
@@ -118,6 +125,7 @@ describe NMatrix::IO do
|
|
118
125
|
end
|
119
126
|
|
120
127
|
it "reads and writes NMatrix dense as hermitian" do
|
128
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
121
129
|
n = NMatrix.new(:dense, 3, [0,1,2,1,3,4,2,4,5], :complex64)
|
122
130
|
n.write(test_out, :hermitian)
|
123
131
|
|
@@ -126,6 +134,7 @@ describe NMatrix::IO do
|
|
126
134
|
end
|
127
135
|
|
128
136
|
it "reads and writes NMatrix dense as upper" do
|
137
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
129
138
|
n = NMatrix.new(:dense, 3, [-1,1,2,3,4,5,6,7,8], :int32)
|
130
139
|
n.write(test_out, :upper)
|
131
140
|
|
@@ -137,6 +146,7 @@ describe NMatrix::IO do
|
|
137
146
|
end
|
138
147
|
|
139
148
|
it "reads and writes NMatrix dense as lower" do
|
149
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
140
150
|
n = NMatrix.new(:dense, 3, [-1,1,2,3,4,5,6,7,8], :int32)
|
141
151
|
n.write(test_out, :lower)
|
142
152
|
|
data/spec/math_spec.rb
CHANGED
@@ -99,14 +99,14 @@ describe "math" do
|
|
99
99
|
[:asin, :acos, :atan, :atanh].each do |atf|
|
100
100
|
|
101
101
|
it "should correctly apply elementwise #{atf}" do
|
102
|
-
expect(@m.send(atf)).to eq N.new(@size,
|
102
|
+
expect(@m.send(atf)).to eq N.new(@size,
|
103
103
|
@a.map{ |e| Math.send(atf, e) },
|
104
104
|
dtype: :float64, stype: stype)
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
108
|
it "should correctly apply elementtwise atan2" do
|
109
|
-
expect(@m.atan2(@m*0+1)).to eq N.new(@size,
|
109
|
+
expect(@m.atan2(@m*0+1)).to eq N.new(@size,
|
110
110
|
@a.map { |e| Math.send(:atan2, e, 1) }, dtype: :float64, stype: stype)
|
111
111
|
end
|
112
112
|
|
@@ -120,21 +120,22 @@ describe "math" do
|
|
120
120
|
end
|
121
121
|
end
|
122
122
|
end
|
123
|
-
|
124
|
-
context "Floor and ceil for #{stype}" do
|
123
|
+
|
124
|
+
context "Floor and ceil for #{stype}" do
|
125
125
|
|
126
126
|
[:floor, :ceil].each do |meth|
|
127
127
|
ALL_DTYPES.each do |dtype|
|
128
128
|
context dtype do
|
129
129
|
before :each do
|
130
130
|
@size = [2,2]
|
131
|
-
@m = NMatrix.seq(@size, dtype: dtype, stype: stype)+1
|
131
|
+
@m = NMatrix.seq(@size, dtype: dtype, stype: stype)+1 unless jruby? and dtype == :object
|
132
132
|
@a = @m.to_a.flatten
|
133
133
|
end
|
134
134
|
|
135
135
|
if dtype.to_s.match(/int/) or [:byte, :object].include?(dtype)
|
136
136
|
it "should return #{dtype} for #{dtype}" do
|
137
|
-
|
137
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby? and dtype == :object
|
138
|
+
|
138
139
|
expect(@m.send(meth)).to eq N.new(@size, @a.map { |e| e.send(meth) }, dtype: dtype, stype: stype)
|
139
140
|
|
140
141
|
if dtype == :object
|
@@ -147,11 +148,12 @@ describe "math" do
|
|
147
148
|
it "should return dtype int64 for #{dtype}" do
|
148
149
|
|
149
150
|
expect(@m.send(meth)).to eq N.new(@size, @a.map { |e| e.send(meth) }, dtype: dtype, stype: stype)
|
150
|
-
|
151
|
+
|
151
152
|
expect(@m.send(meth).dtype).to eq :int64
|
152
153
|
end
|
153
|
-
elsif dtype.to_s.match(/complex/)
|
154
|
+
elsif dtype.to_s.match(/complex/)
|
154
155
|
it "should properly calculate #{meth} for #{dtype}" do
|
156
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
155
157
|
|
156
158
|
expect(@m.send(meth)).to eq N.new(@size, @a.map { |e| e = Complex(e.real.send(meth), e.imag.send(meth)) }, dtype: dtype, stype: stype)
|
157
159
|
|
@@ -169,41 +171,44 @@ describe "math" do
|
|
169
171
|
context dtype do
|
170
172
|
before :each do
|
171
173
|
@size = [2,2]
|
172
|
-
@mat = NMatrix.new @size, [1.33334, 0.9998, 1.9999, -8.9999],
|
174
|
+
@mat = NMatrix.new @size, [1.33334, 0.9998, 1.9999, -8.9999],
|
173
175
|
dtype: dtype, stype: stype
|
174
|
-
@ans = @mat.to_a.flatten
|
176
|
+
@ans = @mat.to_a.flatten unless jruby? and dtype == :object
|
175
177
|
end
|
176
178
|
|
177
179
|
it "rounds" do
|
178
|
-
|
180
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby? and dtype == :object
|
181
|
+
expect(@mat.round).to eq(N.new(@size, @ans.map { |a| a.round},
|
179
182
|
dtype: dtype, stype: stype))
|
180
183
|
end unless(/complex/ =~ dtype)
|
181
184
|
|
182
185
|
it "rounds with args" do
|
183
|
-
|
186
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
187
|
+
expect(@mat.round(2)).to eq(N.new(@size, @ans.map { |a| a.round(2)},
|
184
188
|
dtype: dtype, stype: stype))
|
185
189
|
end unless(/complex/ =~ dtype)
|
186
190
|
|
187
191
|
it "rounds complex with args" do
|
192
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
188
193
|
puts @mat.round(2)
|
189
|
-
expect(@mat.round(2)).to be_within(0.0001).of(N.new [2,2], @ans.map {|a|
|
194
|
+
expect(@mat.round(2)).to be_within(0.0001).of(N.new [2,2], @ans.map {|a|
|
190
195
|
Complex(a.real.round(2), a.imag.round(2))},dtype: dtype, stype: stype)
|
191
196
|
end if(/complex/ =~ dtype)
|
192
197
|
|
193
198
|
it "rounds complex" do
|
194
|
-
|
199
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
200
|
+
expect(@mat.round).to eq(N.new [2,2], @ans.map {|a|
|
195
201
|
Complex(a.real.round, a.imag.round)},dtype: dtype, stype: stype)
|
196
202
|
end if(/complex/ =~ dtype)
|
197
203
|
end
|
198
204
|
end
|
199
205
|
end
|
200
|
-
|
206
|
+
|
201
207
|
end
|
202
208
|
end
|
203
209
|
end
|
204
210
|
|
205
211
|
NON_INTEGER_DTYPES.each do |dtype|
|
206
|
-
next if dtype == :object
|
207
212
|
context dtype do
|
208
213
|
before do
|
209
214
|
@m = NMatrix.new([3,4], GETRF_EXAMPLE_ARRAY, dtype: dtype)
|
@@ -217,11 +222,16 @@ describe "math" do
|
|
217
222
|
|
218
223
|
#haven't check this spec yet. Also it doesn't check all the elements of the matrix.
|
219
224
|
it "should correctly factorize a matrix" do
|
225
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
226
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
220
227
|
a = @m.factorize_lu
|
221
228
|
expect(a).to be_within(@err).of(NMatrix.new([3,4], GETRF_SOLUTION_ARRAY, dtype: dtype))
|
222
229
|
end
|
223
230
|
|
224
231
|
it "also returns the permutation matrix" do
|
232
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
233
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
234
|
+
|
225
235
|
a, p = @m.factorize_lu perm_matrix: true
|
226
236
|
|
227
237
|
expect(a).to be_within(@err).of(NMatrix.new([3,4], GETRF_SOLUTION_ARRAY, dtype: dtype))
|
@@ -233,7 +243,6 @@ describe "math" do
|
|
233
243
|
end
|
234
244
|
|
235
245
|
NON_INTEGER_DTYPES.each do |dtype|
|
236
|
-
next if dtype == :object
|
237
246
|
context dtype do
|
238
247
|
|
239
248
|
it "calculates cholesky decomposition using potrf (lower)" do
|
@@ -244,6 +253,8 @@ describe "math" do
|
|
244
253
|
# 1 2 6
|
245
254
|
# which is symmetric and positive-definite as required, but
|
246
255
|
# we need only store the lower-half of the matrix.
|
256
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
257
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
247
258
|
a = NMatrix.new([3,3],[1,0,0, 1,2,0, 1,2,6], dtype: dtype)
|
248
259
|
begin
|
249
260
|
r = a.potrf!(:lower)
|
@@ -257,6 +268,9 @@ describe "math" do
|
|
257
268
|
end
|
258
269
|
|
259
270
|
it "calculates cholesky decomposition using potrf (upper)" do
|
271
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
272
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
273
|
+
|
260
274
|
a = NMatrix.new([3,3],[1,1,1, 0,2,2, 0,0,6], dtype: dtype)
|
261
275
|
begin
|
262
276
|
r = a.potrf!(:upper)
|
@@ -270,6 +284,7 @@ describe "math" do
|
|
270
284
|
end
|
271
285
|
|
272
286
|
it "calculates cholesky decomposition using #factorize_cholesky" do
|
287
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
273
288
|
a = NMatrix.new([3,3],[1,2,1, 2,13,5, 1,5,6], dtype: dtype)
|
274
289
|
begin
|
275
290
|
u,l = a.factorize_cholesky
|
@@ -286,19 +301,18 @@ describe "math" do
|
|
286
301
|
end
|
287
302
|
|
288
303
|
NON_INTEGER_DTYPES.each do |dtype|
|
289
|
-
next if dtype == :object
|
290
304
|
context dtype do
|
291
|
-
|
292
|
-
it "calculates QR decomposition using factorize_qr for a square matrix" do
|
293
305
|
|
294
|
-
|
295
|
-
|
306
|
+
it "calculates QR decomposition using factorize_qr for a square matrix" do
|
307
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
308
|
+
a = NMatrix.new(3, [12.0, -51.0, 4.0,
|
309
|
+
6.0, 167.0, -68.0,
|
296
310
|
-4.0, 24.0, -41.0] , dtype: dtype)
|
297
|
-
|
311
|
+
|
298
312
|
q_solution = NMatrix.new([3,3], Q_SOLUTION_ARRAY_2, dtype: dtype)
|
299
313
|
|
300
|
-
r_solution = NMatrix.new([3,3], [-14.0, -21.0, 14,
|
301
|
-
0.0, -175, 70,
|
314
|
+
r_solution = NMatrix.new([3,3], [-14.0, -21.0, 14,
|
315
|
+
0.0, -175, 70,
|
302
316
|
0.0, 0.0, -35] , dtype: dtype)
|
303
317
|
|
304
318
|
err = case dtype
|
@@ -307,30 +321,32 @@ describe "math" do
|
|
307
321
|
when :float64, :complex128
|
308
322
|
1e-13
|
309
323
|
end
|
310
|
-
|
324
|
+
|
311
325
|
begin
|
312
326
|
q,r = a.factorize_qr
|
313
|
-
|
327
|
+
|
314
328
|
expect(q).to be_within(err).of(q_solution)
|
315
329
|
expect(r).to be_within(err).of(r_solution)
|
316
|
-
|
330
|
+
|
317
331
|
rescue NotImplementedError
|
318
332
|
pending "Suppressing a NotImplementedError when the lapacke plugin is not available"
|
319
333
|
end
|
320
334
|
end
|
321
335
|
|
322
336
|
it "calculates QR decomposition using factorize_qr for a tall and narrow rectangular matrix" do
|
337
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
338
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
323
339
|
|
324
|
-
a = NMatrix.new([4,2], [34.0, 21.0,
|
325
|
-
23.0, 53.0,
|
326
|
-
26.0, 346.0,
|
340
|
+
a = NMatrix.new([4,2], [34.0, 21.0,
|
341
|
+
23.0, 53.0,
|
342
|
+
26.0, 346.0,
|
327
343
|
23.0, 121.0] , dtype: dtype)
|
328
|
-
|
344
|
+
|
329
345
|
q_solution = NMatrix.new([4,4], Q_SOLUTION_ARRAY_1, dtype: dtype)
|
330
346
|
|
331
|
-
r_solution = NMatrix.new([4,2], [-53.75872022286244, -255.06559574252242,
|
332
|
-
0.0, 269.34836526051555,
|
333
|
-
0.0, 0.0,
|
347
|
+
r_solution = NMatrix.new([4,2], [-53.75872022286244, -255.06559574252242,
|
348
|
+
0.0, 269.34836526051555,
|
349
|
+
0.0, 0.0,
|
334
350
|
0.0, 0.0] , dtype: dtype)
|
335
351
|
|
336
352
|
err = case dtype
|
@@ -339,22 +355,24 @@ describe "math" do
|
|
339
355
|
when :float64, :complex128
|
340
356
|
1e-13
|
341
357
|
end
|
342
|
-
|
358
|
+
|
343
359
|
begin
|
344
360
|
q,r = a.factorize_qr
|
345
|
-
|
361
|
+
|
346
362
|
expect(q).to be_within(err).of(q_solution)
|
347
363
|
expect(r).to be_within(err).of(r_solution)
|
348
|
-
|
364
|
+
|
349
365
|
rescue NotImplementedError
|
350
366
|
pending "Suppressing a NotImplementedError when the lapacke plugin is not available"
|
351
367
|
end
|
352
368
|
end
|
353
369
|
|
354
370
|
it "calculates QR decomposition using factorize_qr for a short and wide rectangular matrix" do
|
355
|
-
|
371
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
372
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
373
|
+
|
356
374
|
a = NMatrix.new([3,4], [123,31,57,81,92,14,17,36,42,34,11,28], dtype: dtype)
|
357
|
-
|
375
|
+
|
358
376
|
q_solution = NMatrix.new([3,3], Q_SOLUTION_ARRAY_3, dtype: dtype)
|
359
377
|
|
360
378
|
r_solution = NMatrix.new([3,4], R_SOLUTION_ARRAY, dtype: dtype)
|
@@ -365,37 +383,37 @@ describe "math" do
|
|
365
383
|
when :float64, :complex128
|
366
384
|
1e-13
|
367
385
|
end
|
368
|
-
|
386
|
+
|
369
387
|
begin
|
370
388
|
q,r = a.factorize_qr
|
371
|
-
|
389
|
+
|
372
390
|
expect(q).to be_within(err).of(q_solution)
|
373
391
|
expect(r).to be_within(err).of(r_solution)
|
374
|
-
|
392
|
+
|
375
393
|
rescue NotImplementedError
|
376
394
|
pending "Suppressing a NotImplementedError when the lapacke plugin is not available"
|
377
395
|
end
|
378
396
|
end
|
379
|
-
|
380
|
-
it "calculates QR decomposition such that A - QR ~ 0" do
|
381
397
|
|
382
|
-
|
383
|
-
|
398
|
+
it "calculates QR decomposition such that A - QR ~ 0" do
|
399
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
400
|
+
a = NMatrix.new([3,3], [ 9.0, 0.0, 26.0,
|
401
|
+
12.0, 0.0, -7.0,
|
384
402
|
0.0, 4.0, 0.0] , dtype: dtype)
|
385
|
-
|
403
|
+
|
386
404
|
err = case dtype
|
387
405
|
when :float32, :complex64
|
388
406
|
1e-4
|
389
407
|
when :float64, :complex128
|
390
408
|
1e-13
|
391
409
|
end
|
392
|
-
|
410
|
+
|
393
411
|
begin
|
394
412
|
q,r = a.factorize_qr
|
395
|
-
a_expected = q.dot(r)
|
396
|
-
|
413
|
+
a_expected = q.dot(r)
|
414
|
+
|
397
415
|
expect(a_expected).to be_within(err).of(a)
|
398
|
-
|
416
|
+
|
399
417
|
rescue NotImplementedError
|
400
418
|
pending "Suppressing a NotImplementedError when the lapacke plugin is not available"
|
401
419
|
end
|
@@ -403,7 +421,7 @@ describe "math" do
|
|
403
421
|
|
404
422
|
|
405
423
|
it "calculates the orthogonal matrix Q in QR decomposition" do
|
406
|
-
|
424
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
407
425
|
a = N.new([2,2], [34.0, 21, 23, 53] , dtype: dtype)
|
408
426
|
|
409
427
|
err = case dtype
|
@@ -412,10 +430,10 @@ describe "math" do
|
|
412
430
|
when :float64, :complex128
|
413
431
|
1e-13
|
414
432
|
end
|
415
|
-
|
433
|
+
|
416
434
|
begin
|
417
435
|
q,r = a.factorize_qr
|
418
|
-
|
436
|
+
|
419
437
|
#Q is orthogonal if Q x Q.transpose = I
|
420
438
|
product = q.dot(q.transpose)
|
421
439
|
|
@@ -433,7 +451,6 @@ describe "math" do
|
|
433
451
|
|
434
452
|
ALL_DTYPES.each do |dtype|
|
435
453
|
next if dtype == :byte #doesn't work for unsigned types
|
436
|
-
next if dtype == :object
|
437
454
|
|
438
455
|
context dtype do
|
439
456
|
err = case dtype
|
@@ -444,9 +461,10 @@ describe "math" do
|
|
444
461
|
end
|
445
462
|
|
446
463
|
it "should correctly invert a matrix in place (bang)" do
|
447
|
-
|
448
|
-
|
449
|
-
0,
|
464
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
465
|
+
a = NMatrix.new(:dense, 5, [1, 8,-9, 7, 5,
|
466
|
+
0, 1, 0, 4, 4,
|
467
|
+
0, 0, 1, 2, 5,
|
450
468
|
0, 0, 0, 1,-5,
|
451
469
|
0, 0, 0, 0, 1 ], dtype)
|
452
470
|
b = NMatrix.new(:dense, 5, [1,-8, 9, 7, 17,
|
@@ -464,7 +482,9 @@ describe "math" do
|
|
464
482
|
end
|
465
483
|
end
|
466
484
|
|
467
|
-
|
485
|
+
|
486
|
+
it "should correctly invert a dense matrix out-of-place" do
|
487
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
468
488
|
a = NMatrix.new(:dense, 3, [1,2,3,0,1,4,5,6,0], dtype)
|
469
489
|
|
470
490
|
if a.integer_dtype?
|
@@ -475,12 +495,87 @@ describe "math" do
|
|
475
495
|
|
476
496
|
expect(a.invert).to be_within(err).of(b)
|
477
497
|
end
|
498
|
+
|
499
|
+
it "should correctly find exact inverse" do
|
500
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
501
|
+
a = NMatrix.new(:dense, 3, [1,2,3,0,1,4,5,6,0], dtype)
|
502
|
+
b = NMatrix.new(:dense, 3, [-24,18,5,20,-15,-4,-5,4,1], dtype)
|
503
|
+
|
504
|
+
expect(a.exact_inverse).to be_within(err).of(b)
|
505
|
+
end
|
506
|
+
|
507
|
+
it "should correctly find exact inverse" do
|
508
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
509
|
+
a = NMatrix.new(:dense, 2, [1,3,3,8], dtype)
|
510
|
+
b = NMatrix.new(:dense, 2, [-8,3,3,-1], dtype)
|
511
|
+
|
512
|
+
expect(a.exact_inverse).to be_within(err).of(b)
|
513
|
+
end
|
478
514
|
end
|
479
515
|
end
|
480
516
|
|
517
|
+
NON_INTEGER_DTYPES.each do |dtype|
|
518
|
+
context dtype do
|
519
|
+
err = Complex(1e-3, 1e-3)
|
520
|
+
it "should correctly invert a 2x2 matrix" do
|
521
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
522
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
523
|
+
if dtype == :complex64 || dtype == :complex128
|
524
|
+
a = NMatrix.new([2, 2], [Complex(16, 81), Complex(91, 51), \
|
525
|
+
Complex(13, 54), Complex(71, 24)], dtype: dtype)
|
526
|
+
b = NMatrix.identity(2, dtype: dtype)
|
527
|
+
|
528
|
+
begin
|
529
|
+
expect(a.dot(a.pinv)).to be_within(err).of(b)
|
530
|
+
rescue NotImplementedError
|
531
|
+
pending "Suppressing a NotImplementedError when the atlas plugin is not available"
|
532
|
+
end
|
533
|
+
|
534
|
+
else
|
535
|
+
a = NMatrix.new([2, 2], [141, 612, 9123, 654], dtype: dtype)
|
536
|
+
b = NMatrix.identity(2, dtype: dtype)
|
537
|
+
|
538
|
+
begin
|
539
|
+
expect(a.dot(a.pinv)).to be_within(err).of(b)
|
540
|
+
rescue NotImplementedError
|
541
|
+
pending "Suppressing a NotImplementedError when the atlas plugin is not available"
|
542
|
+
end
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
it "should verify a.dot(b.dot(a)) == a and b.dot(a.dot(b)) == b" do
|
547
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
548
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
549
|
+
if dtype == :complex64 || dtype == :complex128
|
550
|
+
a = NMatrix.new([3, 2], [Complex(94, 11), Complex(87, 51), Complex(82, 39), \
|
551
|
+
Complex(45, 16), Complex(25, 32), Complex(91, 43) ], dtype: dtype)
|
552
|
+
|
553
|
+
begin
|
554
|
+
b = a.pinv # pseudo inverse
|
555
|
+
expect(a.dot(b.dot(a))).to be_within(err).of(a)
|
556
|
+
expect(b.dot(a.dot(b))).to be_within(err).of(b)
|
557
|
+
rescue NotImplementedError
|
558
|
+
pending "Suppressing a NotImplementedError when the atlas plugin is not available"
|
559
|
+
end
|
560
|
+
|
561
|
+
else
|
562
|
+
a = NMatrix.new([3, 3], [9, 4, 52, 12, 52, 1, 3, 55, 6], dtype: dtype)
|
563
|
+
|
564
|
+
begin
|
565
|
+
b = a.pinv # pseudo inverse
|
566
|
+
expect(a.dot(b.dot(a))).to be_within(err).of(a)
|
567
|
+
expect(b.dot(a.dot(b))).to be_within(err).of(b)
|
568
|
+
rescue NotImplementedError
|
569
|
+
pending "Suppressing a NotImplementedError when the atlas plugin is not available"
|
570
|
+
end
|
571
|
+
end
|
572
|
+
end
|
573
|
+
end
|
574
|
+
end
|
575
|
+
|
576
|
+
|
481
577
|
ALL_DTYPES.each do |dtype|
|
482
578
|
next if dtype == :byte #doesn't work for unsigned types
|
483
|
-
next if dtype == :object
|
484
579
|
|
485
580
|
context dtype do
|
486
581
|
err = case dtype
|
@@ -491,6 +586,7 @@ describe "math" do
|
|
491
586
|
end
|
492
587
|
|
493
588
|
it "should correctly find adjugate a matrix in place (bang)" do
|
589
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
494
590
|
a = NMatrix.new(:dense, 2, [2, 3, 3, 5], dtype)
|
495
591
|
b = NMatrix.new(:dense, 2, [5, -3, -3, 2], dtype)
|
496
592
|
|
@@ -506,6 +602,7 @@ describe "math" do
|
|
506
602
|
|
507
603
|
|
508
604
|
it "should correctly find adjugate of a matrix out-of-place" do
|
605
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
509
606
|
a = NMatrix.new(:dense, 3, [-3, 2, -5, -1, 0, -2, 3, -4, 1], dtype)
|
510
607
|
|
511
608
|
if a.integer_dtype?
|
@@ -521,6 +618,7 @@ describe "math" do
|
|
521
618
|
end
|
522
619
|
end
|
523
620
|
|
621
|
+
|
524
622
|
# TODO: Get it working with ROBJ too
|
525
623
|
[:byte,:int8,:int16,:int32,:int64,:float32,:float64].each do |left_dtype|
|
526
624
|
[:byte,:int8,:int16,:int32,:int64,:float32,:float64].each do |right_dtype|
|
@@ -613,7 +711,7 @@ describe "math" do
|
|
613
711
|
ALL_DTYPES.each do |dtype|
|
614
712
|
next if integer_dtype?(dtype)
|
615
713
|
context "#cov dtype #{dtype}" do
|
616
|
-
before do
|
714
|
+
before do
|
617
715
|
@n = NMatrix.new( [5,3], [4.0,2.0,0.60,
|
618
716
|
4.2,2.1,0.59,
|
619
717
|
3.9,2.0,0.58,
|
@@ -621,16 +719,18 @@ describe "math" do
|
|
621
719
|
4.1,2.2,0.63], dtype: dtype)
|
622
720
|
end
|
623
721
|
|
624
|
-
it "calculates
|
625
|
-
|
722
|
+
it "calculates sample covariance matrix" do
|
723
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby? and dtype == :object
|
724
|
+
expect(@n.cov).to be_within(0.0001).of(NMatrix.new([3,3],
|
626
725
|
[0.025 , 0.0075, 0.00175,
|
627
726
|
0.0075, 0.007 , 0.00135,
|
628
727
|
0.00175, 0.00135 , 0.00043 ], dtype: dtype)
|
629
728
|
)
|
630
729
|
end
|
631
730
|
|
632
|
-
it "calculates
|
633
|
-
|
731
|
+
it "calculates population covariance matrix" do
|
732
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby? and dtype == :object
|
733
|
+
expect(@n.cov(for_sample_data: false)).to be_within(0.0001).of(NMatrix.new([3,3],
|
634
734
|
[2.0000e-02, 6.0000e-03, 1.4000e-03,
|
635
735
|
6.0000e-03, 5.6000e-03, 1.0800e-03,
|
636
736
|
1.4000e-03, 1.0800e-03, 3.4400e-04], dtype: dtype)
|
@@ -640,12 +740,13 @@ describe "math" do
|
|
640
740
|
|
641
741
|
context "#corr #{dtype}" do
|
642
742
|
it "calculates the correlation matrix" do
|
743
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby? and dtype == :object
|
643
744
|
n = NMatrix.new([5,3], [4.0,2.0,0.60,
|
644
745
|
4.2,2.1,0.59,
|
645
746
|
3.9,2.0,0.58,
|
646
747
|
4.3,2.1,0.62,
|
647
748
|
4.1,2.2,0.63], dtype: dtype)
|
648
|
-
expect(n.corr).to be_within(0.001).of(NMatrix.new([3,3],
|
749
|
+
expect(n.corr).to be_within(0.001).of(NMatrix.new([3,3],
|
649
750
|
[1.00000, 0.56695, 0.53374,
|
650
751
|
0.56695, 1.00000, 0.77813,
|
651
752
|
0.53374, 0.77813, 1.00000], dtype: dtype))
|
@@ -653,7 +754,7 @@ describe "math" do
|
|
653
754
|
end
|
654
755
|
|
655
756
|
context "#symmetric? for #{dtype}" do
|
656
|
-
it "should return true for symmetric matrix" do
|
757
|
+
it "should return true for symmetric matrix" do
|
657
758
|
n = NMatrix.new([3,3], [1.00000, 0.56695, 0.53374,
|
658
759
|
0.56695, 1.00000, 0.77813,
|
659
760
|
0.53374, 0.77813, 1.00000], dtype: dtype)
|
@@ -662,7 +763,7 @@ describe "math" do
|
|
662
763
|
end
|
663
764
|
|
664
765
|
context "#hermitian? for #{dtype}" do
|
665
|
-
it "should return true for complex hermitian or non-complex symmetric matrix" do
|
766
|
+
it "should return true for complex hermitian or non-complex symmetric matrix" do
|
666
767
|
n = NMatrix.new([3,3], [1.00000, 0.56695, 0.53374,
|
667
768
|
0.56695, 1.00000, 0.77813,
|
668
769
|
0.53374, 0.77813, 1.00000], dtype: dtype) unless dtype =~ /complex/
|
@@ -675,6 +776,7 @@ describe "math" do
|
|
675
776
|
|
676
777
|
context "#permute_columns for #{dtype}" do
|
677
778
|
it "check that #permute_columns works correctly by considering every premutation of a 3x3 matrix" do
|
779
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
678
780
|
n = NMatrix.new([3,3], [1,0,0,
|
679
781
|
0,2,0,
|
680
782
|
0,0,3], dtype: dtype)
|
@@ -716,6 +818,7 @@ describe "math" do
|
|
716
818
|
3,0,0], dtype: dtype))
|
717
819
|
end
|
718
820
|
it "additional tests for #permute_columns with convention :intuitive" do
|
821
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
719
822
|
m = NMatrix.new([1,4], [0,1,2,3], dtype: dtype)
|
720
823
|
perm = [1,0,3,2]
|
721
824
|
expect(m.permute_columns(perm, {convention: :intuitive})).to eq(NMatrix.new([1,4], perm, dtype: dtype))
|
@@ -741,9 +844,10 @@ describe "math" do
|
|
741
844
|
|
742
845
|
context "#solve" do
|
743
846
|
NON_INTEGER_DTYPES.each do |dtype|
|
744
|
-
next if dtype == :object # LU factorization doesnt work for :object yet
|
745
847
|
|
746
848
|
it "solves linear equation for dtype #{dtype}" do
|
849
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
850
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
747
851
|
a = NMatrix.new [2,2], [3,1,1,2], dtype: dtype
|
748
852
|
b = NMatrix.new [2,1], [9,8], dtype: dtype
|
749
853
|
|
@@ -751,6 +855,9 @@ describe "math" do
|
|
751
855
|
end
|
752
856
|
|
753
857
|
it "solves linear equation for #{dtype} (non-symmetric matrix)" do
|
858
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
859
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
860
|
+
|
754
861
|
a = NMatrix.new [3,3], [1,1,1, -1,0,1, 3,4,6], dtype: dtype
|
755
862
|
b = NMatrix.new [3,1], [6,2,29], dtype: dtype
|
756
863
|
|
@@ -765,6 +872,9 @@ describe "math" do
|
|
765
872
|
end
|
766
873
|
|
767
874
|
it "solves linear equation for dtype #{dtype} (non-vector rhs)" do
|
875
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
876
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
877
|
+
|
768
878
|
a = NMatrix.new [3,3], [1,0,0, -1,0,1, 2,1,1], dtype: dtype
|
769
879
|
b = NMatrix.new [3,2], [1,0, 1,2, 4,2], dtype: dtype
|
770
880
|
|
@@ -777,6 +887,7 @@ describe "math" do
|
|
777
887
|
let(:a) { NMatrix.new([3,3], [1, 0, 0, 2, 0.5, 0, 3, 3, 9], dtype: dtype) }
|
778
888
|
|
779
889
|
it "solves a lower triangular linear system A * x = b with vector b" do
|
890
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
780
891
|
b = NMatrix.new([3,1], [1,2,3], dtype: dtype)
|
781
892
|
x = a.solve(b, form: :lower_tri)
|
782
893
|
r = a.dot(x) - b
|
@@ -784,6 +895,7 @@ describe "math" do
|
|
784
895
|
end
|
785
896
|
|
786
897
|
it "solves a lower triangular linear system A * X = B with narrow B" do
|
898
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
787
899
|
b = NMatrix.new([3,2], [1,2,3,4,5,6], dtype: dtype)
|
788
900
|
x = a.solve(b, form: :lower_tri)
|
789
901
|
r = (a.dot(x) - b).abs.to_flat_a
|
@@ -791,6 +903,7 @@ describe "math" do
|
|
791
903
|
end
|
792
904
|
|
793
905
|
it "solves a lower triangular linear system A * X = B with wide B" do
|
906
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
794
907
|
b = NMatrix.new([3,5], (1..15).to_a, dtype: dtype)
|
795
908
|
x = a.solve(b, form: :lower_tri)
|
796
909
|
r = (a.dot(x) - b).abs.to_flat_a
|
@@ -802,6 +915,7 @@ describe "math" do
|
|
802
915
|
let(:a) { NMatrix.new([3,3], [3, 2, 1, 0, 2, 0.5, 0, 0, 9], dtype: dtype) }
|
803
916
|
|
804
917
|
it "solves an upper triangular linear system A * x = b with vector b" do
|
918
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
805
919
|
b = NMatrix.new([3,1], [1,2,3], dtype: dtype)
|
806
920
|
x = a.solve(b, form: :upper_tri)
|
807
921
|
r = a.dot(x) - b
|
@@ -809,6 +923,7 @@ describe "math" do
|
|
809
923
|
end
|
810
924
|
|
811
925
|
it "solves an upper triangular linear system A * X = B with narrow B" do
|
926
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
812
927
|
b = NMatrix.new([3,2], [1,2,3,4,5,6], dtype: dtype)
|
813
928
|
x = a.solve(b, form: :upper_tri)
|
814
929
|
r = (a.dot(x) - b).abs.to_flat_a
|
@@ -816,6 +931,7 @@ describe "math" do
|
|
816
931
|
end
|
817
932
|
|
818
933
|
it "solves an upper triangular linear system A * X = B with a wide B" do
|
934
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
819
935
|
b = NMatrix.new([3,5], (1..15).to_a, dtype: dtype)
|
820
936
|
x = a.solve(b, form: :upper_tri)
|
821
937
|
r = (a.dot(x) - b).abs.to_flat_a
|
@@ -828,6 +944,7 @@ describe "math" do
|
|
828
944
|
|
829
945
|
it "solves a linear system A * X = b with positive definite A and vector b" do
|
830
946
|
b = NMatrix.new([3,1], [6,4,8], dtype: dtype)
|
947
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
831
948
|
begin
|
832
949
|
x = a.solve(b, form: :pos_def)
|
833
950
|
expect(x).to be_within(1e-6).of(NMatrix.new([3,1], [1,0,1], dtype: dtype))
|
@@ -835,9 +952,10 @@ describe "math" do
|
|
835
952
|
"Suppressing a NotImplementedError when the lapacke or atlas plugin is not available"
|
836
953
|
end
|
837
954
|
end
|
838
|
-
|
955
|
+
|
839
956
|
it "solves a linear system A * X = B with positive definite A and matrix B" do
|
840
957
|
b = NMatrix.new([3,2], [8,3,14,13,14,19], dtype: dtype)
|
958
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
841
959
|
begin
|
842
960
|
x = a.solve(b, form: :pos_def)
|
843
961
|
expect(x).to be_within(1e-6).of(NMatrix.new([3,2], [1,-1,2,1,1,3], dtype: dtype))
|
@@ -849,11 +967,41 @@ describe "math" do
|
|
849
967
|
end
|
850
968
|
end
|
851
969
|
|
970
|
+
context "#least_squares" do
|
971
|
+
it "finds the least squares approximation to the equation A * X = B" do
|
972
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
973
|
+
a = NMatrix.new([3,2], [2.0, 0, -1, 1, 0, 2])
|
974
|
+
b = NMatrix.new([3,1], [1.0, 0, -1])
|
975
|
+
solution = NMatrix.new([2,1], [1.0 / 3 , -1.0 / 3], dtype: :float64)
|
976
|
+
|
977
|
+
begin
|
978
|
+
least_squares = a.least_squares(b)
|
979
|
+
expect(least_squares).to be_within(0.0001).of solution
|
980
|
+
rescue NotImplementedError
|
981
|
+
"Suppressing a NotImplementedError when the lapacke or atlas plugin is not available"
|
982
|
+
end
|
983
|
+
end
|
984
|
+
|
985
|
+
it "finds the least squares approximation to the equation A * X = B with high tolerance" do
|
986
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
987
|
+
a = NMatrix.new([4,2], [1.0, 1, 1, 2, 1, 3,1,4])
|
988
|
+
b = NMatrix.new([4,1], [6.0, 5, 7, 10])
|
989
|
+
solution = NMatrix.new([2,1], [3.5 , 1.4], dtype: :float64)
|
990
|
+
|
991
|
+
begin
|
992
|
+
least_squares = a.least_squares(b, tolerance: 10e-5)
|
993
|
+
expect(least_squares).to be_within(0.0001).of solution
|
994
|
+
rescue NotImplementedError
|
995
|
+
"Suppressing a NotImplementedError when the lapacke or atlas plugin is not available"
|
996
|
+
end
|
997
|
+
end
|
998
|
+
end
|
999
|
+
|
852
1000
|
context "#hessenberg" do
|
853
1001
|
FLOAT_DTYPES.each do |dtype|
|
854
1002
|
context dtype do
|
855
1003
|
before do
|
856
|
-
@n = NMatrix.new [5,5],
|
1004
|
+
@n = NMatrix.new [5,5],
|
857
1005
|
[0, 2, 0, 1, 1,
|
858
1006
|
2, 2, 3, 2, 2,
|
859
1007
|
4,-3, 0, 1, 3,
|
@@ -862,7 +1010,8 @@ describe "math" do
|
|
862
1010
|
end
|
863
1011
|
|
864
1012
|
it "transforms a matrix to Hessenberg form" do
|
865
|
-
|
1013
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
1014
|
+
expect(@n.hessenberg).to be_within(0.0001).of(NMatrix.new([5,5],
|
866
1015
|
[0.00000,-1.66667, 0.79432,-0.45191,-1.54501,
|
867
1016
|
-9.00000, 2.95062,-6.89312, 3.22250,-0.19012,
|
868
1017
|
0.00000,-8.21682,-0.57379, 5.26966,-1.69976,
|
@@ -877,9 +1026,9 @@ describe "math" do
|
|
877
1026
|
[:dense, :yale].each do |stype|
|
878
1027
|
answer_dtype = integer_dtype?(dtype) ? :int64 : dtype
|
879
1028
|
next if dtype == :byte
|
880
|
-
|
1029
|
+
|
881
1030
|
context "#pow #{dtype} #{stype}" do
|
882
|
-
before do
|
1031
|
+
before do
|
883
1032
|
@n = NMatrix.new [4,4], [0, 2, 0, 1,
|
884
1033
|
2, 2, 3, 2,
|
885
1034
|
4,-3, 0, 1,
|
@@ -887,15 +1036,17 @@ describe "math" do
|
|
887
1036
|
end
|
888
1037
|
|
889
1038
|
it "raises a square matrix to even power" do
|
890
|
-
|
1039
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby? and dtype == :object
|
1040
|
+
expect(@n.pow(4)).to eq(NMatrix.new([4,4], [292, 28,-63, -42,
|
891
1041
|
360, 96, 51, -14,
|
892
1042
|
448,-231,-24,-87,
|
893
|
-
-1168, 595,234, 523],
|
1043
|
+
-1168, 595,234, 523],
|
894
1044
|
dtype: answer_dtype,
|
895
1045
|
stype: stype))
|
896
1046
|
end
|
897
1047
|
|
898
1048
|
it "raises a square matrix to odd power" do
|
1049
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby? and dtype == :object
|
899
1050
|
expect(@n.pow(9)).to eq(NMatrix.new([4,4],[-275128, 279917, 176127, 237451,
|
900
1051
|
-260104, 394759, 166893, 296081,
|
901
1052
|
-704824, 285700, 186411, 262002,
|
@@ -906,18 +1057,20 @@ describe "math" do
|
|
906
1057
|
it "raises a sqaure matrix to negative power" do
|
907
1058
|
expect(@n.pow(-3)).to be_within(0.00001).of (NMatrix.new([4,4],
|
908
1059
|
[1.0647e-02, 4.2239e-04,-6.2281e-05, 2.7680e-03,
|
909
|
-
-1.6415e-02, 2.1296e-02, 1.0718e-02, 4.8589e-03,
|
1060
|
+
-1.6415e-02, 2.1296e-02, 1.0718e-02, 4.8589e-03,
|
910
1061
|
8.6956e-03,-8.6569e-03, 2.8993e-02, 7.2015e-03,
|
911
|
-
5.0034e-02,-1.7500e-02,-3.6777e-02,-1.2128e-02], dtype: answer_dtype,
|
912
|
-
stype: stype))
|
1062
|
+
5.0034e-02,-1.7500e-02,-3.6777e-02,-1.2128e-02], dtype: answer_dtype,
|
1063
|
+
stype: stype))
|
913
1064
|
end unless stype =~ /yale/ or dtype == :object or ALL_DTYPES.grep(/int/).include? dtype
|
914
1065
|
|
915
1066
|
it "raises a square matrix to zero" do
|
916
|
-
|
1067
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby? and dtype == :object
|
1068
|
+
expect(@n.pow(0)).to eq(NMatrix.eye([4,4], dtype: answer_dtype,
|
917
1069
|
stype: stype))
|
918
1070
|
end
|
919
1071
|
|
920
1072
|
it "raises a square matrix to one" do
|
1073
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby? and dtype == :object
|
921
1074
|
expect(@n.pow(1)).to eq(@n)
|
922
1075
|
end
|
923
1076
|
end
|
@@ -927,7 +1080,7 @@ describe "math" do
|
|
927
1080
|
ALL_DTYPES.each do |dtype|
|
928
1081
|
[:dense, :yale].each do |stype|
|
929
1082
|
context "#kron_prod #{dtype} #{stype}" do
|
930
|
-
before do
|
1083
|
+
before do
|
931
1084
|
@a = NMatrix.new([2,2], [1,2,
|
932
1085
|
3,4], dtype: dtype, stype: stype)
|
933
1086
|
@b = NMatrix.new([2,3], [1,1,1,
|
@@ -935,9 +1088,10 @@ describe "math" do
|
|
935
1088
|
@c = NMatrix.new([4,6], [1, 1, 1, 2, 2, 2,
|
936
1089
|
1, 1, 1, 2, 2, 2,
|
937
1090
|
3, 3, 3, 4, 4, 4,
|
938
|
-
3, 3, 3, 4, 4, 4], dtype: dtype, stype: stype)
|
1091
|
+
3, 3, 3, 4, 4, 4], dtype: dtype, stype: stype)
|
939
1092
|
end
|
940
|
-
it "
|
1093
|
+
it "computes the Kronecker product of two NMatrix objects" do
|
1094
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby? and dtype == :object
|
941
1095
|
expect(@a.kron_prod(@b)).to eq(@c)
|
942
1096
|
end
|
943
1097
|
end
|
@@ -947,6 +1101,7 @@ describe "math" do
|
|
947
1101
|
context "determinants" do
|
948
1102
|
ALL_DTYPES.each do |dtype|
|
949
1103
|
context dtype do
|
1104
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
950
1105
|
before do
|
951
1106
|
@a = NMatrix.new([2,2], [1,2,
|
952
1107
|
3,4], dtype: dtype)
|
@@ -967,31 +1122,32 @@ describe "math" do
|
|
967
1122
|
end
|
968
1123
|
end
|
969
1124
|
it "computes the determinant of 2x2 matrix" do
|
970
|
-
if dtype
|
971
|
-
|
972
|
-
end
|
1125
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
1126
|
+
expect(@a.det).to be_within(@err).of(-2)
|
973
1127
|
end
|
974
1128
|
it "computes the determinant of 3x3 matrix" do
|
975
|
-
if dtype
|
976
|
-
|
977
|
-
end
|
1129
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
1130
|
+
expect(@b.det).to be_within(@err).of(-8)
|
978
1131
|
end
|
979
1132
|
it "computes the determinant of 4x4 matrix" do
|
980
|
-
if dtype
|
981
|
-
|
982
|
-
end
|
1133
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
1134
|
+
expect(@c.det).to be_within(@err).of(-18)
|
983
1135
|
end
|
984
1136
|
it "computes the exact determinant of 2x2 matrix" do
|
1137
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
985
1138
|
if dtype == :byte
|
986
1139
|
expect{@a.det_exact}.to raise_error(DataTypeError)
|
987
1140
|
else
|
1141
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby? and dtype == :object
|
988
1142
|
expect(@a.det_exact).to be_within(@err).of(-2)
|
989
1143
|
end
|
990
1144
|
end
|
991
1145
|
it "computes the exact determinant of 3x3 matrix" do
|
1146
|
+
pending("not yet implemented for :object dtype") if dtype == :objectx
|
992
1147
|
if dtype == :byte
|
993
1148
|
expect{@a.det_exact}.to raise_error(DataTypeError)
|
994
1149
|
else
|
1150
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby? and dtype == :object
|
995
1151
|
expect(@b.det_exact).to be_within(@err).of(-8)
|
996
1152
|
end
|
997
1153
|
end
|
@@ -1002,34 +1158,122 @@ describe "math" do
|
|
1002
1158
|
context "#scale and #scale!" do
|
1003
1159
|
[:dense,:list,:yale].each do |stype|
|
1004
1160
|
ALL_DTYPES.each do |dtype|
|
1005
|
-
next if dtype == :object
|
1006
1161
|
context "for #{dtype}" do
|
1007
1162
|
before do
|
1008
1163
|
@m = NMatrix.new([3, 3], [0, 1, 2,
|
1009
1164
|
3, 4, 5,
|
1010
1165
|
6, 7, 8], stype: stype, dtype: dtype)
|
1011
1166
|
end
|
1167
|
+
|
1012
1168
|
it "scales the matrix by a given factor and return the result" do
|
1169
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
1013
1170
|
if integer_dtype? dtype
|
1014
1171
|
expect{@m.scale 2.0}.to raise_error(DataTypeError)
|
1015
1172
|
else
|
1173
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby? and (dtype == :complex64 || dtype == :complex128)
|
1016
1174
|
expect(@m.scale 2.0).to eq(NMatrix.new([3, 3], [0, 2, 4,
|
1017
1175
|
6, 8, 10,
|
1018
1176
|
12, 14, 16], stype: stype, dtype: dtype))
|
1019
1177
|
end
|
1020
1178
|
end
|
1179
|
+
|
1021
1180
|
it "scales the matrix in place by a given factor" do
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1029
|
-
|
1181
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
1182
|
+
if dtype == :int8
|
1183
|
+
expect{@m.scale! 2}.to raise_error(DataTypeError)
|
1184
|
+
else
|
1185
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby? and (dtype == :complex64 || dtype == :complex128)
|
1186
|
+
@m.scale! 2
|
1187
|
+
expect(@m).to eq(NMatrix.new([3, 3], [0, 2, 4,
|
1188
|
+
6, 8, 10,
|
1189
|
+
12, 14, 16], stype: stype, dtype: dtype))
|
1190
|
+
end
|
1191
|
+
end
|
1192
|
+
end
|
1193
|
+
end
|
1194
|
+
end
|
1195
|
+
end
|
1196
|
+
context "matrix_norm" do
|
1197
|
+
ALL_DTYPES.each do |dtype|
|
1198
|
+
context dtype do
|
1199
|
+
pending("not yet implemented for :object dtype") if dtype == :object
|
1200
|
+
before do
|
1201
|
+
@n = NMatrix.new([3,3], [-4,-3,-2,
|
1202
|
+
-1, 0, 1,
|
1203
|
+
2, 3, 4], dtype: dtype)
|
1204
|
+
|
1205
|
+
@matrix_norm_TOLERANCE = 1.0e-10
|
1206
|
+
end
|
1207
|
+
|
1208
|
+
it "should default to 2-matrix_norm" do
|
1209
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
1210
|
+
if(dtype == :byte)
|
1211
|
+
expect{@n.matrix_norm}.to raise_error(ArgumentError)
|
1212
|
+
else
|
1213
|
+
begin
|
1214
|
+
expect(@n.matrix_norm).to be_within(@matrix_norm_TOLERANCE).of(7.348469228349535)
|
1215
|
+
|
1216
|
+
rescue NotImplementedError
|
1217
|
+
pending "Suppressing a NotImplementedError when the lapacke plugin is not available"
|
1218
|
+
end
|
1219
|
+
end
|
1220
|
+
end
|
1221
|
+
|
1222
|
+
it "should reject invalid arguments" do
|
1223
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
1224
|
+
|
1225
|
+
expect{@n.matrix_norm(0.5)}.to raise_error(ArgumentError)
|
1226
|
+
end
|
1227
|
+
|
1228
|
+
it "should calculate 1 and 2(minus) matrix_norms correctly" do
|
1229
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
1230
|
+
if(dtype == :byte)
|
1231
|
+
expect{@n.matrix_norm(1)}.to raise_error(ArgumentError)
|
1232
|
+
expect{@n.matrix_norm(-2)}.to raise_error(ArgumentError)
|
1233
|
+
expect{@n.matrix_norm(-1)}.to raise_error(ArgumentError)
|
1234
|
+
else
|
1235
|
+
expect(@n.matrix_norm(1)).to eq(7)
|
1236
|
+
begin
|
1237
|
+
|
1238
|
+
#FIXME: change to the correct value when overflow issue is resolved
|
1239
|
+
#expect(@n.matrix_norm(-2)).to eq(1.8628605857884395e-07)
|
1240
|
+
expect(@n.matrix_norm(-2)).to be_within(@matrix_norm_TOLERANCE).of(0.0)
|
1241
|
+
rescue NotImplementedError
|
1242
|
+
pending "Suppressing a NotImplementedError when the lapacke plugin is not available"
|
1243
|
+
end
|
1244
|
+
expect(@n.matrix_norm(-1)).to eq(6)
|
1245
|
+
end
|
1246
|
+
end
|
1247
|
+
|
1248
|
+
it "should calculate infinity matrix_norms correctly" do
|
1249
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
1250
|
+
if(dtype == :byte)
|
1251
|
+
expect{@n.matrix_norm(:inf)}.to raise_error(ArgumentError)
|
1252
|
+
expect{@n.matrix_norm(:'-inf')}.to raise_error(ArgumentError)
|
1253
|
+
else
|
1254
|
+
expect(@n.matrix_norm(:inf)).to eq(9)
|
1255
|
+
expect(@n.matrix_norm(:'-inf')).to eq(2)
|
1256
|
+
end
|
1257
|
+
end
|
1258
|
+
|
1259
|
+
it "should calculate frobenius matrix_norms correctly" do
|
1260
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
1261
|
+
if(dtype == :byte)
|
1262
|
+
expect{@n.matrix_norm(:fro)}.to raise_error(ArgumentError)
|
1263
|
+
else
|
1264
|
+
expect(@n.matrix_norm(:fro)).to be_within(@matrix_norm_TOLERANCE).of(7.745966692414834)
|
1030
1265
|
end
|
1031
1266
|
end
|
1032
1267
|
end
|
1033
1268
|
end
|
1034
1269
|
end
|
1270
|
+
|
1271
|
+
context "#positive_definite?" do
|
1272
|
+
it "should return true for positive_definite? matrix" do
|
1273
|
+
n = NMatrix.new([3,3], [2, -1, -1,
|
1274
|
+
-1, 2, -1,
|
1275
|
+
-1, -1, 3])
|
1276
|
+
expect(n.positive_definite?).to be_truthy
|
1277
|
+
end
|
1278
|
+
end
|
1035
1279
|
end
|