nmatrix 0.0.4 → 0.0.5
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.
- 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
|