numo-linalg 0.1.2 → 0.1.3
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 +4 -4
- data/README.md +7 -3
- data/ext/numo/linalg/blas/extconf.rb +1 -2
- data/ext/numo/linalg/blas/numo_blas.h +6 -0
- data/ext/numo/linalg/blas/tmpl/mv.c +3 -2
- data/ext/numo/linalg/lapack/gen/spec.rb +5 -0
- data/ext/numo/linalg/lapack/lapack.c +29 -0
- data/ext/numo/linalg/lapack/numo_lapack.h +3 -0
- data/ext/numo/linalg/lapack/tmpl/gqr.c +1 -1
- data/ext/numo/linalg/lapack/tmpl/sygvx.c +130 -0
- data/ext/numo/linalg/mkmf_linalg.rb +2 -19
- data/lib/numo/linalg/function.rb +168 -77
- data/lib/numo/linalg/loader.rb +6 -14
- data/lib/numo/linalg/version.rb +1 -1
- data/numo-linalg.gemspec +2 -1
- data/spec/linalg/autoloader_spec.rb +27 -0
- data/spec/linalg/function/cho_fact_spec.rb +31 -0
- data/spec/linalg/function/cho_inv_spec.rb +39 -0
- data/spec/linalg/function/cho_solve_spec.rb +66 -0
- data/spec/linalg/function/cholesky_spec.rb +43 -0
- data/spec/linalg/function/cond_spec.rb +57 -0
- data/spec/linalg/function/det_spec.rb +21 -0
- data/spec/linalg/function/dot_spec.rb +84 -0
- data/spec/linalg/function/eig_spec.rb +53 -0
- data/spec/linalg/function/eigh_spec.rb +81 -0
- data/spec/linalg/function/eigvals_spec.rb +27 -0
- data/spec/linalg/function/eigvalsh_spec.rb +60 -0
- data/spec/linalg/function/inv_spec.rb +57 -0
- data/spec/linalg/function/ldl_spec.rb +51 -0
- data/spec/linalg/function/lstsq_spec.rb +80 -0
- data/spec/linalg/function/lu_fact_spec.rb +34 -0
- data/spec/linalg/function/lu_inv_spec.rb +21 -0
- data/spec/linalg/function/lu_solve_spec.rb +40 -0
- data/spec/linalg/function/lu_spec.rb +46 -0
- data/spec/linalg/function/matmul_spec.rb +41 -0
- data/spec/linalg/function/matrix_power_spec.rb +31 -0
- data/spec/linalg/function/matrix_rank_spec.rb +33 -0
- data/spec/linalg/function/norm_spec.rb +81 -0
- data/spec/linalg/function/pinv_spec.rb +48 -0
- data/spec/linalg/function/qr_spec.rb +82 -0
- data/spec/linalg/function/slogdet_spec.rb +21 -0
- data/spec/linalg/function/solve_spec.rb +98 -0
- data/spec/linalg/function/svd_spec.rb +88 -0
- data/spec/linalg/function/svdvals_spec.rb +40 -0
- data/spec/spec_helper.rb +55 -0
- metadata +79 -6
- data/spec/lapack_spec.rb +0 -13
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Numo::Linalg do
|
6
|
+
describe 'svd' do
|
7
|
+
let(:m) { 5 }
|
8
|
+
let(:n) { 3 }
|
9
|
+
let(:mat_a) { rand_rect_real_mat(m, n) }
|
10
|
+
let(:mat_b) { rand_rect_complex_mat(m, n) }
|
11
|
+
|
12
|
+
it 'raises ArgumentError given a invalid driver option' do
|
13
|
+
expect { described_class.svd(mat_a, driver: 'foo') }.to raise_error(ArgumentError)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'raises ArgumentError given a invalid job option' do
|
17
|
+
expect { described_class.svd(mat_a, job: '@') }.to raise_error(ArgumentError)
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'perfoms the singular value decomposition of a rectangular real matrix' do
|
21
|
+
s, u, vt = described_class.svd(mat_a, driver: 'svd')
|
22
|
+
expect((u.transpose.dot(u) - Numo::DFloat.eye(m)).abs.max).to be < ERR_TOL
|
23
|
+
expect((vt.dot(vt.transpose) - Numo::DFloat.eye(n)).abs.max).to be < ERR_TOL
|
24
|
+
mat_a_rec = u.dot(Numo::NArray.vstack([s.diag.dot(vt), Numo::DFloat.zeros(m - n, n)]))
|
25
|
+
expect((mat_a - mat_a_rec).abs.max).to be < ERR_TOL
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'perfoms the singular value decomposition of a rectangular complex matrix' do
|
29
|
+
s, u, vt = described_class.svd(mat_b, driver: 'svd')
|
30
|
+
expect((u.transpose.conj.dot(u) - Numo::DFloat.eye(m)).abs.max).to be < ERR_TOL
|
31
|
+
expect((vt.dot(vt.transpose.conj) - Numo::DFloat.eye(n)).abs.max).to be < ERR_TOL
|
32
|
+
mat_b_rec = u.dot(Numo::NArray.vstack([s.diag.dot(vt), Numo::DFloat.zeros(m - n, n)]))
|
33
|
+
expect((mat_b - mat_b_rec).abs.max).to be < ERR_TOL
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'perfoms the singular value decomposition of a rectangular real matrix with S job option' do
|
37
|
+
s, u, vt = described_class.svd(mat_a, driver: 'svd', job: 'S')
|
38
|
+
expect(u.shape[0]).to eq(m)
|
39
|
+
expect(u.shape[1]).to eq(n)
|
40
|
+
expect((u.transpose.dot(u) - Numo::DFloat.eye(n)).abs.max).to be < ERR_TOL
|
41
|
+
expect((vt.dot(vt.transpose) - Numo::DFloat.eye(n)).abs.max).to be < ERR_TOL
|
42
|
+
mat_a_rec = u.dot(s.diag.dot(vt))
|
43
|
+
expect((mat_a - mat_a_rec).abs.max).to be < ERR_TOL
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'perfoms the singular value decomposition of a rectangular complex matrix with S job option' do
|
47
|
+
s, u, vt = described_class.svd(mat_b, driver: 'svd', job: 'S')
|
48
|
+
expect(u.shape[0]).to eq(m)
|
49
|
+
expect(u.shape[1]).to eq(n)
|
50
|
+
expect((u.transpose.conj.dot(u) - Numo::DFloat.eye(n)).abs.max).to be < ERR_TOL
|
51
|
+
expect((vt.dot(vt.transpose.conj) - Numo::DFloat.eye(n)).abs.max).to be < ERR_TOL
|
52
|
+
mat_b_rec = u.dot(s.diag.dot(vt))
|
53
|
+
expect((mat_b - mat_b_rec).abs.max).to be < ERR_TOL
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'calculates the singular values of a rectangular real matrix' do
|
57
|
+
s1, = described_class.svd(mat_a, driver: 'svd')
|
58
|
+
s2, u, vt = described_class.svd(mat_a, driver: 'svd', job: 'N')
|
59
|
+
expect(u).to be_nil
|
60
|
+
expect(vt).to be_nil
|
61
|
+
expect((s1 - s2).abs.max).to be < ERR_TOL
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'calculates the singular values of a rectangular complex matrix' do
|
65
|
+
s1, = described_class.svd(mat_b, driver: 'svd')
|
66
|
+
s2, u, vt = described_class.svd(mat_b, driver: 'svd', job: 'N')
|
67
|
+
expect(u).to be_nil
|
68
|
+
expect(vt).to be_nil
|
69
|
+
expect((s1 - s2).abs.max).to be < ERR_TOL
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'perfoms the singular value decomposition of a rectangular real matrix with divide and conquer algorithm' do
|
73
|
+
s, u, vt = described_class.svd(mat_a, driver: 'sdd')
|
74
|
+
mat_a_rec = u.dot(Numo::NArray.vstack([s.diag.dot(vt), Numo::DFloat.zeros(m - n, n)]))
|
75
|
+
expect((u.dot(u.transpose) - Numo::DFloat.eye(m)).abs.max).to be < ERR_TOL
|
76
|
+
expect((vt.transpose.dot(vt) - Numo::DFloat.eye(n)).abs.max).to be < ERR_TOL
|
77
|
+
expect((mat_a - mat_a_rec).abs.max).to be < ERR_TOL
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'perfoms the singular value decomposition of a rectangular complex matrix with divide and conquer algorithm' do
|
81
|
+
s, u, vt = described_class.svd(mat_b, driver: 'sdd')
|
82
|
+
mat_b_rec = u.dot(Numo::NArray.vstack([s.diag.dot(vt), Numo::DFloat.zeros(m - n, n)]))
|
83
|
+
expect((u.dot(u.transpose.conj) - Numo::DFloat.eye(m)).abs.max).to be < ERR_TOL
|
84
|
+
expect((vt.transpose.conj.dot(vt) - Numo::DFloat.eye(n)).abs.max).to be < ERR_TOL
|
85
|
+
expect((mat_b - mat_b_rec).abs.max).to be < ERR_TOL
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
RSpec.describe Numo::Linalg do
|
6
|
+
describe 'svdvals' do
|
7
|
+
let(:m) { 5 }
|
8
|
+
let(:n) { 3 }
|
9
|
+
let(:mat_a) { rand_rect_real_mat(m, n) }
|
10
|
+
let(:mat_b) { rand_rect_complex_mat(m, n) }
|
11
|
+
|
12
|
+
it 'raises ArgumentError given a invalid driver option' do
|
13
|
+
expect { described_class.svdvals(mat_a, driver: 'foo') }.to raise_error(ArgumentError)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'calculates the singular values of a rectangular real matrix' do
|
17
|
+
s1, = described_class.svd(mat_a, driver: 'svd', job: 'N')
|
18
|
+
s2 = described_class.svdvals(mat_a, driver: 'svd')
|
19
|
+
expect((s1 - s2).abs.max).to be < ERR_TOL
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'calculates the singular values of a rectangular complex matrix' do
|
23
|
+
s1, = described_class.svd(mat_b, driver: 'svd', job: 'N')
|
24
|
+
s2 = described_class.svdvals(mat_b, driver: 'svd')
|
25
|
+
expect((s1 - s2).abs.max).to be < ERR_TOL
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'calculates the singular values of a rectangular real matrix with divide and conquer algorithm' do
|
29
|
+
s1, = described_class.svd(mat_a, driver: 'sdd', job: 'N')
|
30
|
+
s2 = described_class.svdvals(mat_a, driver: 'sdd')
|
31
|
+
expect((s1 - s2).abs.max).to be < ERR_TOL
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'calculates the singular values of a rectangular complex matrix with divide and conquer algorithm' do
|
35
|
+
s1, = described_class.svd(mat_b, driver: 'sdd', job: 'N')
|
36
|
+
s2 = described_class.svdvals(mat_b, driver: 'sdd')
|
37
|
+
expect((s1 - s2).abs.max).to be < ERR_TOL
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'numo/linalg/autoloader'
|
4
|
+
|
5
|
+
ERR_TOL = 1e-6
|
6
|
+
|
7
|
+
def rand_symmetric_mat(n)
|
8
|
+
a = Numo::DFloat.new(n, n).rand
|
9
|
+
0.5 * (a + a.transpose) - 0.5
|
10
|
+
end
|
11
|
+
|
12
|
+
def rand_hermitian_mat(n)
|
13
|
+
a = rand_symmetric_mat(n)
|
14
|
+
b = Numo::DFloat.new(n, n).rand
|
15
|
+
b = 0.5 * (b + b.transpose)
|
16
|
+
b = (b.triu - b.tril)
|
17
|
+
b[b.diag_indices] = 0.0
|
18
|
+
a + b * Complex::I
|
19
|
+
end
|
20
|
+
|
21
|
+
def rand_square_real_mat(m)
|
22
|
+
Numo::DFloat.new(m, m).rand - 0.5
|
23
|
+
end
|
24
|
+
|
25
|
+
def rand_square_complex_mat(m)
|
26
|
+
rand_rect_real_mat(m, m) + Complex::I * (rand_rect_real_mat(m, m) - 0.5)
|
27
|
+
end
|
28
|
+
|
29
|
+
def rand_rect_real_mat(m, n)
|
30
|
+
Numo::DFloat.new(m, n).rand - 0.5
|
31
|
+
end
|
32
|
+
|
33
|
+
def rand_rect_complex_mat(m, n)
|
34
|
+
rand_rect_real_mat(m, n) + Complex::I * (rand_rect_real_mat(m, n) - 0.5)
|
35
|
+
end
|
36
|
+
|
37
|
+
def rand_real_vec(m)
|
38
|
+
Numo::DFloat.new(m).rand - 0.5
|
39
|
+
end
|
40
|
+
|
41
|
+
def rand_complex_vec(m)
|
42
|
+
rand_real_vec(m) + Complex::I * (rand_real_vec(m) - 0.5)
|
43
|
+
end
|
44
|
+
|
45
|
+
RSpec.configure do |config|
|
46
|
+
# Enable flags like --only-failures and --next-failure
|
47
|
+
config.example_status_persistence_file_path = '.rspec_status'
|
48
|
+
|
49
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
50
|
+
config.disable_monkey_patching!
|
51
|
+
|
52
|
+
config.expect_with :rspec do |c|
|
53
|
+
c.syntax = :expect
|
54
|
+
end
|
55
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: numo-linalg
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Masahiro TANAKA
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-
|
12
|
+
date: 2018-08-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -31,14 +31,28 @@ dependencies:
|
|
31
31
|
requirements:
|
32
32
|
- - "~>"
|
33
33
|
- !ruby/object:Gem::Version
|
34
|
-
version: '0'
|
34
|
+
version: '12.0'
|
35
35
|
type: :development
|
36
36
|
prerelease: false
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
38
38
|
requirements:
|
39
39
|
- - "~>"
|
40
40
|
- !ruby/object:Gem::Version
|
41
|
-
version: '0'
|
41
|
+
version: '12.0'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: rspec
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - "~>"
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '3.0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - "~>"
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '3.0'
|
42
56
|
- !ruby/object:Gem::Dependency
|
43
57
|
name: numo-narray
|
44
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -133,6 +147,7 @@ files:
|
|
133
147
|
- ext/numo/linalg/lapack/tmpl/module.c
|
134
148
|
- ext/numo/linalg/lapack/tmpl/syev.c
|
135
149
|
- ext/numo/linalg/lapack/tmpl/sygv.c
|
150
|
+
- ext/numo/linalg/lapack/tmpl/sygvx.c
|
136
151
|
- ext/numo/linalg/lapack/tmpl/trf.c
|
137
152
|
- ext/numo/linalg/mkmf_linalg.rb
|
138
153
|
- ext/numo/linalg/numo_linalg.h
|
@@ -147,7 +162,36 @@ files:
|
|
147
162
|
- lib/numo/linalg/use/openblas.rb
|
148
163
|
- lib/numo/linalg/version.rb
|
149
164
|
- numo-linalg.gemspec
|
150
|
-
- spec/
|
165
|
+
- spec/linalg/autoloader_spec.rb
|
166
|
+
- spec/linalg/function/cho_fact_spec.rb
|
167
|
+
- spec/linalg/function/cho_inv_spec.rb
|
168
|
+
- spec/linalg/function/cho_solve_spec.rb
|
169
|
+
- spec/linalg/function/cholesky_spec.rb
|
170
|
+
- spec/linalg/function/cond_spec.rb
|
171
|
+
- spec/linalg/function/det_spec.rb
|
172
|
+
- spec/linalg/function/dot_spec.rb
|
173
|
+
- spec/linalg/function/eig_spec.rb
|
174
|
+
- spec/linalg/function/eigh_spec.rb
|
175
|
+
- spec/linalg/function/eigvals_spec.rb
|
176
|
+
- spec/linalg/function/eigvalsh_spec.rb
|
177
|
+
- spec/linalg/function/inv_spec.rb
|
178
|
+
- spec/linalg/function/ldl_spec.rb
|
179
|
+
- spec/linalg/function/lstsq_spec.rb
|
180
|
+
- spec/linalg/function/lu_fact_spec.rb
|
181
|
+
- spec/linalg/function/lu_inv_spec.rb
|
182
|
+
- spec/linalg/function/lu_solve_spec.rb
|
183
|
+
- spec/linalg/function/lu_spec.rb
|
184
|
+
- spec/linalg/function/matmul_spec.rb
|
185
|
+
- spec/linalg/function/matrix_power_spec.rb
|
186
|
+
- spec/linalg/function/matrix_rank_spec.rb
|
187
|
+
- spec/linalg/function/norm_spec.rb
|
188
|
+
- spec/linalg/function/pinv_spec.rb
|
189
|
+
- spec/linalg/function/qr_spec.rb
|
190
|
+
- spec/linalg/function/slogdet_spec.rb
|
191
|
+
- spec/linalg/function/solve_spec.rb
|
192
|
+
- spec/linalg/function/svd_spec.rb
|
193
|
+
- spec/linalg/function/svdvals_spec.rb
|
194
|
+
- spec/spec_helper.rb
|
151
195
|
homepage: https://github.com/ruby-numo/numo-linalg
|
152
196
|
licenses:
|
153
197
|
- BSD-3-Clause
|
@@ -173,4 +217,33 @@ signing_key:
|
|
173
217
|
specification_version: 4
|
174
218
|
summary: Ruby/Numo Linear Algebra library with BLAS/LAPACK
|
175
219
|
test_files:
|
176
|
-
- spec/
|
220
|
+
- spec/linalg/autoloader_spec.rb
|
221
|
+
- spec/linalg/function/cho_fact_spec.rb
|
222
|
+
- spec/linalg/function/cho_inv_spec.rb
|
223
|
+
- spec/linalg/function/cho_solve_spec.rb
|
224
|
+
- spec/linalg/function/cholesky_spec.rb
|
225
|
+
- spec/linalg/function/cond_spec.rb
|
226
|
+
- spec/linalg/function/det_spec.rb
|
227
|
+
- spec/linalg/function/dot_spec.rb
|
228
|
+
- spec/linalg/function/eig_spec.rb
|
229
|
+
- spec/linalg/function/eigh_spec.rb
|
230
|
+
- spec/linalg/function/eigvals_spec.rb
|
231
|
+
- spec/linalg/function/eigvalsh_spec.rb
|
232
|
+
- spec/linalg/function/inv_spec.rb
|
233
|
+
- spec/linalg/function/ldl_spec.rb
|
234
|
+
- spec/linalg/function/lstsq_spec.rb
|
235
|
+
- spec/linalg/function/lu_fact_spec.rb
|
236
|
+
- spec/linalg/function/lu_inv_spec.rb
|
237
|
+
- spec/linalg/function/lu_solve_spec.rb
|
238
|
+
- spec/linalg/function/lu_spec.rb
|
239
|
+
- spec/linalg/function/matmul_spec.rb
|
240
|
+
- spec/linalg/function/matrix_power_spec.rb
|
241
|
+
- spec/linalg/function/matrix_rank_spec.rb
|
242
|
+
- spec/linalg/function/norm_spec.rb
|
243
|
+
- spec/linalg/function/pinv_spec.rb
|
244
|
+
- spec/linalg/function/qr_spec.rb
|
245
|
+
- spec/linalg/function/slogdet_spec.rb
|
246
|
+
- spec/linalg/function/solve_spec.rb
|
247
|
+
- spec/linalg/function/svd_spec.rb
|
248
|
+
- spec/linalg/function/svdvals_spec.rb
|
249
|
+
- spec/spec_helper.rb
|
data/spec/lapack_spec.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
require 'numo/narray'
|
2
|
-
require File.join(File.dirname(__FILE__), "../ext/numo/lapack/lapack")
|
3
|
-
#Numo::NArray.debug = true
|
4
|
-
|
5
|
-
RSpec.configure do |config|
|
6
|
-
config.filter_run :focus
|
7
|
-
config.run_all_when_everything_filtered = true
|
8
|
-
end
|
9
|
-
#context :focus=>true do ... end
|
10
|
-
|
11
|
-
describe 'something' do
|
12
|
-
it{expect(Numo::LAPACK).to be_a(Module)}
|
13
|
-
end
|