pnmatrix 1.2.4
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/ext/nmatrix/binary_format.txt +53 -0
- data/ext/nmatrix/data/complex.h +388 -0
- data/ext/nmatrix/data/data.cpp +274 -0
- data/ext/nmatrix/data/data.h +651 -0
- data/ext/nmatrix/data/meta.h +64 -0
- data/ext/nmatrix/data/ruby_object.h +386 -0
- data/ext/nmatrix/extconf.rb +70 -0
- data/ext/nmatrix/math/asum.h +99 -0
- data/ext/nmatrix/math/cblas_enums.h +36 -0
- data/ext/nmatrix/math/cblas_templates_core.h +507 -0
- data/ext/nmatrix/math/gemm.h +241 -0
- data/ext/nmatrix/math/gemv.h +178 -0
- data/ext/nmatrix/math/getrf.h +255 -0
- data/ext/nmatrix/math/getrs.h +121 -0
- data/ext/nmatrix/math/imax.h +82 -0
- data/ext/nmatrix/math/laswp.h +165 -0
- data/ext/nmatrix/math/long_dtype.h +62 -0
- data/ext/nmatrix/math/magnitude.h +54 -0
- data/ext/nmatrix/math/math.h +751 -0
- data/ext/nmatrix/math/nrm2.h +165 -0
- data/ext/nmatrix/math/rot.h +117 -0
- data/ext/nmatrix/math/rotg.h +106 -0
- data/ext/nmatrix/math/scal.h +71 -0
- data/ext/nmatrix/math/trsm.h +336 -0
- data/ext/nmatrix/math/util.h +162 -0
- data/ext/nmatrix/math.cpp +1368 -0
- data/ext/nmatrix/nm_memory.h +60 -0
- data/ext/nmatrix/nmatrix.cpp +285 -0
- data/ext/nmatrix/nmatrix.h +476 -0
- data/ext/nmatrix/ruby_constants.cpp +151 -0
- data/ext/nmatrix/ruby_constants.h +106 -0
- data/ext/nmatrix/ruby_nmatrix.c +3130 -0
- data/ext/nmatrix/storage/common.cpp +77 -0
- data/ext/nmatrix/storage/common.h +183 -0
- data/ext/nmatrix/storage/dense/dense.cpp +1096 -0
- data/ext/nmatrix/storage/dense/dense.h +129 -0
- data/ext/nmatrix/storage/list/list.cpp +1628 -0
- data/ext/nmatrix/storage/list/list.h +138 -0
- data/ext/nmatrix/storage/storage.cpp +730 -0
- data/ext/nmatrix/storage/storage.h +99 -0
- data/ext/nmatrix/storage/yale/class.h +1139 -0
- data/ext/nmatrix/storage/yale/iterators/base.h +143 -0
- data/ext/nmatrix/storage/yale/iterators/iterator.h +131 -0
- data/ext/nmatrix/storage/yale/iterators/row.h +450 -0
- data/ext/nmatrix/storage/yale/iterators/row_stored.h +140 -0
- data/ext/nmatrix/storage/yale/iterators/row_stored_nd.h +169 -0
- data/ext/nmatrix/storage/yale/iterators/stored_diagonal.h +124 -0
- data/ext/nmatrix/storage/yale/math/transpose.h +110 -0
- data/ext/nmatrix/storage/yale/yale.cpp +2074 -0
- data/ext/nmatrix/storage/yale/yale.h +203 -0
- data/ext/nmatrix/types.h +55 -0
- data/ext/nmatrix/util/io.cpp +279 -0
- data/ext/nmatrix/util/io.h +115 -0
- data/ext/nmatrix/util/sl_list.cpp +627 -0
- data/ext/nmatrix/util/sl_list.h +144 -0
- data/ext/nmatrix/util/util.h +78 -0
- data/lib/nmatrix/blas.rb +378 -0
- data/lib/nmatrix/cruby/math.rb +744 -0
- data/lib/nmatrix/enumerate.rb +253 -0
- data/lib/nmatrix/homogeneous.rb +241 -0
- data/lib/nmatrix/io/fortran_format.rb +138 -0
- data/lib/nmatrix/io/harwell_boeing.rb +221 -0
- data/lib/nmatrix/io/market.rb +263 -0
- data/lib/nmatrix/io/point_cloud.rb +189 -0
- data/lib/nmatrix/jruby/decomposition.rb +24 -0
- data/lib/nmatrix/jruby/enumerable.rb +13 -0
- data/lib/nmatrix/jruby/error.rb +4 -0
- data/lib/nmatrix/jruby/math.rb +501 -0
- data/lib/nmatrix/jruby/nmatrix_java.rb +840 -0
- data/lib/nmatrix/jruby/operators.rb +283 -0
- data/lib/nmatrix/jruby/slice.rb +264 -0
- data/lib/nmatrix/lapack_core.rb +181 -0
- data/lib/nmatrix/lapack_plugin.rb +44 -0
- data/lib/nmatrix/math.rb +953 -0
- data/lib/nmatrix/mkmf.rb +100 -0
- data/lib/nmatrix/monkeys.rb +137 -0
- data/lib/nmatrix/nmatrix.rb +1172 -0
- data/lib/nmatrix/rspec.rb +75 -0
- data/lib/nmatrix/shortcuts.rb +1163 -0
- data/lib/nmatrix/version.rb +39 -0
- data/lib/nmatrix/yale_functions.rb +118 -0
- data/lib/nmatrix.rb +28 -0
- data/spec/00_nmatrix_spec.rb +892 -0
- data/spec/01_enum_spec.rb +196 -0
- data/spec/02_slice_spec.rb +407 -0
- data/spec/03_nmatrix_monkeys_spec.rb +80 -0
- data/spec/2x2_dense_double.mat +0 -0
- data/spec/4x4_sparse.mat +0 -0
- data/spec/4x5_dense.mat +0 -0
- data/spec/blas_spec.rb +215 -0
- data/spec/elementwise_spec.rb +311 -0
- data/spec/homogeneous_spec.rb +100 -0
- data/spec/io/fortran_format_spec.rb +88 -0
- data/spec/io/harwell_boeing_spec.rb +98 -0
- data/spec/io/test.rua +9 -0
- data/spec/io_spec.rb +159 -0
- data/spec/lapack_core_spec.rb +482 -0
- data/spec/leakcheck.rb +16 -0
- data/spec/math_spec.rb +1363 -0
- data/spec/nmatrix_yale_resize_test_associations.yaml +2802 -0
- data/spec/nmatrix_yale_spec.rb +286 -0
- data/spec/rspec_monkeys.rb +56 -0
- data/spec/rspec_spec.rb +35 -0
- data/spec/shortcuts_spec.rb +474 -0
- data/spec/slice_set_spec.rb +162 -0
- data/spec/spec_helper.rb +172 -0
- data/spec/stat_spec.rb +214 -0
- data/spec/test.pcd +20 -0
- data/spec/utm5940.mtx +83844 -0
- metadata +295 -0
|
@@ -0,0 +1,892 @@
|
|
|
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 - 2014, Ruby Science Foundation
|
|
12
|
+
# NMatrix is Copyright (c) 2012 - 2014, John Woods and the 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
|
+
# == 00_nmatrix_spec.rb
|
|
24
|
+
#
|
|
25
|
+
# Basic tests for NMatrix. These should load first, as they're
|
|
26
|
+
# essential to NMatrix operation.
|
|
27
|
+
#
|
|
28
|
+
require 'spec_helper'
|
|
29
|
+
|
|
30
|
+
describe NMatrix do
|
|
31
|
+
it "creates a matrix with the new constructor" do
|
|
32
|
+
n = NMatrix.new([2,2], [0,1,2,3], dtype: :int64)
|
|
33
|
+
expect(n.shape).to eq([2,2])
|
|
34
|
+
expect(n.entries).to eq([0,1,2,3])
|
|
35
|
+
expect(n.dtype).to eq(:int64)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "adequately requires information to access a single entry of a dense matrix" do
|
|
39
|
+
n = NMatrix.new(:dense, 4, [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], :float64)
|
|
40
|
+
expect(n[0,0]).to eq(0)
|
|
41
|
+
expect { n[0] }.to raise_error(ArgumentError)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it "calculates exact determinants on small dense matrices" do
|
|
45
|
+
expect(NMatrix.new(2, [1,2,3,4], stype: :dense, dtype: :int64).det_exact).to eq(-2)
|
|
46
|
+
expect(NMatrix.new(3, [1,2,3,0,5,6,7,8,0], stype: :dense, dtype: :int64)
|
|
47
|
+
.det_exact).to eq(-69)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it "calculates exact determinants on small yale square matrices" do
|
|
51
|
+
expect(NMatrix.new(2, [1,2,3,4], stype: :yale, dtype: :int64).det_exact).to eq(-2)
|
|
52
|
+
expect(NMatrix.new(3, [1,2,3,0,5,6,7,8,0], stype: :yale, dtype: :int64)
|
|
53
|
+
.det_exact).to eq(-69)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
it "calculates exact determinants on small list square matrices" do
|
|
57
|
+
expect(NMatrix.new(2, [1,2,3,4], stype: :list, dtype: :int64).det_exact).to eq(-2)
|
|
58
|
+
expect(NMatrix.new(3, [1,2,3,0,5,6,7,8,0], stype: :list, dtype: :int64)
|
|
59
|
+
.det_exact).to eq(-69)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
it "calculates inverse exact determinants on small dense matrices" do
|
|
63
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
|
64
|
+
a = NMatrix.new(3, [1,2,3,0,1,4,5,6,0], stype: :dense, dtype: :int64)
|
|
65
|
+
inversed = a.method(:__inverse_exact__).call(a.clone, 3, 3)
|
|
66
|
+
b = NMatrix.new(3, [-24,18,5,20,-15,-4,-5,4,1], stype: :dense, dtype: :int64)
|
|
67
|
+
expect(inversed).to eq(b)
|
|
68
|
+
|
|
69
|
+
c = NMatrix.new(3, [1,0,3,0,0,1,0,6,0], stype: :dense, dtype: :int64)
|
|
70
|
+
inversed = c.method(:__inverse_exact__).call(c.clone, 3, 3)
|
|
71
|
+
d = NMatrix.new(3, [1,-3,0,0,0,0,0,1,0], stype: :dense, dtype: :int64)
|
|
72
|
+
expect(inversed).to eq(d)
|
|
73
|
+
|
|
74
|
+
e = NMatrix.new(2, [3,1,2,1], stype: :dense, dtype: :int64)
|
|
75
|
+
inversed = e.method(:__inverse_exact__).call(e.clone, 2, 2)
|
|
76
|
+
f = NMatrix.new(2, [1,-1,-2,3], stype: :dense, dtype: :int64)
|
|
77
|
+
expect(inversed).to eq(f)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
it "calculates inverse exact determinants on small yale matrices" do
|
|
81
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
|
82
|
+
a = NMatrix.new(3, [1,2,3,0,1,4,5,6,0], stype: :yale, dtype: :int64)
|
|
83
|
+
inversed = a.method(:__inverse_exact__).call(a.clone, 3, 3)
|
|
84
|
+
b = NMatrix.new(3, [-24,18,5,20,-15,-4,-5,4,1], stype: :yale, dtype: :int64)
|
|
85
|
+
expect(inversed).to eq(b)
|
|
86
|
+
|
|
87
|
+
c = NMatrix.new(3, [1,0,3,0,0,1,0,6,0], stype: :yale, dtype: :int64)
|
|
88
|
+
inversed = c.method(:__inverse_exact__).call(c.clone, 3, 3)
|
|
89
|
+
d = NMatrix.new(3, [1,-3,0,0,0,0,0,1,0], stype: :yale, dtype: :int64)
|
|
90
|
+
expect(inversed).to eq(d)
|
|
91
|
+
|
|
92
|
+
e = NMatrix.new(2, [3,1,2,1], stype: :yale, dtype: :int64)
|
|
93
|
+
inversed = e.method(:__inverse_exact__).call(e.clone, 2, 2)
|
|
94
|
+
f = NMatrix.new(2, [1,-1,-2,3], stype: :yale, dtype: :int64)
|
|
95
|
+
expect(inversed).to eq(f)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
it "calculates inverse exact determinants on small list matrices" do
|
|
99
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
|
100
|
+
a = NMatrix.new(3, [1,2,3,0,1,4,5,6,0], stype: :list, dtype: :int64)
|
|
101
|
+
inversed = a.method(:__inverse_exact__).call(a.clone, 3, 3)
|
|
102
|
+
b = NMatrix.new(3, [-24,18,5,20,-15,-4,-5,4,1], stype: :list, dtype: :int64)
|
|
103
|
+
expect(inversed).to eq(b)
|
|
104
|
+
|
|
105
|
+
c = NMatrix.new(2, [3,1,2,1], stype: :list, dtype: :int64)
|
|
106
|
+
inversed = c.method(:__inverse_exact__).call(c.clone, 2, 2)
|
|
107
|
+
d = NMatrix.new(2, [1,-1,-2,3], stype: :list, dtype: :int64)
|
|
108
|
+
expect(inversed).to eq(d)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
it "calculates determinants" do
|
|
112
|
+
expect(NMatrix.new(3, [-2,2,3,-1,1,3,2,0,-1], stype: :dense, dtype: :int64).det).to eq(6)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "allows casting to Ruby objects" do
|
|
116
|
+
m = NMatrix.new([3,3], [0,0,1,0,2,0,3,4,5], dtype: :int64, stype: :dense)
|
|
117
|
+
n = m.cast(:dense, :object)
|
|
118
|
+
expect(n).to eq(m)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
it "allows casting from Ruby objects" do
|
|
122
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
|
123
|
+
m = NMatrix.new(:dense, [3,3], [0,0,1,0,2,0,3,4,5], :object)
|
|
124
|
+
n = m.cast(:dense, :int64)
|
|
125
|
+
expect(m).to eq(n)
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it "allows stype casting of a dim 2 matrix between dense, sparse, and list (different dtypes)" do
|
|
129
|
+
m = NMatrix.new(:dense, [3,3], [0,0,1,0,2,0,3,4,5], :int64).
|
|
130
|
+
cast(:yale, :int32).
|
|
131
|
+
cast(:dense, :float64).
|
|
132
|
+
cast(:list, :object).
|
|
133
|
+
cast(:dense, :int16).
|
|
134
|
+
cast(:list, :int32).
|
|
135
|
+
cast(:yale, :int64) #.
|
|
136
|
+
#cast(:list, :int32).
|
|
137
|
+
#cast(:dense, :int16)
|
|
138
|
+
#m.should.equal?(original)
|
|
139
|
+
# For some reason this causes some weird garbage collector problems when we uncomment these. The above lines won't
|
|
140
|
+
# work at all in IRB, but work fine when run in a regular Ruby session.
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
it "fills dense Ruby object matrix with nil" do
|
|
144
|
+
n = NMatrix.new([4,3], dtype: :object)
|
|
145
|
+
pending("not yet implemented for object dtype for NMatrix-JRuby") if jruby?
|
|
146
|
+
expect(n[0,0]).to eq(nil)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
it "fills dense with individual assignments" do
|
|
150
|
+
n = NMatrix.new([4,3], dtype: :float64)
|
|
151
|
+
n[0,0] = 14.0
|
|
152
|
+
n[0,1] = 9.0
|
|
153
|
+
n[0,2] = 3.0
|
|
154
|
+
n[1,0] = 2.0
|
|
155
|
+
n[1,1] = 11.0
|
|
156
|
+
n[1,2] = 15.0
|
|
157
|
+
n[2,0] = 0.0
|
|
158
|
+
n[2,1] = 12.0
|
|
159
|
+
n[2,2] = 17.0
|
|
160
|
+
n[3,0] = 5.0
|
|
161
|
+
n[3,1] = 2.0
|
|
162
|
+
n[3,2] = 3.0
|
|
163
|
+
|
|
164
|
+
expect(n[0,0]).to eq(14.0)
|
|
165
|
+
expect(n[0,1]).to eq(9.0)
|
|
166
|
+
expect(n[0,2]).to eq(3.0)
|
|
167
|
+
expect(n[1,0]).to eq(2.0)
|
|
168
|
+
expect(n[1,1]).to eq(11.0)
|
|
169
|
+
expect(n[1,2]).to eq(15.0)
|
|
170
|
+
expect(n[2,0]).to eq(0.0)
|
|
171
|
+
expect(n[2,1]).to eq(12.0)
|
|
172
|
+
expect(n[2,2]).to eq(17.0)
|
|
173
|
+
expect(n[3,0]).to eq(5.0)
|
|
174
|
+
expect(n[3,1]).to eq(2.0)
|
|
175
|
+
expect(n[3,2]).to eq(3.0)
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it "fills dense with a single mass assignment" do
|
|
179
|
+
n = NMatrix.new([4,3], [14.0, 9.0, 3.0, 2.0, 11.0, 15.0, 0.0, 12.0, 17.0, 5.0, 2.0, 3.0])
|
|
180
|
+
|
|
181
|
+
expect(n[0,0]).to eq(14.0)
|
|
182
|
+
expect(n[0,1]).to eq(9.0)
|
|
183
|
+
expect(n[0,2]).to eq(3.0)
|
|
184
|
+
expect(n[1,0]).to eq(2.0)
|
|
185
|
+
expect(n[1,1]).to eq(11.0)
|
|
186
|
+
expect(n[1,2]).to eq(15.0)
|
|
187
|
+
expect(n[2,0]).to eq(0.0)
|
|
188
|
+
expect(n[2,1]).to eq(12.0)
|
|
189
|
+
expect(n[2,2]).to eq(17.0)
|
|
190
|
+
expect(n[3,0]).to eq(5.0)
|
|
191
|
+
expect(n[3,1]).to eq(2.0)
|
|
192
|
+
expect(n[3,2]).to eq(3.0)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
it "fills dense with a single mass assignment, with dtype specified" do
|
|
196
|
+
m = NMatrix.new([4,3], [14.0, 9.0, 3.0, 2.0, 11.0, 15.0, 0.0, 12.0, 17.0, 5.0, 2.0, 3.0], dtype: :float32)
|
|
197
|
+
|
|
198
|
+
expect(m[0,0]).to eq(14.0)
|
|
199
|
+
expect(m[0,1]).to eq(9.0)
|
|
200
|
+
expect(m[0,2]).to eq(3.0)
|
|
201
|
+
expect(m[1,0]).to eq(2.0)
|
|
202
|
+
expect(m[1,1]).to eq(11.0)
|
|
203
|
+
expect(m[1,2]).to eq(15.0)
|
|
204
|
+
expect(m[2,0]).to eq(0.0)
|
|
205
|
+
expect(m[2,1]).to eq(12.0)
|
|
206
|
+
expect(m[2,2]).to eq(17.0)
|
|
207
|
+
expect(m[3,0]).to eq(5.0)
|
|
208
|
+
expect(m[3,1]).to eq(2.0)
|
|
209
|
+
expect(m[3,2]).to eq(3.0)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it "dense handles missing initialization value" do
|
|
213
|
+
n = NMatrix.new(3, dtype: :int8)
|
|
214
|
+
pending("not yet implemented for int dtype for NMatrix-JRuby") if jruby?
|
|
215
|
+
expect(n.stype).to eq(:dense)
|
|
216
|
+
expect(n.dtype).to eq(:int8)
|
|
217
|
+
|
|
218
|
+
m = NMatrix.new(4, dtype: :float64)
|
|
219
|
+
expect(m.stype).to eq(:dense)
|
|
220
|
+
expect(m.dtype).to eq(:float64)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
[:dense, :list, :yale].each do |storage_type|
|
|
224
|
+
context storage_type do
|
|
225
|
+
it "can be duplicated" do
|
|
226
|
+
n = NMatrix.new([2,3], 1.1, stype: storage_type, dtype: :float64)
|
|
227
|
+
# FIXME
|
|
228
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby? #and storage_type != :dense
|
|
229
|
+
expect(n.stype).to eq(storage_type)
|
|
230
|
+
|
|
231
|
+
n[0,0] = 0.0
|
|
232
|
+
n[0,1] = 0.1
|
|
233
|
+
n[1,0] = 1.0
|
|
234
|
+
|
|
235
|
+
m = n.dup
|
|
236
|
+
expect(m.shape).to eq(n.shape)
|
|
237
|
+
expect(m.dim).to eq(n.dim)
|
|
238
|
+
expect(m.object_id).not_to eq(n.object_id)
|
|
239
|
+
expect(m.stype).to eq(storage_type)
|
|
240
|
+
expect(m[0,0]).to eq(n[0,0])
|
|
241
|
+
m[0,0] = 3.0
|
|
242
|
+
expect(m[0,0]).not_to eq(n[0,0])
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
it "enforces shape boundaries" do
|
|
246
|
+
expect { NMatrix.new([1,10], 0, dtype: :int8, stype: storage_type, default: 0)[1,0] }.to raise_error(RangeError)
|
|
247
|
+
expect { NMatrix.new([1,10], 0, dtype: :int8, stype: storage_type, default: 0)[0,10] }.to raise_error(RangeError)
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it "sets and gets" do
|
|
251
|
+
n = NMatrix.new(2, 0, stype: storage_type, dtype: :int8)
|
|
252
|
+
n[0,1] = 1
|
|
253
|
+
expect(n[0,0]).to eq(0)
|
|
254
|
+
expect(n[1,0]).to eq(0)
|
|
255
|
+
expect(n[0,1]).to eq(1)
|
|
256
|
+
expect(n[1,1]).to eq(0)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
it "sets and gets references" do
|
|
260
|
+
n = NMatrix.new(2, stype: storage_type, dtype: :int8, default: 0)
|
|
261
|
+
expect(n[0,1] = 1).to eq(1)
|
|
262
|
+
expect(n[0,1]).to eq(1)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
# Tests Ruby object versus any C dtype (in this case we use :int64)
|
|
266
|
+
[:object, :int64].each do |dtype|
|
|
267
|
+
c = dtype == :object ? "Ruby object" : "non-Ruby object"
|
|
268
|
+
context c do
|
|
269
|
+
it "allows iteration of matrices" do
|
|
270
|
+
n = nil
|
|
271
|
+
if storage_type == :dense
|
|
272
|
+
n = NMatrix.new(:dense, [3,3], [1,2,3,4,5,6,7,8,9], dtype)
|
|
273
|
+
else
|
|
274
|
+
n = NMatrix.new([3,4], 0, stype: storage_type, dtype: dtype)
|
|
275
|
+
n[0,0] = 1
|
|
276
|
+
n[0,1] = 2
|
|
277
|
+
n[2,3] = 4
|
|
278
|
+
n[2,0] = 3
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
ary = []
|
|
282
|
+
n.each do |x|
|
|
283
|
+
ary << x
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
if storage_type == :dense
|
|
287
|
+
expect(ary).to eq([1,2,3,4,5,6,7,8,9])
|
|
288
|
+
else
|
|
289
|
+
expect(ary).to eq([1,2,0,0,0,0,0,0,3,0,0,4])
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
it "allows storage-based iteration of matrices" do
|
|
294
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby? and storage_type != :dense
|
|
295
|
+
STDERR.puts storage_type.inspect
|
|
296
|
+
STDERR.puts dtype.inspect
|
|
297
|
+
n = NMatrix.new([3,3], 0, stype: storage_type, dtype: dtype)
|
|
298
|
+
n[0,0] = 1
|
|
299
|
+
n[0,1] = 2
|
|
300
|
+
n[2,0] = 5 if storage_type == :yale
|
|
301
|
+
n[2,1] = 4
|
|
302
|
+
n[2,2] = 3
|
|
303
|
+
|
|
304
|
+
values = []
|
|
305
|
+
is = []
|
|
306
|
+
js = []
|
|
307
|
+
|
|
308
|
+
n.each_stored_with_indices do |v,i,j|
|
|
309
|
+
values << v
|
|
310
|
+
is << i
|
|
311
|
+
js << j
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
if storage_type == :yale
|
|
315
|
+
expect(is).to eq([0,1,2,0,2,2])
|
|
316
|
+
expect(js).to eq([0,1,2,1,0,1])
|
|
317
|
+
expect(values).to eq([1,0,3,2,5,4])
|
|
318
|
+
elsif storage_type == :list
|
|
319
|
+
expect(values).to eq([1,2,4,3])
|
|
320
|
+
expect(is).to eq([0,0,2,2])
|
|
321
|
+
expect(js).to eq([0,1,1,2])
|
|
322
|
+
elsif storage_type == :dense
|
|
323
|
+
expect(values).to eq([1,2,0,0,0,0,0,4,3])
|
|
324
|
+
expect(is).to eq([0,0,0,1,1,1,2,2,2])
|
|
325
|
+
expect(js).to eq([0,1,2,0,1,2,0,1,2])
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
# dense and list, not yale
|
|
333
|
+
context "(storage: #{storage_type})" do
|
|
334
|
+
it "gets default value" do
|
|
335
|
+
pending("not yet implemented for sparse matrices for NMatrix-JRuby") if jruby?
|
|
336
|
+
expect(NMatrix.new(3, 0, stype: storage_type)[1,1]).to eq(0)
|
|
337
|
+
expect(NMatrix.new(3, 0.1, stype: storage_type)[1,1]).to eq(0.1)
|
|
338
|
+
expect(NMatrix.new(3, 1, stype: storage_type)[1,1]).to eq(1)
|
|
339
|
+
|
|
340
|
+
end
|
|
341
|
+
it "returns shape and dim" do
|
|
342
|
+
expect(NMatrix.new([3,2,8], 0, stype: storage_type).shape).to eq([3,2,8])
|
|
343
|
+
expect(NMatrix.new([3,2,8], 0, stype: storage_type).dim).to eq(3)
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
it "returns number of rows and columns" do
|
|
347
|
+
expect(NMatrix.new([7, 4], 3, stype: storage_type).rows).to eq(7)
|
|
348
|
+
expect(NMatrix.new([7, 4], 3, stype: storage_type).cols).to eq(4)
|
|
349
|
+
end
|
|
350
|
+
end unless storage_type == :yale
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
it "handles dense construction" do
|
|
355
|
+
expect(NMatrix.new(3,0)[1,1]).to eq(0)
|
|
356
|
+
expect(lambda { NMatrix.new(3,dtype: :int8)[1,1] }).to_not raise_error
|
|
357
|
+
end
|
|
358
|
+
|
|
359
|
+
it "converts from list to yale properly" do
|
|
360
|
+
m = NMatrix.new(3, 0, stype: :list)
|
|
361
|
+
m[0,2] = 333
|
|
362
|
+
m[2,2] = 777
|
|
363
|
+
n = m.cast(:yale, :int32)
|
|
364
|
+
#puts n.capacity
|
|
365
|
+
#n.extend NMatrix::YaleFunctions
|
|
366
|
+
#puts n.yale_ija.inspect
|
|
367
|
+
#puts n.yale_a.inspect
|
|
368
|
+
|
|
369
|
+
expect(n[0,0]).to eq(0)
|
|
370
|
+
expect(n[0,1]).to eq(0)
|
|
371
|
+
expect(n[0,2]).to eq(333)
|
|
372
|
+
expect(n[1,0]).to eq(0)
|
|
373
|
+
expect(n[1,1]).to eq(0)
|
|
374
|
+
expect(n[1,2]).to eq(0)
|
|
375
|
+
expect(n[2,0]).to eq(0)
|
|
376
|
+
expect(n[2,1]).to eq(0)
|
|
377
|
+
expect(n[2,2]).to eq(777)
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
it "should return an enumerator when each is called without a block" do
|
|
381
|
+
a = NMatrix.new(2, 1)
|
|
382
|
+
b = NMatrix.new(2, [-1,0,1,0])
|
|
383
|
+
enums = [a.each, b.each]
|
|
384
|
+
|
|
385
|
+
begin
|
|
386
|
+
atans = []
|
|
387
|
+
atans << Math.atan2(*enums.map(&:next)) while true
|
|
388
|
+
rescue StopIteration
|
|
389
|
+
end
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
context "dense" do
|
|
393
|
+
it "should return the matrix being iterated over when each is called with a block" do
|
|
394
|
+
# FIXME
|
|
395
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
|
396
|
+
a = NMatrix.new(2, 1)
|
|
397
|
+
val = (a.each { })
|
|
398
|
+
expect(val).to eq(a)
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
it "should return the matrix being iterated over when each_stored_with_indices is called with a block" do
|
|
402
|
+
# FIXME
|
|
403
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
|
404
|
+
a = NMatrix.new(2,1)
|
|
405
|
+
val = (a.each_stored_with_indices { })
|
|
406
|
+
expect(val).to eq(a)
|
|
407
|
+
end
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
[:list, :yale].each do |storage_type|
|
|
411
|
+
context storage_type do
|
|
412
|
+
it "should return the matrix being iterated over when each_stored_with_indices is called with a block" do
|
|
413
|
+
pending("not yet implemented for Complex dtype for NMatrix-JRuby") if jruby?
|
|
414
|
+
n = NMatrix.new([2,3], 1.1, stype: storage_type, dtype: :float64, default: 0)
|
|
415
|
+
val = (n.each_stored_with_indices { })
|
|
416
|
+
expect(val).to eq(n)
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
it "should return an enumerator when each_stored_with_indices is called without a block" do
|
|
420
|
+
pending("not yet implemented for Complex dtype for NMatrix-JRuby") if jruby?
|
|
421
|
+
n = NMatrix.new([2,3], 1.1, stype: storage_type, dtype: :float64, default: 0)
|
|
422
|
+
val = n.each_stored_with_indices
|
|
423
|
+
expect(val).to be_a Enumerator
|
|
424
|
+
end
|
|
425
|
+
end
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
it "should iterate through element 256 without a segfault" do
|
|
429
|
+
t = NVector.random(256)
|
|
430
|
+
t.each { |x| x + 0 }
|
|
431
|
+
end
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
describe 'NMatrix' do
|
|
436
|
+
context "#upper_triangle" do
|
|
437
|
+
it "should create a copy with the lower corner set to zero" do
|
|
438
|
+
n = NMatrix.seq(4)+1
|
|
439
|
+
expect(n.upper_triangle).to eq(NMatrix.new(4, [1,2,3,4,0,6,7,8,0,0,11,12,0,0,0,16]))
|
|
440
|
+
expect(n.upper_triangle(2)).to eq(NMatrix.new(4, [1,2,3,4,5,6,7,8,9,10,11,12,0,14,15,16]))
|
|
441
|
+
end
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
context "#lower_triangle" do
|
|
445
|
+
it "should create a copy with the lower corner set to zero" do
|
|
446
|
+
n = NMatrix.seq(4)+1
|
|
447
|
+
expect(n.lower_triangle).to eq(NMatrix.new(4, [1,0,0,0,5,6,0,0,9,10,11,0,13,14,15,16]))
|
|
448
|
+
expect(n.lower_triangle(2)).to eq(NMatrix.new(4, [1,2,3,0,5,6,7,8,9,10,11,12,13,14,15,16]))
|
|
449
|
+
end
|
|
450
|
+
end
|
|
451
|
+
|
|
452
|
+
context "#upper_triangle!" do
|
|
453
|
+
it "should create a copy with the lower corner set to zero" do
|
|
454
|
+
n = NMatrix.seq(4)+1
|
|
455
|
+
expect(n.upper_triangle!).to eq(NMatrix.new(4, [1,2,3,4,0,6,7,8,0,0,11,12,0,0,0,16]))
|
|
456
|
+
n = NMatrix.seq(4)+1
|
|
457
|
+
expect(n.upper_triangle!(2)).to eq(NMatrix.new(4, [1,2,3,4,5,6,7,8,9,10,11,12,0,14,15,16]))
|
|
458
|
+
end
|
|
459
|
+
end
|
|
460
|
+
|
|
461
|
+
context "#lower_triangle!" do
|
|
462
|
+
it "should create a copy with the lower corner set to zero" do
|
|
463
|
+
n = NMatrix.seq(4)+1
|
|
464
|
+
expect(n.lower_triangle!).to eq(NMatrix.new(4, [1,0,0,0,5,6,0,0,9,10,11,0,13,14,15,16]))
|
|
465
|
+
n = NMatrix.seq(4)+1
|
|
466
|
+
expect(n.lower_triangle!(2)).to eq(NMatrix.new(4, [1,2,3,0,5,6,7,8,9,10,11,12,13,14,15,16]))
|
|
467
|
+
end
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
context "#rank" do
|
|
471
|
+
it "should get the rank of a 2-dimensional matrix" do
|
|
472
|
+
n = NMatrix.seq([2,3])
|
|
473
|
+
expect(n.rank(0, 0)).to eq(N[[0,1,2]])
|
|
474
|
+
end
|
|
475
|
+
|
|
476
|
+
it "should raise an error when the rank is out of bounds" do
|
|
477
|
+
n = NMatrix.seq([2,3])
|
|
478
|
+
expect { n.rank(2, 0) }.to raise_error(RangeError)
|
|
479
|
+
end
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
context "#reshape" do
|
|
483
|
+
it "should change the shape of a matrix without the contents changing" do
|
|
484
|
+
# FIXME
|
|
485
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
|
486
|
+
n = NMatrix.seq(4)+1
|
|
487
|
+
expect(n.reshape([8,2]).to_flat_array).to eq(n.to_flat_array)
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
it "should permit a change of dimensionality" do
|
|
491
|
+
# FIXME
|
|
492
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
|
493
|
+
n = NMatrix.seq(4)+1
|
|
494
|
+
expect(n.reshape([8,1,2]).to_flat_array).to eq(n.to_flat_array)
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
it "should prevent a resize" do
|
|
498
|
+
n = NMatrix.seq(4)+1
|
|
499
|
+
expect { n.reshape([5,2]) }.to raise_error(ArgumentError)
|
|
500
|
+
end
|
|
501
|
+
|
|
502
|
+
it "should do the reshape operation in place" do
|
|
503
|
+
n = NMatrix.seq(4)+1
|
|
504
|
+
expect(n.reshape!([8,2]).eql?(n)).to eq(true) # because n itself changes
|
|
505
|
+
end
|
|
506
|
+
|
|
507
|
+
it "should do the reshape operation in place, changing dimension" do
|
|
508
|
+
# FIXME
|
|
509
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
|
510
|
+
n = NMatrix.seq(4)
|
|
511
|
+
a = n.reshape!([4,2,2])
|
|
512
|
+
expect(n).to eq(NMatrix.seq([4,2,2]))
|
|
513
|
+
expect(a).to eq(NMatrix.seq([4,2,2]))
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
it "reshape and reshape! must produce same result" do
|
|
517
|
+
# FIXME
|
|
518
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
|
519
|
+
n = NMatrix.seq(4)+1
|
|
520
|
+
a = NMatrix.seq(4)+1
|
|
521
|
+
expect(n.reshape!([8,2])==a.reshape(8,2)).to eq(true) # because n itself changes
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
it "should prevent a resize in place" do
|
|
525
|
+
n = NMatrix.seq(4)+1
|
|
526
|
+
expect { n.reshape!([5,2]) }.to raise_error(ArgumentError)
|
|
527
|
+
end
|
|
528
|
+
end
|
|
529
|
+
|
|
530
|
+
context "#transpose" do
|
|
531
|
+
[:dense, :list, :yale].each do |stype|
|
|
532
|
+
context(stype) do
|
|
533
|
+
it "should transpose a #{stype} matrix (2-dimensional)" do
|
|
534
|
+
n = NMatrix.seq(4, stype: stype)
|
|
535
|
+
expect(n.transpose.to_a.flatten).to eq([0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15])
|
|
536
|
+
end
|
|
537
|
+
end
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
[:dense, :list].each do |stype|
|
|
541
|
+
context(stype) do
|
|
542
|
+
it "should transpose a #{stype} matrix (3-dimensional)" do
|
|
543
|
+
n = NMatrix.new([4,4,1], [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15], stype: stype)
|
|
544
|
+
expect(n.transpose([2,1,0]).to_flat_array).to eq([0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15])
|
|
545
|
+
expect(n.transpose([1,0,2]).to_flat_array).to eq([0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15])
|
|
546
|
+
expect(n.transpose([0,2,1]).to_flat_array).to eq(n.to_flat_array) # for dense, make this reshape!
|
|
547
|
+
end
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
it "should just copy a 1-dimensional #{stype} matrix" do
|
|
551
|
+
n = NMatrix.new([3], [1,2,3], stype: stype)
|
|
552
|
+
expect(n.transpose).to eq n
|
|
553
|
+
expect(n.transpose).not_to be n
|
|
554
|
+
end
|
|
555
|
+
|
|
556
|
+
it "should check permute argument if supplied for #{stype} matrix" do
|
|
557
|
+
n = NMatrix.new([2,2], [1,2,3,4], stype: stype)
|
|
558
|
+
expect{n.transpose *4 }.to raise_error(ArgumentError)
|
|
559
|
+
expect{n.transpose [1,1,2] }.to raise_error(ArgumentError)
|
|
560
|
+
end
|
|
561
|
+
end
|
|
562
|
+
end
|
|
563
|
+
|
|
564
|
+
context "#dot_product" do
|
|
565
|
+
[:dense].each do |stype| # list storage transpose not yet implemented
|
|
566
|
+
context(stype) do # yale support only 2-dim matrix
|
|
567
|
+
it "should work like vector product on a #{stype} (1-dimensional)" do
|
|
568
|
+
# FIXME
|
|
569
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
|
570
|
+
m = NMatrix.new([3], [1,2,3], stype: stype)
|
|
571
|
+
expect(m.dot(m)).to eq (NMatrix.new([1],[14]))
|
|
572
|
+
end
|
|
573
|
+
end
|
|
574
|
+
end
|
|
575
|
+
end
|
|
576
|
+
|
|
577
|
+
context "#==" do
|
|
578
|
+
[:dense, :list, :yale].each do |left|
|
|
579
|
+
[:dense, :list, :yale].each do |right|
|
|
580
|
+
context ("#{left}?#{right}") do
|
|
581
|
+
it "tests equality of two equal matrices" do
|
|
582
|
+
n = NMatrix.new([3,4], [0,0,1,2,0,0,3,4,0,0,0,0], stype: left)
|
|
583
|
+
m = NMatrix.new([3,4], [0,0,1,2,0,0,3,4,0,0,0,0], stype: right)
|
|
584
|
+
|
|
585
|
+
expect(n==m).to eq(true)
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
it "tests equality of two unequal matrices" do
|
|
589
|
+
n = NMatrix.new([3,4], [0,0,1,2,0,0,3,4,0,0,0,1], stype: left)
|
|
590
|
+
m = NMatrix.new([3,4], [0,0,1,2,0,0,3,4,0,0,0,0], stype: right)
|
|
591
|
+
|
|
592
|
+
expect(n==m).to eq(false)
|
|
593
|
+
end
|
|
594
|
+
|
|
595
|
+
it "tests equality of matrices with different shapes" do
|
|
596
|
+
n = NMatrix.new([2,2], [1,2, 3,4], stype: left)
|
|
597
|
+
m = NMatrix.new([2,3], [1,2, 3,4, 5,6], stype: right)
|
|
598
|
+
x = NMatrix.new([1,4], [1,2, 3,4], stype: right)
|
|
599
|
+
|
|
600
|
+
expect{n==m}.to raise_error(ShapeError)
|
|
601
|
+
expect{n==x}.to raise_error(ShapeError)
|
|
602
|
+
end
|
|
603
|
+
|
|
604
|
+
it "tests equality of matrices with different dimension" do
|
|
605
|
+
n = NMatrix.new([2,1], [1,2], stype: left)
|
|
606
|
+
m = NMatrix.new([2], [1,2], stype: right)
|
|
607
|
+
|
|
608
|
+
expect{n==m}.to raise_error(ShapeError)
|
|
609
|
+
end if left != :yale && right != :yale # yale must have dimension 2
|
|
610
|
+
end
|
|
611
|
+
end
|
|
612
|
+
end
|
|
613
|
+
end
|
|
614
|
+
|
|
615
|
+
context "#concat" do
|
|
616
|
+
it "should default to horizontal concatenation" do
|
|
617
|
+
n = NMatrix.new([1,3], [1,2,3])
|
|
618
|
+
expect(n.concat(n)).to eq(NMatrix.new([1,6], [1,2,3,1,2,3]))
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
it "should permit vertical concatenation" do
|
|
622
|
+
n = NMatrix.new([1,3], [1,2,3])
|
|
623
|
+
expect(n.vconcat(n)).to eq(NMatrix.new([2,3], [1,2,3]))
|
|
624
|
+
end
|
|
625
|
+
|
|
626
|
+
it "should permit depth concatenation on tensors" do
|
|
627
|
+
# FIXME
|
|
628
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
|
629
|
+
n = NMatrix.new([1,3,1], [1,2,3])
|
|
630
|
+
expect(n.dconcat(n)).to eq(NMatrix.new([1,3,2], [1,1,2,2,3,3]))
|
|
631
|
+
end
|
|
632
|
+
|
|
633
|
+
it "should work on matrices with different size along concat dim" do
|
|
634
|
+
n = N[[1, 2, 3],
|
|
635
|
+
[4, 5, 6]]
|
|
636
|
+
m = N[[7],
|
|
637
|
+
[8]]
|
|
638
|
+
|
|
639
|
+
# FIXME
|
|
640
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
|
641
|
+
expect(n.hconcat(m)).to eq N[[1, 2, 3, 7], [4, 5, 6, 8]]
|
|
642
|
+
expect(m.hconcat(n)).to eq N[[7, 1, 2, 3], [8, 4, 5, 6]]
|
|
643
|
+
end
|
|
644
|
+
|
|
645
|
+
it "should work on matrices with different size along concat dim" do
|
|
646
|
+
n = N[[1, 2, 3],
|
|
647
|
+
[4, 5, 6]]
|
|
648
|
+
|
|
649
|
+
m = N[[7, 8, 9]]
|
|
650
|
+
|
|
651
|
+
# FIXME
|
|
652
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
|
653
|
+
expect(n.vconcat(m)).to eq N[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
|
|
654
|
+
expect(m.vconcat(n)).to eq N[[7, 8, 9], [1, 2, 3], [4, 5, 6]]
|
|
655
|
+
end
|
|
656
|
+
end
|
|
657
|
+
|
|
658
|
+
context "#[]" do
|
|
659
|
+
it "should return values based on indices" do
|
|
660
|
+
n = NMatrix.new([2,5], [1,2,3,4,5,6,7,8,9,0])
|
|
661
|
+
expect(n[1,0]).to eq 6
|
|
662
|
+
expect(n[1,0..3]).to eq NMatrix.new([1,4],[6,7,8,9])
|
|
663
|
+
end
|
|
664
|
+
|
|
665
|
+
it "should work for negative indices" do
|
|
666
|
+
n = NMatrix.new([1,5], [1,2,3,4,5])
|
|
667
|
+
expect(n[-1]).to eq(5)
|
|
668
|
+
expect(n[0,0..-2]).to eq(NMatrix.new([1,4],[1,2,3,4]))
|
|
669
|
+
end
|
|
670
|
+
end
|
|
671
|
+
|
|
672
|
+
context "#complex_conjugate!" do
|
|
673
|
+
[:dense, :yale, :list].each do |stype|
|
|
674
|
+
context(stype) do
|
|
675
|
+
it "should work in-place for complex dtypes" do
|
|
676
|
+
pending("not yet implemented for list stype") if stype == :list
|
|
677
|
+
pending("not yet implemented for Complex dtype for NMatrix-JRuby") if jruby?
|
|
678
|
+
n = NMatrix.new([2,3], [Complex(2,3)], stype: stype, dtype: :complex128)
|
|
679
|
+
n.complex_conjugate!
|
|
680
|
+
expect(n).to eq(NMatrix.new([2,3], [Complex(2,-3)], stype: stype, dtype: :complex128))
|
|
681
|
+
end
|
|
682
|
+
|
|
683
|
+
[:object, :int64].each do |dtype|
|
|
684
|
+
it "should work in-place for non-complex dtypes" do
|
|
685
|
+
pending("not yet implemented for list stype") if stype == :list
|
|
686
|
+
pending("not yet implemented for Complex dtype for NMatrix-JRuby") if jruby?
|
|
687
|
+
n = NMatrix.new([2,3], 1, stype: stype, dtype: dtype)
|
|
688
|
+
n.complex_conjugate!
|
|
689
|
+
expect(n).to eq(NMatrix.new([2,3], [1], stype: stype, dtype: dtype))
|
|
690
|
+
end
|
|
691
|
+
end
|
|
692
|
+
end
|
|
693
|
+
end
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
context "#complex_conjugate" do
|
|
697
|
+
[:dense, :yale, :list].each do |stype|
|
|
698
|
+
context(stype) do
|
|
699
|
+
it "should work out-of-place for complex dtypes" do
|
|
700
|
+
pending("not yet implemented for list stype") if stype == :list
|
|
701
|
+
pending("not yet implemented for Complex dtype for NMatrix-JRuby") if jruby?
|
|
702
|
+
n = NMatrix.new([2,3], [Complex(2,3)], stype: stype, dtype: :complex128)
|
|
703
|
+
expect(n.complex_conjugate).to eq(NMatrix.new([2,3], [Complex(2,-3)], stype: stype, dtype: :complex128))
|
|
704
|
+
end
|
|
705
|
+
|
|
706
|
+
[:object, :int64].each do |dtype|
|
|
707
|
+
it "should work out-of-place for non-complex dtypes" do
|
|
708
|
+
pending("not yet implemented for list stype") if stype == :list
|
|
709
|
+
pending("not yet implemented for Complex dtype for NMatrix-JRuby") if jruby?
|
|
710
|
+
n = NMatrix.new([2,3], 1, stype: stype, dtype: dtype)
|
|
711
|
+
expect(n.complex_conjugate).to eq(NMatrix.new([2,3], [1], stype: stype, dtype: dtype))
|
|
712
|
+
end
|
|
713
|
+
end
|
|
714
|
+
end
|
|
715
|
+
end
|
|
716
|
+
end
|
|
717
|
+
|
|
718
|
+
context "#inject" do
|
|
719
|
+
it "should sum columns of yale matrix correctly" do
|
|
720
|
+
n = NMatrix.new([4, 3], stype: :yale, default: 0)
|
|
721
|
+
n[0,0] = 1
|
|
722
|
+
n[1,1] = 2
|
|
723
|
+
n[2,2] = 4
|
|
724
|
+
n[3,2] = 8
|
|
725
|
+
column_sums = []
|
|
726
|
+
n.cols.times do |i|
|
|
727
|
+
column_sums << n.col(i).inject(:+)
|
|
728
|
+
end
|
|
729
|
+
expect(column_sums).to eq([1, 2, 12])
|
|
730
|
+
end
|
|
731
|
+
end
|
|
732
|
+
|
|
733
|
+
context "#index" do
|
|
734
|
+
it "returns index of first occurence of an element for a vector" do
|
|
735
|
+
n = NMatrix.new([5], [0,22,22,11,11])
|
|
736
|
+
|
|
737
|
+
expect(n.index(22)).to eq([1])
|
|
738
|
+
end
|
|
739
|
+
|
|
740
|
+
it "returns index of first occurence of an element for 2-D matrix" do
|
|
741
|
+
n = NMatrix.new([3,3], [23,11,23,
|
|
742
|
+
44, 2, 0,
|
|
743
|
+
33, 0, 32])
|
|
744
|
+
|
|
745
|
+
expect(n.index(0)).to eq([1,2])
|
|
746
|
+
end
|
|
747
|
+
|
|
748
|
+
it "returns index of first occerence of an element for N-D matrix" do
|
|
749
|
+
n = NMatrix.new([3,3,3], [23,11,23, 44, 2, 0, 33, 0, 32,
|
|
750
|
+
23,11,23, 44, 2, 0, 33, 0, 32,
|
|
751
|
+
23,11,23, 44, 2, 0, 33, 0, 32])
|
|
752
|
+
|
|
753
|
+
expect(n.index(44)).to eq([0,1,0])
|
|
754
|
+
end
|
|
755
|
+
end
|
|
756
|
+
|
|
757
|
+
context "#last" do
|
|
758
|
+
it "returns the last element of a 1-dimensional NMatrix" do
|
|
759
|
+
n = NMatrix.new([1,4], [1,2,3,4])
|
|
760
|
+
expect(n.last).to eq(4)
|
|
761
|
+
end
|
|
762
|
+
|
|
763
|
+
it "returns the last element of a 2-dimensional NMatrix" do
|
|
764
|
+
n = NMatrix.new([2,2], [4,8,12,16])
|
|
765
|
+
expect(n.last).to eq(16)
|
|
766
|
+
end
|
|
767
|
+
|
|
768
|
+
it "returns the last element of a 3-dimensional NMatrix" do
|
|
769
|
+
n = NMatrix.new([2,2,2], [1,2,3,4,5,6,7,8])
|
|
770
|
+
expect(n.last).to eq(8)
|
|
771
|
+
end
|
|
772
|
+
end
|
|
773
|
+
|
|
774
|
+
context "#diagonal" do
|
|
775
|
+
ALL_DTYPES.each do |dtype|
|
|
776
|
+
before do
|
|
777
|
+
@square_matrix = NMatrix.new([3,3], [
|
|
778
|
+
23,11,23,
|
|
779
|
+
44, 2, 0,
|
|
780
|
+
33, 0, 32
|
|
781
|
+
], dtype: dtype
|
|
782
|
+
)
|
|
783
|
+
|
|
784
|
+
@rect_matrix = NMatrix.new([4,3], [
|
|
785
|
+
23,11,23,
|
|
786
|
+
44, 2, 0,
|
|
787
|
+
33, 0,32,
|
|
788
|
+
11,22,33
|
|
789
|
+
], dtype: dtype
|
|
790
|
+
)
|
|
791
|
+
end
|
|
792
|
+
|
|
793
|
+
it "returns main diagonal for square matrix" do
|
|
794
|
+
expect(@square_matrix.diagonal).to eq(NMatrix.new [3], [23,2,32])
|
|
795
|
+
end
|
|
796
|
+
|
|
797
|
+
it "returns main diagonal for rectangular matrix" do
|
|
798
|
+
expect(@rect_matrix.diagonal).to eq(NMatrix.new [3], [23,2,32])
|
|
799
|
+
end
|
|
800
|
+
|
|
801
|
+
it "returns anti-diagonal for square matrix" do
|
|
802
|
+
expect(@square_matrix.diagonal(false)).to eq(NMatrix.new [3], [23,2,33])
|
|
803
|
+
end
|
|
804
|
+
|
|
805
|
+
it "returns anti-diagonal for rectangular matrix" do
|
|
806
|
+
expect(@square_matrix.diagonal(false)).to eq(NMatrix.new [3], [23,2,33])
|
|
807
|
+
end
|
|
808
|
+
end
|
|
809
|
+
end
|
|
810
|
+
|
|
811
|
+
context "#repeat" do
|
|
812
|
+
before do
|
|
813
|
+
@sample_matrix = NMatrix.new([2, 2], [1, 2, 3, 4])
|
|
814
|
+
end
|
|
815
|
+
|
|
816
|
+
it "checks count argument" do
|
|
817
|
+
expect{@sample_matrix.repeat(1, 0)}.to raise_error(ArgumentError)
|
|
818
|
+
expect{@sample_matrix.repeat(-2, 0)}.to raise_error(ArgumentError)
|
|
819
|
+
end
|
|
820
|
+
|
|
821
|
+
it "returns repeated matrix" do
|
|
822
|
+
pending("Not yet implemented for NMatrix JRuby") if jruby?
|
|
823
|
+
expect(@sample_matrix.repeat(2, 0)).to eq(NMatrix.new([4, 2], [1, 2, 3, 4, 1, 2, 3, 4]))
|
|
824
|
+
expect(@sample_matrix.repeat(2, 1)).to eq(NMatrix.new([2, 4], [1, 2, 1, 2, 3, 4, 3, 4]))
|
|
825
|
+
end
|
|
826
|
+
|
|
827
|
+
it "preserves dtype" do
|
|
828
|
+
# FIXME
|
|
829
|
+
pending("not yet implemented for NMatrix-JRuby") if jruby?
|
|
830
|
+
expect(@sample_matrix.repeat(2, 0).dtype).to eq(@sample_matrix.dtype)
|
|
831
|
+
expect(@sample_matrix.repeat(2, 1).dtype).to eq(@sample_matrix.dtype)
|
|
832
|
+
end
|
|
833
|
+
end
|
|
834
|
+
|
|
835
|
+
context "#meshgrid" do
|
|
836
|
+
before do
|
|
837
|
+
@x, @y, @z = [1, 2, 3], NMatrix.new([2, 1], [4, 5]), [6, 7]
|
|
838
|
+
@two_dim = NMatrix.new([2, 2], [1, 2, 3, 4])
|
|
839
|
+
@two_dim_array = [[4], [5]]
|
|
840
|
+
@expected_result = [NMatrix.new([2, 3], [1, 2, 3, 1, 2, 3]), NMatrix.new([2, 3], [4, 4, 4, 5, 5, 5])]
|
|
841
|
+
@expected_for_ij = [NMatrix.new([3, 2], [1, 1, 2, 2, 3, 3]), NMatrix.new([3, 2], [4, 5, 4, 5, 4, 5])]
|
|
842
|
+
@expected_for_sparse = [NMatrix.new([1, 3], [1, 2, 3]), NMatrix.new([2, 1], [4, 5])]
|
|
843
|
+
@expected_for_sparse_ij = [NMatrix.new([3, 1], [1, 2, 3]), NMatrix.new([1, 2], [4, 5])]
|
|
844
|
+
# FIXME
|
|
845
|
+
@expected_3dim = [NMatrix.new([1, 3, 1], [1, 2, 3]).repeat(2, 0).repeat(2, 2),
|
|
846
|
+
NMatrix.new([2, 1, 1], [4, 5]).repeat(3, 1).repeat(2, 2),
|
|
847
|
+
NMatrix.new([1, 1, 2], [6, 7]).repeat(2, 0).repeat(3, 1)] unless jruby?
|
|
848
|
+
@expected_3dim_sparse_ij = [NMatrix.new([3, 1, 1], [1, 2, 3]),
|
|
849
|
+
NMatrix.new([1, 2, 1], [4, 5]),
|
|
850
|
+
NMatrix.new([1, 1, 2], [6, 7])]
|
|
851
|
+
end
|
|
852
|
+
|
|
853
|
+
it "checks arrays count" do
|
|
854
|
+
pending("Not yet implemented for NMatrix JRuby") if jruby?
|
|
855
|
+
expect{NMatrix.meshgrid([@x])}.to raise_error(ArgumentError)
|
|
856
|
+
expect{NMatrix.meshgrid([])}.to raise_error(ArgumentError)
|
|
857
|
+
end
|
|
858
|
+
|
|
859
|
+
it "flattens input arrays before use" do
|
|
860
|
+
pending("Not yet implemented for NMatrix JRuby") if jruby?
|
|
861
|
+
expect(NMatrix.meshgrid([@two_dim, @two_dim_array])).to eq(NMatrix.meshgrid([@two_dim.to_flat_array, @two_dim_array.flatten]))
|
|
862
|
+
end
|
|
863
|
+
|
|
864
|
+
it "returns new NMatrixes" do
|
|
865
|
+
pending("Not yet implemented for NMatrix JRuby") if jruby?
|
|
866
|
+
expect(NMatrix.meshgrid([@x, @y])).to eq(@expected_result)
|
|
867
|
+
end
|
|
868
|
+
|
|
869
|
+
it "has option :sparse" do
|
|
870
|
+
pending("Not yet implemented for NMatrix JRuby") if jruby?
|
|
871
|
+
expect(NMatrix.meshgrid([@x, @y], sparse: true)).to eq(@expected_for_sparse)
|
|
872
|
+
end
|
|
873
|
+
|
|
874
|
+
it "has option :indexing" do
|
|
875
|
+
pending("Not yet implemented for NMatrix JRuby") if jruby?
|
|
876
|
+
expect(NMatrix.meshgrid([@x, @y], indexing: :ij)).to eq(@expected_for_ij)
|
|
877
|
+
expect(NMatrix.meshgrid([@x, @y], indexing: :xy)).to eq(@expected_result)
|
|
878
|
+
expect{NMatrix.meshgrid([@x, @y], indexing: :not_ij_not_xy)}.to raise_error(ArgumentError)
|
|
879
|
+
end
|
|
880
|
+
|
|
881
|
+
it "works well with both options set" do
|
|
882
|
+
pending("Not yet implemented for NMatrix JRuby") if jruby?
|
|
883
|
+
expect(NMatrix.meshgrid([@x, @y], sparse: true, indexing: :ij)).to eq(@expected_for_sparse_ij)
|
|
884
|
+
end
|
|
885
|
+
|
|
886
|
+
it "is able to take more than two arrays as arguments and works well with options" do
|
|
887
|
+
pending("Not yet implemented for NMatrix JRuby") if jruby?
|
|
888
|
+
expect(NMatrix.meshgrid([@x, @y, @z])).to eq(@expected_3dim)
|
|
889
|
+
expect(NMatrix.meshgrid([@x, @y, @z], sparse: true, indexing: :ij)).to eq(@expected_3dim_sparse_ij)
|
|
890
|
+
end
|
|
891
|
+
end
|
|
892
|
+
end
|