nmatrix 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/History.txt +68 -2
- data/Manifest.txt +1 -0
- data/README.rdoc +8 -7
- data/Rakefile +13 -2
- data/ext/nmatrix/data/complex.h +19 -1
- data/ext/nmatrix/data/data.h +8 -0
- data/ext/nmatrix/data/ruby_object.h +1 -0
- data/ext/nmatrix/extconf.rb +6 -4
- data/ext/nmatrix/nmatrix.cpp +97 -35
- data/ext/nmatrix/nmatrix.h +2 -0
- data/ext/nmatrix/ruby_constants.cpp +11 -1
- data/ext/nmatrix/ruby_constants.h +6 -1
- data/ext/nmatrix/storage/dense.cpp +2 -2
- data/ext/nmatrix/storage/yale.cpp +303 -49
- data/ext/nmatrix/storage/yale.h +3 -0
- data/ext/nmatrix/util/math.cpp +112 -0
- data/ext/nmatrix/util/math.h +372 -72
- data/lib/nmatrix/blas.rb +55 -9
- data/lib/nmatrix/nmatrix.rb +315 -2
- data/lib/nmatrix/nvector.rb +156 -95
- data/lib/nmatrix/version.rb +1 -1
- data/lib/nmatrix/yale_functions.rb +112 -0
- data/spec/blas_spec.rb +11 -0
- data/spec/elementwise_spec.rb +4 -1
- data/spec/io_spec.rb +8 -0
- data/spec/lapack_spec.rb +37 -15
- data/spec/leakcheck.rb +16 -0
- data/spec/math_spec.rb +6 -2
- data/spec/nmatrix_spec.rb +209 -3
- data/spec/nmatrix_yale_spec.rb +55 -0
- data/spec/nvector_spec.rb +33 -14
- data/spec/slice_spec.rb +26 -17
- data/spec/spec_helper.rb +17 -0
- metadata +60 -45
- data/ext/nmatrix/new_extconf.rb +0 -55
data/lib/nmatrix/version.rb
CHANGED
@@ -0,0 +1,112 @@
|
|
1
|
+
#--
|
2
|
+
# = NMatrix
|
3
|
+
#
|
4
|
+
# A linear algebra library for scientific computation in Ruby.
|
5
|
+
# NMatrix is part of SciRuby.
|
6
|
+
#
|
7
|
+
# NMatrix was originally inspired by and derived from NArray, by
|
8
|
+
# Masahiro Tanaka: http://narray.rubyforge.org
|
9
|
+
#
|
10
|
+
# == Copyright Information
|
11
|
+
#
|
12
|
+
# SciRuby is Copyright (c) 2010 - 2013, Ruby Science Foundation
|
13
|
+
# NMatrix is Copyright (c) 2013, Ruby Science Foundation
|
14
|
+
#
|
15
|
+
# Please see LICENSE.txt for additional copyright notices.
|
16
|
+
#
|
17
|
+
# == Contributing
|
18
|
+
#
|
19
|
+
# By contributing source code to SciRuby, you agree to be bound by
|
20
|
+
# our Contributor Agreement:
|
21
|
+
#
|
22
|
+
# * https://github.com/SciRuby/sciruby/wiki/Contributor-Agreement
|
23
|
+
#
|
24
|
+
# == yale_functions.rb
|
25
|
+
#
|
26
|
+
# This file contains some shortcut functions for the specialty
|
27
|
+
# Yale matrix extensions (mostly for debugging and experimental
|
28
|
+
# purposes, but sometimes applicable when you need to speed up
|
29
|
+
# your code a lot).
|
30
|
+
#++
|
31
|
+
|
32
|
+
module NMatrix::YaleFunctions
|
33
|
+
# call-seq:
|
34
|
+
# yale_nd_row_size(i) -> Fixnum
|
35
|
+
#
|
36
|
+
# Returns the size of a given non-diagonal row.
|
37
|
+
def yale_nd_row_size i
|
38
|
+
yale_ija(i+1) - yale_ija(i)
|
39
|
+
end
|
40
|
+
|
41
|
+
# call-seq:
|
42
|
+
# yale_nd_row_as_array -> Array
|
43
|
+
#
|
44
|
+
# Returns the non-diagonal column indices which are stored in a given row.
|
45
|
+
def yale_nd_row_as_array i
|
46
|
+
yale_nd_row(i, :array)
|
47
|
+
end
|
48
|
+
|
49
|
+
# call-seq:
|
50
|
+
# yale_nd_row_as_set -> Set
|
51
|
+
#
|
52
|
+
# Returns the non-diagonal column indices which are stored in a given row, as a Set.
|
53
|
+
def yale_nd_row_as_set i
|
54
|
+
require 'set'
|
55
|
+
yale_nd_row(i, :array).to_set
|
56
|
+
end
|
57
|
+
|
58
|
+
# call-seq:
|
59
|
+
# yale_nd_row_as_sorted_set -> SortedSet
|
60
|
+
#
|
61
|
+
# Returns the non-diagonal column indices which are stored in a given row, as a Set.
|
62
|
+
def yale_nd_row_as_sorted_set i
|
63
|
+
require 'set'
|
64
|
+
SortedSet.new(yale_nd_row(i, :array))
|
65
|
+
end
|
66
|
+
|
67
|
+
# call-seq:
|
68
|
+
# yale_nd_row_as_hash -> Hash
|
69
|
+
#
|
70
|
+
# Returns the non-diagonal column indices and entries stored in a given row.
|
71
|
+
def yale_nd_row_as_hash i
|
72
|
+
yale_nd_row(i, :hash)
|
73
|
+
end
|
74
|
+
|
75
|
+
# call-seq:
|
76
|
+
# yale_row_as_array -> Array
|
77
|
+
#
|
78
|
+
# Returns the diagonal and non-digonal column indices stored in a given row.
|
79
|
+
def yale_row_as_array i
|
80
|
+
ary = yale_nd_row(i, :array)
|
81
|
+
return ary if i >= self.shape[1] || self[i,i].nil? || self[i,i] == 0
|
82
|
+
ary << i
|
83
|
+
end
|
84
|
+
|
85
|
+
# call-seq:
|
86
|
+
# yale_row_as_set -> Set
|
87
|
+
#
|
88
|
+
# Returns the diagonal and non-diagonal column indices stored in a given row.
|
89
|
+
def yale_row_as_set i
|
90
|
+
require 'set'
|
91
|
+
yale_row_as_array(i).to_set
|
92
|
+
end
|
93
|
+
|
94
|
+
# call-seq:
|
95
|
+
# yale_row_as_sorted_set -> SortedSet
|
96
|
+
#
|
97
|
+
# Returns the diagonal and non-diagonal column indices stored in a given row.
|
98
|
+
def yale_row_as_sorted_set i
|
99
|
+
require 'set'
|
100
|
+
SortedSet.new(yale_row_as_array(i))
|
101
|
+
end
|
102
|
+
|
103
|
+
# call-seq:
|
104
|
+
# yale_row_as_hash -> Hash
|
105
|
+
#
|
106
|
+
# Returns the diagonal and non-diagonal column indices and entries stored in a given row.
|
107
|
+
def yale_row_as_hash i
|
108
|
+
h = yale_nd_row(i, :hash)
|
109
|
+
return h if i >= self.shape[1] || self[i,i].nil? || self[i,i] == 0
|
110
|
+
h[i] = self[i,i]
|
111
|
+
end
|
112
|
+
end
|
data/spec/blas_spec.rb
CHANGED
@@ -170,6 +170,17 @@ describe NMatrix::BLAS do
|
|
170
170
|
NMatrix::BLAS.gemv(a, x)
|
171
171
|
end
|
172
172
|
|
173
|
+
it "exposes asum" do
|
174
|
+
x = NVector.new(4, [1,2,3,4], :float64)
|
175
|
+
NMatrix::BLAS.asum(x).should == 10.0
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
it "exposes nrm2" do
|
180
|
+
x = NVector.new(4, [2,-4,3,5], :float64)
|
181
|
+
NMatrix::BLAS.nrm2(x, 1, 3).should be_within(1e-10).of(5.385164807134504)
|
182
|
+
end
|
183
|
+
|
173
184
|
end
|
174
185
|
end
|
175
186
|
end
|
data/spec/elementwise_spec.rb
CHANGED
@@ -74,7 +74,9 @@ describe NMatrix do
|
|
74
74
|
(@n/m).should == r
|
75
75
|
end
|
76
76
|
|
77
|
-
it "should perform element-wise modulo"
|
77
|
+
it "should perform element-wise modulo" do
|
78
|
+
pending "% operator not yet implemented for matrices"
|
79
|
+
end
|
78
80
|
|
79
81
|
it "should handle element-wise equality (=~)" do
|
80
82
|
(@n =~ @m).cast(:dense, :byte).should == NMatrix.new(:dense, 2, [0, 1, 1, 0], :byte)
|
@@ -131,6 +133,7 @@ describe NMatrix do
|
|
131
133
|
end
|
132
134
|
|
133
135
|
it "modulo" do
|
136
|
+
pending "% operator not yet implemented"
|
134
137
|
r = @n % @m
|
135
138
|
r.should == NMatrix.new(:dense, [2,2], [0, 1, 2, 3], :int64)
|
136
139
|
end
|
data/spec/io_spec.rb
CHANGED
@@ -70,6 +70,14 @@ describe NMatrix::IO do
|
|
70
70
|
`wc -l spec/utm5940.mtx`.split[0].should == `wc -l spec/utm5940.saved.mtx`.split[0]
|
71
71
|
end
|
72
72
|
|
73
|
+
it "raises an error when reading a non-existent file" do
|
74
|
+
fn = rand(10000000).to_i.to_s
|
75
|
+
while File.exist?(fn)
|
76
|
+
fn = rand(10000000).to_i.to_s
|
77
|
+
end
|
78
|
+
expect{ NMatrix.read(fn) }.to raise_error(Errno::ENOENT)
|
79
|
+
end
|
80
|
+
|
73
81
|
it "reads and writes NMatrix dense" do
|
74
82
|
n = NMatrix.new(:dense, [4,3], [0,1,2,3,4,5,6,7,8,9,10,11], :int32)
|
75
83
|
n.write("test-out")
|
data/spec/lapack_spec.rb
CHANGED
@@ -47,13 +47,26 @@ describe NMatrix::LAPACK do
|
|
47
47
|
it "exposes clapack getrf" do
|
48
48
|
a = NMatrix.new(:dense, 3, [4,9,2,3,5,7,8,1,6], dtype)
|
49
49
|
NMatrix::LAPACK::clapack_getrf(:row, 3, 3, a, 3)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
50
|
+
|
51
|
+
# delta varies for different dtypes
|
52
|
+
err = case dtype
|
53
|
+
when :float32, :complex64
|
54
|
+
1e-6
|
55
|
+
when :float64, :complex128
|
56
|
+
1e-15
|
57
|
+
else
|
58
|
+
1e-64 # FIXME: should be 0, but be_within(0) does not work.
|
59
|
+
end
|
60
|
+
|
61
|
+
a[0,0].should == 9 # 8
|
62
|
+
a[0,1].should be_within(err).of(2.quo(9)) # 1
|
63
|
+
a[0,2].should be_within(err).of(4.quo(9)) # 6
|
64
|
+
a[1,0].should == 5 # 1.quo(2)
|
65
|
+
a[1,1].should be_within(err).of(53.quo(9)) # 17.quo(2)
|
66
|
+
a[1,2].should be_within(err).of(7.quo(53)) # -1
|
67
|
+
a[2,0].should == 1 # 3.quo(8)
|
68
|
+
a[2,1].should be_within(err).of(52.quo(9))
|
69
|
+
a[2,2].should be_within(err).of(360.quo(53))
|
57
70
|
# FIXME: these are rounded, == won't work
|
58
71
|
#a[2,1].should == 0.544118
|
59
72
|
#a[2,2].should == 5.294118
|
@@ -61,10 +74,14 @@ describe NMatrix::LAPACK do
|
|
61
74
|
|
62
75
|
it "exposes clapack potrf" do
|
63
76
|
# first do upper
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
77
|
+
begin
|
78
|
+
a = NMatrix.new(:dense, 3, [25,15,-5, 0,18,0, 0,0,11], dtype)
|
79
|
+
NMatrix::LAPACK::clapack_potrf(:row, :upper, 3, a, 3)
|
80
|
+
b = NMatrix.new(:dense, 3, [5,3,-1, 0,3,1, 0,0,3], dtype)
|
81
|
+
a.should == b
|
82
|
+
rescue NotImplementedError => e
|
83
|
+
pending e.to_s
|
84
|
+
end
|
68
85
|
|
69
86
|
# then do lower
|
70
87
|
a = NMatrix.new(:dense, 3, [25,0,0, 15,18,0,-5,0,11], dtype)
|
@@ -89,13 +106,18 @@ describe NMatrix::LAPACK do
|
|
89
106
|
it "exposes clapack getri" do
|
90
107
|
a = NMatrix.new(:dense, 3, [1,0,4,1,1,6,-3,0,-10], dtype)
|
91
108
|
ipiv = NMatrix::LAPACK::clapack_getrf(:row, 3, 3, a, 3) # get pivot from getrf, use for getri
|
92
|
-
NMatrix::LAPACK::clapack_getri(:row, 3, a, 3, ipiv)
|
93
109
|
|
94
|
-
|
95
|
-
|
110
|
+
begin
|
111
|
+
NMatrix::LAPACK::clapack_getri(:row, 3, a, 3, ipiv)
|
112
|
+
|
113
|
+
b = NMatrix.new(:dense, 3, [-5,0,-2,-4,1,-1,1.5,0,0.5], dtype)
|
114
|
+
a.should == b
|
115
|
+
rescue NotImplementedError => e
|
116
|
+
pending e.to_s
|
117
|
+
end
|
96
118
|
end
|
97
119
|
|
98
120
|
|
99
121
|
end
|
100
122
|
end
|
101
|
-
end
|
123
|
+
end
|
data/spec/leakcheck.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require "./lib/nmatrix"
|
2
|
+
|
3
|
+
# Fixed:
|
4
|
+
#n = NMatrix.new(:yale, [8,2], :int64)
|
5
|
+
#m = NMatrix.new(:yale, [2,8], :int64)
|
6
|
+
#100.times do
|
7
|
+
# n.dot(m)
|
8
|
+
#end
|
9
|
+
#GC.start
|
10
|
+
|
11
|
+
# Remaining:
|
12
|
+
100.times do |t|
|
13
|
+
n = NMatrix.new(:dense, 1000, :float64)
|
14
|
+
n[0,t] = 1.0
|
15
|
+
puts n[t,0]
|
16
|
+
end
|
data/spec/math_spec.rb
CHANGED
@@ -50,7 +50,11 @@ describe "math" do
|
|
50
50
|
it "should correctly invert a matrix" do
|
51
51
|
a = NMatrix.new(:dense, 3, [1,0,4,1,1,6,-3,0,-10], dtype)
|
52
52
|
b = NMatrix.new(:dense, 3, [-5,0,-2,-4,1,-1,1.5,0,0.5], dtype)
|
53
|
-
|
53
|
+
begin
|
54
|
+
a.invert!
|
55
|
+
rescue NotImplementedError => e
|
56
|
+
pending e.to_s
|
57
|
+
end
|
54
58
|
a.should == b
|
55
59
|
end
|
56
60
|
end
|
@@ -125,7 +129,7 @@ describe "math" do
|
|
125
129
|
#STDERR.puts "2"
|
126
130
|
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)
|
127
131
|
|
128
|
-
m = NVector.new(3, [2.0, 1.0, 0.0], right_dtype)
|
132
|
+
m = NVector.new(3, [2.0, 1.0, 0.0], right_dtype).transpose
|
129
133
|
|
130
134
|
m.shape[0].should == 3
|
131
135
|
m.shape[1].should == 1
|
data/spec/nmatrix_spec.rb
CHANGED
@@ -25,8 +25,7 @@
|
|
25
25
|
# Basic tests for NMatrix.
|
26
26
|
#
|
27
27
|
|
28
|
-
|
29
|
-
require File.join(File.dirname(__FILE__), "spec_helper.rb")
|
28
|
+
require File.dirname(__FILE__) + "/spec_helper.rb"
|
30
29
|
|
31
30
|
describe NMatrix do
|
32
31
|
|
@@ -142,7 +141,7 @@ describe NMatrix do
|
|
142
141
|
|
143
142
|
[:dense, :list, :yale].each do |storage_type|
|
144
143
|
context storage_type do
|
145
|
-
|
144
|
+
it "can be duplicated" do
|
146
145
|
n = NMatrix.new(storage_type, [2,3], storage_type == :yale ? :float64 : 1.1)
|
147
146
|
n.stype.should equal(storage_type)
|
148
147
|
|
@@ -292,8 +291,215 @@ describe NMatrix do
|
|
292
291
|
end
|
293
292
|
end
|
294
293
|
|
294
|
+
context "dense" do
|
295
|
+
it "should return the matrix being iterated over when each is called with a block" do
|
296
|
+
a = NMatrix.new(2, 1)
|
297
|
+
val = (a.each { })
|
298
|
+
val.should eq a
|
299
|
+
end
|
300
|
+
|
301
|
+
it "should return the matrix being iterated over when each_stored_with_indices is called with a block" do
|
302
|
+
a = NMatrix.new(2,1)
|
303
|
+
val = (a.each_stored_with_indices { })
|
304
|
+
val.should eq a
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
[:list, :yale].each do |storage_type|
|
309
|
+
context storage_type do
|
310
|
+
it "should return the matrix being iterated over when each_stored_with_indices is called with a block" do
|
311
|
+
n = NMatrix.new(storage_type, [2,3], storage_type == :yale ? :float64 : 1.1)
|
312
|
+
val = (n.each_stored_with_indices { })
|
313
|
+
val.should eq n
|
314
|
+
end
|
315
|
+
|
316
|
+
it "should return an enumerator when each_stored_with_indices is called without a block" do
|
317
|
+
n = NMatrix.new(storage_type, [2,3], storage_type == :yale ? :float64 : 1.1)
|
318
|
+
val = n.each_stored_with_indices
|
319
|
+
val.should be_a Enumerator
|
320
|
+
end
|
321
|
+
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
295
325
|
it "should iterate through element 256 without a segfault" do
|
296
326
|
t = NVector.random(256)
|
297
327
|
t.each { |x| x + 0 }
|
298
328
|
end
|
329
|
+
|
330
|
+
context "mapping and reduction related functions" do
|
331
|
+
|
332
|
+
before :each do
|
333
|
+
@nm_1d = N[5.0,0.0,1.0,2.0,3.0]
|
334
|
+
@nm_2d = N[[0.0,1.0],[2.0,3.0]]
|
335
|
+
end
|
336
|
+
|
337
|
+
it "behaves like Enumerable#reduce with no argument to reduce" do
|
338
|
+
@nm_1d.reduce_along_dim(0) { |acc, el| acc + el }.to_f.should eq 11
|
339
|
+
@nm_2d.reduce_along_dim(1) { |acc, el| acc + el }.should eq N[[1, 5]]
|
340
|
+
end
|
341
|
+
|
342
|
+
it "should calculate the mean along the specified dimension" do
|
343
|
+
@nm_1d.mean.should eq N[2.2]
|
344
|
+
@nm_2d.mean.should eq N[[1.0,2.0]]
|
345
|
+
end
|
346
|
+
|
347
|
+
it "should calculate the minimum along the specified dimension" do
|
348
|
+
@nm_1d.min.should eq 0.0
|
349
|
+
@nm_2d.min.should eq N[[0.0, 1.0]]
|
350
|
+
@nm_2d.min(1).should eq N[[0.0], [2.0]]
|
351
|
+
end
|
352
|
+
|
353
|
+
it "should calculate the maximum along the specified dimension" do
|
354
|
+
@nm_1d.max.should eq 5.0
|
355
|
+
@nm_2d.max.should eq N[[2.0, 3.0]]
|
356
|
+
end
|
357
|
+
|
358
|
+
it "should calculate the variance along the specified dimension" do
|
359
|
+
@nm_1d.variance.should eq N[3.7]
|
360
|
+
@nm_2d.variance(1).should eq N[[0.5], [0.5]]
|
361
|
+
end
|
362
|
+
|
363
|
+
it "should calculate the sum along the specified dimension" do
|
364
|
+
@nm_1d.sum.should eq N[11]
|
365
|
+
@nm_2d.sum.should eq N[[2], [4]]
|
366
|
+
end
|
367
|
+
|
368
|
+
it "should calculate the standard deviation along the specified dimension" do
|
369
|
+
@nm_1d.std.should eq N[Math.sqrt(3.7)]
|
370
|
+
@nm_2d.std(1).should eq N[[Math.sqrt(0.5)], [Math.sqrt(0.5)]]
|
371
|
+
end
|
372
|
+
|
373
|
+
it "should raise an ArgumentError when any invalid dimension is provided" do
|
374
|
+
expect { @nm_1d.mean(3) }.to raise_exception(ArgumentError)
|
375
|
+
end
|
376
|
+
|
377
|
+
it "should convert to float if it contains only a single element" do
|
378
|
+
N[4.0].to_f.should eq 4.0
|
379
|
+
N[[[[4.0]]]].to_f.should eq 4.0
|
380
|
+
end
|
381
|
+
|
382
|
+
it "should raise an index error if it contains more than a single element" do
|
383
|
+
expect { @nm_1d.to_f }.to raise_error(IndexError)
|
384
|
+
end
|
385
|
+
|
386
|
+
it "should map a block to all elements" do
|
387
|
+
@nm_1d.map { |e| e ** 2 }.should eq N[25.0,0.0,1.0,4.0,9.0]
|
388
|
+
@nm_2d.map { |e| e ** 2 }.should eq N[[0.0,1.0],[4.0,9.0]]
|
389
|
+
end
|
390
|
+
|
391
|
+
it "should map! a block to all elements in place" do
|
392
|
+
fct = Proc.new { |e| e ** 2 }
|
393
|
+
expected1 = @nm_1d.map &fct
|
394
|
+
expected2 = @nm_2d.map &fct
|
395
|
+
@nm_1d.map! &fct
|
396
|
+
@nm_1d.should eq expected1
|
397
|
+
@nm_2d.map! &fct
|
398
|
+
@nm_2d.should eq expected2
|
399
|
+
end
|
400
|
+
|
401
|
+
it "should return an enumerator for map without a block" do
|
402
|
+
@nm_1d.map.should be_a Enumerator
|
403
|
+
end
|
404
|
+
|
405
|
+
it "should return an enumerator for reduce without a block" do
|
406
|
+
@nm_1d.reduce_along_dim(0).should be_a Enumerator
|
407
|
+
end
|
408
|
+
|
409
|
+
it "should return an enumerator for each_along_dim without a block" do
|
410
|
+
@nm_1d.each_along_dim(0).should be_a Enumerator
|
411
|
+
end
|
412
|
+
|
413
|
+
it "should iterate correctly for map without a block" do
|
414
|
+
en = @nm_1d.map
|
415
|
+
en.each { |e| e**2 }.should eq @nm_1d.map { |e| e**2 }
|
416
|
+
en = @nm_2d.map
|
417
|
+
en.each { |e| e**2 }.should eq @nm_2d.map { |e| e**2 }
|
418
|
+
end
|
419
|
+
|
420
|
+
it "should iterate correctly for reduce without a block" do
|
421
|
+
en = @nm_1d.reduce_along_dim(0, 1.0)
|
422
|
+
en.each { |a, e| a+e }.to_f.should eq 12
|
423
|
+
en = @nm_2d.reduce_along_dim(1, 1.0)
|
424
|
+
en.each { |a, e| a+e }.should eq N[[2.0],[6.0]]
|
425
|
+
end
|
426
|
+
|
427
|
+
it "should iterate correctly for each_along_dim without a block" do
|
428
|
+
res = NMatrix.zeros_like(@nm_1d[0...1])
|
429
|
+
en = @nm_1d.each_along_dim(0)
|
430
|
+
en.each { |e| res += e }
|
431
|
+
res.to_f.should eq 11
|
432
|
+
|
433
|
+
res = NMatrix.zeros_like (@nm_2d[0...2, 0])
|
434
|
+
en = @nm_2d.each_along_dim(1)
|
435
|
+
en.each { |e| res += e }
|
436
|
+
res.should eq N[[1.0], [5.0]]
|
437
|
+
end
|
438
|
+
|
439
|
+
it "should yield matrices of matching dtype for each_along_dim" do
|
440
|
+
m = NMatrix.new([2,3], [1,2,3,3,4,5], :complex128)
|
441
|
+
m.each_along_dim(1) do |sub_m|
|
442
|
+
sub_m.dtype.should eq :complex128
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
it "should reduce to a matrix of matching dtype for reduce_along_dim" do
|
447
|
+
m = NMatrix.new([2,3], [1,2,3,3,4,5], :complex128)
|
448
|
+
m.reduce_along_dim(1) do |acc, sub_m|
|
449
|
+
sub_m.dtype.should eq :complex128
|
450
|
+
acc
|
451
|
+
end
|
452
|
+
|
453
|
+
m = NMatrix.new([2,3], [1,2,3,3,4,5], :complex128)
|
454
|
+
m.reduce_along_dim(1, 0.0) do |acc, sub_m|
|
455
|
+
sub_m.dtype.should eq :complex128
|
456
|
+
acc
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
it "should allow overriding the dtype for reduce_along_dim" do
|
461
|
+
m = N[[1,2,3], [3,4,5], :complex128]
|
462
|
+
m.reduce_along_dim(1, 0.0, :float64) do |acc, sub_m|
|
463
|
+
acc.dtype.should eq :float64
|
464
|
+
acc
|
465
|
+
end
|
466
|
+
|
467
|
+
m = N[[1,2,3], [3,4,5], :complex128]
|
468
|
+
m.reduce_along_dim(1, nil, :float64) do |acc, sub_m|
|
469
|
+
acc.dtype.should eq :float64
|
470
|
+
acc
|
471
|
+
end
|
472
|
+
end
|
473
|
+
|
474
|
+
it "should convert integer dtypes to float when calculating mean" do
|
475
|
+
m = N[[1,2,3], [3,4,5], :int32]
|
476
|
+
m.mean(0).dtype.should eq :float64
|
477
|
+
end
|
478
|
+
|
479
|
+
it "should convert integer dtypes to float when calculating variance" do
|
480
|
+
m = N[[1,2,3], [3,4,5], :int32]
|
481
|
+
m.mean(0).dtype.should eq :float64
|
482
|
+
end
|
483
|
+
|
484
|
+
it "should convert integer dtypes to float when calculating standard deviation" do
|
485
|
+
m = N[[1,2,3], [3,4,5], :int32]
|
486
|
+
m.mean(0).dtype.should eq :float64
|
487
|
+
end
|
488
|
+
|
489
|
+
context "_like constructors" do
|
490
|
+
|
491
|
+
it "should create an nmatrix of ones with dimensions and type the same as its argument" do
|
492
|
+
NMatrix.ones_like(@nm_1d).should eq N[1.0, 1.0, 1.0, 1.0, 1.0]
|
493
|
+
NMatrix.ones_like(@nm_2d).should eq N[[1.0, 1.0], [1.0, 1.0]]
|
494
|
+
end
|
495
|
+
|
496
|
+
it "should create an nmatrix of zeros with dimensions and type the same as its argument" do
|
497
|
+
NMatrix.zeros_like(@nm_1d).should eq N[0.0, 0.0, 0.0, 0.0, 0.0]
|
498
|
+
NMatrix.zeros_like(@nm_2d).should eq N[[0.0, 0.0], [0.0, 0.0]]
|
499
|
+
end
|
500
|
+
|
501
|
+
end
|
502
|
+
|
503
|
+
end
|
504
|
+
|
299
505
|
end
|